@samitouri / QOSamiQemu / commits / 128f3dc70b

hw/riscv: add create_fdt_socket_cpus()

Consolidate the creation of CPUs socket FDT in a helper that can be shared across all boards. The code was basically moved from the function with the same name from 'virt.c', with additional bits to create the cluster subnode beforehand. Signed-off-by: Daniel Henrique Barboza <daniel.barboza@oss.qualcomm.com> Reviewed-by: Alistair Francis <alistair.francis@wdc.com> Message-ID: <20260615203734.954428-11-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 128f3dc70b4b93967775cc5d877afafb5352a97e
3 files changed +87 -77
hw/riscv/fdt-common.c
+74
@@ -93,3 +93,77 @@ void fdt_create_cpu_socket_subnode(void *fdt, uint64_t timebase_frequency)
93 qemu_fdt_setprop_cell(fdt, "/cpus", "#address-cells", 0x1);
94 qemu_fdt_add_subnode(fdt, "/cpus/cpu-map");
95 }
96 +
97 +void create_fdt_socket_cpus(void *fdt, RISCVCPU *socket_harts,
98 + int socket_id, int num_harts_socket,
99 + int socket_hartid_base, uint32_t *phandle,
100 + uint32_t *intc_phandles, bool numa_enabled,
101 + bool is_32_bit)
102 +{
103 + g_autofree char *clust_name = NULL;
104 + uint32_t cpu_phandle;
105 +
106 + clust_name = g_strdup_printf("/cpus/cpu-map/cluster%d", socket_id);
107 + qemu_fdt_add_subnode(fdt, clust_name);
108 +
109 + for (int cpu = num_harts_socket - 1; cpu >= 0; cpu--) {
110 + RISCVCPU *cpu_ptr = &socket_harts[cpu];
111 + int8_t satp_mode_max = cpu_ptr->cfg.max_satp_mode;
112 + g_autofree char *cpu_name = NULL;
113 + g_autofree char *core_name = NULL;
114 + g_autofree char *intc_name = NULL;
115 +
116 + cpu_phandle = (*phandle)++;
117 +
118 + cpu_name = g_strdup_printf("/cpus/cpu@%d", socket_hartid_base + cpu);
119 + qemu_fdt_add_subnode(fdt, cpu_name);
120 +
121 + if (satp_mode_max != -1) {
122 + g_autofree char *sv_name = NULL;
123 + sv_name = g_strdup_printf("riscv,%s",
124 + satp_mode_str(satp_mode_max, is_32_bit));
125 + qemu_fdt_setprop_string(fdt, cpu_name, "mmu-type", sv_name);
126 + }
127 + riscv_isa_write_fdt(cpu_ptr, fdt, cpu_name);
128 +
129 + if (cpu_ptr->cfg.ext_zicbom) {
130 + qemu_fdt_setprop_cell(fdt, cpu_name, "riscv,cbom-block-size",
131 + cpu_ptr->cfg.cbom_blocksize);
132 + }
133 +
134 + if (cpu_ptr->cfg.ext_zicboz) {
135 + qemu_fdt_setprop_cell(fdt, cpu_name, "riscv,cboz-block-size",
136 + cpu_ptr->cfg.cboz_blocksize);
137 + }
138 +
139 + if (cpu_ptr->cfg.ext_zicbop) {
140 + qemu_fdt_setprop_cell(fdt, cpu_name, "riscv,cbop-block-size",
141 + cpu_ptr->cfg.cbop_blocksize);
142 + }
143 +
144 + qemu_fdt_setprop_string(fdt, cpu_name, "compatible", "riscv");
145 + qemu_fdt_setprop_string(fdt, cpu_name, "status", "okay");
146 + qemu_fdt_setprop_cell(fdt, cpu_name, "reg",
147 + socket_hartid_base + cpu);
148 + qemu_fdt_setprop_string(fdt, cpu_name, "device_type", "cpu");
149 + if (numa_enabled) {
150 + qemu_fdt_setprop_cell(fdt, cpu_name, "numa-node-id", socket_id);
151 + }
152 + qemu_fdt_setprop_cell(fdt, cpu_name, "phandle", cpu_phandle);
153 +
154 + intc_phandles[cpu] = (*phandle)++;
155 +
156 + intc_name = g_strdup_printf("%s/interrupt-controller", cpu_name);
157 + qemu_fdt_add_subnode(fdt, intc_name);
158 + qemu_fdt_setprop_cell(fdt, intc_name, "phandle",
159 + intc_phandles[cpu]);
160 + qemu_fdt_setprop_string(fdt, intc_name, "compatible",
161 + "riscv,cpu-intc");
162 + qemu_fdt_setprop(fdt, intc_name, "interrupt-controller", NULL, 0);
163 + qemu_fdt_setprop_cell(fdt, intc_name, "#interrupt-cells", 1);
164 +
165 + core_name = g_strdup_printf("%s/core%d", clust_name, cpu);
166 + qemu_fdt_add_subnode(fdt, core_name);
167 + qemu_fdt_setprop_cell(fdt, core_name, "cpu", cpu_phandle);
168 + }
169 +}
hw/riscv/virt.c
+6 -77
@@ -231,77 +231,6 @@ static void create_pcie_irq_map(RISCVVirtState *s, void *fdt, char *nodename,
231 0x1800, 0, 0, 0x7);
232 }
233
234 -static void create_fdt_socket_cpus(RISCVVirtState *s, int socket,
235 - char *clust_name, uint32_t *phandle,
236 - uint32_t *intc_phandles)
237 -{
238 - int cpu;
239 - uint32_t cpu_phandle;
240 - MachineState *ms = MACHINE(s);
241 - bool is_32_bit = riscv_is_32bit(&s->soc[0]);
242 -
243 - for (cpu = s->soc[socket].num_harts - 1; cpu >= 0; cpu--) {
244 - RISCVCPU *cpu_ptr = &s->soc[socket].harts[cpu];
245 - int8_t satp_mode_max = cpu_ptr->cfg.max_satp_mode;
246 - g_autofree char *cpu_name = NULL;
247 - g_autofree char *core_name = NULL;
248 - g_autofree char *intc_name = NULL;
249 - g_autofree char *sv_name = NULL;
250 -
251 - cpu_phandle = (*phandle)++;
252 -
253 - cpu_name = g_strdup_printf("/cpus/cpu@%d",
254 - s->soc[socket].hartid_base + cpu);
255 - qemu_fdt_add_subnode(ms->fdt, cpu_name);
256 -
257 - if (satp_mode_max != -1) {
258 - sv_name = g_strdup_printf("riscv,%s",
259 - satp_mode_str(satp_mode_max, is_32_bit));
260 - qemu_fdt_setprop_string(ms->fdt, cpu_name, "mmu-type", sv_name);
261 - }
262 -
263 - riscv_isa_write_fdt(cpu_ptr, ms->fdt, cpu_name);
264 -
265 - if (cpu_ptr->cfg.ext_zicbom) {
266 - qemu_fdt_setprop_cell(ms->fdt, cpu_name, "riscv,cbom-block-size",
267 - cpu_ptr->cfg.cbom_blocksize);
268 - }
269 -
270 - if (cpu_ptr->cfg.ext_zicboz) {
271 - qemu_fdt_setprop_cell(ms->fdt, cpu_name, "riscv,cboz-block-size",
272 - cpu_ptr->cfg.cboz_blocksize);
273 - }
274 -
275 - if (cpu_ptr->cfg.ext_zicbop) {
276 - qemu_fdt_setprop_cell(ms->fdt, cpu_name, "riscv,cbop-block-size",
277 - cpu_ptr->cfg.cbop_blocksize);
278 - }
279 -
280 - qemu_fdt_setprop_string(ms->fdt, cpu_name, "compatible", "riscv");
281 - qemu_fdt_setprop_string(ms->fdt, cpu_name, "status", "okay");
282 - qemu_fdt_setprop_cell(ms->fdt, cpu_name, "reg",
283 - s->soc[socket].hartid_base + cpu);
284 - qemu_fdt_setprop_string(ms->fdt, cpu_name, "device_type", "cpu");
285 - riscv_socket_fdt_write_id(ms, cpu_name, socket);
286 - qemu_fdt_setprop_cell(ms->fdt, cpu_name, "phandle", cpu_phandle);
287 -
288 - intc_phandles[cpu] = (*phandle)++;
289 -
290 - intc_name = g_strdup_printf("%s/interrupt-controller", cpu_name);
291 - qemu_fdt_add_subnode(ms->fdt, intc_name);
292 - qemu_fdt_setprop_cell(ms->fdt, intc_name, "phandle",
293 - intc_phandles[cpu]);
294 - qemu_fdt_setprop_string(ms->fdt, intc_name, "compatible",
295 - "riscv,cpu-intc");
296 - qemu_fdt_setprop(ms->fdt, intc_name, "interrupt-controller", NULL, 0);
297 - qemu_fdt_setprop_cell(ms->fdt, intc_name, "#interrupt-cells", 1);
298 -
299 - core_name = g_strdup_printf("%s/core%d", clust_name, cpu);
300 - qemu_fdt_add_subnode(ms->fdt, core_name);
301 - qemu_fdt_setprop_cell(ms->fdt, core_name, "cpu", cpu_phandle);
302 - }
303 -}
304 -
234 static void create_fdt_socket_aclint(RISCVVirtState *s,
235 int socket,
236 uint32_t *intc_phandles)
@@ -693,6 +622,7 @@ static void create_fdt_sockets(RISCVVirtState *s,
622 g_autofree uint32_t *intc_phandles = NULL;
623 int socket_count = riscv_socket_count(ms);
624 bool numa_enabled = riscv_numa_enabled(ms);
625 + bool is_32_bit = riscv_is_32bit(&s->soc[0]);
626
627 fdt_create_cpu_socket_subnode(ms->fdt,
628 kvm_enabled() ? kvm_riscv_get_timebase_frequency(&s->soc->harts[0]) :
@@ -702,18 +632,17 @@ static void create_fdt_sockets(RISCVVirtState *s,
632
633 phandle_pos = ms->smp.cpus;
634 for (socket = (socket_count - 1); socket >= 0; socket--) {
705 - g_autofree char *clust_name = NULL;
635 hwaddr memaddr = s->memmap[VIRT_DRAM].base +
636 riscv_socket_mem_offset(ms, socket);
637 uint64_t memsize = riscv_socket_mem_size(ms, socket);
638
639 phandle_pos -= s->soc[socket].num_harts;
640
712 - clust_name = g_strdup_printf("/cpus/cpu-map/cluster%d", socket);
713 - qemu_fdt_add_subnode(ms->fdt, clust_name);
714 -
715 - create_fdt_socket_cpus(s, socket, clust_name, phandle,
716 - &intc_phandles[phandle_pos]);
641 + create_fdt_socket_cpus(ms->fdt, (&s->soc[socket])->harts, socket,
642 + s->soc[socket].num_harts,
643 + s->soc[socket].hartid_base,
644 + phandle, &intc_phandles[phandle_pos],
645 + numa_enabled, is_32_bit);
646
647 create_fdt_socket_memory(ms->fdt, memaddr, memsize,
648 socket, riscv_numa_enabled(ms));
include/hw/riscv/fdt-common.h
+7
@@ -9,6 +9,8 @@
9 #ifndef RISCV_VIRT_FDT_H
10 #define RISCV_VIRT_FDT_H
11
12 +#include "target/riscv/cpu.h"
13 +
14 void *create_board_device_tree(const char *model, const char *compatible,
15 int *fdt_size);
16 void create_fdt_socket_memory(void *fdt, hwaddr addr, uint64_t size,
@@ -19,4 +21,9 @@ void create_fdt_socket_clint(void *fdt, hwaddr addr, uint64_t size,
21 int socket_id, uint32_t *intc_phandles,
22 int num_harts, bool numa_enabled);
23 void fdt_create_cpu_socket_subnode(void *fdt, uint64_t timebase_frequency);
24 +void create_fdt_socket_cpus(void *fdt, RISCVCPU *socket_harts,
25 + int socket_id, int num_harts_socket,
26 + int socket_hartid_base, uint32_t *phandle,
27 + uint32_t *intc_phandles, bool numa_enabled,
28 + bool is_32_bit);
29 #endif