@samitouri / QOSamiQemu / commits / 4f7b570667

hw/intc/arm_gicv5: Create inbound GPIO lines for SPIs

The GICv5 IRS may have inbound GPIO lines corresponding to SPIs (shared peripheral interrupts). Unlike the GICv3, it does not deal with PPIs (private peripheral interrupts, i.e. per-CPU interrupts): in a GICv5 system those are handled entirely within the CPU interface. The inbound GPIO array is therefore a simple sequence of one GPIO per SPI that this IRS handles. Create the GPIO input array in gicv5_common_init_irqs_and_mmio(). Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Jonathan Cameron <jonathan.cameron@huawei.com> Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org> Message-id: 20260327111700.795099-9-peter.maydell@linaro.org

Peter Maydell committed Mar 27, 2026 at 11:16 UTC 4f7b570667af97fe29df17fd81cc95e3c1b58f4d
4 files changed +20 -1
hw/intc/arm_gicv5.c
+10 -1
@@ -160,6 +160,15 @@ static const MemoryRegionOps config_frame_ops[NUM_GICV5_DOMAINS] = {
160 FRAME_OP_ENTRY(el3, GICV5_ID_EL3),
161 };
162
163 +static void gicv5_set_spi(void *opaque, int irq, int level)
164 +{
165 + /* These irqs are all SPIs; the INTID is irq + s->spi_base */
166 + GICv5Common *cs = ARM_GICV5_COMMON(opaque);
167 + uint32_t spi_id = irq + cs->spi_base;
168 +
169 + trace_gicv5_spi(spi_id, level);
170 +}
171 +
172 static void gicv5_reset_hold(Object *obj, ResetType type)
173 {
174 GICv5 *s = ARM_GICV5(obj);
@@ -196,7 +205,7 @@ static void gicv5_realize(DeviceState *dev, Error **errp)
205 * NS domain.
206 */
207 cs->implemented_domains = (1 << GICV5_ID_NS);
199 - gicv5_common_init_irqs_and_mmio(cs, config_frame_ops);
208 + gicv5_common_init_irqs_and_mmio(cs, gicv5_set_spi, config_frame_ops);
209 }
210
211 static void gicv5_init(Object *obj)
hw/intc/arm_gicv5_common.c
+5
@@ -38,10 +38,15 @@ static const MemoryRegionOps bad_frame_ops = {
38 };
39
40 void gicv5_common_init_irqs_and_mmio(GICv5Common *cs,
41 + qemu_irq_handler handler,
42 const MemoryRegionOps config_ops[NUM_GICV5_DOMAINS])
43 {
44 SysBusDevice *sbd = SYS_BUS_DEVICE(cs);
45
46 + if (cs->spi_irs_range) {
47 + qdev_init_gpio_in(DEVICE(cs), handler, cs->spi_irs_range);
48 + }
49 +
50 for (int i = 0; i < NUM_GICV5_DOMAINS; i++) {
51 g_autofree char *memname = g_strdup_printf("gicv5-irs-%d", i);
52 const MemoryRegionOps *ops = gicv5_domain_implemented(cs, i) ?
hw/intc/trace-events
+1
@@ -232,6 +232,7 @@ gicv5_read(const char *domain, uint64_t offset, uint64_t data, unsigned size) "G
232 gicv5_badread(const char *domain, uint64_t offset, unsigned size) "GICv5 IRS %s config frame read: offset 0x%" PRIx64 " size %u: error"
233 gicv5_write(const char *domain, uint64_t offset, uint64_t data, unsigned size) "GICv5 IRS %s config frame write: offset 0x%" PRIx64 " data 0x%" PRIx64 " size %u"
234 gicv5_badwrite(const char *domain, uint64_t offset, uint64_t data, unsigned size) "GICv5 IRS %s config frame write: offset 0x%" PRIx64 " data 0x%" PRIx64 " size %u: error"
235 +gicv5_spi(uint32_t id, int level) "GICv5 SPI ID %u asserted at level %d"
236
237 # arm_gicv5_common.c
238 gicv5_common_realize(uint32_t irsid, uint32_t num_cpus, uint32_t spi_base, uint32_t spi_irs_range, uint32_t spi_range) "GICv5 IRS realized: IRS ID %u, %u CPUs, SPI base %u, SPI IRS range %u, SPI range %u"
include/hw/intc/arm_gicv5_common.h
+4
@@ -29,6 +29,9 @@
29 * IRS (this is IRS_IDR7.SPI_BASE); default is 0
30 * + QOM property "spi-irs-range": number of SPI INTID.ID managed on this
31 * IRS (this is IRS_IDR6.SPI_IRS_RANGE); defaults to value of spi-range
32 + * + unnamed GPIO inputs: the SPIs handled by this IRS
33 + * (so GPIO input 0 is the SPI with INTID SPI_BASE, input 1 is
34 + * SPI_BASE + 1, and so on up to SPI_BASE + SPI_IRS_RANGE - 1)
35 *
36 * sysbus MMIO regions (in order matching IRS_IDR0.INT_DOM encoding):
37 * - IRS config frame for the Secure Interrupt Domain
@@ -91,6 +94,7 @@ struct GICv5CommonClass {
94 * of MemoryRegionOps structs.
95 */
96 void gicv5_common_init_irqs_and_mmio(GICv5Common *cs,
97 + qemu_irq_handler handler,
98 const MemoryRegionOps ops[NUM_GICV5_DOMAINS]);
99
100 /**