target/arm: GICv5 cpuif: Implement GIC CDDI
Implement the GIC CDDI system instruction, which deactivates the specified interrupt. Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Jonathan Cameron <jonathan.cameron@huawei.com> Message-id: 20260327111700.795099-52-peter.maydell@linaro.org
Peter Maydell committed
Mar 27, 2026 at 11:16 UTC
49f4c98648c1a693d5f752c7a2411d4904e94bc7
2 files changed
+50
target/arm/tcg/gicv5-cpuif.c
+49
@@ -17,6 +17,9 @@ FIELD(GIC_CDPRI, ID, 0, 24)
17
FIELD(GIC_CDPRI, TYPE, 29, 3)
18
FIELD(GIC_CDPRI, PRIORITY, 35, 5)
19
20
+FIELD(GIC_CDDI, ID, 0, 24)
21
+FIELD(GIC_CDDI, TYPE, 29, 3)
22
+
23
FIELD(GIC_CDDIS, ID, 0, 24)
24
FIELD(GIC_CDDIS, TYPE, 29, 3)
25
@@ -570,6 +573,47 @@ static void gic_cdeoi_write(CPUARMState *env, const ARMCPRegInfo *ri,
573
*apr &= *apr - 1;
574
}
575
576
+static void gic_cddi_write(CPUARMState *env, const ARMCPRegInfo *ri,
577
+ uint64_t value)
578
+{
579
+ /*
580
+ * Clear the Active state of the specified interrupt in the
581
+ * current interrupt domain.
582
+ */
583
+ GICv5Common *gic = gicv5_get_gic(env);
584
+ GICv5Domain domain = gicv5_current_phys_domain(env);
585
+ GICv5IntType type = FIELD_EX64(value, GIC_CDDI, TYPE);
586
+ uint32_t id = FIELD_EX64(value, GIC_CDDI, ID);
587
+ bool virtual = false;
588
+
589
+ trace_gicv5_cddi(domain, value);
590
+
591
+ switch (type) {
592
+ case GICV5_PPI:
593
+ {
594
+ uint32_t ppireg, ppibit;
595
+
596
+ if (id >= GICV5_NUM_PPIS) {
597
+ break;
598
+ }
599
+
600
+ ppireg = id / 64;
601
+ ppibit = 1 << (id % 64);
602
+
603
+ env->gicv5_cpuif.ppi_active[ppireg] &= ~ppibit;
604
+ gic_recalc_ppi_hppi(env);
605
+ break;
606
+ }
607
+ case GICV5_LPI:
608
+ case GICV5_SPI:
609
+ /* Tell the IRS to deactivate this interrupt */
610
+ gicv5_deactivate(gic, id, domain, type, virtual);
611
+ break;
612
+ default:
613
+ break;
614
+ }
615
+}
616
+
617
static const ARMCPRegInfo gicv5_cpuif_reginfo[] = {
618
/*
619
* Barrier: wait until the effects of a cpuif system register
@@ -627,6 +671,11 @@ static const ARMCPRegInfo gicv5_cpuif_reginfo[] = {
671
.access = PL1_W, .type = ARM_CP_IO | ARM_CP_NO_RAW,
672
.writefn = gic_cdeoi_write,
673
},
674
+ { .name = "GIC_CDDI", .state = ARM_CP_STATE_AA64,
675
+ .opc0 = 1, .opc1 = 0, .crn = 12, .crm = 2, .opc2 = 0,
676
+ .access = PL1_W, .type = ARM_CP_IO | ARM_CP_NO_RAW,
677
+ .writefn = gic_cddi_write,
678
+ },
679
{ .name = "GIC_CDHM", .state = ARM_CP_STATE_AA64,
680
.opc0 = 1, .opc1 = 0, .crn = 12, .crm = 2, .opc2 = 1,
681
.access = PL1_W, .type = ARM_CP_IO | ARM_CP_NO_RAW,
target/arm/tcg/trace-events
+1
@@ -6,3 +6,4 @@ gicv5_recalc_ppi_hppi(int domain, uint32_t id, uint8_t prio) "domain %d new PPI
6
gicv5_gicr_cdia_fail(int domain, const char *reason) "domain %d CDIA attempt failed: %s"
7
gicv5_gicr_cdia(int domain, uint32_t id) "domain %d CDIA acknowledge of interrupt 0x%x"
8
gicv5_cdeoi(int domain) "domain %d CDEOI performing priority drop"
9
+gicv5_cddi(int domain, uint32_t id) "domain %d CDDI deactivating interrupt ID 0x%x"