On Wed, Jul 16, 2025 at 11:54:02AM +0200, Luc Michel wrote:
> Refactor the creation of virtio devices. Use the accessors provided by
> the Versal SoC to retrieve the reserved MMIO and IRQ space. Those are
> defined in the VersalMap structure.
>
> Signed-off-by: Luc Michel <luc.michel@amd.com>
Reviewed-by: Francisco Iglesias <francisco.iglesias@amd.com>
> ---
> include/hw/arm/xlnx-versal.h | 3 +++
> hw/arm/xlnx-versal-virt.c | 31 ++++++++++++-------------------
> hw/arm/xlnx-versal.c | 26 ++++++++++++++++++++++++++
> 3 files changed, 41 insertions(+), 19 deletions(-)
>
> diff --git a/include/hw/arm/xlnx-versal.h b/include/hw/arm/xlnx-versal.h
> index d3ce13e69de..af47acb288f 100644
> --- a/include/hw/arm/xlnx-versal.h
> +++ b/include/hw/arm/xlnx-versal.h
> @@ -100,10 +100,13 @@ void versal_sdhci_plug_card(Versal *s, int sd_idx, BlockBackend *blk);
> void versal_efuse_attach_drive(Versal *s, BlockBackend *blk);
> void versal_bbram_attach_drive(Versal *s, BlockBackend *blk);
> void versal_ospi_create_flash(Versal *s, int flash_idx, const char *flash_mdl,
> BlockBackend *blk);
>
> +qemu_irq versal_get_reserved_irq(Versal *s, int idx, int *dtb_idx);
> +hwaddr versal_get_reserved_mmio_addr(Versal *s);
> +
> int versal_get_num_can(VersalVersion version);
> int versal_get_num_sdhci(VersalVersion version);
>
> /* Memory-map and IRQ definitions. Copied a subset from
> * auto-generated files. */
> diff --git a/hw/arm/xlnx-versal-virt.c b/hw/arm/xlnx-versal-virt.c
> index 01c230491df..a776ee87088 100644
> --- a/hw/arm/xlnx-versal-virt.c
> +++ b/hw/arm/xlnx-versal-virt.c
> @@ -269,41 +269,34 @@ static void create_virtio_regions(VersalVirt *s)
> {
> int virtio_mmio_size = 0x200;
> int i;
>
> for (i = 0; i < NUM_VIRTIO_TRANSPORT; i++) {
> - char *name = g_strdup_printf("virtio%d", i);
> - hwaddr base = MM_TOP_RSVD + i * virtio_mmio_size;
> - int irq = VERSAL_RSVD_IRQ_FIRST + i;
> + hwaddr base = versal_get_reserved_mmio_addr(&s->soc)
> + + i * virtio_mmio_size;
> + g_autofree char *node = g_strdup_printf("/virtio_mmio@%" PRIx64, base);
> + int dtb_irq;
> MemoryRegion *mr;
> DeviceState *dev;
> qemu_irq pic_irq;
>
> - pic_irq = qdev_get_gpio_in(DEVICE(&s->soc.fpd.apu.gic), irq);
> + pic_irq = versal_get_reserved_irq(&s->soc, i, &dtb_irq);
> dev = qdev_new("virtio-mmio");
> - object_property_add_child(OBJECT(&s->soc), name, OBJECT(dev));
> + object_property_add_child(OBJECT(s), "virtio-mmio[*]", OBJECT(dev));
> sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
> sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, pic_irq);
> mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 0);
> memory_region_add_subregion(&s->soc.mr_ps, base, mr);
> - g_free(name);
> - }
>
> - for (i = 0; i < NUM_VIRTIO_TRANSPORT; i++) {
> - hwaddr base = MM_TOP_RSVD + i * virtio_mmio_size;
> - int irq = VERSAL_RSVD_IRQ_FIRST + i;
> - char *name = g_strdup_printf("/virtio_mmio@%" PRIx64, base);
> -
> - qemu_fdt_add_subnode(s->fdt, name);
> - qemu_fdt_setprop(s->fdt, name, "dma-coherent", NULL, 0);
> - qemu_fdt_setprop_cells(s->fdt, name, "interrupts",
> - GIC_FDT_IRQ_TYPE_SPI, irq,
> + qemu_fdt_add_subnode(s->fdt, node);
> + qemu_fdt_setprop(s->fdt, node, "dma-coherent", NULL, 0);
> + qemu_fdt_setprop_cells(s->fdt, node, "interrupts",
> + GIC_FDT_IRQ_TYPE_SPI, dtb_irq,
> GIC_FDT_IRQ_FLAGS_EDGE_LO_HI);
> - qemu_fdt_setprop_sized_cells(s->fdt, name, "reg",
> + qemu_fdt_setprop_sized_cells(s->fdt, node, "reg",
> 2, base, 2, virtio_mmio_size);
> - qemu_fdt_setprop_string(s->fdt, name, "compatible", "virtio,mmio");
> - g_free(name);
> + qemu_fdt_setprop_string(s->fdt, node, "compatible", "virtio,mmio");
> }
> }
>
> static void bbram_attach_drive(VersalVirt *s)
> {
> diff --git a/hw/arm/xlnx-versal.c b/hw/arm/xlnx-versal.c
> index ff55ec62301..fe2c789a557 100644
> --- a/hw/arm/xlnx-versal.c
> +++ b/hw/arm/xlnx-versal.c
> @@ -152,10 +152,17 @@ typedef struct VersalMap {
> uint32_t blktype_frames[7];
> } cframe_cfg[15];
> } cfu;
>
> VersalSimplePeriphMap crl;
> +
> + /* reserved MMIO/IRQ space that can safely be used for virtio devices */
> + struct VersalReserved {
> + uint64_t mmio_start;
> + int irq_start;
> + int irq_num;
> + } reserved;
> } VersalMap;
>
> static const VersalMap VERSAL_MAP = {
> .uart[0] = { 0xff000000, 18 },
> .uart[1] = { 0xff010000, 19 },
> @@ -218,10 +225,12 @@ static const VersalMap VERSAL_MAP = {
> { { 38498, 3841, 15361, 13, 7, 3, 1 } },
> },
> },
>
> .crl = { 0xff5e0000, 10 },
> +
> + .reserved = { 0xa0000000, 111, 8 },
> };
>
> static const VersalMap *VERSION_TO_MAP[] = {
> [VERSAL_VER_VERSAL] = &VERSAL_MAP,
> };
> @@ -1411,10 +1420,27 @@ void versal_ospi_create_flash(Versal *s, int flash_idx, const char *flash_mdl,
>
> sysbus_connect_irq(SYS_BUS_DEVICE(ospi),
> flash_idx + 1, cs_line);
> }
>
> +qemu_irq versal_get_reserved_irq(Versal *s, int idx, int *dtb_idx)
> +{
> + const VersalMap *map = versal_get_map(s);
> +
> + g_assert(idx < map->reserved.irq_num);
> +
> + *dtb_idx = map->reserved.irq_start + idx;
> + return versal_get_irq(s, *dtb_idx);
> +}
> +
> +hwaddr versal_get_reserved_mmio_addr(Versal *s)
> +{
> + const VersalMap *map = versal_get_map(s);
> +
> + return map->reserved.mmio_start;
> +}
> +
> int versal_get_num_can(VersalVersion version)
> {
> const VersalMap *map = VERSION_TO_MAP[version];
>
> return map->num_canfd;
> --
> 2.50.0
>