@samitouri / QOSamiQemu / commits / 0d37a88d47

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>

Daniel Henrique Barboza committed Jun 15, 2026 at 17:37 UTC 0d37a88d474e7c2f15d4698ce99e84c836100d20
5 files changed +54 -86
hw/riscv/fdt-common.c
+33
@@ -12,6 +12,7 @@
12 #include "system/device_tree.h"
13 #include "hw/core/boards.h"
14 #include "hw/riscv/fdt-common.h"
15 +#include "target/riscv/cpu_bits.h"
16
17 void *create_board_device_tree(const char *model, const char *compatible,
18 int *fdt_size)
@@ -50,3 +51,35 @@ void create_fdt_socket_memory(void *fdt, hwaddr addr, uint64_t size,
51 qemu_fdt_setprop_cell(fdt, mem_name, "numa-node-id", socket_id);
52 }
53 }
54 +
55 +void create_fdt_socket_clint(void *fdt, hwaddr addr, uint64_t size,
56 + int socket_id, uint32_t *intc_phandles,
57 + int num_harts, bool numa_enabled)
58 +{
59 + g_autofree uint32_t *clint_cells = g_new0(uint32_t, num_harts * 4);
60 + g_autofree char *clint_name = NULL;
61 + static const char * const clint_compat[2] = {
62 + "sifive,clint0", "riscv,clint0"
63 + };
64 +
65 + for (int cpu = 0; cpu < num_harts; cpu++) {
66 + clint_cells[cpu * 4 + 0] = cpu_to_be32(intc_phandles[cpu]);
67 + clint_cells[cpu * 4 + 1] = cpu_to_be32(IRQ_M_SOFT);
68 + clint_cells[cpu * 4 + 2] = cpu_to_be32(intc_phandles[cpu]);
69 + clint_cells[cpu * 4 + 3] = cpu_to_be32(IRQ_M_TIMER);
70 + }
71 +
72 + clint_name = g_strdup_printf("/soc/clint@%"HWADDR_PRIx, addr);
73 + qemu_fdt_add_subnode(fdt, clint_name);
74 + qemu_fdt_setprop_string_array(fdt, clint_name, "compatible",
75 + (char **)&clint_compat,
76 + ARRAY_SIZE(clint_compat));
77 + qemu_fdt_setprop_sized_cells(fdt, clint_name, "reg",
78 + 2, addr, 2, size);
79 + qemu_fdt_setprop(fdt, clint_name, "interrupts-extended",
80 + clint_cells, num_harts * sizeof(uint32_t) * 4);
81 +
82 + if (numa_enabled) {
83 + qemu_fdt_setprop_cell(fdt, clint_name, "numa-node-id", socket_id);
84 + }
85 +}
hw/riscv/sifive_u.c
+3 -22
@@ -105,9 +105,6 @@ static void create_fdt(SiFiveUState *s, const MemMapEntry *memmap,
105 uint32_t plic_phandle, prci_phandle, gpio_phandle, phandle = 1;
106 uint32_t hfclk_phandle, rtcclk_phandle, phy_phandle;
107 static const char * const ethclk_names[2] = { "pclk", "hclk" };
108 - static const char * const clint_compat[2] = {
109 - "sifive,clint0", "riscv,clint0"
110 - };
108 static const char * const plic_compat[2] = {
109 "sifive,plic-1.0.0", "riscv,plic0"
110 };
@@ -180,25 +177,9 @@ static void create_fdt(SiFiveUState *s, const MemMapEntry *memmap,
177 g_free(nodename);
178 }
179
183 - cells = g_new0(uint32_t, ms->smp.cpus * 4);
184 - for (cpu = 0; cpu < ms->smp.cpus; cpu++) {
185 - cells[cpu * 4 + 0] = cpu_to_be32(intc_phandles[cpu]);
186 - cells[cpu * 4 + 1] = cpu_to_be32(IRQ_M_SOFT);
187 - cells[cpu * 4 + 2] = cpu_to_be32(intc_phandles[cpu]);
188 - cells[cpu * 4 + 3] = cpu_to_be32(IRQ_M_TIMER);
189 - }
190 - nodename = g_strdup_printf("/soc/clint@%lx",
191 - (long)memmap[SIFIVE_U_DEV_CLINT].base);
192 - qemu_fdt_add_subnode(fdt, nodename);
193 - qemu_fdt_setprop_string_array(fdt, nodename, "compatible",
194 - (char **)&clint_compat, ARRAY_SIZE(clint_compat));
195 - qemu_fdt_setprop_cells(fdt, nodename, "reg",
196 - 0x0, memmap[SIFIVE_U_DEV_CLINT].base,
197 - 0x0, memmap[SIFIVE_U_DEV_CLINT].size);
198 - qemu_fdt_setprop(fdt, nodename, "interrupts-extended",
199 - cells, ms->smp.cpus * sizeof(uint32_t) * 4);
200 - g_free(cells);
201 - g_free(nodename);
180 + create_fdt_socket_clint(fdt, memmap[SIFIVE_U_DEV_CLINT].base,
181 + memmap[SIFIVE_U_DEV_CLINT].size, 0,
182 + intc_phandles, ms->smp.cpus, false);
183
184 nodename = g_strdup_printf("/soc/otp@%lx",
185 (long)memmap[SIFIVE_U_DEV_OTP].base);
hw/riscv/spike.c
+5 -26
@@ -58,13 +58,10 @@ static void create_fdt(SpikeState *s, const MemMapEntry *memmap,
58 unsigned long clint_addr;
59 int cpu, socket;
60 MachineState *ms = MACHINE(s);
61 - uint32_t *clint_cells;
61 uint32_t cpu_phandle, phandle = 1;
63 - char *clint_name, *clust_name;
62 + char *clust_name;
63 char *core_name, *cpu_name, *intc_name;
65 - static const char * const clint_compat[2] = {
66 - "sifive,clint0", "riscv,clint0"
67 - };
64 + bool numa_enabled = riscv_numa_enabled(ms);
65
66 fdt = ms->fdt = create_board_device_tree("ucbbar,spike-bare,qemu",
67 "ucbbar,spike-bare-dev", &fdt_size);
@@ -136,29 +133,11 @@ static void create_fdt(SpikeState *s, const MemMapEntry *memmap,
133 create_fdt_socket_memory(fdt, memaddr, memsize, socket,
134 riscv_numa_enabled(ms));
135
139 - clint_cells = g_new0(uint32_t, s->soc[socket].num_harts * 4);
140 -
141 - for (cpu = 0; cpu < s->soc[socket].num_harts; cpu++) {
142 - clint_cells[cpu * 4 + 0] = cpu_to_be32(intc_phandles[cpu]);
143 - clint_cells[cpu * 4 + 1] = cpu_to_be32(IRQ_M_SOFT);
144 - clint_cells[cpu * 4 + 2] = cpu_to_be32(intc_phandles[cpu]);
145 - clint_cells[cpu * 4 + 3] = cpu_to_be32(IRQ_M_TIMER);
146 - }
147 -
136 clint_addr = memmap[SPIKE_CLINT].base +
137 (memmap[SPIKE_CLINT].size * socket);
150 - clint_name = g_strdup_printf("/soc/clint@%lx", clint_addr);
151 - qemu_fdt_add_subnode(fdt, clint_name);
152 - qemu_fdt_setprop_string_array(fdt, clint_name, "compatible",
153 - (char **)&clint_compat, ARRAY_SIZE(clint_compat));
154 - qemu_fdt_setprop_cells(fdt, clint_name, "reg",
155 - 0x0, clint_addr, 0x0, memmap[SPIKE_CLINT].size);
156 - qemu_fdt_setprop(fdt, clint_name, "interrupts-extended",
157 - clint_cells, s->soc[socket].num_harts * sizeof(uint32_t) * 4);
158 - riscv_socket_fdt_write_id(ms, clint_name, socket);
159 -
160 - g_free(clint_name);
161 - g_free(clint_cells);
138 + create_fdt_socket_clint(fdt, clint_addr, memmap[SPIKE_CLINT].size,
139 + socket, intc_phandles,
140 + s->soc[socket].num_harts, numa_enabled);
141 g_free(clust_name);
142 }
143
hw/riscv/virt.c
+8 -38
@@ -302,42 +302,6 @@ static void create_fdt_socket_cpus(RISCVVirtState *s, int socket,
302 }
303 }
304
305 -static void create_fdt_socket_clint(RISCVVirtState *s,
306 - int socket,
307 - uint32_t *intc_phandles)
308 -{
309 - int cpu;
310 - g_autofree char *clint_name = NULL;
311 - g_autofree uint32_t *clint_cells = NULL;
312 - hwaddr clint_addr;
313 - MachineState *ms = MACHINE(s);
314 - static const char * const clint_compat[2] = {
315 - "sifive,clint0", "riscv,clint0"
316 - };
317 -
318 - clint_cells = g_new0(uint32_t, s->soc[socket].num_harts * 4);
319 -
320 - for (cpu = 0; cpu < s->soc[socket].num_harts; cpu++) {
321 - clint_cells[cpu * 4 + 0] = cpu_to_be32(intc_phandles[cpu]);
322 - clint_cells[cpu * 4 + 1] = cpu_to_be32(IRQ_M_SOFT);
323 - clint_cells[cpu * 4 + 2] = cpu_to_be32(intc_phandles[cpu]);
324 - clint_cells[cpu * 4 + 3] = cpu_to_be32(IRQ_M_TIMER);
325 - }
326 -
327 - clint_addr = s->memmap[VIRT_CLINT].base +
328 - s->memmap[VIRT_CLINT].size * socket;
329 - clint_name = g_strdup_printf("/soc/clint@%"HWADDR_PRIx, clint_addr);
330 - qemu_fdt_add_subnode(ms->fdt, clint_name);
331 - qemu_fdt_setprop_string_array(ms->fdt, clint_name, "compatible",
332 - (char **)&clint_compat,
333 - ARRAY_SIZE(clint_compat));
334 - qemu_fdt_setprop_sized_cells(ms->fdt, clint_name, "reg",
335 - 2, clint_addr, 2, s->memmap[VIRT_CLINT].size);
336 - qemu_fdt_setprop(ms->fdt, clint_name, "interrupts-extended",
337 - clint_cells, s->soc[socket].num_harts * sizeof(uint32_t) * 4);
338 - riscv_socket_fdt_write_id(ms, clint_name, socket);
339 -}
340 -
305 static void create_fdt_socket_aclint(RISCVVirtState *s,
306 int socket,
307 uint32_t *intc_phandles)
@@ -728,6 +692,7 @@ static void create_fdt_sockets(RISCVVirtState *s,
692 uint32_t xplic_phandles[MAX_NODES];
693 g_autofree uint32_t *intc_phandles = NULL;
694 int socket_count = riscv_socket_count(ms);
695 + bool numa_enabled = riscv_numa_enabled(ms);
696
697 qemu_fdt_add_subnode(ms->fdt, "/cpus");
698 qemu_fdt_setprop_cell(ms->fdt, "/cpus", "timebase-frequency",
@@ -762,8 +727,13 @@ static void create_fdt_sockets(RISCVVirtState *s,
727 create_fdt_socket_aclint(s, socket,
728 &intc_phandles[phandle_pos]);
729 } else if (tcg_enabled()) {
765 - create_fdt_socket_clint(s, socket,
766 - &intc_phandles[phandle_pos]);
730 + hwaddr clintaddr = s->memmap[VIRT_CLINT].base +
731 + s->memmap[VIRT_CLINT].size * socket;
732 +
733 + create_fdt_socket_clint(ms->fdt, clintaddr,
734 + s->memmap[VIRT_CLINT].size,
735 + socket, &intc_phandles[phandle_pos],
736 + s->soc[socket].num_harts, numa_enabled);
737 }
738 }
739
include/hw/riscv/fdt-common.h
+5
@@ -13,4 +13,9 @@ void *create_board_device_tree(const char *model, const char *compatible,
13 int *fdt_size);
14 void create_fdt_socket_memory(void *fdt, hwaddr addr, uint64_t size,
15 int socket_id, bool numa_enabled);
16 +void create_fdt_clint(void *fdt, hwaddr addr, uint64_t size,
17 + uint32_t *intc_phandles, int num_harts);
18 +void create_fdt_socket_clint(void *fdt, hwaddr addr, uint64_t size,
19 + int socket_id, uint32_t *intc_phandles,
20 + int num_harts, bool numa_enabled);
21 #endif