Commit 0d37a88d47 for qemu.org
commit 0d37a88d474e7c2f15d4698ce99e84c836100d20
Author: Daniel Henrique Barboza <daniel.barboza@oss.qualcomm.com>
Date: Mon Jun 15 17:37:27 2026 -0300
hw/riscv: add create_fdt_clint() helper
Move all clint FDT generation to fdt-common.c reducing code repetition.
Signed-off-by: Daniel Henrique Barboza <daniel.barboza@oss.qualcomm.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Message-ID: <20260615203734.954428-8-daniel.barboza@oss.qualcomm.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
diff --git a/hw/riscv/fdt-common.c b/hw/riscv/fdt-common.c
index 719c36e001..d2661ec389 100644
--- a/hw/riscv/fdt-common.c
+++ b/hw/riscv/fdt-common.c
@@ -12,6 +12,7 @@
#include "system/device_tree.h"
#include "hw/core/boards.h"
#include "hw/riscv/fdt-common.h"
+#include "target/riscv/cpu_bits.h"
void *create_board_device_tree(const char *model, const char *compatible,
int *fdt_size)
@@ -50,3 +51,35 @@ void create_fdt_socket_memory(void *fdt, hwaddr addr, uint64_t size,
qemu_fdt_setprop_cell(fdt, mem_name, "numa-node-id", socket_id);
}
}
+
+void create_fdt_socket_clint(void *fdt, hwaddr addr, uint64_t size,
+ int socket_id, uint32_t *intc_phandles,
+ int num_harts, bool numa_enabled)
+{
+ g_autofree uint32_t *clint_cells = g_new0(uint32_t, num_harts * 4);
+ g_autofree char *clint_name = NULL;
+ static const char * const clint_compat[2] = {
+ "sifive,clint0", "riscv,clint0"
+ };
+
+ for (int cpu = 0; cpu < num_harts; cpu++) {
+ clint_cells[cpu * 4 + 0] = cpu_to_be32(intc_phandles[cpu]);
+ clint_cells[cpu * 4 + 1] = cpu_to_be32(IRQ_M_SOFT);
+ clint_cells[cpu * 4 + 2] = cpu_to_be32(intc_phandles[cpu]);
+ clint_cells[cpu * 4 + 3] = cpu_to_be32(IRQ_M_TIMER);
+ }
+
+ clint_name = g_strdup_printf("/soc/clint@%"HWADDR_PRIx, addr);
+ qemu_fdt_add_subnode(fdt, clint_name);
+ qemu_fdt_setprop_string_array(fdt, clint_name, "compatible",
+ (char **)&clint_compat,
+ ARRAY_SIZE(clint_compat));
+ qemu_fdt_setprop_sized_cells(fdt, clint_name, "reg",
+ 2, addr, 2, size);
+ qemu_fdt_setprop(fdt, clint_name, "interrupts-extended",
+ clint_cells, num_harts * sizeof(uint32_t) * 4);
+
+ if (numa_enabled) {
+ qemu_fdt_setprop_cell(fdt, clint_name, "numa-node-id", socket_id);
+ }
+}
diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
index ce86989bc8..9a791b36d6 100644
--- a/hw/riscv/sifive_u.c
+++ b/hw/riscv/sifive_u.c
@@ -105,9 +105,6 @@ static void create_fdt(SiFiveUState *s, const MemMapEntry *memmap,
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 clint_compat[2] = {
- "sifive,clint0", "riscv,clint0"
- };
static const char * const plic_compat[2] = {
"sifive,plic-1.0.0", "riscv,plic0"
};
@@ -180,25 +177,9 @@ static void create_fdt(SiFiveUState *s, const MemMapEntry *memmap,
g_free(nodename);
}
- cells = g_new0(uint32_t, ms->smp.cpus * 4);
- for (cpu = 0; cpu < ms->smp.cpus; cpu++) {
- cells[cpu * 4 + 0] = cpu_to_be32(intc_phandles[cpu]);
- cells[cpu * 4 + 1] = cpu_to_be32(IRQ_M_SOFT);
- cells[cpu * 4 + 2] = cpu_to_be32(intc_phandles[cpu]);
- cells[cpu * 4 + 3] = cpu_to_be32(IRQ_M_TIMER);
- }
- nodename = g_strdup_printf("/soc/clint@%lx",
- (long)memmap[SIFIVE_U_DEV_CLINT].base);
- qemu_fdt_add_subnode(fdt, nodename);
- qemu_fdt_setprop_string_array(fdt, nodename, "compatible",
- (char **)&clint_compat, ARRAY_SIZE(clint_compat));
- qemu_fdt_setprop_cells(fdt, nodename, "reg",
- 0x0, memmap[SIFIVE_U_DEV_CLINT].base,
- 0x0, memmap[SIFIVE_U_DEV_CLINT].size);
- qemu_fdt_setprop(fdt, nodename, "interrupts-extended",
- cells, ms->smp.cpus * sizeof(uint32_t) * 4);
- g_free(cells);
- g_free(nodename);
+ create_fdt_socket_clint(fdt, memmap[SIFIVE_U_DEV_CLINT].base,
+ memmap[SIFIVE_U_DEV_CLINT].size, 0,
+ intc_phandles, ms->smp.cpus, false);
nodename = g_strdup_printf("/soc/otp@%lx",
(long)memmap[SIFIVE_U_DEV_OTP].base);
diff --git a/hw/riscv/spike.c b/hw/riscv/spike.c
index 82005ec163..b15188fb07 100644
--- a/hw/riscv/spike.c
+++ b/hw/riscv/spike.c
@@ -58,13 +58,10 @@ static void create_fdt(SpikeState *s, const MemMapEntry *memmap,
unsigned long clint_addr;
int cpu, socket;
MachineState *ms = MACHINE(s);
- uint32_t *clint_cells;
uint32_t cpu_phandle, phandle = 1;
- char *clint_name, *clust_name;
+ char *clust_name;
char *core_name, *cpu_name, *intc_name;
- static const char * const clint_compat[2] = {
- "sifive,clint0", "riscv,clint0"
- };
+ bool numa_enabled = riscv_numa_enabled(ms);
fdt = ms->fdt = create_board_device_tree("ucbbar,spike-bare,qemu",
"ucbbar,spike-bare-dev", &fdt_size);
@@ -136,29 +133,11 @@ static void create_fdt(SpikeState *s, const MemMapEntry *memmap,
create_fdt_socket_memory(fdt, memaddr, memsize, socket,
riscv_numa_enabled(ms));
- clint_cells = g_new0(uint32_t, s->soc[socket].num_harts * 4);
-
- for (cpu = 0; cpu < s->soc[socket].num_harts; cpu++) {
- clint_cells[cpu * 4 + 0] = cpu_to_be32(intc_phandles[cpu]);
- clint_cells[cpu * 4 + 1] = cpu_to_be32(IRQ_M_SOFT);
- clint_cells[cpu * 4 + 2] = cpu_to_be32(intc_phandles[cpu]);
- clint_cells[cpu * 4 + 3] = cpu_to_be32(IRQ_M_TIMER);
- }
-
clint_addr = memmap[SPIKE_CLINT].base +
(memmap[SPIKE_CLINT].size * socket);
- clint_name = g_strdup_printf("/soc/clint@%lx", clint_addr);
- qemu_fdt_add_subnode(fdt, clint_name);
- qemu_fdt_setprop_string_array(fdt, clint_name, "compatible",
- (char **)&clint_compat, ARRAY_SIZE(clint_compat));
- qemu_fdt_setprop_cells(fdt, clint_name, "reg",
- 0x0, clint_addr, 0x0, memmap[SPIKE_CLINT].size);
- qemu_fdt_setprop(fdt, clint_name, "interrupts-extended",
- clint_cells, s->soc[socket].num_harts * sizeof(uint32_t) * 4);
- riscv_socket_fdt_write_id(ms, clint_name, socket);
-
- g_free(clint_name);
- g_free(clint_cells);
+ create_fdt_socket_clint(fdt, clint_addr, memmap[SPIKE_CLINT].size,
+ socket, intc_phandles,
+ s->soc[socket].num_harts, numa_enabled);
g_free(clust_name);
}
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
index df3eadef78..b134f11266 100644
--- a/hw/riscv/virt.c
+++ b/hw/riscv/virt.c
@@ -302,42 +302,6 @@ static void create_fdt_socket_cpus(RISCVVirtState *s, int socket,
}
}
-static void create_fdt_socket_clint(RISCVVirtState *s,
- int socket,
- uint32_t *intc_phandles)
-{
- int cpu;
- g_autofree char *clint_name = NULL;
- g_autofree uint32_t *clint_cells = NULL;
- hwaddr clint_addr;
- MachineState *ms = MACHINE(s);
- static const char * const clint_compat[2] = {
- "sifive,clint0", "riscv,clint0"
- };
-
- clint_cells = g_new0(uint32_t, s->soc[socket].num_harts * 4);
-
- for (cpu = 0; cpu < s->soc[socket].num_harts; cpu++) {
- clint_cells[cpu * 4 + 0] = cpu_to_be32(intc_phandles[cpu]);
- clint_cells[cpu * 4 + 1] = cpu_to_be32(IRQ_M_SOFT);
- clint_cells[cpu * 4 + 2] = cpu_to_be32(intc_phandles[cpu]);
- clint_cells[cpu * 4 + 3] = cpu_to_be32(IRQ_M_TIMER);
- }
-
- clint_addr = s->memmap[VIRT_CLINT].base +
- s->memmap[VIRT_CLINT].size * socket;
- clint_name = g_strdup_printf("/soc/clint@%"HWADDR_PRIx, clint_addr);
- qemu_fdt_add_subnode(ms->fdt, clint_name);
- qemu_fdt_setprop_string_array(ms->fdt, clint_name, "compatible",
- (char **)&clint_compat,
- ARRAY_SIZE(clint_compat));
- qemu_fdt_setprop_sized_cells(ms->fdt, clint_name, "reg",
- 2, clint_addr, 2, s->memmap[VIRT_CLINT].size);
- qemu_fdt_setprop(ms->fdt, clint_name, "interrupts-extended",
- clint_cells, s->soc[socket].num_harts * sizeof(uint32_t) * 4);
- riscv_socket_fdt_write_id(ms, clint_name, socket);
-}
-
static void create_fdt_socket_aclint(RISCVVirtState *s,
int socket,
uint32_t *intc_phandles)
@@ -728,6 +692,7 @@ static void create_fdt_sockets(RISCVVirtState *s,
uint32_t xplic_phandles[MAX_NODES];
g_autofree uint32_t *intc_phandles = NULL;
int socket_count = riscv_socket_count(ms);
+ bool numa_enabled = riscv_numa_enabled(ms);
qemu_fdt_add_subnode(ms->fdt, "/cpus");
qemu_fdt_setprop_cell(ms->fdt, "/cpus", "timebase-frequency",
@@ -762,8 +727,13 @@ static void create_fdt_sockets(RISCVVirtState *s,
create_fdt_socket_aclint(s, socket,
&intc_phandles[phandle_pos]);
} else if (tcg_enabled()) {
- create_fdt_socket_clint(s, socket,
- &intc_phandles[phandle_pos]);
+ hwaddr clintaddr = s->memmap[VIRT_CLINT].base +
+ s->memmap[VIRT_CLINT].size * socket;
+
+ create_fdt_socket_clint(ms->fdt, clintaddr,
+ s->memmap[VIRT_CLINT].size,
+ socket, &intc_phandles[phandle_pos],
+ s->soc[socket].num_harts, numa_enabled);
}
}
diff --git a/include/hw/riscv/fdt-common.h b/include/hw/riscv/fdt-common.h
index 81689f418b..6e81d6cd6c 100644
--- a/include/hw/riscv/fdt-common.h
+++ b/include/hw/riscv/fdt-common.h
@@ -13,4 +13,9 @@ void *create_board_device_tree(const char *model, const char *compatible,
int *fdt_size);
void create_fdt_socket_memory(void *fdt, hwaddr addr, uint64_t size,
int socket_id, bool numa_enabled);
+void create_fdt_clint(void *fdt, hwaddr addr, uint64_t size,
+ uint32_t *intc_phandles, int num_harts);
+void create_fdt_socket_clint(void *fdt, hwaddr addr, uint64_t size,
+ int socket_id, uint32_t *intc_phandles,
+ int num_harts, bool numa_enabled);
#endif