Implement the GIC CDDI system instruction, which deactivates the specified interrupt.
Signed-off-by: Peter Maydell <[email protected]> --- target/arm/tcg/gicv5-cpuif.c | 49 ++++++++++++++++++++++++++++++++++++ target/arm/tcg/trace-events | 1 + 2 files changed, 50 insertions(+) diff --git a/target/arm/tcg/gicv5-cpuif.c b/target/arm/tcg/gicv5-cpuif.c index c830938bdc..02129d5936 100644 --- a/target/arm/tcg/gicv5-cpuif.c +++ b/target/arm/tcg/gicv5-cpuif.c @@ -17,6 +17,9 @@ FIELD(GIC_CDPRI, ID, 0, 24) FIELD(GIC_CDPRI, TYPE, 29, 3) FIELD(GIC_CDPRI, PRIORITY, 35, 5) +FIELD(GIC_CDDI, ID, 0, 24) +FIELD(GIC_CDDI, TYPE, 29, 3) + FIELD(GIC_CDDIS, ID, 0, 24) FIELD(GIC_CDDIS, TYPE, 29, 3) @@ -572,6 +575,47 @@ static void gic_cdeoi_write(CPUARMState *env, const ARMCPRegInfo *ri, *apr &= *apr - 1; } +static void gic_cddi_write(CPUARMState *env, const ARMCPRegInfo *ri, + uint64_t value) +{ + /* + * Clear the Active state of the specified interrupt + * in the current interrupt domain. + */ + GICv5Common *gic = gicv5_get_gic(env); + GICv5Domain domain = gicv5_current_phys_domain(env); + GICv5IntType type = FIELD_EX64(value, GIC_CDDI, TYPE); + uint32_t id = FIELD_EX64(value, GIC_CDDI, ID); + bool virtual = false; + + trace_gicv5_cddi(domain, value); + + switch (type) { + case GICV5_PPI: + { + uint32_t ppireg, ppibit; + + if (id >= GICV5_NUM_PPIS) { + break; + } + + ppireg = id / 64; + ppibit = 1 << (id % 64); + + env->gicv5_cpuif.ppi_active[ppireg] &= ~ppibit; + gic_recalc_ppi_hppi(env); + break; + } + case GICV5_LPI: + case GICV5_SPI: + /* Tell the IRS to deactivate this interrupt */ + gicv5_deactivate(gic, id, domain, type, virtual); + break; + default: + break; + } +} + static const ARMCPRegInfo gicv5_cpuif_reginfo[] = { /* * Barrier: wait until the effects of a cpuif system register @@ -629,6 +673,11 @@ static const ARMCPRegInfo gicv5_cpuif_reginfo[] = { .access = PL1_W, .type = ARM_CP_IO | ARM_CP_NO_RAW, .writefn = gic_cdeoi_write, }, + { .name = "GIC_CDDI", .state = ARM_CP_STATE_AA64, + .opc0 = 1, .opc1 = 0, .crn = 12, .crm = 2, .opc2 = 0, + .access = PL1_W, .type = ARM_CP_IO | ARM_CP_NO_RAW, + .writefn = gic_cddi_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, diff --git a/target/arm/tcg/trace-events b/target/arm/tcg/trace-events index fcb3106a96..c60ce6834e 100644 --- a/target/arm/tcg/trace-events +++ b/target/arm/tcg/trace-events @@ -6,3 +6,4 @@ gicv5_recalc_ppi_hppi(int domain, uint32_t id, uint8_t prio) "domain %d new PPI gicv5_gicr_cdia_fail(int domain, const char *reason) "domain %d CDIA attempt failed: %s" gicv5_gicr_cdia(int domain, uint32_t id) "domain %d CDIA acknowledge of interrupt 0x%x" gicv5_cdeoi(int domain) "domain %d CDEOI performing priority drop" +gicv5_cddi(int domain, uint32_t id) "domain %d CDDI deactivating interrupt ID 0x%x" -- 2.43.0
