@samitouri / QOSamiQemu / commits / 8e75c34186

hw/riscv/fdt_common.c: create create_fdt_socket_cpu_internal()

The sifive_u board does not share the same CPU socket FDT bits from the other boards. In particular the riscv,isa creation is done using either CPU0 from soc.e_cpus.harts, and for all other CPUs soc.u_cups.harts is used. It would be too cumbersome to add all these details in the common code so we're going to add a special sifive_u only helper that shares the common bits with the common helper used by the other boards. create_fdt_socket_cpu_internal() contains the common bits shared between the sifive_u board and the rest. Signed-off-by: Daniel Henrique Barboza <daniel.barboza@oss.qualcomm.com> Reviewed-by: Alistair Francis <alistair.francis@wdc.com> Message-ID: <20260615203734.954428-13-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 8e75c341869049cbeeac5ce9a1a8076c08bdcccc
1 file changed +65 -43
hw/riscv/fdt-common.c
+65 -43
@@ -94,28 +94,29 @@ void fdt_create_cpu_socket_subnode(void *fdt, uint64_t timebase_frequency)
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)
97 +static void
98 +create_fdt_socket_cpu_internal(void *fdt, char *clust_name, RISCVCPU *cpu_ptr,
99 + int cpu, int socket_id, int socket_hartid_base,
100 + uint32_t *phandle, uint32_t *intc_phandles,
101 + bool numa_enabled, 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];
103 + g_autofree char *cpu_name = NULL;
104 + g_autofree char *core_name = NULL;
105 + g_autofree char *intc_name = NULL;
106 + uint32_t cpu_phandle = (*phandle)++;
107 + bool is_sifive_u = cpu_ptr == NULL;
108 +
109 + cpu_name = g_strdup_printf("/cpus/cpu@%d", socket_hartid_base + cpu);
110 +
111 + /*
112 + * The sifive_u board has an exclusive satp and riscv,isa
113 + * schema that can't be shared with other boards, so part
114 + * of the CPU FDT creation (i.e. the /cpus/cpu@N subnode)
115 + * is still being done by the board.
116 + */
117 + if (!is_sifive_u) {
118 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)++;
119
118 - cpu_name = g_strdup_printf("/cpus/cpu@%d", socket_hartid_base + cpu);
120 qemu_fdt_add_subnode(fdt, cpu_name);
121
122 if (satp_mode_max != -1) {
@@ -140,30 +141,51 @@ void create_fdt_socket_cpus(void *fdt, RISCVCPU *socket_harts,
141 qemu_fdt_setprop_cell(fdt, cpu_name, "riscv,cbop-block-size",
142 cpu_ptr->cfg.cbop_blocksize);
143 }
144 + }
145
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);
146 + qemu_fdt_setprop_string(fdt, cpu_name, "compatible", "riscv");
147 + qemu_fdt_setprop_string(fdt, cpu_name, "status", "okay");
148 + qemu_fdt_setprop_cell(fdt, cpu_name, "reg",
149 + socket_hartid_base + cpu);
150 + qemu_fdt_setprop_string(fdt, cpu_name, "device_type", "cpu");
151 + if (numa_enabled) {
152 + qemu_fdt_setprop_cell(fdt, cpu_name, "numa-node-id", socket_id);
153 + }
154 + qemu_fdt_setprop_cell(fdt, cpu_name, "phandle", cpu_phandle);
155 +
156 + intc_phandles[cpu] = (*phandle)++;
157 +
158 + intc_name = g_strdup_printf("%s/interrupt-controller", cpu_name);
159 + qemu_fdt_add_subnode(fdt, intc_name);
160 + qemu_fdt_setprop_cell(fdt, intc_name, "phandle",
161 + intc_phandles[cpu]);
162 + qemu_fdt_setprop_string(fdt, intc_name, "compatible",
163 + "riscv,cpu-intc");
164 + qemu_fdt_setprop(fdt, intc_name, "interrupt-controller", NULL, 0);
165 + qemu_fdt_setprop_cell(fdt, intc_name, "#interrupt-cells", 1);
166 +
167 + core_name = g_strdup_printf("%s/core%d", clust_name, cpu);
168 + qemu_fdt_add_subnode(fdt, core_name);
169 + qemu_fdt_setprop_cell(fdt, core_name, "cpu", cpu_phandle);
170 +}
171 +
172 +void create_fdt_socket_cpus(void *fdt, RISCVCPU *socket_harts,
173 + int socket_id, int num_harts_socket,
174 + int socket_hartid_base, uint32_t *phandle,
175 + uint32_t *intc_phandles, bool numa_enabled,
176 + bool is_32_bit)
177 +{
178 + g_autofree char *clust_name = NULL;
179 +
180 + clust_name = g_strdup_printf("/cpus/cpu-map/cluster%d", socket_id);
181 + qemu_fdt_add_subnode(fdt, clust_name);
182 +
183 + for (int cpu = num_harts_socket - 1; cpu >= 0; cpu--) {
184 + RISCVCPU *cpu_ptr = &socket_harts[cpu];
185 +
186 + create_fdt_socket_cpu_internal(fdt, clust_name, cpu_ptr, cpu,
187 + socket_id, socket_hartid_base,
188 + phandle, intc_phandles, numa_enabled,
189 + is_32_bit);
190 }
191 }