diff options
| author | Daniel Henrique Barboza <daniel.barboza@oss.qualcomm.com> | 2026-06-16 20:59:39 -0300 |
|---|---|---|
| committer | Alistair Francis <alistair.francis@wdc.com> | 2026-07-01 19:59:09 +1000 |
| commit | b3b4a424e2b29b6b88b2ed9a47a2c908ae1ec182 (patch) | |
| tree | 4170464d50602d2891b6c29533c7fec1be840da6 | |
| parent | c50dbdc750e47bbdcc27713f0d402b5d25c46511 (diff) | |
| download | qemu-b3b4a424e2b29b6b88b2ed9a47a2c908ae1ec182.tar.gz qemu-b3b4a424e2b29b6b88b2ed9a47a2c908ae1ec182.zip | |
hw/riscv: add create_fdt_plic() helper
Consolidate the common plic FDT code between 'virt' and sifive_u boards
into a single place.
Signed-off-by: Daniel Henrique Barboza <daniel.barboza@oss.qualcomm.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Message-ID: <20260616235939.1358663-6-daniel.barboza@oss.qualcomm.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
| -rw-r--r-- | hw/riscv/fdt-common.c | 30 | ||||
| -rw-r--r-- | hw/riscv/sifive_u.c | 34 | ||||
| -rw-r--r-- | hw/riscv/virt.c | 49 | ||||
| -rw-r--r-- | include/hw/riscv/fdt-common.h | 5 |
4 files changed, 61 insertions, 57 deletions
diff --git a/hw/riscv/fdt-common.c b/hw/riscv/fdt-common.c index b27ff13bca..e0e31af09b 100644 --- a/hw/riscv/fdt-common.c +++ b/hw/riscv/fdt-common.c @@ -200,3 +200,33 @@ create_fdt_socket_cpu_sifive(void *fdt, char *clust_name, socket_id, socket_hartid_base, phandle, intc_phandles, false, false); } + +void create_fdt_plic(void *fdt, hwaddr addr, uint64_t size, + uint32_t plic_phandle, uint32_t int_cells, + uint32_t addr_cells, uint32_t *plic_cells, + uint32_t cells_size, uint32_t ndev_sources, + bool numa_enabled, int socket_id) +{ + g_autofree char *nodename = NULL; + static const char * const plic_compat[2] = { + "sifive,plic-1.0.0", "riscv,plic0" + }; + + nodename = g_strdup_printf("/soc/interrupt-controller@%"HWADDR_PRIx, addr); + + qemu_fdt_add_subnode(fdt, nodename); + qemu_fdt_setprop_cell(fdt, nodename, "#interrupt-cells", int_cells); + qemu_fdt_setprop_cell(fdt, nodename, "#address-cells", addr_cells); + qemu_fdt_setprop_string_array(fdt, nodename, "compatible", + (char **)&plic_compat, ARRAY_SIZE(plic_compat)); + qemu_fdt_setprop(fdt, nodename, "interrupt-controller", NULL, 0); + qemu_fdt_setprop(fdt, nodename, "interrupts-extended", + plic_cells, cells_size); + qemu_fdt_setprop_sized_cells(fdt, nodename, "reg", + 2, addr, 2, size); + qemu_fdt_setprop_cell(fdt, nodename, "riscv,ndev", ndev_sources); + if (numa_enabled) { + qemu_fdt_setprop_cell(fdt, nodename, "numa-node-id", socket_id); + } + qemu_fdt_setprop_cell(fdt, nodename, "phandle", plic_phandle); +} diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c index 7dfc18d3ec..d923f041e0 100644 --- a/hw/riscv/sifive_u.c +++ b/hw/riscv/sifive_u.c @@ -100,14 +100,11 @@ static void create_fdt(SiFiveUState *s, const MemMapEntry *memmap, MachineState *ms = MACHINE(s); void *fdt; int cpu; - uint32_t *cells; + uint32_t *cells, cells_length; char *nodename; uint32_t plic_phandle, prci_phandle, gpio_phandle, phandle = 1; uint32_t hfclk_phandle, rtcclk_phandle, phy_phandle; static const char * const ethclk_names[2] = { "pclk", "hclk" }; - static const char * const plic_compat[2] = { - "sifive,plic-1.0.0", "riscv,plic0" - }; g_autofree uint32_t *intc_phandles = g_new0(uint32_t, ms->smp.cpus); g_autofree char *clust_name = NULL; @@ -197,7 +194,8 @@ static void create_fdt(SiFiveUState *s, const MemMapEntry *memmap, g_free(nodename); plic_phandle = phandle++; - cells = g_new0(uint32_t, ms->smp.cpus * 4 - 2); + cells_length = ms->smp.cpus * 4 - 2; + cells = g_new0(uint32_t, cells_length); for (cpu = 0; cpu < ms->smp.cpus; cpu++) { /* cpu 0 is the management hart that does not have S-mode */ if (cpu == 0) { @@ -210,26 +208,14 @@ static void create_fdt(SiFiveUState *s, const MemMapEntry *memmap, cells[cpu * 4 + 1] = cpu_to_be32(IRQ_S_EXT); } } - nodename = g_strdup_printf("/soc/interrupt-controller@%lx", - (long)memmap[SIFIVE_U_DEV_PLIC].base); - qemu_fdt_add_subnode(fdt, nodename); - qemu_fdt_setprop_cell(fdt, nodename, "#interrupt-cells", - SIFIVE_U_PLIC_INT_CELLS); - qemu_fdt_setprop_cell(fdt, nodename, "#address-cells", - SIFIVE_U_PLIC_ADDR_CELLS); - qemu_fdt_setprop_string_array(fdt, nodename, "compatible", - (char **)&plic_compat, ARRAY_SIZE(plic_compat)); - qemu_fdt_setprop(fdt, nodename, "interrupt-controller", NULL, 0); - qemu_fdt_setprop(fdt, nodename, "interrupts-extended", - cells, (ms->smp.cpus * 4 - 2) * sizeof(uint32_t)); - qemu_fdt_setprop_cells(fdt, nodename, "reg", - 0x0, memmap[SIFIVE_U_DEV_PLIC].base, - 0x0, memmap[SIFIVE_U_DEV_PLIC].size); - qemu_fdt_setprop_cell(fdt, nodename, "riscv,ndev", - SIFIVE_U_PLIC_NUM_SOURCES - 1); - qemu_fdt_setprop_cell(fdt, nodename, "phandle", plic_phandle); + + create_fdt_plic(fdt, memmap[SIFIVE_U_DEV_PLIC].base, + memmap[SIFIVE_U_DEV_PLIC].size, + plic_phandle, SIFIVE_U_PLIC_INT_CELLS, + SIFIVE_U_PLIC_ADDR_CELLS, cells, + cells_length * sizeof(uint32_t), + SIFIVE_U_PLIC_NUM_SOURCES - 1, false, 0); g_free(cells); - g_free(nodename); gpio_phandle = phandle++; nodename = g_strdup_printf("/soc/gpio@%lx", diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c index fa464e644f..92c30a6f4c 100644 --- a/hw/riscv/virt.c +++ b/hw/riscv/virt.c @@ -326,39 +326,25 @@ static void create_fdt_socket_plic(RISCVVirtState *s, int cpu; g_autofree char *plic_name = NULL; g_autofree uint32_t *plic_cells; - unsigned long plic_addr; MachineState *ms = MACHINE(s); - static const char * const plic_compat[2] = { - "sifive,plic-1.0.0", "riscv,plic0" - }; + unsigned long plic_addr = s->memmap[VIRT_PLIC].base + + (s->memmap[VIRT_PLIC].size * socket); + bool numa_enabled = riscv_numa_enabled(MACHINE(s)); + uint32_t cells_length; - plic_phandles[socket] = (*phandle)++; - plic_addr = s->memmap[VIRT_PLIC].base + - (s->memmap[VIRT_PLIC].size * socket); plic_name = g_strdup_printf("/soc/interrupt-controller@%lx", plic_addr); - qemu_fdt_add_subnode(ms->fdt, plic_name); - qemu_fdt_setprop_cell(ms->fdt, plic_name, - "#interrupt-cells", FDT_PLIC_INT_CELLS); - qemu_fdt_setprop_cell(ms->fdt, plic_name, - "#address-cells", FDT_PLIC_ADDR_CELLS); - qemu_fdt_setprop_string_array(ms->fdt, plic_name, "compatible", - (char **)&plic_compat, - ARRAY_SIZE(plic_compat)); - qemu_fdt_setprop(ms->fdt, plic_name, "interrupt-controller", NULL, 0); if (kvm_enabled()) { - plic_cells = g_new0(uint32_t, s->soc[socket].num_harts * 2); + cells_length = s->soc[socket].num_harts * 2; + plic_cells = g_new0(uint32_t, cells_length); for (cpu = 0; cpu < s->soc[socket].num_harts; cpu++) { plic_cells[cpu * 2 + 0] = cpu_to_be32(intc_phandles[cpu]); plic_cells[cpu * 2 + 1] = cpu_to_be32(IRQ_S_EXT); } - - qemu_fdt_setprop(ms->fdt, plic_name, "interrupts-extended", - plic_cells, - s->soc[socket].num_harts * sizeof(uint32_t) * 2); } else { - plic_cells = g_new0(uint32_t, s->soc[socket].num_harts * 4); + cells_length = s->soc[socket].num_harts * 4; + plic_cells = g_new0(uint32_t, cells_length); for (cpu = 0; cpu < s->soc[socket].num_harts; cpu++) { plic_cells[cpu * 4 + 0] = cpu_to_be32(intc_phandles[cpu]); @@ -366,19 +352,16 @@ static void create_fdt_socket_plic(RISCVVirtState *s, plic_cells[cpu * 4 + 2] = cpu_to_be32(intc_phandles[cpu]); plic_cells[cpu * 4 + 3] = cpu_to_be32(IRQ_S_EXT); } - - qemu_fdt_setprop(ms->fdt, plic_name, "interrupts-extended", - plic_cells, - s->soc[socket].num_harts * sizeof(uint32_t) * 4); } - qemu_fdt_setprop_sized_cells(ms->fdt, plic_name, "reg", - 2, plic_addr, 2, s->memmap[VIRT_PLIC].size); - qemu_fdt_setprop_cell(ms->fdt, plic_name, "riscv,ndev", - VIRT_IRQCHIP_NUM_SOURCES - 1); - riscv_socket_fdt_write_id(ms, plic_name, socket); - qemu_fdt_setprop_cell(ms->fdt, plic_name, "phandle", - plic_phandles[socket]); + plic_phandles[socket] = (*phandle)++; + + create_fdt_plic(ms->fdt, plic_addr, s->memmap[VIRT_PLIC].size, + plic_phandles[socket], FDT_PLIC_INT_CELLS, + FDT_PLIC_ADDR_CELLS, plic_cells, + cells_length * sizeof(uint32_t), + VIRT_IRQCHIP_NUM_SOURCES - 1, + numa_enabled, socket); if (!socket) { platform_bus_add_all_fdt_nodes(ms->fdt, plic_name, diff --git a/include/hw/riscv/fdt-common.h b/include/hw/riscv/fdt-common.h index 2d6b9a5d03..017278b611 100644 --- a/include/hw/riscv/fdt-common.h +++ b/include/hw/riscv/fdt-common.h @@ -30,4 +30,9 @@ void create_fdt_socket_cpu_sifive(void *fdt, char *clust_name, int cpu_id, int socket_id, int socket_hartid_base, uint32_t *phandle, uint32_t *intc_phandles); +void create_fdt_plic(void *fdt, hwaddr addr, uint64_t size, + uint32_t plic_phandle, uint32_t int_cells, + uint32_t addr_cells, uint32_t *plic_cells, + uint32_t cells_size, uint32_t ndev_sources, + bool numa_enabled, int socket); #endif |
