Commit 8e75c34186 for qemu.org
commit 8e75c341869049cbeeac5ce9a1a8076c08bdcccc
Author: Daniel Henrique Barboza <daniel.barboza@oss.qualcomm.com>
Date: Mon Jun 15 17:37:32 2026 -0300
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>
diff --git a/hw/riscv/fdt-common.c b/hw/riscv/fdt-common.c
index 6c795409a4..70168ad657 100644
--- a/hw/riscv/fdt-common.c
+++ b/hw/riscv/fdt-common.c
@@ -94,28 +94,29 @@ void fdt_create_cpu_socket_subnode(void *fdt, uint64_t timebase_frequency)
qemu_fdt_add_subnode(fdt, "/cpus/cpu-map");
}
-void create_fdt_socket_cpus(void *fdt, RISCVCPU *socket_harts,
- int socket_id, int num_harts_socket,
- int socket_hartid_base, uint32_t *phandle,
- uint32_t *intc_phandles, bool numa_enabled,
- bool is_32_bit)
+static void
+create_fdt_socket_cpu_internal(void *fdt, char *clust_name, RISCVCPU *cpu_ptr,
+ int cpu, int socket_id, int socket_hartid_base,
+ uint32_t *phandle, uint32_t *intc_phandles,
+ bool numa_enabled, bool is_32_bit)
{
- g_autofree char *clust_name = NULL;
- uint32_t cpu_phandle;
-
- clust_name = g_strdup_printf("/cpus/cpu-map/cluster%d", socket_id);
- qemu_fdt_add_subnode(fdt, clust_name);
-
- for (int cpu = num_harts_socket - 1; cpu >= 0; cpu--) {
- RISCVCPU *cpu_ptr = &socket_harts[cpu];
+ g_autofree char *cpu_name = NULL;
+ g_autofree char *core_name = NULL;
+ g_autofree char *intc_name = NULL;
+ uint32_t cpu_phandle = (*phandle)++;
+ bool is_sifive_u = cpu_ptr == NULL;
+
+ cpu_name = g_strdup_printf("/cpus/cpu@%d", socket_hartid_base + cpu);
+
+ /*
+ * The sifive_u board has an exclusive satp and riscv,isa
+ * schema that can't be shared with other boards, so part
+ * of the CPU FDT creation (i.e. the /cpus/cpu@N subnode)
+ * is still being done by the board.
+ */
+ if (!is_sifive_u) {
int8_t satp_mode_max = cpu_ptr->cfg.max_satp_mode;
- g_autofree char *cpu_name = NULL;
- g_autofree char *core_name = NULL;
- g_autofree char *intc_name = NULL;
-
- cpu_phandle = (*phandle)++;
- cpu_name = g_strdup_printf("/cpus/cpu@%d", socket_hartid_base + cpu);
qemu_fdt_add_subnode(fdt, cpu_name);
if (satp_mode_max != -1) {
@@ -140,30 +141,51 @@ void create_fdt_socket_cpus(void *fdt, RISCVCPU *socket_harts,
qemu_fdt_setprop_cell(fdt, cpu_name, "riscv,cbop-block-size",
cpu_ptr->cfg.cbop_blocksize);
}
+ }
- qemu_fdt_setprop_string(fdt, cpu_name, "compatible", "riscv");
- qemu_fdt_setprop_string(fdt, cpu_name, "status", "okay");
- qemu_fdt_setprop_cell(fdt, cpu_name, "reg",
- socket_hartid_base + cpu);
- qemu_fdt_setprop_string(fdt, cpu_name, "device_type", "cpu");
- if (numa_enabled) {
- qemu_fdt_setprop_cell(fdt, cpu_name, "numa-node-id", socket_id);
- }
- qemu_fdt_setprop_cell(fdt, cpu_name, "phandle", cpu_phandle);
-
- intc_phandles[cpu] = (*phandle)++;
-
- intc_name = g_strdup_printf("%s/interrupt-controller", cpu_name);
- qemu_fdt_add_subnode(fdt, intc_name);
- qemu_fdt_setprop_cell(fdt, intc_name, "phandle",
- intc_phandles[cpu]);
- qemu_fdt_setprop_string(fdt, intc_name, "compatible",
- "riscv,cpu-intc");
- qemu_fdt_setprop(fdt, intc_name, "interrupt-controller", NULL, 0);
- qemu_fdt_setprop_cell(fdt, intc_name, "#interrupt-cells", 1);
-
- core_name = g_strdup_printf("%s/core%d", clust_name, cpu);
- qemu_fdt_add_subnode(fdt, core_name);
- qemu_fdt_setprop_cell(fdt, core_name, "cpu", cpu_phandle);
+ qemu_fdt_setprop_string(fdt, cpu_name, "compatible", "riscv");
+ qemu_fdt_setprop_string(fdt, cpu_name, "status", "okay");
+ qemu_fdt_setprop_cell(fdt, cpu_name, "reg",
+ socket_hartid_base + cpu);
+ qemu_fdt_setprop_string(fdt, cpu_name, "device_type", "cpu");
+ if (numa_enabled) {
+ qemu_fdt_setprop_cell(fdt, cpu_name, "numa-node-id", socket_id);
+ }
+ qemu_fdt_setprop_cell(fdt, cpu_name, "phandle", cpu_phandle);
+
+ intc_phandles[cpu] = (*phandle)++;
+
+ intc_name = g_strdup_printf("%s/interrupt-controller", cpu_name);
+ qemu_fdt_add_subnode(fdt, intc_name);
+ qemu_fdt_setprop_cell(fdt, intc_name, "phandle",
+ intc_phandles[cpu]);
+ qemu_fdt_setprop_string(fdt, intc_name, "compatible",
+ "riscv,cpu-intc");
+ qemu_fdt_setprop(fdt, intc_name, "interrupt-controller", NULL, 0);
+ qemu_fdt_setprop_cell(fdt, intc_name, "#interrupt-cells", 1);
+
+ core_name = g_strdup_printf("%s/core%d", clust_name, cpu);
+ qemu_fdt_add_subnode(fdt, core_name);
+ qemu_fdt_setprop_cell(fdt, core_name, "cpu", cpu_phandle);
+}
+
+void create_fdt_socket_cpus(void *fdt, RISCVCPU *socket_harts,
+ int socket_id, int num_harts_socket,
+ int socket_hartid_base, uint32_t *phandle,
+ uint32_t *intc_phandles, bool numa_enabled,
+ bool is_32_bit)
+{
+ g_autofree char *clust_name = NULL;
+
+ clust_name = g_strdup_printf("/cpus/cpu-map/cluster%d", socket_id);
+ qemu_fdt_add_subnode(fdt, clust_name);
+
+ for (int cpu = num_harts_socket - 1; cpu >= 0; cpu--) {
+ RISCVCPU *cpu_ptr = &socket_harts[cpu];
+
+ create_fdt_socket_cpu_internal(fdt, clust_name, cpu_ptr, cpu,
+ socket_id, socket_hartid_base,
+ phandle, intc_phandles, numa_enabled,
+ is_32_bit);
}
}