* [PATCH 0/3] hw/arm/xlnx-zynqmp: wire a second GIC for the Cortex-R5
@ 2025-09-30 11:57 Clément Chigot
2025-09-30 11:57 ` [PATCH 1/3] hw/arm/xlnx-zynqmp: move GIC_NUM_SPI_INTR define in header Clément Chigot
` (3 more replies)
0 siblings, 4 replies; 8+ messages in thread
From: Clément Chigot @ 2025-09-30 11:57 UTC (permalink / raw)
To: qemu-devel
Cc: qemu-arm, peter.maydell, edgar.iglesias, alistair,
Clément Chigot
The first two patches are minor improvements before the core third
patch.
This was initially a single patch split as per review comments (see [1])
[1] https://lists.gnu.org/archive/html/qemu-devel/2025-09/msg05899.html
Clément Chigot (2):
hw/arm/xlnx-zynqmp: move GIC_NUM_SPI_INTR define in header
hw/arm/xlnx-zynqmp: introduce helper to compute RPU number
Frederic Konrad (1):
hw/arm/xlnx-zynqmp: wire a second GIC for the Cortex-R5
hw/arm/xlnx-zynqmp.c | 103 +++++++++++++++++++++++++++++++----
include/hw/arm/xlnx-zynqmp.h | 5 ++
2 files changed, 98 insertions(+), 10 deletions(-)
--
2.34.1
^ permalink raw reply [flat|nested] 8+ messages in thread* [PATCH 1/3] hw/arm/xlnx-zynqmp: move GIC_NUM_SPI_INTR define in header 2025-09-30 11:57 [PATCH 0/3] hw/arm/xlnx-zynqmp: wire a second GIC for the Cortex-R5 Clément Chigot @ 2025-09-30 11:57 ` Clément Chigot 2025-10-02 7:33 ` Edgar E. Iglesias 2025-09-30 11:57 ` [PATCH 2/3] hw/arm/xlnx-zynqmp: introduce helper to compute RPU number Clément Chigot ` (2 subsequent siblings) 3 siblings, 1 reply; 8+ messages in thread From: Clément Chigot @ 2025-09-30 11:57 UTC (permalink / raw) To: qemu-devel Cc: qemu-arm, peter.maydell, edgar.iglesias, alistair, Clément Chigot This define will be needed in a later patch in XlnxZynqMPState structure, hence move it within xlnx-zynqmp header. Add XLXN_ZYNQMP prefix as it's now public. Signed-off-by: Clément Chigot <chigot@adacore.com> --- hw/arm/xlnx-zynqmp.c | 11 +++++------ include/hw/arm/xlnx-zynqmp.h | 1 + 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/hw/arm/xlnx-zynqmp.c b/hw/arm/xlnx-zynqmp.c index ec96a46eec..d7adc070f8 100644 --- a/hw/arm/xlnx-zynqmp.c +++ b/hw/arm/xlnx-zynqmp.c @@ -26,8 +26,6 @@ #include "target/arm/cpu-qom.h" #include "target/arm/gtimer.h" -#define GIC_NUM_SPI_INTR 160 - #define ARM_PHYS_TIMER_PPI 30 #define ARM_VIRT_TIMER_PPI 27 #define ARM_HYP_TIMER_PPI 26 @@ -206,7 +204,7 @@ static const XlnxZynqMPGICRegion xlnx_zynqmp_gic_regions[] = { static inline int arm_gic_ppi_index(int cpu_nr, int ppi_index) { - return GIC_NUM_SPI_INTR + cpu_nr * GIC_INTERNAL + ppi_index; + return XLNX_ZYNQMP_GIC_NUM_SPI_INTR + cpu_nr * GIC_INTERNAL + ppi_index; } static void xlnx_zynqmp_create_rpu(MachineState *ms, XlnxZynqMPState *s, @@ -454,7 +452,7 @@ static void xlnx_zynqmp_realize(DeviceState *dev, Error **errp) int num_apus = MIN(ms->smp.cpus, XLNX_ZYNQMP_NUM_APU_CPUS); const char *boot_cpu = s->boot_cpu ? s->boot_cpu : "apu-cpu[0]"; ram_addr_t ddr_low_size, ddr_high_size; - qemu_irq gic_spi[GIC_NUM_SPI_INTR]; + qemu_irq gic_spi[XLNX_ZYNQMP_GIC_NUM_SPI_INTR]; Error *err = NULL; ram_size = memory_region_size(s->ddr_ram); @@ -502,7 +500,8 @@ static void xlnx_zynqmp_realize(DeviceState *dev, Error **errp) g_free(ocm_name); } - qdev_prop_set_uint32(DEVICE(&s->gic), "num-irq", GIC_NUM_SPI_INTR + 32); + qdev_prop_set_uint32(DEVICE(&s->gic), "num-irq", + XLNX_ZYNQMP_GIC_NUM_SPI_INTR + 32); qdev_prop_set_uint32(DEVICE(&s->gic), "revision", 2); qdev_prop_set_uint32(DEVICE(&s->gic), "num-cpu", num_apus); qdev_prop_set_bit(DEVICE(&s->gic), "has-security-extensions", s->secure); @@ -613,7 +612,7 @@ static void xlnx_zynqmp_realize(DeviceState *dev, Error **errp) return; } - for (i = 0; i < GIC_NUM_SPI_INTR; i++) { + for (i = 0; i < XLNX_ZYNQMP_GIC_NUM_SPI_INTR; i++) { gic_spi[i] = qdev_get_gpio_in(DEVICE(&s->gic), i); } diff --git a/include/hw/arm/xlnx-zynqmp.h b/include/hw/arm/xlnx-zynqmp.h index c137ac59e8..6a407c2962 100644 --- a/include/hw/arm/xlnx-zynqmp.h +++ b/include/hw/arm/xlnx-zynqmp.h @@ -67,6 +67,7 @@ OBJECT_DECLARE_SIMPLE_TYPE(XlnxZynqMPState, XLNX_ZYNQMP) #define XLNX_ZYNQMP_OCM_RAM_SIZE 0x10000 #define XLNX_ZYNQMP_GIC_REGIONS 6 +#define XLNX_ZYNQMP_GIC_NUM_SPI_INTR 160 /* * ZynqMP maps the ARM GIC regions (GICC, GICD ...) at consecutive 64k offsets -- 2.34.1 ^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH 1/3] hw/arm/xlnx-zynqmp: move GIC_NUM_SPI_INTR define in header 2025-09-30 11:57 ` [PATCH 1/3] hw/arm/xlnx-zynqmp: move GIC_NUM_SPI_INTR define in header Clément Chigot @ 2025-10-02 7:33 ` Edgar E. Iglesias 0 siblings, 0 replies; 8+ messages in thread From: Edgar E. Iglesias @ 2025-10-02 7:33 UTC (permalink / raw) To: Clément Chigot; +Cc: qemu-devel, qemu-arm, peter.maydell, alistair On Tue, Sep 30, 2025 at 01:57:16PM +0200, Clément Chigot wrote: > This define will be needed in a later patch in XlnxZynqMPState > structure, hence move it within xlnx-zynqmp header. > > Add XLXN_ZYNQMP prefix as it's now public. > > Signed-off-by: Clément Chigot <chigot@adacore.com> Reviewed-by: Edgar E. Iglesias <edgar.iglesias@amd.com> > --- > hw/arm/xlnx-zynqmp.c | 11 +++++------ > include/hw/arm/xlnx-zynqmp.h | 1 + > 2 files changed, 6 insertions(+), 6 deletions(-) > > diff --git a/hw/arm/xlnx-zynqmp.c b/hw/arm/xlnx-zynqmp.c > index ec96a46eec..d7adc070f8 100644 > --- a/hw/arm/xlnx-zynqmp.c > +++ b/hw/arm/xlnx-zynqmp.c > @@ -26,8 +26,6 @@ > #include "target/arm/cpu-qom.h" > #include "target/arm/gtimer.h" > > -#define GIC_NUM_SPI_INTR 160 > - > #define ARM_PHYS_TIMER_PPI 30 > #define ARM_VIRT_TIMER_PPI 27 > #define ARM_HYP_TIMER_PPI 26 > @@ -206,7 +204,7 @@ static const XlnxZynqMPGICRegion xlnx_zynqmp_gic_regions[] = { > > static inline int arm_gic_ppi_index(int cpu_nr, int ppi_index) > { > - return GIC_NUM_SPI_INTR + cpu_nr * GIC_INTERNAL + ppi_index; > + return XLNX_ZYNQMP_GIC_NUM_SPI_INTR + cpu_nr * GIC_INTERNAL + ppi_index; > } > > static void xlnx_zynqmp_create_rpu(MachineState *ms, XlnxZynqMPState *s, > @@ -454,7 +452,7 @@ static void xlnx_zynqmp_realize(DeviceState *dev, Error **errp) > int num_apus = MIN(ms->smp.cpus, XLNX_ZYNQMP_NUM_APU_CPUS); > const char *boot_cpu = s->boot_cpu ? s->boot_cpu : "apu-cpu[0]"; > ram_addr_t ddr_low_size, ddr_high_size; > - qemu_irq gic_spi[GIC_NUM_SPI_INTR]; > + qemu_irq gic_spi[XLNX_ZYNQMP_GIC_NUM_SPI_INTR]; > Error *err = NULL; > > ram_size = memory_region_size(s->ddr_ram); > @@ -502,7 +500,8 @@ static void xlnx_zynqmp_realize(DeviceState *dev, Error **errp) > g_free(ocm_name); > } > > - qdev_prop_set_uint32(DEVICE(&s->gic), "num-irq", GIC_NUM_SPI_INTR + 32); > + qdev_prop_set_uint32(DEVICE(&s->gic), "num-irq", > + XLNX_ZYNQMP_GIC_NUM_SPI_INTR + 32); > qdev_prop_set_uint32(DEVICE(&s->gic), "revision", 2); > qdev_prop_set_uint32(DEVICE(&s->gic), "num-cpu", num_apus); > qdev_prop_set_bit(DEVICE(&s->gic), "has-security-extensions", s->secure); > @@ -613,7 +612,7 @@ static void xlnx_zynqmp_realize(DeviceState *dev, Error **errp) > return; > } > > - for (i = 0; i < GIC_NUM_SPI_INTR; i++) { > + for (i = 0; i < XLNX_ZYNQMP_GIC_NUM_SPI_INTR; i++) { > gic_spi[i] = qdev_get_gpio_in(DEVICE(&s->gic), i); > } > > diff --git a/include/hw/arm/xlnx-zynqmp.h b/include/hw/arm/xlnx-zynqmp.h > index c137ac59e8..6a407c2962 100644 > --- a/include/hw/arm/xlnx-zynqmp.h > +++ b/include/hw/arm/xlnx-zynqmp.h > @@ -67,6 +67,7 @@ OBJECT_DECLARE_SIMPLE_TYPE(XlnxZynqMPState, XLNX_ZYNQMP) > #define XLNX_ZYNQMP_OCM_RAM_SIZE 0x10000 > > #define XLNX_ZYNQMP_GIC_REGIONS 6 > +#define XLNX_ZYNQMP_GIC_NUM_SPI_INTR 160 > > /* > * ZynqMP maps the ARM GIC regions (GICC, GICD ...) at consecutive 64k offsets > -- > 2.34.1 > ^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH 2/3] hw/arm/xlnx-zynqmp: introduce helper to compute RPU number 2025-09-30 11:57 [PATCH 0/3] hw/arm/xlnx-zynqmp: wire a second GIC for the Cortex-R5 Clément Chigot 2025-09-30 11:57 ` [PATCH 1/3] hw/arm/xlnx-zynqmp: move GIC_NUM_SPI_INTR define in header Clément Chigot @ 2025-09-30 11:57 ` Clément Chigot 2025-10-02 7:35 ` Edgar E. Iglesias 2025-09-30 11:57 ` [PATCH 3/3] hw/arm/xlnx-zynqmp: wire a second GIC for the Cortex-R5 Clément Chigot 2025-10-07 9:50 ` [PATCH 0/3] " Peter Maydell 3 siblings, 1 reply; 8+ messages in thread From: Clément Chigot @ 2025-09-30 11:57 UTC (permalink / raw) To: qemu-devel Cc: qemu-arm, peter.maydell, edgar.iglesias, alistair, Clément Chigot This helper will avoid repeating the MIN/MAX formula everytime the number of RPUs available is requested. Signed-off-by: Clément Chigot <chigot@adacore.com> --- hw/arm/xlnx-zynqmp.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/hw/arm/xlnx-zynqmp.c b/hw/arm/xlnx-zynqmp.c index d7adc070f8..3d8c46986e 100644 --- a/hw/arm/xlnx-zynqmp.c +++ b/hw/arm/xlnx-zynqmp.c @@ -207,14 +207,23 @@ static inline int arm_gic_ppi_index(int cpu_nr, int ppi_index) return XLNX_ZYNQMP_GIC_NUM_SPI_INTR + cpu_nr * GIC_INTERNAL + ppi_index; } +static unsigned int xlnx_zynqmp_get_rpu_number(MachineState *ms) +{ + /* + * RPUs will be created only if "-smp" is higher than the maximum + * of APUs. Round it up to 0 to avoid dealing with negative values. + */ + return MAX(0, MIN((int)(ms->smp.cpus - XLNX_ZYNQMP_NUM_APU_CPUS), + XLNX_ZYNQMP_NUM_RPU_CPUS)); +} + static void xlnx_zynqmp_create_rpu(MachineState *ms, XlnxZynqMPState *s, const char *boot_cpu, Error **errp) { int i; - int num_rpus = MIN((int)(ms->smp.cpus - XLNX_ZYNQMP_NUM_APU_CPUS), - XLNX_ZYNQMP_NUM_RPU_CPUS); + int num_rpus = xlnx_zynqmp_get_rpu_number(ms); - if (num_rpus <= 0) { + if (!num_rpus) { /* Don't create rpu-cluster object if there's nothing to put in it */ return; } -- 2.34.1 ^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH 2/3] hw/arm/xlnx-zynqmp: introduce helper to compute RPU number 2025-09-30 11:57 ` [PATCH 2/3] hw/arm/xlnx-zynqmp: introduce helper to compute RPU number Clément Chigot @ 2025-10-02 7:35 ` Edgar E. Iglesias 0 siblings, 0 replies; 8+ messages in thread From: Edgar E. Iglesias @ 2025-10-02 7:35 UTC (permalink / raw) To: Clément Chigot; +Cc: qemu-devel, qemu-arm, peter.maydell, alistair On Tue, Sep 30, 2025 at 01:57:17PM +0200, Clément Chigot wrote: > This helper will avoid repeating the MIN/MAX formula everytime the > number of RPUs available is requested. > > Signed-off-by: Clément Chigot <chigot@adacore.com> Reviewed-by: Edgar E. Iglesias <edgar.iglesias@amd.com> > --- > hw/arm/xlnx-zynqmp.c | 15 ++++++++++++--- > 1 file changed, 12 insertions(+), 3 deletions(-) > > diff --git a/hw/arm/xlnx-zynqmp.c b/hw/arm/xlnx-zynqmp.c > index d7adc070f8..3d8c46986e 100644 > --- a/hw/arm/xlnx-zynqmp.c > +++ b/hw/arm/xlnx-zynqmp.c > @@ -207,14 +207,23 @@ static inline int arm_gic_ppi_index(int cpu_nr, int ppi_index) > return XLNX_ZYNQMP_GIC_NUM_SPI_INTR + cpu_nr * GIC_INTERNAL + ppi_index; > } > > +static unsigned int xlnx_zynqmp_get_rpu_number(MachineState *ms) > +{ > + /* > + * RPUs will be created only if "-smp" is higher than the maximum > + * of APUs. Round it up to 0 to avoid dealing with negative values. > + */ > + return MAX(0, MIN((int)(ms->smp.cpus - XLNX_ZYNQMP_NUM_APU_CPUS), > + XLNX_ZYNQMP_NUM_RPU_CPUS)); > +} > + > static void xlnx_zynqmp_create_rpu(MachineState *ms, XlnxZynqMPState *s, > const char *boot_cpu, Error **errp) > { > int i; > - int num_rpus = MIN((int)(ms->smp.cpus - XLNX_ZYNQMP_NUM_APU_CPUS), > - XLNX_ZYNQMP_NUM_RPU_CPUS); > + int num_rpus = xlnx_zynqmp_get_rpu_number(ms); > > - if (num_rpus <= 0) { > + if (!num_rpus) { > /* Don't create rpu-cluster object if there's nothing to put in it */ > return; > } > -- > 2.34.1 > ^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH 3/3] hw/arm/xlnx-zynqmp: wire a second GIC for the Cortex-R5 2025-09-30 11:57 [PATCH 0/3] hw/arm/xlnx-zynqmp: wire a second GIC for the Cortex-R5 Clément Chigot 2025-09-30 11:57 ` [PATCH 1/3] hw/arm/xlnx-zynqmp: move GIC_NUM_SPI_INTR define in header Clément Chigot 2025-09-30 11:57 ` [PATCH 2/3] hw/arm/xlnx-zynqmp: introduce helper to compute RPU number Clément Chigot @ 2025-09-30 11:57 ` Clément Chigot 2025-10-02 7:36 ` Edgar E. Iglesias 2025-10-07 9:50 ` [PATCH 0/3] " Peter Maydell 3 siblings, 1 reply; 8+ messages in thread From: Clément Chigot @ 2025-09-30 11:57 UTC (permalink / raw) To: qemu-devel Cc: qemu-arm, peter.maydell, edgar.iglesias, alistair, Frederic Konrad, Clément Chigot From: Frederic Konrad <konrad.frederic@yahoo.fr> This wires a second GIC for the Cortex-R5, all the IRQs are split when there is an RPU instanciated. Signed-off-by: Clément Chigot <chigot@adacore.com> --- hw/arm/xlnx-zynqmp.c | 77 +++++++++++++++++++++++++++++++++++- include/hw/arm/xlnx-zynqmp.h | 4 ++ 2 files changed, 80 insertions(+), 1 deletion(-) diff --git a/hw/arm/xlnx-zynqmp.c b/hw/arm/xlnx-zynqmp.c index 3d8c46986e..ffed6e5126 100644 --- a/hw/arm/xlnx-zynqmp.c +++ b/hw/arm/xlnx-zynqmp.c @@ -384,6 +384,7 @@ static void xlnx_zynqmp_init(Object *obj) XlnxZynqMPState *s = XLNX_ZYNQMP(obj); int i; int num_apus = MIN(ms->smp.cpus, XLNX_ZYNQMP_NUM_APU_CPUS); + int num_rpus = xlnx_zynqmp_get_rpu_number(ms); object_initialize_child(obj, "apu-cluster", &s->apu_cluster, TYPE_CPU_CLUSTER); @@ -397,6 +398,12 @@ static void xlnx_zynqmp_init(Object *obj) object_initialize_child(obj, "gic", &s->gic, gic_class_name()); + if (num_rpus) { + /* Do not create the rpu_gic if we don't have rpus */ + object_initialize_child(obj, "rpu_gic", &s->rpu_gic, + gic_class_name()); + } + for (i = 0; i < XLNX_ZYNQMP_NUM_GEMS; i++) { object_initialize_child(obj, "gem[*]", &s->gem[i], TYPE_CADENCE_GEM); object_initialize_child(obj, "gem-irq-orgate[*]", @@ -446,6 +453,15 @@ static void xlnx_zynqmp_init(Object *obj) object_initialize_child(obj, "qspi-irq-orgate", &s->qspi_irq_orgate, TYPE_OR_IRQ); + if (num_rpus) { + for (i = 0; i < ARRAY_SIZE(s->splitter); i++) { + g_autofree char *name = g_strdup_printf("irq-splitter%d", i); + object_initialize_child(obj, name, &s->splitter[i], TYPE_SPLIT_IRQ); + } + } + + + for (i = 0; i < XLNX_ZYNQMP_NUM_USB; i++) { object_initialize_child(obj, "usb[*]", &s->usb[i], TYPE_USB_DWC3); } @@ -459,6 +475,7 @@ static void xlnx_zynqmp_realize(DeviceState *dev, Error **errp) uint8_t i; uint64_t ram_size; int num_apus = MIN(ms->smp.cpus, XLNX_ZYNQMP_NUM_APU_CPUS); + int num_rpus = xlnx_zynqmp_get_rpu_number(ms); const char *boot_cpu = s->boot_cpu ? s->boot_cpu : "apu-cpu[0]"; ram_addr_t ddr_low_size, ddr_high_size; qemu_irq gic_spi[XLNX_ZYNQMP_GIC_NUM_SPI_INTR]; @@ -517,6 +534,14 @@ static void xlnx_zynqmp_realize(DeviceState *dev, Error **errp) qdev_prop_set_bit(DEVICE(&s->gic), "has-virtualization-extensions", s->virt); + if (num_rpus) { + qdev_prop_set_uint32(DEVICE(&s->rpu_gic), "num-irq", + XLNX_ZYNQMP_GIC_NUM_SPI_INTR + 32); + qdev_prop_set_uint32(DEVICE(&s->rpu_gic), "revision", 1); + qdev_prop_set_uint32(DEVICE(&s->rpu_gic), "num-cpu", num_rpus); + qdev_prop_set_uint32(DEVICE(&s->rpu_gic), "first-cpu-index", 4); + } + qdev_realize(DEVICE(&s->apu_cluster), NULL, &error_fatal); /* Realize APUs before realizing the GIC. KVM requires this. */ @@ -616,13 +641,63 @@ static void xlnx_zynqmp_realize(DeviceState *dev, Error **errp) return; } + if (num_rpus) { + if (!sysbus_realize(SYS_BUS_DEVICE(&s->rpu_gic), errp)) { + return; + } + + for (i = 0; i < num_rpus; i++) { + qemu_irq irq; + + sysbus_mmio_map(SYS_BUS_DEVICE(&s->rpu_gic), i + 1, + GIC_BASE_ADDR + i * 0x1000); + sysbus_connect_irq(SYS_BUS_DEVICE(&s->rpu_gic), i, + qdev_get_gpio_in(DEVICE(&s->rpu_cpu[i]), + ARM_CPU_IRQ)); + sysbus_connect_irq(SYS_BUS_DEVICE(&s->rpu_gic), i + num_rpus, + qdev_get_gpio_in(DEVICE(&s->rpu_cpu[i]), + ARM_CPU_FIQ)); + sysbus_connect_irq(SYS_BUS_DEVICE(&s->rpu_gic), i + num_rpus * 2, + qdev_get_gpio_in(DEVICE(&s->rpu_cpu[i]), + ARM_CPU_VIRQ)); + sysbus_connect_irq(SYS_BUS_DEVICE(&s->rpu_gic), i + num_rpus * 3, + qdev_get_gpio_in(DEVICE(&s->rpu_cpu[i]), + ARM_CPU_VFIQ)); + irq = qdev_get_gpio_in(DEVICE(&s->rpu_gic), + arm_gic_ppi_index(i, ARM_PHYS_TIMER_PPI)); + qdev_connect_gpio_out(DEVICE(&s->rpu_cpu[i]), GTIMER_PHYS, irq); + irq = qdev_get_gpio_in(DEVICE(&s->rpu_gic), + arm_gic_ppi_index(i, ARM_VIRT_TIMER_PPI)); + qdev_connect_gpio_out(DEVICE(&s->rpu_cpu[i]), GTIMER_VIRT, irq); + irq = qdev_get_gpio_in(DEVICE(&s->rpu_gic), + arm_gic_ppi_index(i, ARM_HYP_TIMER_PPI)); + qdev_connect_gpio_out(DEVICE(&s->rpu_cpu[i]), GTIMER_HYP, irq); + irq = qdev_get_gpio_in(DEVICE(&s->rpu_gic), + arm_gic_ppi_index(i, ARM_SEC_TIMER_PPI)); + qdev_connect_gpio_out(DEVICE(&s->rpu_cpu[i]), GTIMER_SEC, irq); + } + + sysbus_mmio_map(SYS_BUS_DEVICE(&s->rpu_gic), 0, GIC_BASE_ADDR); + } + if (!s->boot_cpu_ptr) { error_setg(errp, "ZynqMP Boot cpu %s not found", boot_cpu); return; } for (i = 0; i < XLNX_ZYNQMP_GIC_NUM_SPI_INTR; i++) { - gic_spi[i] = qdev_get_gpio_in(DEVICE(&s->gic), i); + if (num_rpus) { + DeviceState *splitter = DEVICE(&s->splitter[i]); + qdev_prop_set_uint16(splitter, "num-lines", 2); + qdev_realize(splitter, NULL, &error_abort); + gic_spi[i] = qdev_get_gpio_in(splitter, 0); + qdev_connect_gpio_out(splitter, 0, + qdev_get_gpio_in(DEVICE(&s->gic), i)); + qdev_connect_gpio_out(splitter, 1, + qdev_get_gpio_in(DEVICE(&s->rpu_gic), i)); + } else { + gic_spi[i] = qdev_get_gpio_in(DEVICE(&s->gic), i); + } } for (i = 0; i < XLNX_ZYNQMP_NUM_GEMS; i++) { diff --git a/include/hw/arm/xlnx-zynqmp.h b/include/hw/arm/xlnx-zynqmp.h index 6a407c2962..a3117bd6c5 100644 --- a/include/hw/arm/xlnx-zynqmp.h +++ b/include/hw/arm/xlnx-zynqmp.h @@ -42,6 +42,7 @@ #include "hw/misc/xlnx-zynqmp-crf.h" #include "hw/timer/cadence_ttc.h" #include "hw/usb/hcd-dwc3.h" +#include "hw/core/split-irq.h" #define TYPE_XLNX_ZYNQMP "xlnx-zynqmp" OBJECT_DECLARE_SIMPLE_TYPE(XlnxZynqMPState, XLNX_ZYNQMP) @@ -106,6 +107,9 @@ struct XlnxZynqMPState { GICState gic; MemoryRegion gic_mr[XLNX_ZYNQMP_GIC_REGIONS][XLNX_ZYNQMP_GIC_ALIASES]; + GICState rpu_gic; + SplitIRQ splitter[XLNX_ZYNQMP_GIC_NUM_SPI_INTR]; + MemoryRegion ocm_ram[XLNX_ZYNQMP_NUM_OCM_BANKS]; MemoryRegion *ddr_ram; -- 2.34.1 ^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH 3/3] hw/arm/xlnx-zynqmp: wire a second GIC for the Cortex-R5 2025-09-30 11:57 ` [PATCH 3/3] hw/arm/xlnx-zynqmp: wire a second GIC for the Cortex-R5 Clément Chigot @ 2025-10-02 7:36 ` Edgar E. Iglesias 0 siblings, 0 replies; 8+ messages in thread From: Edgar E. Iglesias @ 2025-10-02 7:36 UTC (permalink / raw) To: Clément Chigot Cc: qemu-devel, qemu-arm, peter.maydell, alistair, Frederic Konrad On Tue, Sep 30, 2025 at 01:57:18PM +0200, Clément Chigot wrote: > From: Frederic Konrad <konrad.frederic@yahoo.fr> > > This wires a second GIC for the Cortex-R5, all the IRQs are split when there > is an RPU instanciated. > > Signed-off-by: Clément Chigot <chigot@adacore.com> Acked-by: Edgar E. Iglesias <edgar.iglesias@amd.com> > --- > hw/arm/xlnx-zynqmp.c | 77 +++++++++++++++++++++++++++++++++++- > include/hw/arm/xlnx-zynqmp.h | 4 ++ > 2 files changed, 80 insertions(+), 1 deletion(-) > > diff --git a/hw/arm/xlnx-zynqmp.c b/hw/arm/xlnx-zynqmp.c > index 3d8c46986e..ffed6e5126 100644 > --- a/hw/arm/xlnx-zynqmp.c > +++ b/hw/arm/xlnx-zynqmp.c > @@ -384,6 +384,7 @@ static void xlnx_zynqmp_init(Object *obj) > XlnxZynqMPState *s = XLNX_ZYNQMP(obj); > int i; > int num_apus = MIN(ms->smp.cpus, XLNX_ZYNQMP_NUM_APU_CPUS); > + int num_rpus = xlnx_zynqmp_get_rpu_number(ms); > > object_initialize_child(obj, "apu-cluster", &s->apu_cluster, > TYPE_CPU_CLUSTER); > @@ -397,6 +398,12 @@ static void xlnx_zynqmp_init(Object *obj) > > object_initialize_child(obj, "gic", &s->gic, gic_class_name()); > > + if (num_rpus) { > + /* Do not create the rpu_gic if we don't have rpus */ > + object_initialize_child(obj, "rpu_gic", &s->rpu_gic, > + gic_class_name()); > + } > + > for (i = 0; i < XLNX_ZYNQMP_NUM_GEMS; i++) { > object_initialize_child(obj, "gem[*]", &s->gem[i], TYPE_CADENCE_GEM); > object_initialize_child(obj, "gem-irq-orgate[*]", > @@ -446,6 +453,15 @@ static void xlnx_zynqmp_init(Object *obj) > object_initialize_child(obj, "qspi-irq-orgate", > &s->qspi_irq_orgate, TYPE_OR_IRQ); > > + if (num_rpus) { > + for (i = 0; i < ARRAY_SIZE(s->splitter); i++) { > + g_autofree char *name = g_strdup_printf("irq-splitter%d", i); > + object_initialize_child(obj, name, &s->splitter[i], TYPE_SPLIT_IRQ); > + } > + } > + > + > + > for (i = 0; i < XLNX_ZYNQMP_NUM_USB; i++) { > object_initialize_child(obj, "usb[*]", &s->usb[i], TYPE_USB_DWC3); > } > @@ -459,6 +475,7 @@ static void xlnx_zynqmp_realize(DeviceState *dev, Error **errp) > uint8_t i; > uint64_t ram_size; > int num_apus = MIN(ms->smp.cpus, XLNX_ZYNQMP_NUM_APU_CPUS); > + int num_rpus = xlnx_zynqmp_get_rpu_number(ms); > const char *boot_cpu = s->boot_cpu ? s->boot_cpu : "apu-cpu[0]"; > ram_addr_t ddr_low_size, ddr_high_size; > qemu_irq gic_spi[XLNX_ZYNQMP_GIC_NUM_SPI_INTR]; > @@ -517,6 +534,14 @@ static void xlnx_zynqmp_realize(DeviceState *dev, Error **errp) > qdev_prop_set_bit(DEVICE(&s->gic), > "has-virtualization-extensions", s->virt); > > + if (num_rpus) { > + qdev_prop_set_uint32(DEVICE(&s->rpu_gic), "num-irq", > + XLNX_ZYNQMP_GIC_NUM_SPI_INTR + 32); > + qdev_prop_set_uint32(DEVICE(&s->rpu_gic), "revision", 1); > + qdev_prop_set_uint32(DEVICE(&s->rpu_gic), "num-cpu", num_rpus); > + qdev_prop_set_uint32(DEVICE(&s->rpu_gic), "first-cpu-index", 4); > + } > + > qdev_realize(DEVICE(&s->apu_cluster), NULL, &error_fatal); > > /* Realize APUs before realizing the GIC. KVM requires this. */ > @@ -616,13 +641,63 @@ static void xlnx_zynqmp_realize(DeviceState *dev, Error **errp) > return; > } > > + if (num_rpus) { > + if (!sysbus_realize(SYS_BUS_DEVICE(&s->rpu_gic), errp)) { > + return; > + } > + > + for (i = 0; i < num_rpus; i++) { > + qemu_irq irq; > + > + sysbus_mmio_map(SYS_BUS_DEVICE(&s->rpu_gic), i + 1, > + GIC_BASE_ADDR + i * 0x1000); > + sysbus_connect_irq(SYS_BUS_DEVICE(&s->rpu_gic), i, > + qdev_get_gpio_in(DEVICE(&s->rpu_cpu[i]), > + ARM_CPU_IRQ)); > + sysbus_connect_irq(SYS_BUS_DEVICE(&s->rpu_gic), i + num_rpus, > + qdev_get_gpio_in(DEVICE(&s->rpu_cpu[i]), > + ARM_CPU_FIQ)); > + sysbus_connect_irq(SYS_BUS_DEVICE(&s->rpu_gic), i + num_rpus * 2, > + qdev_get_gpio_in(DEVICE(&s->rpu_cpu[i]), > + ARM_CPU_VIRQ)); > + sysbus_connect_irq(SYS_BUS_DEVICE(&s->rpu_gic), i + num_rpus * 3, > + qdev_get_gpio_in(DEVICE(&s->rpu_cpu[i]), > + ARM_CPU_VFIQ)); > + irq = qdev_get_gpio_in(DEVICE(&s->rpu_gic), > + arm_gic_ppi_index(i, ARM_PHYS_TIMER_PPI)); > + qdev_connect_gpio_out(DEVICE(&s->rpu_cpu[i]), GTIMER_PHYS, irq); > + irq = qdev_get_gpio_in(DEVICE(&s->rpu_gic), > + arm_gic_ppi_index(i, ARM_VIRT_TIMER_PPI)); > + qdev_connect_gpio_out(DEVICE(&s->rpu_cpu[i]), GTIMER_VIRT, irq); > + irq = qdev_get_gpio_in(DEVICE(&s->rpu_gic), > + arm_gic_ppi_index(i, ARM_HYP_TIMER_PPI)); > + qdev_connect_gpio_out(DEVICE(&s->rpu_cpu[i]), GTIMER_HYP, irq); > + irq = qdev_get_gpio_in(DEVICE(&s->rpu_gic), > + arm_gic_ppi_index(i, ARM_SEC_TIMER_PPI)); > + qdev_connect_gpio_out(DEVICE(&s->rpu_cpu[i]), GTIMER_SEC, irq); > + } > + > + sysbus_mmio_map(SYS_BUS_DEVICE(&s->rpu_gic), 0, GIC_BASE_ADDR); > + } > + > if (!s->boot_cpu_ptr) { > error_setg(errp, "ZynqMP Boot cpu %s not found", boot_cpu); > return; > } > > for (i = 0; i < XLNX_ZYNQMP_GIC_NUM_SPI_INTR; i++) { > - gic_spi[i] = qdev_get_gpio_in(DEVICE(&s->gic), i); > + if (num_rpus) { > + DeviceState *splitter = DEVICE(&s->splitter[i]); > + qdev_prop_set_uint16(splitter, "num-lines", 2); > + qdev_realize(splitter, NULL, &error_abort); > + gic_spi[i] = qdev_get_gpio_in(splitter, 0); > + qdev_connect_gpio_out(splitter, 0, > + qdev_get_gpio_in(DEVICE(&s->gic), i)); > + qdev_connect_gpio_out(splitter, 1, > + qdev_get_gpio_in(DEVICE(&s->rpu_gic), i)); > + } else { > + gic_spi[i] = qdev_get_gpio_in(DEVICE(&s->gic), i); > + } > } > > for (i = 0; i < XLNX_ZYNQMP_NUM_GEMS; i++) { > diff --git a/include/hw/arm/xlnx-zynqmp.h b/include/hw/arm/xlnx-zynqmp.h > index 6a407c2962..a3117bd6c5 100644 > --- a/include/hw/arm/xlnx-zynqmp.h > +++ b/include/hw/arm/xlnx-zynqmp.h > @@ -42,6 +42,7 @@ > #include "hw/misc/xlnx-zynqmp-crf.h" > #include "hw/timer/cadence_ttc.h" > #include "hw/usb/hcd-dwc3.h" > +#include "hw/core/split-irq.h" > > #define TYPE_XLNX_ZYNQMP "xlnx-zynqmp" > OBJECT_DECLARE_SIMPLE_TYPE(XlnxZynqMPState, XLNX_ZYNQMP) > @@ -106,6 +107,9 @@ struct XlnxZynqMPState { > GICState gic; > MemoryRegion gic_mr[XLNX_ZYNQMP_GIC_REGIONS][XLNX_ZYNQMP_GIC_ALIASES]; > > + GICState rpu_gic; > + SplitIRQ splitter[XLNX_ZYNQMP_GIC_NUM_SPI_INTR]; > + > MemoryRegion ocm_ram[XLNX_ZYNQMP_NUM_OCM_BANKS]; > > MemoryRegion *ddr_ram; > -- > 2.34.1 > ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH 0/3] hw/arm/xlnx-zynqmp: wire a second GIC for the Cortex-R5 2025-09-30 11:57 [PATCH 0/3] hw/arm/xlnx-zynqmp: wire a second GIC for the Cortex-R5 Clément Chigot ` (2 preceding siblings ...) 2025-09-30 11:57 ` [PATCH 3/3] hw/arm/xlnx-zynqmp: wire a second GIC for the Cortex-R5 Clément Chigot @ 2025-10-07 9:50 ` Peter Maydell 3 siblings, 0 replies; 8+ messages in thread From: Peter Maydell @ 2025-10-07 9:50 UTC (permalink / raw) To: Clément Chigot; +Cc: qemu-devel, qemu-arm, edgar.iglesias, alistair On Tue, 30 Sept 2025 at 12:57, Clément Chigot <chigot@adacore.com> wrote: > > The first two patches are minor improvements before the core third > patch. > > This was initially a single patch split as per review comments (see [1]) > > [1] https://lists.gnu.org/archive/html/qemu-devel/2025-09/msg05899.html > > Clément Chigot (2): > hw/arm/xlnx-zynqmp: move GIC_NUM_SPI_INTR define in header > hw/arm/xlnx-zynqmp: introduce helper to compute RPU number > > Frederic Konrad (1): > hw/arm/xlnx-zynqmp: wire a second GIC for the Cortex-R5 Applied to target-arm.next, thanks. -- PMM ^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2025-10-07 9:51 UTC | newest] Thread overview: 8+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2025-09-30 11:57 [PATCH 0/3] hw/arm/xlnx-zynqmp: wire a second GIC for the Cortex-R5 Clément Chigot 2025-09-30 11:57 ` [PATCH 1/3] hw/arm/xlnx-zynqmp: move GIC_NUM_SPI_INTR define in header Clément Chigot 2025-10-02 7:33 ` Edgar E. Iglesias 2025-09-30 11:57 ` [PATCH 2/3] hw/arm/xlnx-zynqmp: introduce helper to compute RPU number Clément Chigot 2025-10-02 7:35 ` Edgar E. Iglesias 2025-09-30 11:57 ` [PATCH 3/3] hw/arm/xlnx-zynqmp: wire a second GIC for the Cortex-R5 Clément Chigot 2025-10-02 7:36 ` Edgar E. Iglesias 2025-10-07 9:50 ` [PATCH 0/3] " Peter Maydell
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).