On Thu, 27 Aug 2026 at 07:16, Daniel Henrique Barboza
<[email protected]> wrote:
> void *riscv_create_board_device_tree(const char *model, const char
> *compatible,
> int *fdt_size)
> @@ -348,3 +350,41 @@ void riscv_create_fdt_syscon(void *fdt, uint32_t
> *phandle,
> qemu_fdt_setprop_cell(fdt, name, "value", poweroff);
> g_free(name);
> }
> +
> +void riscv_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,
> + };
Any reason to pack them into an array? Seems like they could be part
of the qemu_fdt_setprop_cells call:
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);
> +
> + iommu_node = g_strdup_printf("/soc/iommu@%"HWADDR_PRIx, addr);
> + iommu_phandle = qemu_fdt_alloc_phandle(fdt);
Ohh, that's neat. Any reason we don't use this for all of phandle
allocation needs?
We should be consistent, so switch this one to the pattern used by the
rest of the file, or (preferably, IMO) switch them all over.
> + 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;
Could we just return it? Or have it passed in, so we don't need to return it?