[PATCH 20/48] hw/arm/xlnx-versal-virt: virtio: refactor creation

Luc Michel posted 48 patches 4 months ago
Maintainers: Alistair Francis <alistair@alistair23.me>, "Edgar E. Iglesias" <edgar.iglesias@gmail.com>, Peter Maydell <peter.maydell@linaro.org>, Jason Wang <jasowang@redhat.com>
There is a newer version of this series
[PATCH 20/48] hw/arm/xlnx-versal-virt: virtio: refactor creation
Posted by Luc Michel 4 months ago
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>
---
 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
Re: [PATCH 20/48] hw/arm/xlnx-versal-virt: virtio: refactor creation
Posted by Francisco Iglesias 3 months, 2 weeks ago
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
>