mirror of
https://github.com/openRuyi-Project/openRuyi.git
synced 2026-04-28 11:03:42 +00:00
184 lines
6.9 KiB
Diff
184 lines
6.9 KiB
Diff
From ce40aec415eccc5865b2e876ddde3302d9668674 Mon Sep 17 00:00:00 2001
|
|
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
|
|
Date: Tue, 11 Nov 2025 15:29:43 -0300
|
|
Subject: [PATCH 4/6] hw/riscv/server_platform_ref.c: add riscv-iommu-sys
|
|
|
|
Add an always present IOMMU platform device for the rvsp-ref board.
|
|
|
|
The IRQs being used are similar to what the 'virt' board is using: IRQs
|
|
36 to 39, one IRQ for queue.
|
|
|
|
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
|
|
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
|
|
---
|
|
hw/riscv/Kconfig | 1 +
|
|
hw/riscv/server_platform_ref.c | 78 ++++++++++++++++++++++++++++++++--
|
|
2 files changed, 75 insertions(+), 4 deletions(-)
|
|
|
|
diff --git a/hw/riscv/Kconfig b/hw/riscv/Kconfig
|
|
index 6a5085c7a5..4f8cbfe77f 100644
|
|
--- a/hw/riscv/Kconfig
|
|
+++ b/hw/riscv/Kconfig
|
|
@@ -82,6 +82,7 @@ config SERVER_PLATFORM_REF
|
|
select RISCV_ACLINT
|
|
select RISCV_APLIC
|
|
select RISCV_IMSIC
|
|
+ select RISCV_IOMMU
|
|
|
|
config SHAKTI_C
|
|
bool
|
|
diff --git a/hw/riscv/server_platform_ref.c b/hw/riscv/server_platform_ref.c
|
|
index ef2891a9d7..dc6caf72a6 100644
|
|
--- a/hw/riscv/server_platform_ref.c
|
|
+++ b/hw/riscv/server_platform_ref.c
|
|
@@ -31,6 +31,8 @@
|
|
#include "hw/riscv/riscv_hart.h"
|
|
#include "hw/riscv/boot.h"
|
|
#include "hw/riscv/numa.h"
|
|
+#include "hw/riscv/iommu.h"
|
|
+#include "hw/riscv/riscv-iommu-bits.h"
|
|
#include "hw/intc/riscv_aclint.h"
|
|
#include "hw/intc/riscv_aplic.h"
|
|
#include "hw/intc/riscv_imsic.h"
|
|
@@ -94,6 +96,7 @@ enum {
|
|
RVSP_MROM,
|
|
RVSP_RESET_SYSCON,
|
|
RVSP_RTC,
|
|
+ RVSP_IOMMU_SYS,
|
|
RVSP_ACLINT,
|
|
RVSP_APLIC_M,
|
|
RVSP_APLIC_S,
|
|
@@ -112,6 +115,7 @@ enum {
|
|
RVSP_UART0_IRQ = 10,
|
|
RVSP_RTC_IRQ = 11,
|
|
RVSP_PCIE_IRQ = 0x20, /* 32 to 35 */
|
|
+ IOMMU_SYS_IRQ = 0x24 /* 36 to 39 */
|
|
};
|
|
|
|
/*
|
|
@@ -141,6 +145,7 @@ static const MemMapEntry rvsp_ref_memmap[] = {
|
|
[RVSP_MROM] = { 0x1000, 0xf000 },
|
|
[RVSP_RESET_SYSCON] = { 0x100000, 0x1000 },
|
|
[RVSP_RTC] = { 0x101000, 0x1000 },
|
|
+ [RVSP_IOMMU_SYS] = { 0x102000, 0x1000 },
|
|
[RVSP_ACLINT] = { 0x2000000, 0x10000 },
|
|
[RVSP_PCIE_PIO] = { 0x3000000, 0x10000 },
|
|
[RVSP_APLIC_M] = { 0xc000000, APLIC_SIZE(RVSP_CPUS_MAX) },
|
|
@@ -638,9 +643,51 @@ static void create_fdt_sockets(RVSPMachineState *s, const MemMapEntry *memmap,
|
|
riscv_socket_fdt_write_distance_matrix(ms);
|
|
}
|
|
|
|
+static void create_fdt_iommu_sys(RVSPMachineState *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[RVSP_IOMMU_SYS].base;
|
|
+ hwaddr size = s->memmap[RVSP_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@%"HWADDR_PRIx,
|
|
+ s->memmap[RVSP_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_cells(fdt, iommu_node, "reg",
|
|
+ addr >> 32, addr, size >> 32, 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_pcie(RVSPMachineState *s, const MemMapEntry *memmap,
|
|
uint32_t irq_pcie_phandle,
|
|
- uint32_t msi_pcie_phandle)
|
|
+ uint32_t msi_pcie_phandle,
|
|
+ uint32_t iommu_sys_phandle)
|
|
{
|
|
g_autofree char *name = NULL;
|
|
MachineState *ms = MACHINE(s);
|
|
@@ -675,6 +722,10 @@ static void create_fdt_pcie(RVSPMachineState *s, const MemMapEntry *memmap,
|
|
memmap[RVSP_PCIE_MMIO_HIGH].size);
|
|
|
|
create_pcie_irq_map(s, ms->fdt, name, irq_pcie_phandle);
|
|
+
|
|
+ qemu_fdt_setprop_cells(ms->fdt, name, "iommu-map",
|
|
+ 0, iommu_sys_phandle, 0, 0, 0,
|
|
+ iommu_sys_phandle, 0, 0xffff);
|
|
}
|
|
|
|
static void create_fdt_reset(RVSPMachineState *s, const MemMapEntry *memmap,
|
|
@@ -768,12 +819,16 @@ static void create_fdt_flash(RVSPMachineState *s, const MemMapEntry *memmap)
|
|
static void finalize_fdt(RVSPMachineState *s)
|
|
{
|
|
uint32_t phandle = 1, irq_mmio_phandle = 1, msi_pcie_phandle = 1;
|
|
- uint32_t irq_pcie_phandle = 1;
|
|
+ uint32_t irq_pcie_phandle = 1, iommu_sys_phandle;
|
|
|
|
create_fdt_sockets(s, rvsp_ref_memmap, &phandle, &irq_mmio_phandle,
|
|
&irq_pcie_phandle, &msi_pcie_phandle);
|
|
|
|
- create_fdt_pcie(s, rvsp_ref_memmap, irq_pcie_phandle, msi_pcie_phandle);
|
|
+ create_fdt_iommu_sys(s, irq_mmio_phandle, msi_pcie_phandle,
|
|
+ &iommu_sys_phandle);
|
|
+
|
|
+ create_fdt_pcie(s, rvsp_ref_memmap, irq_pcie_phandle,
|
|
+ msi_pcie_phandle, iommu_sys_phandle);
|
|
|
|
create_fdt_reset(s, rvsp_ref_memmap, &phandle);
|
|
|
|
@@ -1078,7 +1133,7 @@ static void rvsp_ref_machine_init(MachineState *machine)
|
|
MemoryRegion *system_memory = get_system_memory();
|
|
MemoryRegion *mask_rom = g_new(MemoryRegion, 1);
|
|
MemoryRegion *reset_syscon_io = g_new(MemoryRegion, 1);
|
|
- DeviceState *mmio_irqchip, *pcie_irqchip;
|
|
+ DeviceState *mmio_irqchip, *pcie_irqchip, *iommu_sys;
|
|
int i, base_hartid, hart_count;
|
|
int socket_count = riscv_socket_count(machine);
|
|
|
|
@@ -1196,6 +1251,21 @@ static void rvsp_ref_machine_init(MachineState *machine)
|
|
create_fdt(s, memmap);
|
|
}
|
|
|
|
+ iommu_sys = qdev_new(TYPE_RISCV_IOMMU_SYS);
|
|
+ object_property_set_uint(OBJECT(iommu_sys), "addr",
|
|
+ s->memmap[RVSP_IOMMU_SYS].base,
|
|
+ &error_fatal);
|
|
+
|
|
+ object_property_set_uint(OBJECT(iommu_sys), "base-irq",
|
|
+ IOMMU_SYS_IRQ,
|
|
+ &error_fatal);
|
|
+
|
|
+ object_property_set_link(OBJECT(iommu_sys), "irqchip",
|
|
+ OBJECT(mmio_irqchip),
|
|
+ &error_fatal);
|
|
+
|
|
+ sysbus_realize_and_unref(SYS_BUS_DEVICE(iommu_sys), &error_fatal);
|
|
+
|
|
s->machine_done.notify = rvsp_ref_machine_done;
|
|
qemu_add_machine_init_done_notifier(&s->machine_done);
|
|
}
|
|
--
|
|
2.52.0
|
|
|