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 <[email protected]> --- hw/intc/arm_gicv5.c | 11 ++++++++++- hw/intc/arm_gicv5_common.c | 5 +++++ hw/intc/trace-events | 1 + include/hw/intc/arm_gicv5_common.h | 4 ++++ 4 files changed, 20 insertions(+), 1 deletion(-) diff --git a/hw/intc/arm_gicv5.c b/hw/intc/arm_gicv5.c index 73a6e629df..7ef48bb450 100644 --- a/hw/intc/arm_gicv5.c +++ b/hw/intc/arm_gicv5.c @@ -181,6 +181,15 @@ static const MemoryRegionOps config_frame_ops[NUM_GICV5_DOMAINS] = { }, }; +static void gicv5_set_spi(void *opaque, int irq, int level) +{ + /* These irqs are all SPIs; the INTID is irq + s->spi_base */ + GICv5Common *cs = ARM_GICV5_COMMON(opaque); + uint32_t spi_id = irq + cs->spi_base; + + trace_gicv5_spi(spi_id, level); +} + static void gicv5_reset_hold(Object *obj, ResetType type) { GICv5 *s = ARM_GICV5(obj); @@ -217,7 +226,7 @@ static void gicv5_realize(DeviceState *dev, Error **errp) * NS domain. */ cs->implemented_domains = (1 << GICV5_ID_NS); - gicv5_common_init_irqs_and_mmio(cs, config_frame_ops); + gicv5_common_init_irqs_and_mmio(cs, gicv5_set_spi, config_frame_ops); } static void gicv5_init(Object *obj) diff --git a/hw/intc/arm_gicv5_common.c b/hw/intc/arm_gicv5_common.c index c8b6704fe4..0f966dfd1b 100644 --- a/hw/intc/arm_gicv5_common.c +++ b/hw/intc/arm_gicv5_common.c @@ -38,10 +38,15 @@ static const MemoryRegionOps bad_frame_ops = { }; void gicv5_common_init_irqs_and_mmio(GICv5Common *cs, + qemu_irq_handler handler, const MemoryRegionOps config_ops[NUM_GICV5_DOMAINS]) { SysBusDevice *sbd = SYS_BUS_DEVICE(cs); + if (cs->spi_irs_range) { + qdev_init_gpio_in(DEVICE(cs), handler, cs->spi_irs_range); + } + for (int i = 0; i < NUM_GICV5_DOMAINS; i++) { g_autofree char *memname = g_strdup_printf("gicv5-irs-%d", i); const MemoryRegionOps *ops = gicv5_domain_implemented(cs, i) ? diff --git a/hw/intc/trace-events b/hw/intc/trace-events index 54777f6da3..0797a23c1a 100644 --- a/hw/intc/trace-events +++ b/hw/intc/trace-events @@ -232,6 +232,7 @@ gicv5_read(const char *domain, uint64_t offset, uint64_t data, unsigned size) "G gicv5_badread(const char *domain, uint64_t offset, unsigned size) "GICv5 IRS %s config frame read: offset 0x%" PRIx64 " size %u: error" 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" 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" +gicv5_spi(uint32_t id, int level) "GICv5 SPI ID %u asserted at level %d" # arm_gicv5_common.c 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" diff --git a/include/hw/intc/arm_gicv5_common.h b/include/hw/intc/arm_gicv5_common.h index b22f020a53..be898abcd5 100644 --- a/include/hw/intc/arm_gicv5_common.h +++ b/include/hw/intc/arm_gicv5_common.h @@ -29,6 +29,9 @@ * IRS (this is IRS_IDR7.SPI_BASE); default is 0 * + QOM property "spi-irs-range": number of SPI INTID.ID managed on this * IRS (this is IRS_IDR6.SPI_IRS_RANGE); defaults to value of spi-range + * + unnamed GPIO inputs: the SPIs handled by this IRS + * (so GPIO input 0 is the SPI with INTID SPI_BASE, input 1 is + * SPI_BASE+1, and so on up to SPI_BASE + SPI_IRS_RANGE - 1) * * sysbus MMIO regions (in order matching IRS_IDR0.INT_DOM encoding): * - IRS config frame for the Secure Interrupt Domain @@ -91,6 +94,7 @@ struct GICv5CommonClass { * of MemoryRegionOps structs. */ void gicv5_common_init_irqs_and_mmio(GICv5Common *cs, + qemu_irq_handler handler, const MemoryRegionOps ops[NUM_GICV5_DOMAINS]); /** -- 2.43.0
