On Tue, Jun 16, 2026 at 6:40 AM Daniel Henrique Barboza <[email protected]> wrote: > > 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 <[email protected]>
Reviewed-by: Alistair Francis <[email protected]> Alistair > --- > hw/riscv/fdt-common.c | 108 +++++++++++++++++++++++++----------------- > 1 file changed, 65 insertions(+), 43 deletions(-) > > 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); > } > } > -- > 2.43.0 > >
