The riscv-iommu-sys device inherits all properties from its associated
riscv-iommu device via qdev_alias_all_properties() during sys_init().

We're also providing riscv_create_iommu_sys(), a helper to instantiate
the device and avoid duplicating code between boards.  In its current
state the helper is realizing the device before returning it to the
caller, prevents any additional setup of the device (we can't change
device props after realize).

Split the realization code from the helper and make the boards realize
the device manually.  It's a small inconvenience to pay to be able to
config the iommu-sys device.

Signed-off-by: Daniel Henrique Barboza <[email protected]>
---
 hw/riscv/riscv-iommu-sys.c     | 3 +--
 hw/riscv/server_platform_ref.c | 7 +++++--
 hw/riscv/virt.c                | 9 +++++++--
 3 files changed, 13 insertions(+), 6 deletions(-)

diff --git a/hw/riscv/riscv-iommu-sys.c b/hw/riscv/riscv-iommu-sys.c
index 258c171efd..190ab0b646 100644
--- a/hw/riscv/riscv-iommu-sys.c
+++ b/hw/riscv/riscv-iommu-sys.c
@@ -217,6 +217,7 @@ static void riscv_iommu_sys_init(Object *obj)
     riscv_iommu_set_cap_igs(iommu, RISCV_IOMMU_CAP_IGS_BOTH);
 }
 
+/* Note: the returned iommu_sys device needs to be realized.  */
 DeviceState *riscv_create_iommu_sys(DeviceState *mmio_irqchip,
                                     hwaddr addr, int base_irq,
                                     bool is_32_bit)
@@ -237,8 +238,6 @@ DeviceState *riscv_create_iommu_sys(DeviceState 
*mmio_irqchip,
                              is_32_bit ? 34 : 56,
                              &error_fatal);
 
-    sysbus_realize_and_unref(SYS_BUS_DEVICE(iommu_sys), &error_fatal);
-
     return iommu_sys;
 }
 
diff --git a/hw/riscv/server_platform_ref.c b/hw/riscv/server_platform_ref.c
index 5f485b1c79..e9536515da 100644
--- a/hw/riscv/server_platform_ref.c
+++ b/hw/riscv/server_platform_ref.c
@@ -481,6 +481,7 @@ static void rvserver_ref_machine_init(MachineState *machine)
     MemoryRegion *mask_rom = g_new(MemoryRegion, 1);
     MemoryRegion *reset_syscon_io = g_new(MemoryRegion, 1);
     DeviceState *mmio_irqchip, *pcie_irqchip;
+    DeviceState *iommu_sys;
     int i, base_hartid, hart_count;
     int socket_count = riscv_socket_count(machine);
     int imsic_bits;
@@ -635,8 +636,10 @@ static void rvserver_ref_machine_init(MachineState 
*machine)
         create_fdt(s, memmap);
     }
 
-    riscv_create_iommu_sys(mmio_irqchip, s->memmap[RVSERVER_IOMMU_SYS].base,
-                           IOMMU_SYS_IRQ, false);
+    iommu_sys = riscv_create_iommu_sys(mmio_irqchip,
+                                       s->memmap[RVSERVER_IOMMU_SYS].base,
+                                       IOMMU_SYS_IRQ, false);
+    sysbus_realize_and_unref(SYS_BUS_DEVICE(iommu_sys), &error_fatal);
 
     s->machine_done.notify = rvserver_ref_machine_done;
     qemu_add_machine_init_done_notifier(&s->machine_done);
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
index d4b501802f..39381cb21d 100644
--- a/hw/riscv/virt.c
+++ b/hw/riscv/virt.c
@@ -940,8 +940,13 @@ static void virt_machine_init(MachineState *machine)
     }
 
     if (virt_is_iommu_sys_enabled(s)) {
-        riscv_create_iommu_sys(mmio_irqchip, s->memmap[VIRT_IOMMU_SYS].base,
-                               IOMMU_SYS_IRQ, riscv_is_32bit(&s->soc[0]));
+        DeviceState *iommu_sys;
+
+        iommu_sys = riscv_create_iommu_sys(mmio_irqchip,
+                                           s->memmap[VIRT_IOMMU_SYS].base,
+                                           IOMMU_SYS_IRQ,
+                                           riscv_is_32bit(&s->soc[0]));
+        sysbus_realize_and_unref(SYS_BUS_DEVICE(iommu_sys), &error_fatal);
     }
 
     s->machine_done.notify = virt_machine_done;
-- 
2.43.0


Reply via email to