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);
     }
 }