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>
---
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 f626774c52..cd70095687 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 5102286103..9740b395f6 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] = { 0102000, 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.49.0
On Wed, May 28, 2025 at 05:01:29PM -0300, Daniel Henrique Barboza wrote:
>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>
>---
> 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 f626774c52..cd70095687 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 5102286103..9740b395f6 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] = { 0102000, 0x1000 },
This might be a typo:
0102000 -> 0x102000
Thanks,
Chao
On 10/30/25 8:40 AM, Chao Liu wrote:
> On Wed, May 28, 2025 at 05:01:29PM -0300, Daniel Henrique Barboza wrote:
>> 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>
>> ---
>> 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 f626774c52..cd70095687 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 5102286103..9740b395f6 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] = { 0102000, 0x1000 },
> This might be a typo:
> 0102000 -> 0x102000
Good call. I'll fix it in v4. Thanks,
Daniel
>
> Thanks,
> Chao
>
On Wed, May 28, 2025 at 05:01:29PM -0300, Daniel Henrique Barboza wrote: > 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> > --- > hw/riscv/Kconfig | 1 + > hw/riscv/server_platform_ref.c | 78 ++++++++++++++++++++++++++++++++-- > 2 files changed, 75 insertions(+), 4 deletions(-) > Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
© 2016 - 2025 Red Hat, Inc.