On Thu, Aug 27, 2026 at 07:25:57PM +0800, Daniel Henrique Barboza wrote:
> Both the 'virt' board and the future 'riscv-server-ref' boards uses an
> iommu-sys device that is declared in the DT.  Create a helper to
> encapsulate the logic and avoid copy/pasting stuff between boards.
> 
> The helper will return the iommu phandle value instead of returning void
> and writing the used phandle in an extra argument.
> 
> Signed-off-by: Daniel Henrique Barboza <[email protected]>
> Reviewed-by: Philippe Mathieu-Daudé <[email protected]>
Reviewed-by: Chao Liu <[email protected]>

Thanks,
Chao

> ---
>  hw/riscv/fdt-common.c         | 35 ++++++++++++++++++++++++
>  hw/riscv/virt.c               | 50 ++++++-----------------------------
>  include/hw/riscv/fdt-common.h |  5 ++++
>  3 files changed, 48 insertions(+), 42 deletions(-)
> 
> diff --git a/hw/riscv/fdt-common.c b/hw/riscv/fdt-common.c
> index eac5ca9322..88589330fb 100644
> --- a/hw/riscv/fdt-common.c
> +++ b/hw/riscv/fdt-common.c
> @@ -13,6 +13,8 @@
>  #include "hw/core/boards.h"
>  #include "hw/riscv/fdt-common.h"
>  #include "target/riscv/cpu_bits.h"
> +#include "hw/riscv/riscv-iommu-bits.h"
> +#include "hw/riscv/iommu.h"
>  
>  void *riscv_create_board_device_tree(const char *model, const char 
> *compatible,
>                                       int *fdt_size)
> @@ -349,3 +351,36 @@ void riscv_create_fdt_syscon(void *fdt, uint32_t 
> *next_phandle,
>      qemu_fdt_setprop_cell(fdt, name, "value", poweroff);
>      g_free(name);
>  }
> +
> +uint32_t riscv_create_fdt_riscv_iommu_sys(void *fdt, hwaddr addr, hwaddr 
> size,
> +                                          uint32_t *next_phandle,
> +                                          uint32_t irq_chip,
> +                                          uint32_t msi_phandle,
> +                                          uint32_t iommu_sys_irq)
> +{
> +    const char comp[] = "riscv,iommu";
> +    g_autofree char *iommu_node = NULL;
> +    uint32_t iommu_phandle;
> +
> +    iommu_node = g_strdup_printf("/soc/iommu@%"HWADDR_PRIx, addr);
> +    qemu_fdt_add_subnode(fdt, iommu_node);
> +
> +    qemu_fdt_setprop(fdt, iommu_node, "compatible", comp, sizeof(comp));
> +    qemu_fdt_setprop_cell(fdt, iommu_node, "#iommu-cells", 1);
> +
> +    iommu_phandle = next_phandle ? (*next_phandle)++ : 
> qemu_fdt_alloc_phandle(fdt);
> +    qemu_fdt_setprop_cell(fdt, iommu_node, "phandle", iommu_phandle);
> +
> +    qemu_fdt_setprop_sized_cells(fdt, iommu_node, "reg", 2, addr, 2, size);
> +    qemu_fdt_setprop_cell(fdt, iommu_node, "interrupt-parent", irq_chip);
> +
> +    qemu_fdt_setprop_cells(fdt, iommu_node, "interrupts",
> +        iommu_sys_irq + RISCV_IOMMU_INTR_CQ, FDT_IRQ_TYPE_EDGE_LOW,
> +        iommu_sys_irq + RISCV_IOMMU_INTR_FQ, FDT_IRQ_TYPE_EDGE_LOW,
> +        iommu_sys_irq + RISCV_IOMMU_INTR_PM, FDT_IRQ_TYPE_EDGE_LOW,
> +        iommu_sys_irq + RISCV_IOMMU_INTR_PQ, FDT_IRQ_TYPE_EDGE_LOW);
> +
> +    qemu_fdt_setprop_cell(fdt, iommu_node, "msi-parent", msi_phandle);
> +
> +    return iommu_phandle;
> +}
> diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
> index ab6c53c78a..8a165f4d9e 100644
> --- a/hw/riscv/virt.c
> +++ b/hw/riscv/virt.c
> @@ -869,46 +869,6 @@ static void create_fdt_virtio_iommu(RISCVVirtState *s, 
> uint16_t bdf)
>                             bdf + 1, iommu_phandle, bdf + 1, 0xffff - bdf);
>  }
>  
> -static void create_fdt_iommu_sys(RISCVVirtState *s, uint32_t irq_chip,
> -                                 uint32_t msi_phandle,
> -                                 uint32_t *iommu_sys_phandle)
> -{
> -    const char comp[] = "riscv,iommu";
> -    void *fdt = MACHINE(s)->fdt;
> -    uint32_t iommu_phandle;
> -    g_autofree char *iommu_node = NULL;
> -    hwaddr addr = s->memmap[VIRT_IOMMU_SYS].base;
> -    hwaddr size = s->memmap[VIRT_IOMMU_SYS].size;
> -    uint32_t iommu_irq_map[RISCV_IOMMU_INTR_COUNT] = {
> -        IOMMU_SYS_IRQ + RISCV_IOMMU_INTR_CQ,
> -        IOMMU_SYS_IRQ + RISCV_IOMMU_INTR_FQ,
> -        IOMMU_SYS_IRQ + RISCV_IOMMU_INTR_PM,
> -        IOMMU_SYS_IRQ + RISCV_IOMMU_INTR_PQ,
> -    };
> -
> -    iommu_node = g_strdup_printf("/soc/iommu@%x",
> -                               (unsigned int) 
> s->memmap[VIRT_IOMMU_SYS].base);
> -    iommu_phandle = qemu_fdt_alloc_phandle(fdt);
> -    qemu_fdt_add_subnode(fdt, iommu_node);
> -
> -    qemu_fdt_setprop(fdt, iommu_node, "compatible", comp, sizeof(comp));
> -    qemu_fdt_setprop_cell(fdt, iommu_node, "#iommu-cells", 1);
> -    qemu_fdt_setprop_cell(fdt, iommu_node, "phandle", iommu_phandle);
> -
> -    qemu_fdt_setprop_sized_cells(fdt, iommu_node, "reg", 2, addr, 2, size);
> -    qemu_fdt_setprop_cell(fdt, iommu_node, "interrupt-parent", irq_chip);
> -
> -    qemu_fdt_setprop_cells(fdt, iommu_node, "interrupts",
> -        iommu_irq_map[0], FDT_IRQ_TYPE_EDGE_LOW,
> -        iommu_irq_map[1], FDT_IRQ_TYPE_EDGE_LOW,
> -        iommu_irq_map[2], FDT_IRQ_TYPE_EDGE_LOW,
> -        iommu_irq_map[3], FDT_IRQ_TYPE_EDGE_LOW);
> -
> -    qemu_fdt_setprop_cell(fdt, iommu_node, "msi-parent", msi_phandle);
> -
> -    *iommu_sys_phandle = iommu_phandle;
> -}
> -
>  static void create_fdt_iommu(RISCVVirtState *s, uint16_t bdf)
>  {
>      const char comp[] = "riscv,pci-iommu";
> @@ -947,8 +907,14 @@ static void finalize_fdt(RISCVVirtState *s)
>      create_fdt_virtio(s, irq_virtio_phandle);
>  
>      if (virt_is_iommu_sys_enabled(s)) {
> -        create_fdt_iommu_sys(s, irq_mmio_phandle, msi_pcie_phandle,
> -                             &iommu_sys_phandle);
> +        iommu_sys_phandle =
> +            riscv_create_fdt_riscv_iommu_sys(MACHINE(s)->fdt,
> +                                             s->memmap[VIRT_IOMMU_SYS].base,
> +                                             s->memmap[VIRT_IOMMU_SYS].size,
> +                                             &phandle,
> +                                             irq_mmio_phandle,
> +                                             msi_pcie_phandle,
> +                                             IOMMU_SYS_IRQ);
>      }
>      create_fdt_pcie(s, irq_pcie_phandle, msi_pcie_phandle,
>                      iommu_sys_phandle);
> diff --git a/include/hw/riscv/fdt-common.h b/include/hw/riscv/fdt-common.h
> index e377682b32..65711468b8 100644
> --- a/include/hw/riscv/fdt-common.h
> +++ b/include/hw/riscv/fdt-common.h
> @@ -43,4 +43,9 @@ void riscv_create_fdt_syscon(void *fdt, uint32_t 
> *next_phandle,
>                               hwaddr addr, hwaddr size,
>                               uint32_t reboot, uint32_t poweroff,
>                               bool sifive_test_compat);
> +uint32_t riscv_create_fdt_riscv_iommu_sys(void *fdt, hwaddr addr, hwaddr 
> size,
> +                                          uint32_t *next_phandle,
> +                                          uint32_t irq_chip,
> +                                          uint32_t msi_phandle,
> +                                          uint32_t iommu_sys_irq);
>  #endif
> -- 
> 2.43.0
> 

Reply via email to