* [PATCH 0/5] hw/riscv: more FDT cleanups (PLIC)
@ 2026-06-16 23:59 Daniel Henrique Barboza
2026-06-16 23:59 ` [PATCH 1/5] hw/riscv/sifive_u.c: remove unneeded qemu_fdt_get_phandle() call Daniel Henrique Barboza
` (5 more replies)
0 siblings, 6 replies; 17+ messages in thread
From: Daniel Henrique Barboza @ 2026-06-16 23:59 UTC (permalink / raw)
To: qemu-devel
Cc: qemu-riscv, alistair.francis, liwei1518, zhiwei_liu,
chao.liu.zevorn, Daniel Henrique Barboza
Hello,
Here is the follow-up I talked about in the first FDT series that was
just merged [1]. This short series handles just the PLIC controller
FDT. This time there are 2 FDT bug fixes in the mix (patches 3 and 4)
that we were lucky to find.
Expected changes after this series are related to patches 3 and 4 only:
$ diff virt.dts virt_patch.dts
189c189
< rng-seed = (...)
---
> rng-seed = (...)
285c285
< plic@c000000 {
---
> interrupt-controller@c000000 {
297c297
< plic@c600000 {
---
> interrupt-controller@c600000 {
$ diff sifive.dts sifive_patch.dts
> #address-cells = <0x00>;
Patches based on master.
[1] https://lore.kernel.org/qemu-devel/20260615203734.954428-1-daniel.barboza@oss.qualcomm.com/
Daniel Henrique Barboza (5):
hw/riscv/sifive_u.c: remove unneeded qemu_fdt_get_phandle() call
hw/riscv/sifive_u.c: use intc_phandle in plic creation
hw/riscv/sifive_u: add #address-cells in PLIC FDT
hw/riscv/virt.c: change 'plic' nodename to 'interrupt-controller'
hw/riscv: add create_fdt_plic() helper
hw/riscv/fdt-common.c | 30 +++++++++++++++++++++
hw/riscv/sifive_u.c | 42 +++++++++--------------------
hw/riscv/virt.c | 51 ++++++++++++-----------------------
include/hw/riscv/fdt-common.h | 5 ++++
include/hw/riscv/sifive_u.h | 2 ++
5 files changed, 67 insertions(+), 63 deletions(-)
--
2.43.0
^ permalink raw reply [flat|nested] 17+ messages in thread
* [PATCH 1/5] hw/riscv/sifive_u.c: remove unneeded qemu_fdt_get_phandle() call
2026-06-16 23:59 [PATCH 0/5] hw/riscv: more FDT cleanups (PLIC) Daniel Henrique Barboza
@ 2026-06-16 23:59 ` Daniel Henrique Barboza
2026-06-22 4:56 ` Alistair Francis
2026-06-23 4:12 ` Chao Liu
2026-06-16 23:59 ` [PATCH 2/5] hw/riscv/sifive_u.c: use intc_phandle in plic creation Daniel Henrique Barboza
` (4 subsequent siblings)
5 siblings, 2 replies; 17+ messages in thread
From: Daniel Henrique Barboza @ 2026-06-16 23:59 UTC (permalink / raw)
To: qemu-devel
Cc: qemu-riscv, alistair.francis, liwei1518, zhiwei_liu,
chao.liu.zevorn, Daniel Henrique Barboza, Alistair Francis,
Palmer Dabbelt
create_fdt() has the following code sequence:
plic_phandle = phandle++;
(...)
qemu_fdt_setprop_cell(fdt, nodename, "phandle", plic_phandle);
plic_phandle = qemu_fdt_get_phandle(fdt, nodename);
What this is doing is assigning a value to plic_phandle, then use that
as phandle of "nodename", and then fetching the phandle of "nodename"
again in the same variable that already had the right phandle val.
Here's how it looks like in gdb:
Thread 1 "qemu-system-ris" hit Breakpoint 1, create_fdt
(s=0xaaaaac162a30, memmap=0xaaaaab8f70c8 <sifive_u_memmap>,
is_32_bit=false) at ../hw/riscv/sifive_u.c:199
199 plic_phandle = phandle++;
(gdb) n
200 cells = g_new0(uint32_t, ms->smp.cpus * 4 - 2);
(gdb) p plic_phandle
$3 = 12
(gdb) c
Continuing.
Thread 1 "qemu-system-ris" hit Breakpoint 2, create_fdt
(s=0xaaaaac162a30, memmap=0xaaaaab8f70c8 <sifive_u_memmap>,
is_32_bit=false) at ../hw/riscv/sifive_u.c:232
232 plic_phandle = qemu_fdt_get_phandle(fdt, nodename);
(gdb) n
233 g_free(cells);
(gdb) p plic_phandle
$4 = 12
(gdb)
Remove the extra qemu_fdt_get_phandle() call.
Signed-off-by: Daniel Henrique Barboza <daniel.barboza@oss.qualcomm.com>
---
hw/riscv/sifive_u.c | 1 -
1 file changed, 1 deletion(-)
diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
index 0c6e4204cb..fda9a09f06 100644
--- a/hw/riscv/sifive_u.c
+++ b/hw/riscv/sifive_u.c
@@ -229,7 +229,6 @@ static void create_fdt(SiFiveUState *s, const MemMapEntry *memmap,
qemu_fdt_setprop_cell(fdt, nodename, "riscv,ndev",
SIFIVE_U_PLIC_NUM_SOURCES - 1);
qemu_fdt_setprop_cell(fdt, nodename, "phandle", plic_phandle);
- plic_phandle = qemu_fdt_get_phandle(fdt, nodename);
g_free(cells);
g_free(nodename);
--
2.43.0
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH 2/5] hw/riscv/sifive_u.c: use intc_phandle in plic creation
2026-06-16 23:59 [PATCH 0/5] hw/riscv: more FDT cleanups (PLIC) Daniel Henrique Barboza
2026-06-16 23:59 ` [PATCH 1/5] hw/riscv/sifive_u.c: remove unneeded qemu_fdt_get_phandle() call Daniel Henrique Barboza
@ 2026-06-16 23:59 ` Daniel Henrique Barboza
2026-06-22 4:57 ` Alistair Francis
2026-06-23 4:14 ` Chao Liu
2026-06-16 23:59 ` [PATCH 3/5] hw/riscv/sifive_u: add #address-cells in PLIC FDT Daniel Henrique Barboza
` (3 subsequent siblings)
5 siblings, 2 replies; 17+ messages in thread
From: Daniel Henrique Barboza @ 2026-06-16 23:59 UTC (permalink / raw)
To: qemu-devel
Cc: qemu-riscv, alistair.francis, liwei1518, zhiwei_liu,
chao.liu.zevorn, Daniel Henrique Barboza, Alistair Francis,
Palmer Dabbelt
The info about intc_phandles for each CPU is already stored in the
intc_phandles array. We don't need to fetch them again using
qemu_fdt_get_phandle().
Signed-off-by: Daniel Henrique Barboza <daniel.barboza@oss.qualcomm.com>
---
hw/riscv/sifive_u.c | 10 +++-------
1 file changed, 3 insertions(+), 7 deletions(-)
diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
index fda9a09f06..b3468254f5 100644
--- a/hw/riscv/sifive_u.c
+++ b/hw/riscv/sifive_u.c
@@ -199,20 +199,16 @@ static void create_fdt(SiFiveUState *s, const MemMapEntry *memmap,
plic_phandle = phandle++;
cells = g_new0(uint32_t, ms->smp.cpus * 4 - 2);
for (cpu = 0; cpu < ms->smp.cpus; cpu++) {
- nodename =
- g_strdup_printf("/cpus/cpu@%d/interrupt-controller", cpu);
- uint32_t intc_phandle = qemu_fdt_get_phandle(fdt, nodename);
/* cpu 0 is the management hart that does not have S-mode */
if (cpu == 0) {
- cells[0] = cpu_to_be32(intc_phandle);
+ cells[0] = cpu_to_be32(intc_phandles[cpu]);
cells[1] = cpu_to_be32(IRQ_M_EXT);
} else {
- cells[cpu * 4 - 2] = cpu_to_be32(intc_phandle);
+ cells[cpu * 4 - 2] = cpu_to_be32(intc_phandles[cpu]);
cells[cpu * 4 - 1] = cpu_to_be32(IRQ_M_EXT);
- cells[cpu * 4 + 0] = cpu_to_be32(intc_phandle);
+ cells[cpu * 4 + 0] = cpu_to_be32(intc_phandles[cpu]);
cells[cpu * 4 + 1] = cpu_to_be32(IRQ_S_EXT);
}
- g_free(nodename);
}
nodename = g_strdup_printf("/soc/interrupt-controller@%lx",
(long)memmap[SIFIVE_U_DEV_PLIC].base);
--
2.43.0
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH 3/5] hw/riscv/sifive_u: add #address-cells in PLIC FDT
2026-06-16 23:59 [PATCH 0/5] hw/riscv: more FDT cleanups (PLIC) Daniel Henrique Barboza
2026-06-16 23:59 ` [PATCH 1/5] hw/riscv/sifive_u.c: remove unneeded qemu_fdt_get_phandle() call Daniel Henrique Barboza
2026-06-16 23:59 ` [PATCH 2/5] hw/riscv/sifive_u.c: use intc_phandle in plic creation Daniel Henrique Barboza
@ 2026-06-16 23:59 ` Daniel Henrique Barboza
2026-06-22 4:59 ` Alistair Francis
2026-06-23 4:14 ` Chao Liu
2026-06-16 23:59 ` [PATCH 4/5] hw/riscv/virt.c: change 'plic' nodename to 'interrupt-controller' Daniel Henrique Barboza
` (2 subsequent siblings)
5 siblings, 2 replies; 17+ messages in thread
From: Daniel Henrique Barboza @ 2026-06-16 23:59 UTC (permalink / raw)
To: qemu-devel
Cc: qemu-riscv, alistair.francis, liwei1518, zhiwei_liu,
chao.liu.zevorn, Daniel Henrique Barboza, Alistair Francis,
Palmer Dabbelt
By Linux FDT docs in [1] the "address-cells" property is mandatory. Set
it to zero.
While we're at it let's also put this new value and the interrupt-cells
value in macros, like the 'virt' board is doing.
[1] https://www.kernel.org/doc/Documentation/devicetree/bindings/interrupt-controller/sifive%2Cplic-1.0.0.txt
Signed-off-by: Daniel Henrique Barboza <daniel.barboza@oss.qualcomm.com>
---
hw/riscv/sifive_u.c | 5 ++++-
include/hw/riscv/sifive_u.h | 2 ++
2 files changed, 6 insertions(+), 1 deletion(-)
diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
index b3468254f5..7dfc18d3ec 100644
--- a/hw/riscv/sifive_u.c
+++ b/hw/riscv/sifive_u.c
@@ -213,7 +213,10 @@ static void create_fdt(SiFiveUState *s, const MemMapEntry *memmap,
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", 1);
+ 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);
diff --git a/include/hw/riscv/sifive_u.h b/include/hw/riscv/sifive_u.h
index e4c9860d50..aed966a62d 100644
--- a/include/hw/riscv/sifive_u.h
+++ b/include/hw/riscv/sifive_u.h
@@ -156,6 +156,8 @@ enum {
#define SIFIVE_U_MANAGEMENT_CPU_COUNT 1
#define SIFIVE_U_COMPUTE_CPU_COUNT 4
+#define SIFIVE_U_PLIC_ADDR_CELLS 0
+#define SIFIVE_U_PLIC_INT_CELLS 1
#define SIFIVE_U_PLIC_NUM_SOURCES 54
#define SIFIVE_U_PLIC_NUM_PRIORITIES 7
#define SIFIVE_U_PLIC_PRIORITY_BASE 0x00
--
2.43.0
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH 4/5] hw/riscv/virt.c: change 'plic' nodename to 'interrupt-controller'
2026-06-16 23:59 [PATCH 0/5] hw/riscv: more FDT cleanups (PLIC) Daniel Henrique Barboza
` (2 preceding siblings ...)
2026-06-16 23:59 ` [PATCH 3/5] hw/riscv/sifive_u: add #address-cells in PLIC FDT Daniel Henrique Barboza
@ 2026-06-16 23:59 ` Daniel Henrique Barboza
2026-06-22 5:00 ` Alistair Francis
2026-06-23 4:15 ` Chao Liu
2026-06-16 23:59 ` [PATCH 5/5] hw/riscv: add create_fdt_plic() helper Daniel Henrique Barboza
2026-06-22 23:09 ` [PATCH 0/5] hw/riscv: more FDT cleanups (PLIC) Alistair Francis
5 siblings, 2 replies; 17+ messages in thread
From: Daniel Henrique Barboza @ 2026-06-16 23:59 UTC (permalink / raw)
To: qemu-devel
Cc: qemu-riscv, alistair.francis, liwei1518, zhiwei_liu,
chao.liu.zevorn, Daniel Henrique Barboza, Palmer Dabbelt
We're still using "/soc/plic@..." as FDT nodename in virt.c. This is
not the right nodename per the DT docs:
https://www.kernel.org/doc/Documentation/devicetree/bindings/interrupt-controller/sifive%2Cplic-1.0.0.txt
The nodename must be 'interrupt-controller@...' since the node inherits
the 'interrupt-controller' type. In fact, ever since at least the 2020
Linux kernel commit c825a081c169cc7f ("dt-bindings: riscv: convert plic
bindings to json-schema") the correct nodename has been
'interrupt-controller' for the sifive PLIC controller.
There's no deprecation needed for bug fixes so we're just fixing the
name. This was the policy we dud when fixing the aplic [1] and the
imsic [2] nodenames to 'interrupt-controller@...' as well.
The sifive_u PLIC FDT already uses the correct nodename for PLIC, so it
is safe to assume that available SW is already aware of the correct
nodename and this change won't affect well-behaved SW.
[1] commit 29390fd ("hw/riscv/virt.c: rename aplic nodename to 'interrupt-controller'")
[2] commit e8ad581 ("hw/riscv/virt.c: change imsic nodename to 'interrupt-controller'")
Signed-off-by: Daniel Henrique Barboza <daniel.barboza@oss.qualcomm.com>
---
hw/riscv/virt.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
index 33775a61fd..fa464e644f 100644
--- a/hw/riscv/virt.c
+++ b/hw/riscv/virt.c
@@ -335,7 +335,7 @@ static void create_fdt_socket_plic(RISCVVirtState *s,
plic_phandles[socket] = (*phandle)++;
plic_addr = s->memmap[VIRT_PLIC].base +
(s->memmap[VIRT_PLIC].size * socket);
- plic_name = g_strdup_printf("/soc/plic@%lx", plic_addr);
+ 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);
--
2.43.0
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH 5/5] hw/riscv: add create_fdt_plic() helper
2026-06-16 23:59 [PATCH 0/5] hw/riscv: more FDT cleanups (PLIC) Daniel Henrique Barboza
` (3 preceding siblings ...)
2026-06-16 23:59 ` [PATCH 4/5] hw/riscv/virt.c: change 'plic' nodename to 'interrupt-controller' Daniel Henrique Barboza
@ 2026-06-16 23:59 ` Daniel Henrique Barboza
2026-06-22 5:02 ` Alistair Francis
2026-06-23 4:16 ` Chao Liu
2026-06-22 23:09 ` [PATCH 0/5] hw/riscv: more FDT cleanups (PLIC) Alistair Francis
5 siblings, 2 replies; 17+ messages in thread
From: Daniel Henrique Barboza @ 2026-06-16 23:59 UTC (permalink / raw)
To: qemu-devel
Cc: qemu-riscv, alistair.francis, liwei1518, zhiwei_liu,
chao.liu.zevorn, Daniel Henrique Barboza, Palmer Dabbelt
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>
---
hw/riscv/fdt-common.c | 30 +++++++++++++++++++++
hw/riscv/sifive_u.c | 34 +++++++-----------------
hw/riscv/virt.c | 49 ++++++++++++-----------------------
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
--
2.43.0
^ permalink raw reply related [flat|nested] 17+ messages in thread
* Re: [PATCH 1/5] hw/riscv/sifive_u.c: remove unneeded qemu_fdt_get_phandle() call
2026-06-16 23:59 ` [PATCH 1/5] hw/riscv/sifive_u.c: remove unneeded qemu_fdt_get_phandle() call Daniel Henrique Barboza
@ 2026-06-22 4:56 ` Alistair Francis
2026-06-23 4:12 ` Chao Liu
1 sibling, 0 replies; 17+ messages in thread
From: Alistair Francis @ 2026-06-22 4:56 UTC (permalink / raw)
To: Daniel Henrique Barboza
Cc: qemu-devel, qemu-riscv, alistair.francis, liwei1518, zhiwei_liu,
chao.liu.zevorn, Palmer Dabbelt
On Wed, Jun 17, 2026 at 10:00 AM Daniel Henrique Barboza
<daniel.barboza@oss.qualcomm.com> wrote:
>
> create_fdt() has the following code sequence:
>
> plic_phandle = phandle++;
> (...)
> qemu_fdt_setprop_cell(fdt, nodename, "phandle", plic_phandle);
> plic_phandle = qemu_fdt_get_phandle(fdt, nodename);
>
> What this is doing is assigning a value to plic_phandle, then use that
> as phandle of "nodename", and then fetching the phandle of "nodename"
> again in the same variable that already had the right phandle val.
>
> Here's how it looks like in gdb:
>
> Thread 1 "qemu-system-ris" hit Breakpoint 1, create_fdt
> (s=0xaaaaac162a30, memmap=0xaaaaab8f70c8 <sifive_u_memmap>,
> is_32_bit=false) at ../hw/riscv/sifive_u.c:199
> 199 plic_phandle = phandle++;
> (gdb) n
> 200 cells = g_new0(uint32_t, ms->smp.cpus * 4 - 2);
> (gdb) p plic_phandle
> $3 = 12
> (gdb) c
> Continuing.
>
> Thread 1 "qemu-system-ris" hit Breakpoint 2, create_fdt
> (s=0xaaaaac162a30, memmap=0xaaaaab8f70c8 <sifive_u_memmap>,
> is_32_bit=false) at ../hw/riscv/sifive_u.c:232
> 232 plic_phandle = qemu_fdt_get_phandle(fdt, nodename);
> (gdb) n
> 233 g_free(cells);
> (gdb) p plic_phandle
> $4 = 12
> (gdb)
>
> Remove the extra qemu_fdt_get_phandle() call.
>
> Signed-off-by: Daniel Henrique Barboza <daniel.barboza@oss.qualcomm.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Alistair
> ---
> hw/riscv/sifive_u.c | 1 -
> 1 file changed, 1 deletion(-)
>
> diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
> index 0c6e4204cb..fda9a09f06 100644
> --- a/hw/riscv/sifive_u.c
> +++ b/hw/riscv/sifive_u.c
> @@ -229,7 +229,6 @@ static void create_fdt(SiFiveUState *s, const MemMapEntry *memmap,
> qemu_fdt_setprop_cell(fdt, nodename, "riscv,ndev",
> SIFIVE_U_PLIC_NUM_SOURCES - 1);
> qemu_fdt_setprop_cell(fdt, nodename, "phandle", plic_phandle);
> - plic_phandle = qemu_fdt_get_phandle(fdt, nodename);
> g_free(cells);
> g_free(nodename);
>
> --
> 2.43.0
>
>
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH 2/5] hw/riscv/sifive_u.c: use intc_phandle in plic creation
2026-06-16 23:59 ` [PATCH 2/5] hw/riscv/sifive_u.c: use intc_phandle in plic creation Daniel Henrique Barboza
@ 2026-06-22 4:57 ` Alistair Francis
2026-06-23 4:14 ` Chao Liu
1 sibling, 0 replies; 17+ messages in thread
From: Alistair Francis @ 2026-06-22 4:57 UTC (permalink / raw)
To: Daniel Henrique Barboza
Cc: qemu-devel, qemu-riscv, alistair.francis, liwei1518, zhiwei_liu,
chao.liu.zevorn, Palmer Dabbelt
On Wed, Jun 17, 2026 at 10:01 AM Daniel Henrique Barboza
<daniel.barboza@oss.qualcomm.com> wrote:
>
> The info about intc_phandles for each CPU is already stored in the
> intc_phandles array. We don't need to fetch them again using
> qemu_fdt_get_phandle().
>
> Signed-off-by: Daniel Henrique Barboza <daniel.barboza@oss.qualcomm.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Alistair
> ---
> hw/riscv/sifive_u.c | 10 +++-------
> 1 file changed, 3 insertions(+), 7 deletions(-)
>
> diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
> index fda9a09f06..b3468254f5 100644
> --- a/hw/riscv/sifive_u.c
> +++ b/hw/riscv/sifive_u.c
> @@ -199,20 +199,16 @@ static void create_fdt(SiFiveUState *s, const MemMapEntry *memmap,
> plic_phandle = phandle++;
> cells = g_new0(uint32_t, ms->smp.cpus * 4 - 2);
> for (cpu = 0; cpu < ms->smp.cpus; cpu++) {
> - nodename =
> - g_strdup_printf("/cpus/cpu@%d/interrupt-controller", cpu);
> - uint32_t intc_phandle = qemu_fdt_get_phandle(fdt, nodename);
> /* cpu 0 is the management hart that does not have S-mode */
> if (cpu == 0) {
> - cells[0] = cpu_to_be32(intc_phandle);
> + cells[0] = cpu_to_be32(intc_phandles[cpu]);
> cells[1] = cpu_to_be32(IRQ_M_EXT);
> } else {
> - cells[cpu * 4 - 2] = cpu_to_be32(intc_phandle);
> + cells[cpu * 4 - 2] = cpu_to_be32(intc_phandles[cpu]);
> cells[cpu * 4 - 1] = cpu_to_be32(IRQ_M_EXT);
> - cells[cpu * 4 + 0] = cpu_to_be32(intc_phandle);
> + cells[cpu * 4 + 0] = cpu_to_be32(intc_phandles[cpu]);
> cells[cpu * 4 + 1] = cpu_to_be32(IRQ_S_EXT);
> }
> - g_free(nodename);
> }
> nodename = g_strdup_printf("/soc/interrupt-controller@%lx",
> (long)memmap[SIFIVE_U_DEV_PLIC].base);
> --
> 2.43.0
>
>
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH 3/5] hw/riscv/sifive_u: add #address-cells in PLIC FDT
2026-06-16 23:59 ` [PATCH 3/5] hw/riscv/sifive_u: add #address-cells in PLIC FDT Daniel Henrique Barboza
@ 2026-06-22 4:59 ` Alistair Francis
2026-06-23 4:14 ` Chao Liu
1 sibling, 0 replies; 17+ messages in thread
From: Alistair Francis @ 2026-06-22 4:59 UTC (permalink / raw)
To: Daniel Henrique Barboza
Cc: qemu-devel, qemu-riscv, alistair.francis, liwei1518, zhiwei_liu,
chao.liu.zevorn, Palmer Dabbelt
On Wed, Jun 17, 2026 at 10:01 AM Daniel Henrique Barboza
<daniel.barboza@oss.qualcomm.com> wrote:
>
> By Linux FDT docs in [1] the "address-cells" property is mandatory. Set
> it to zero.
>
> While we're at it let's also put this new value and the interrupt-cells
> value in macros, like the 'virt' board is doing.
>
> [1] https://www.kernel.org/doc/Documentation/devicetree/bindings/interrupt-controller/sifive%2Cplic-1.0.0.txt
>
> Signed-off-by: Daniel Henrique Barboza <daniel.barboza@oss.qualcomm.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Alistair
> ---
> hw/riscv/sifive_u.c | 5 ++++-
> include/hw/riscv/sifive_u.h | 2 ++
> 2 files changed, 6 insertions(+), 1 deletion(-)
>
> diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
> index b3468254f5..7dfc18d3ec 100644
> --- a/hw/riscv/sifive_u.c
> +++ b/hw/riscv/sifive_u.c
> @@ -213,7 +213,10 @@ static void create_fdt(SiFiveUState *s, const MemMapEntry *memmap,
> 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", 1);
> + 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);
> diff --git a/include/hw/riscv/sifive_u.h b/include/hw/riscv/sifive_u.h
> index e4c9860d50..aed966a62d 100644
> --- a/include/hw/riscv/sifive_u.h
> +++ b/include/hw/riscv/sifive_u.h
> @@ -156,6 +156,8 @@ enum {
> #define SIFIVE_U_MANAGEMENT_CPU_COUNT 1
> #define SIFIVE_U_COMPUTE_CPU_COUNT 4
>
> +#define SIFIVE_U_PLIC_ADDR_CELLS 0
> +#define SIFIVE_U_PLIC_INT_CELLS 1
> #define SIFIVE_U_PLIC_NUM_SOURCES 54
> #define SIFIVE_U_PLIC_NUM_PRIORITIES 7
> #define SIFIVE_U_PLIC_PRIORITY_BASE 0x00
> --
> 2.43.0
>
>
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH 4/5] hw/riscv/virt.c: change 'plic' nodename to 'interrupt-controller'
2026-06-16 23:59 ` [PATCH 4/5] hw/riscv/virt.c: change 'plic' nodename to 'interrupt-controller' Daniel Henrique Barboza
@ 2026-06-22 5:00 ` Alistair Francis
2026-06-23 4:15 ` Chao Liu
1 sibling, 0 replies; 17+ messages in thread
From: Alistair Francis @ 2026-06-22 5:00 UTC (permalink / raw)
To: Daniel Henrique Barboza
Cc: qemu-devel, qemu-riscv, alistair.francis, liwei1518, zhiwei_liu,
chao.liu.zevorn, Palmer Dabbelt
On Wed, Jun 17, 2026 at 10:01 AM Daniel Henrique Barboza
<daniel.barboza@oss.qualcomm.com> wrote:
>
> We're still using "/soc/plic@..." as FDT nodename in virt.c. This is
> not the right nodename per the DT docs:
>
> https://www.kernel.org/doc/Documentation/devicetree/bindings/interrupt-controller/sifive%2Cplic-1.0.0.txt
>
> The nodename must be 'interrupt-controller@...' since the node inherits
> the 'interrupt-controller' type. In fact, ever since at least the 2020
> Linux kernel commit c825a081c169cc7f ("dt-bindings: riscv: convert plic
> bindings to json-schema") the correct nodename has been
> 'interrupt-controller' for the sifive PLIC controller.
>
> There's no deprecation needed for bug fixes so we're just fixing the
> name. This was the policy we dud when fixing the aplic [1] and the
> imsic [2] nodenames to 'interrupt-controller@...' as well.
>
> The sifive_u PLIC FDT already uses the correct nodename for PLIC, so it
> is safe to assume that available SW is already aware of the correct
> nodename and this change won't affect well-behaved SW.
>
> [1] commit 29390fd ("hw/riscv/virt.c: rename aplic nodename to 'interrupt-controller'")
> [2] commit e8ad581 ("hw/riscv/virt.c: change imsic nodename to 'interrupt-controller'")
>
> Signed-off-by: Daniel Henrique Barboza <daniel.barboza@oss.qualcomm.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Alistair
> ---
> hw/riscv/virt.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
> index 33775a61fd..fa464e644f 100644
> --- a/hw/riscv/virt.c
> +++ b/hw/riscv/virt.c
> @@ -335,7 +335,7 @@ static void create_fdt_socket_plic(RISCVVirtState *s,
> plic_phandles[socket] = (*phandle)++;
> plic_addr = s->memmap[VIRT_PLIC].base +
> (s->memmap[VIRT_PLIC].size * socket);
> - plic_name = g_strdup_printf("/soc/plic@%lx", plic_addr);
> + 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);
> --
> 2.43.0
>
>
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH 5/5] hw/riscv: add create_fdt_plic() helper
2026-06-16 23:59 ` [PATCH 5/5] hw/riscv: add create_fdt_plic() helper Daniel Henrique Barboza
@ 2026-06-22 5:02 ` Alistair Francis
2026-06-23 4:16 ` Chao Liu
1 sibling, 0 replies; 17+ messages in thread
From: Alistair Francis @ 2026-06-22 5:02 UTC (permalink / raw)
To: Daniel Henrique Barboza
Cc: qemu-devel, qemu-riscv, alistair.francis, liwei1518, zhiwei_liu,
chao.liu.zevorn, Palmer Dabbelt
On Wed, Jun 17, 2026 at 10:01 AM Daniel Henrique Barboza
<daniel.barboza@oss.qualcomm.com> wrote:
>
> 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>
Alistair
> ---
> hw/riscv/fdt-common.c | 30 +++++++++++++++++++++
> hw/riscv/sifive_u.c | 34 +++++++-----------------
> hw/riscv/virt.c | 49 ++++++++++++-----------------------
> 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
> --
> 2.43.0
>
>
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH 0/5] hw/riscv: more FDT cleanups (PLIC)
2026-06-16 23:59 [PATCH 0/5] hw/riscv: more FDT cleanups (PLIC) Daniel Henrique Barboza
` (4 preceding siblings ...)
2026-06-16 23:59 ` [PATCH 5/5] hw/riscv: add create_fdt_plic() helper Daniel Henrique Barboza
@ 2026-06-22 23:09 ` Alistair Francis
5 siblings, 0 replies; 17+ messages in thread
From: Alistair Francis @ 2026-06-22 23:09 UTC (permalink / raw)
To: Daniel Henrique Barboza
Cc: qemu-devel, qemu-riscv, alistair.francis, liwei1518, zhiwei_liu,
chao.liu.zevorn
On Wed, Jun 17, 2026 at 10:00 AM Daniel Henrique Barboza
<daniel.barboza@oss.qualcomm.com> wrote:
>
> Hello,
>
> Here is the follow-up I talked about in the first FDT series that was
> just merged [1]. This short series handles just the PLIC controller
> FDT. This time there are 2 FDT bug fixes in the mix (patches 3 and 4)
> that we were lucky to find.
>
> Expected changes after this series are related to patches 3 and 4 only:
>
> $ diff virt.dts virt_patch.dts
> 189c189
> < rng-seed = (...)
> ---
> > rng-seed = (...)
> 285c285
> < plic@c000000 {
> ---
> > interrupt-controller@c000000 {
> 297c297
> < plic@c600000 {
> ---
> > interrupt-controller@c600000 {
>
> $ diff sifive.dts sifive_patch.dts
> > #address-cells = <0x00>;
>
>
> Patches based on master.
>
> [1] https://lore.kernel.org/qemu-devel/20260615203734.954428-1-daniel.barboza@oss.qualcomm.com/
>
>
> Daniel Henrique Barboza (5):
> hw/riscv/sifive_u.c: remove unneeded qemu_fdt_get_phandle() call
> hw/riscv/sifive_u.c: use intc_phandle in plic creation
> hw/riscv/sifive_u: add #address-cells in PLIC FDT
> hw/riscv/virt.c: change 'plic' nodename to 'interrupt-controller'
> hw/riscv: add create_fdt_plic() helper
Thanks!
Applied to riscv-to-apply.next
Alistair
>
> hw/riscv/fdt-common.c | 30 +++++++++++++++++++++
> hw/riscv/sifive_u.c | 42 +++++++++--------------------
> hw/riscv/virt.c | 51 ++++++++++++-----------------------
> include/hw/riscv/fdt-common.h | 5 ++++
> include/hw/riscv/sifive_u.h | 2 ++
> 5 files changed, 67 insertions(+), 63 deletions(-)
>
> --
> 2.43.0
>
>
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH 1/5] hw/riscv/sifive_u.c: remove unneeded qemu_fdt_get_phandle() call
2026-06-16 23:59 ` [PATCH 1/5] hw/riscv/sifive_u.c: remove unneeded qemu_fdt_get_phandle() call Daniel Henrique Barboza
2026-06-22 4:56 ` Alistair Francis
@ 2026-06-23 4:12 ` Chao Liu
1 sibling, 0 replies; 17+ messages in thread
From: Chao Liu @ 2026-06-23 4:12 UTC (permalink / raw)
To: Daniel Henrique Barboza
Cc: qemu-devel, qemu-riscv, alistair.francis, liwei1518, zhiwei_liu,
Palmer Dabbelt
On Tue, Jun 16, 2026 at 08:59:35PM +0800, Daniel Henrique Barboza wrote:
> create_fdt() has the following code sequence:
>
> plic_phandle = phandle++;
> (...)
> qemu_fdt_setprop_cell(fdt, nodename, "phandle", plic_phandle);
> plic_phandle = qemu_fdt_get_phandle(fdt, nodename);
>
> What this is doing is assigning a value to plic_phandle, then use that
> as phandle of "nodename", and then fetching the phandle of "nodename"
> again in the same variable that already had the right phandle val.
>
> Here's how it looks like in gdb:
>
> Thread 1 "qemu-system-ris" hit Breakpoint 1, create_fdt
> (s=0xaaaaac162a30, memmap=0xaaaaab8f70c8 <sifive_u_memmap>,
> is_32_bit=false) at ../hw/riscv/sifive_u.c:199
> 199 plic_phandle = phandle++;
> (gdb) n
> 200 cells = g_new0(uint32_t, ms->smp.cpus * 4 - 2);
> (gdb) p plic_phandle
> $3 = 12
> (gdb) c
> Continuing.
>
> Thread 1 "qemu-system-ris" hit Breakpoint 2, create_fdt
> (s=0xaaaaac162a30, memmap=0xaaaaab8f70c8 <sifive_u_memmap>,
> is_32_bit=false) at ../hw/riscv/sifive_u.c:232
> 232 plic_phandle = qemu_fdt_get_phandle(fdt, nodename);
> (gdb) n
> 233 g_free(cells);
> (gdb) p plic_phandle
> $4 = 12
> (gdb)
>
> Remove the extra qemu_fdt_get_phandle() call.
>
> Signed-off-by: Daniel Henrique Barboza <daniel.barboza@oss.qualcomm.com>
Reviewed-by: Chao Liu <chao.liu.zevorn@gmail.com>
Thanks,
Chao
> ---
> hw/riscv/sifive_u.c | 1 -
> 1 file changed, 1 deletion(-)
>
> diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
> index 0c6e4204cb..fda9a09f06 100644
> --- a/hw/riscv/sifive_u.c
> +++ b/hw/riscv/sifive_u.c
> @@ -229,7 +229,6 @@ static void create_fdt(SiFiveUState *s, const MemMapEntry *memmap,
> qemu_fdt_setprop_cell(fdt, nodename, "riscv,ndev",
> SIFIVE_U_PLIC_NUM_SOURCES - 1);
> qemu_fdt_setprop_cell(fdt, nodename, "phandle", plic_phandle);
> - plic_phandle = qemu_fdt_get_phandle(fdt, nodename);
> g_free(cells);
> g_free(nodename);
>
> --
> 2.43.0
>
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH 2/5] hw/riscv/sifive_u.c: use intc_phandle in plic creation
2026-06-16 23:59 ` [PATCH 2/5] hw/riscv/sifive_u.c: use intc_phandle in plic creation Daniel Henrique Barboza
2026-06-22 4:57 ` Alistair Francis
@ 2026-06-23 4:14 ` Chao Liu
1 sibling, 0 replies; 17+ messages in thread
From: Chao Liu @ 2026-06-23 4:14 UTC (permalink / raw)
To: Daniel Henrique Barboza
Cc: qemu-devel, qemu-riscv, alistair.francis, liwei1518, zhiwei_liu,
Palmer Dabbelt
On Tue, Jun 16, 2026 at 08:59:36PM +0800, Daniel Henrique Barboza wrote:
> The info about intc_phandles for each CPU is already stored in the
> intc_phandles array. We don't need to fetch them again using
> qemu_fdt_get_phandle().
>
> Signed-off-by: Daniel Henrique Barboza <daniel.barboza@oss.qualcomm.com>
Reviewed-by: Chao Liu <chao.liu.zevorn@gmail.com>
Thanks,
Chao
> ---
> hw/riscv/sifive_u.c | 10 +++-------
> 1 file changed, 3 insertions(+), 7 deletions(-)
>
> diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
> index fda9a09f06..b3468254f5 100644
> --- a/hw/riscv/sifive_u.c
> +++ b/hw/riscv/sifive_u.c
> @@ -199,20 +199,16 @@ static void create_fdt(SiFiveUState *s, const MemMapEntry *memmap,
> plic_phandle = phandle++;
> cells = g_new0(uint32_t, ms->smp.cpus * 4 - 2);
> for (cpu = 0; cpu < ms->smp.cpus; cpu++) {
> - nodename =
> - g_strdup_printf("/cpus/cpu@%d/interrupt-controller", cpu);
> - uint32_t intc_phandle = qemu_fdt_get_phandle(fdt, nodename);
> /* cpu 0 is the management hart that does not have S-mode */
> if (cpu == 0) {
> - cells[0] = cpu_to_be32(intc_phandle);
> + cells[0] = cpu_to_be32(intc_phandles[cpu]);
> cells[1] = cpu_to_be32(IRQ_M_EXT);
> } else {
> - cells[cpu * 4 - 2] = cpu_to_be32(intc_phandle);
> + cells[cpu * 4 - 2] = cpu_to_be32(intc_phandles[cpu]);
> cells[cpu * 4 - 1] = cpu_to_be32(IRQ_M_EXT);
> - cells[cpu * 4 + 0] = cpu_to_be32(intc_phandle);
> + cells[cpu * 4 + 0] = cpu_to_be32(intc_phandles[cpu]);
> cells[cpu * 4 + 1] = cpu_to_be32(IRQ_S_EXT);
> }
> - g_free(nodename);
> }
> nodename = g_strdup_printf("/soc/interrupt-controller@%lx",
> (long)memmap[SIFIVE_U_DEV_PLIC].base);
> --
> 2.43.0
>
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH 3/5] hw/riscv/sifive_u: add #address-cells in PLIC FDT
2026-06-16 23:59 ` [PATCH 3/5] hw/riscv/sifive_u: add #address-cells in PLIC FDT Daniel Henrique Barboza
2026-06-22 4:59 ` Alistair Francis
@ 2026-06-23 4:14 ` Chao Liu
1 sibling, 0 replies; 17+ messages in thread
From: Chao Liu @ 2026-06-23 4:14 UTC (permalink / raw)
To: Daniel Henrique Barboza
Cc: qemu-devel, qemu-riscv, alistair.francis, liwei1518, zhiwei_liu,
Palmer Dabbelt
On Tue, Jun 16, 2026 at 08:59:37PM +0800, Daniel Henrique Barboza wrote:
> By Linux FDT docs in [1] the "address-cells" property is mandatory. Set
> it to zero.
>
> While we're at it let's also put this new value and the interrupt-cells
> value in macros, like the 'virt' board is doing.
>
> [1] https://www.kernel.org/doc/Documentation/devicetree/bindings/interrupt-controller/sifive%2Cplic-1.0.0.txt
>
> Signed-off-by: Daniel Henrique Barboza <daniel.barboza@oss.qualcomm.com>
Reviewed-by: Chao Liu <chao.liu.zevorn@gmail.com>
Thanks,
Chao
> ---
> hw/riscv/sifive_u.c | 5 ++++-
> include/hw/riscv/sifive_u.h | 2 ++
> 2 files changed, 6 insertions(+), 1 deletion(-)
>
> diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
> index b3468254f5..7dfc18d3ec 100644
> --- a/hw/riscv/sifive_u.c
> +++ b/hw/riscv/sifive_u.c
> @@ -213,7 +213,10 @@ static void create_fdt(SiFiveUState *s, const MemMapEntry *memmap,
> 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", 1);
> + 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);
> diff --git a/include/hw/riscv/sifive_u.h b/include/hw/riscv/sifive_u.h
> index e4c9860d50..aed966a62d 100644
> --- a/include/hw/riscv/sifive_u.h
> +++ b/include/hw/riscv/sifive_u.h
> @@ -156,6 +156,8 @@ enum {
> #define SIFIVE_U_MANAGEMENT_CPU_COUNT 1
> #define SIFIVE_U_COMPUTE_CPU_COUNT 4
>
> +#define SIFIVE_U_PLIC_ADDR_CELLS 0
> +#define SIFIVE_U_PLIC_INT_CELLS 1
> #define SIFIVE_U_PLIC_NUM_SOURCES 54
> #define SIFIVE_U_PLIC_NUM_PRIORITIES 7
> #define SIFIVE_U_PLIC_PRIORITY_BASE 0x00
> --
> 2.43.0
>
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH 4/5] hw/riscv/virt.c: change 'plic' nodename to 'interrupt-controller'
2026-06-16 23:59 ` [PATCH 4/5] hw/riscv/virt.c: change 'plic' nodename to 'interrupt-controller' Daniel Henrique Barboza
2026-06-22 5:00 ` Alistair Francis
@ 2026-06-23 4:15 ` Chao Liu
1 sibling, 0 replies; 17+ messages in thread
From: Chao Liu @ 2026-06-23 4:15 UTC (permalink / raw)
To: Daniel Henrique Barboza
Cc: qemu-devel, qemu-riscv, alistair.francis, liwei1518, zhiwei_liu,
Palmer Dabbelt
On Tue, Jun 16, 2026 at 08:59:38PM +0800, Daniel Henrique Barboza wrote:
> We're still using "/soc/plic@..." as FDT nodename in virt.c. This is
> not the right nodename per the DT docs:
>
> https://www.kernel.org/doc/Documentation/devicetree/bindings/interrupt-controller/sifive%2Cplic-1.0.0.txt
>
> The nodename must be 'interrupt-controller@...' since the node inherits
> the 'interrupt-controller' type. In fact, ever since at least the 2020
> Linux kernel commit c825a081c169cc7f ("dt-bindings: riscv: convert plic
> bindings to json-schema") the correct nodename has been
> 'interrupt-controller' for the sifive PLIC controller.
>
> There's no deprecation needed for bug fixes so we're just fixing the
> name. This was the policy we dud when fixing the aplic [1] and the
> imsic [2] nodenames to 'interrupt-controller@...' as well.
>
> The sifive_u PLIC FDT already uses the correct nodename for PLIC, so it
> is safe to assume that available SW is already aware of the correct
> nodename and this change won't affect well-behaved SW.
>
> [1] commit 29390fd ("hw/riscv/virt.c: rename aplic nodename to 'interrupt-controller'")
> [2] commit e8ad581 ("hw/riscv/virt.c: change imsic nodename to 'interrupt-controller'")
>
> Signed-off-by: Daniel Henrique Barboza <daniel.barboza@oss.qualcomm.com>
Reviewed-by: Chao Liu <chao.liu.zevorn@gmail.com>
Thanks,
Chao
> ---
> hw/riscv/virt.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
> index 33775a61fd..fa464e644f 100644
> --- a/hw/riscv/virt.c
> +++ b/hw/riscv/virt.c
> @@ -335,7 +335,7 @@ static void create_fdt_socket_plic(RISCVVirtState *s,
> plic_phandles[socket] = (*phandle)++;
> plic_addr = s->memmap[VIRT_PLIC].base +
> (s->memmap[VIRT_PLIC].size * socket);
> - plic_name = g_strdup_printf("/soc/plic@%lx", plic_addr);
> + 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);
> --
> 2.43.0
>
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH 5/5] hw/riscv: add create_fdt_plic() helper
2026-06-16 23:59 ` [PATCH 5/5] hw/riscv: add create_fdt_plic() helper Daniel Henrique Barboza
2026-06-22 5:02 ` Alistair Francis
@ 2026-06-23 4:16 ` Chao Liu
1 sibling, 0 replies; 17+ messages in thread
From: Chao Liu @ 2026-06-23 4:16 UTC (permalink / raw)
To: Daniel Henrique Barboza
Cc: qemu-devel, qemu-riscv, alistair.francis, liwei1518, zhiwei_liu,
Palmer Dabbelt
On Tue, Jun 16, 2026 at 08:59:39PM +0800, Daniel Henrique Barboza wrote:
> 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: Chao Liu <chao.liu.zevorn@gmail.com>
Thanks,
Chao
> ---
> hw/riscv/fdt-common.c | 30 +++++++++++++++++++++
> hw/riscv/sifive_u.c | 34 +++++++-----------------
> hw/riscv/virt.c | 49 ++++++++++++-----------------------
> 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
> --
> 2.43.0
>
^ permalink raw reply [flat|nested] 17+ messages in thread
end of thread, other threads:[~2026-06-23 4:16 UTC | newest]
Thread overview: 17+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-06-16 23:59 [PATCH 0/5] hw/riscv: more FDT cleanups (PLIC) Daniel Henrique Barboza
2026-06-16 23:59 ` [PATCH 1/5] hw/riscv/sifive_u.c: remove unneeded qemu_fdt_get_phandle() call Daniel Henrique Barboza
2026-06-22 4:56 ` Alistair Francis
2026-06-23 4:12 ` Chao Liu
2026-06-16 23:59 ` [PATCH 2/5] hw/riscv/sifive_u.c: use intc_phandle in plic creation Daniel Henrique Barboza
2026-06-22 4:57 ` Alistair Francis
2026-06-23 4:14 ` Chao Liu
2026-06-16 23:59 ` [PATCH 3/5] hw/riscv/sifive_u: add #address-cells in PLIC FDT Daniel Henrique Barboza
2026-06-22 4:59 ` Alistair Francis
2026-06-23 4:14 ` Chao Liu
2026-06-16 23:59 ` [PATCH 4/5] hw/riscv/virt.c: change 'plic' nodename to 'interrupt-controller' Daniel Henrique Barboza
2026-06-22 5:00 ` Alistair Francis
2026-06-23 4:15 ` Chao Liu
2026-06-16 23:59 ` [PATCH 5/5] hw/riscv: add create_fdt_plic() helper Daniel Henrique Barboza
2026-06-22 5:02 ` Alistair Francis
2026-06-23 4:16 ` Chao Liu
2026-06-22 23:09 ` [PATCH 0/5] hw/riscv: more FDT cleanups (PLIC) Alistair Francis
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.