Implement the GIC CDDIS, GIC CDEN, GIC CDAFF, GIC CDPEND and GIC CDHM system instructions. These are all simple wrappers around the equivalent gicv5_set_* functions, like GIC CDPRI.
Signed-off-by: Peter Maydell <[email protected]> --- target/arm/tcg/gicv5-cpuif.c | 108 +++++++++++++++++++++++++++++++++++ 1 file changed, 108 insertions(+) diff --git a/target/arm/tcg/gicv5-cpuif.c b/target/arm/tcg/gicv5-cpuif.c index 072b38e785..c426e045d9 100644 --- a/target/arm/tcg/gicv5-cpuif.c +++ b/target/arm/tcg/gicv5-cpuif.c @@ -16,6 +16,25 @@ FIELD(GIC_CDPRI, ID, 0, 24) FIELD(GIC_CDPRI, TYPE, 29, 3) FIELD(GIC_CDPRI, PRIORITY, 35, 5) +FIELD(GIC_CDDIS, ID, 0, 24) +FIELD(GIC_CDDIS, TYPE, 29, 3) + +FIELD(GIC_CDEN, ID, 0, 24) +FIELD(GIC_CDEN, TYPE, 29, 3) + +FIELD(GIC_CDAFF, ID, 0, 24) +FIELD(GIC_CDAFF, IRM, 28, 1) +FIELD(GIC_CDAFF, TYPE, 29, 3) +FIELD(GIC_CDAFF, IAFFID, 32, 16) + +FIELD(GIC_CDPEND, ID, 0, 24) +FIELD(GIC_CDPEND, TYPE, 29, 3) +FIELD(GIC_CDPEND, PENDING, 32, 1) + +FIELD(GIC_CDHM, ID, 0, 24) +FIELD(GIC_CDHM, TYPE, 29, 3) +FIELD(GIC_CDHM, HM, 32, 1) + static GICv5Common *gicv5_get_gic(CPUARMState *env) { return env->gicv5state; @@ -51,6 +70,30 @@ static GICv5Domain gicv5_current_phys_domain(CPUARMState *env) return gicv5_logical_domain(env); } +static void gic_cddis_write(CPUARMState *env, const ARMCPRegInfo *ri, + uint64_t value) +{ + GICv5Common *gic = gicv5_get_gic(env); + GICv5IntType type = FIELD_EX64(value, GIC_CDDIS, TYPE); + uint32_t id = FIELD_EX64(value, GIC_CDDIS, ID); + bool virtual = false; + GICv5Domain domain = gicv5_current_phys_domain(env); + + gicv5_set_enabled(gic, id, false, domain, type, virtual); +} + +static void gic_cden_write(CPUARMState *env, const ARMCPRegInfo *ri, + uint64_t value) +{ + GICv5Common *gic = gicv5_get_gic(env); + GICv5IntType type = FIELD_EX64(value, GIC_CDEN, TYPE); + uint32_t id = FIELD_EX64(value, GIC_CDEN, ID); + bool virtual = false; + GICv5Domain domain = gicv5_current_phys_domain(env); + + gicv5_set_enabled(gic, id, true, domain, type, virtual); +} + static void gic_cdpri_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value) { @@ -64,6 +107,46 @@ static void gic_cdpri_write(CPUARMState *env, const ARMCPRegInfo *ri, gicv5_set_priority(gic, id, priority, domain, type, virtual); } +static void gic_cdaff_write(CPUARMState *env, const ARMCPRegInfo *ri, + uint64_t value) +{ + GICv5Common *gic = gicv5_get_gic(env); + uint32_t iaffid = FIELD_EX64(value, GIC_CDAFF, IAFFID); + GICv5RoutingMode irm = FIELD_EX64(value, GIC_CDAFF, IRM); + GICv5IntType type = FIELD_EX64(value, GIC_CDAFF, TYPE); + uint32_t id = FIELD_EX64(value, GIC_CDAFF, ID); + bool virtual = false; + GICv5Domain domain = gicv5_current_phys_domain(env); + + gicv5_set_target(gic, id, iaffid, irm, domain, type, virtual); +} + +static void gic_cdpend_write(CPUARMState *env, const ARMCPRegInfo *ri, + uint64_t value) +{ + GICv5Common *gic = gicv5_get_gic(env); + bool pending = FIELD_EX64(value, GIC_CDPEND, PENDING); + GICv5IntType type = FIELD_EX64(value, GIC_CDPEND, TYPE); + uint32_t id = FIELD_EX64(value, GIC_CDPEND, ID); + bool virtual = false; + GICv5Domain domain = gicv5_current_phys_domain(env); + + gicv5_set_pending(gic, id, pending, domain, type, virtual); +} + +static void gic_cdhm_write(CPUARMState *env, const ARMCPRegInfo *ri, + uint64_t value) +{ + GICv5Common *gic = gicv5_get_gic(env); + GICv5HandlingMode hm = FIELD_EX64(value, GIC_CDHM, HM); + GICv5IntType type = FIELD_EX64(value, GIC_CDAFF, TYPE); + uint32_t id = FIELD_EX64(value, GIC_CDAFF, ID); + bool virtual = false; + GICv5Domain domain = gicv5_current_phys_domain(env); + + gicv5_set_handling(gic, id, hm, domain, type, virtual); +} + static const ARMCPRegInfo gicv5_cpuif_reginfo[] = { /* * Barrier: wait until the effects of a cpuif system register @@ -86,11 +169,36 @@ static const ARMCPRegInfo gicv5_cpuif_reginfo[] = { .opc0 = 1, .opc1 = 0, .crn = 12, .crm = 0, .opc2 = 1, .access = PL1_W, .type = ARM_CP_NOP, }, + { .name = "GIC_CDDIS", .state = ARM_CP_STATE_AA64, + .opc0 = 1, .opc1 = 0, .crn = 12, .crm = 1, .opc2 = 0, + .access = PL1_W, .type = ARM_CP_IO | ARM_CP_NO_RAW, + .writefn = gic_cddis_write, + }, + { .name = "GIC_CDEN", .state = ARM_CP_STATE_AA64, + .opc0 = 1, .opc1 = 0, .crn = 12, .crm = 1, .opc2 = 1, + .access = PL1_W, .type = ARM_CP_IO | ARM_CP_NO_RAW, + .writefn = gic_cden_write, + }, { .name = "GIC_CDPRI", .state = ARM_CP_STATE_AA64, .opc0 = 1, .opc1 = 0, .crn = 12, .crm = 1, .opc2 = 2, .access = PL1_W, .type = ARM_CP_IO | ARM_CP_NO_RAW, .writefn = gic_cdpri_write, }, + { .name = "GIC_CDAFF", .state = ARM_CP_STATE_AA64, + .opc0 = 1, .opc1 = 0, .crn = 12, .crm = 1, .opc2 = 3, + .access = PL1_W, .type = ARM_CP_IO | ARM_CP_NO_RAW, + .writefn = gic_cdaff_write, + }, + { .name = "GIC_CDPEND", .state = ARM_CP_STATE_AA64, + .opc0 = 1, .opc1 = 0, .crn = 12, .crm = 1, .opc2 = 4, + .access = PL1_W, .type = ARM_CP_IO | ARM_CP_NO_RAW, + .writefn = gic_cdpend_write, + }, + { .name = "GIC_CDHM", .state = ARM_CP_STATE_AA64, + .opc0 = 1, .opc1 = 0, .crn = 12, .crm = 2, .opc2 = 1, + .access = PL1_W, .type = ARM_CP_IO | ARM_CP_NO_RAW, + .writefn = gic_cdhm_write, + }, }; void define_gicv5_cpuif_regs(ARMCPU *cpu) -- 2.43.0
