[PATCH 03/13] hw/riscv/fdt-common, virt.c: add create_fdt_riscv_iommu_sys()
Daniel Henrique Barboza <[email protected]>
| Newsgroups | org.nongnu.qemu-riscv,org.nongnu.qemu-devel |
|---|---|
| Message-ID | <[email protected]> |
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. No FDT changes intended. Signed-off-by: Daniel Henrique Barboza <[email protected]> --- hw/riscv/fdt-common.c | 40 +++++++++++++++++++++++++++++ hw/riscv/virt.c | 47 ++++------------------------------- include/hw/riscv/fdt-common.h | 5 ++++ 3 files changed, 50 insertions(+), 42 deletions(-) diff --git a/hw/riscv/fdt-common.c b/hw/riscv/fdt-common.c index a2168c09ec..ddc56821d3 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 *create_board_device_tree(const char *model, const char *compatible, int *fdt_size) @@ -347,3 +349,41 @@ void create_fdt_syscon(void *fdt, uint32_t *phandle, qemu_fdt_setprop_cell(fdt, name, "value", poweroff); g_free(name); } + +void create_fdt_riscv_iommu_sys(void *fdt, hwaddr addr, hwaddr size, + uint32_t irq_chip, + uint32_t msi_phandle, + uint32_t *iommu_sys_phandle, + uint32_t iommu_sys_irq) +{ + const char comp[] = "riscv,iommu"; + uint32_t iommu_phandle; + g_autofree char *iommu_node = NULL; + 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@%"HWADDR_PRIx, addr); + 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; +} diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c index acbbe458fa..9417aa7a06 100644 --- a/hw/riscv/virt.c +++ b/hw/riscv/virt.c @@ -867,46 +867,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"; @@ -945,8 +905,11 @@ 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); + create_fdt_riscv_iommu_sys(MACHINE(s)->fdt, + s->memmap[VIRT_IOMMU_SYS].base, + s->memmap[VIRT_IOMMU_SYS].size, + irq_mmio_phandle, msi_pcie_phandle, + &iommu_sys_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 31203df517..37a1544706 100644 --- a/include/hw/riscv/fdt-common.h +++ b/include/hw/riscv/fdt-common.h @@ -41,4 +41,9 @@ void create_fdt_syscon(void *fdt, uint32_t *phandle, hwaddr addr, hwaddr size, uint32_t reboot, uint32_t poweroff, bool sifive_test_compat); +void create_fdt_riscv_iommu_sys(void *fdt, hwaddr addr, hwaddr size, + uint32_t irq_chip, + uint32_t msi_phandle, + uint32_t *iommu_sys_phandle, + uint32_t iommu_sys_irq); #endif -- 2.43.0