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