On Sun, Aug 11, 2019 at 1:10 AM Bin Meng <bmeng...@gmail.com> wrote: > > The FU540-C000 includes a 64-bit E51 RISC-V core and four 64-bit U54 > RISC-V cores. Currently the sifive_u machine only populates 4 U54 > cores. Update the max cpu number to 5 to reflect the real hardware, > and pass "cpu-type" to populate heterogeneous harts. > > The cpu nodes in the generated DTS have been updated as well. > > Signed-off-by: Bin Meng <bmeng...@gmail.com>
Reviewed-by: Alistair Francis <alistair.fran...@wdc.com> Alistair > > --- > > Changes in v3: > - changed to use macros for management and compute cpu count > > Changes in v2: > - fixed the "interrupts-extended" property size > > hw/riscv/sifive_u.c | 40 +++++++++++++++++++++++++++------------- > include/hw/riscv/sifive_u.h | 3 +++ > 2 files changed, 30 insertions(+), 13 deletions(-) > > diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c > index 623ee64..295ca77 100644 > --- a/hw/riscv/sifive_u.c > +++ b/hw/riscv/sifive_u.c > @@ -10,7 +10,8 @@ > * 1) CLINT (Core Level Interruptor) > * 2) PLIC (Platform Level Interrupt Controller) > * > - * This board currently uses a hardcoded devicetree that indicates one hart. > + * This board currently generates devicetree dynamically that indicates at > most > + * five harts. > * > * This program is free software; you can redistribute it and/or modify it > * under the terms and conditions of the GNU General Public License, > @@ -26,6 +27,7 @@ > */ > > #include "qemu/osdep.h" > +#include "qemu/cutils.h" > #include "qemu/log.h" > #include "qemu/error-report.h" > #include "qapi/error.h" > @@ -117,7 +119,10 @@ static void create_fdt(SiFiveUState *s, const struct > MemmapEntry *memmap, > qemu_fdt_add_subnode(fdt, nodename); > qemu_fdt_setprop_cell(fdt, nodename, "clock-frequency", > SIFIVE_U_CLOCK_FREQ); > - qemu_fdt_setprop_string(fdt, nodename, "mmu-type", "riscv,sv48"); > + /* cpu 0 is the management hart that does not have mmu */ > + if (cpu != 0) { > + qemu_fdt_setprop_string(fdt, nodename, "mmu-type", "riscv,sv48"); > + } > qemu_fdt_setprop_string(fdt, nodename, "riscv,isa", isa); > qemu_fdt_setprop_string(fdt, nodename, "compatible", "riscv"); > qemu_fdt_setprop_string(fdt, nodename, "status", "okay"); > @@ -157,15 +162,21 @@ static void create_fdt(SiFiveUState *s, const struct > MemmapEntry *memmap, > g_free(nodename); > > plic_phandle = phandle++; > - cells = g_new0(uint32_t, s->soc.cpus.num_harts * 4); > + cells = g_new0(uint32_t, s->soc.cpus.num_harts * 4 - 2); > for (cpu = 0; cpu < s->soc.cpus.num_harts; cpu++) { > nodename = > g_strdup_printf("/cpus/cpu@%d/interrupt-controller", cpu); > uint32_t intc_phandle = qemu_fdt_get_phandle(fdt, nodename); > - cells[cpu * 4 + 0] = cpu_to_be32(intc_phandle); > - cells[cpu * 4 + 1] = cpu_to_be32(IRQ_M_EXT); > - cells[cpu * 4 + 2] = cpu_to_be32(intc_phandle); > - cells[cpu * 4 + 3] = cpu_to_be32(IRQ_S_EXT); > + /* cpu 0 is the management hart that does not have S-mode */ > + if (cpu == 0) { > + cells[0] = cpu_to_be32(intc_phandle); > + cells[1] = cpu_to_be32(IRQ_M_EXT); > + } else { > + cells[cpu * 4 - 2] = cpu_to_be32(intc_phandle); > + cells[cpu * 4 - 1] = cpu_to_be32(IRQ_M_EXT); > + cells[cpu * 4 + 0] = cpu_to_be32(intc_phandle); > + cells[cpu * 4 + 1] = cpu_to_be32(IRQ_S_EXT); > + } > g_free(nodename); > } > nodename = g_strdup_printf("/soc/interrupt-controller@%lx", > @@ -175,7 +186,7 @@ static void create_fdt(SiFiveUState *s, const struct > MemmapEntry *memmap, > qemu_fdt_setprop_string(fdt, nodename, "compatible", "riscv,plic0"); > qemu_fdt_setprop(fdt, nodename, "interrupt-controller", NULL, 0); > qemu_fdt_setprop(fdt, nodename, "interrupts-extended", > - cells, s->soc.cpus.num_harts * sizeof(uint32_t) * 4); > + cells, (s->soc.cpus.num_harts * 4 - 2) * sizeof(uint32_t)); > qemu_fdt_setprop_cells(fdt, nodename, "reg", > 0x0, memmap[SIFIVE_U_PLIC].base, > 0x0, memmap[SIFIVE_U_PLIC].size); > @@ -315,10 +326,16 @@ static void riscv_sifive_u_soc_init(Object *obj) > { > MachineState *ms = MACHINE(qdev_get_machine()); > SiFiveUSoCState *s = RISCV_U_SOC(obj); > + char cpu_type[64]; > + > + /* create cpu type representing SiFive FU540 SoC */ > + pstrcpy(cpu_type, sizeof(cpu_type), SIFIVE_E_CPU); > + pstrcat(cpu_type, sizeof(cpu_type), ","); > + pstrcat(cpu_type, sizeof(cpu_type), SIFIVE_U_CPU); > > object_initialize_child(obj, "cpus", &s->cpus, sizeof(s->cpus), > TYPE_RISCV_HART_ARRAY, &error_abort, NULL); > - object_property_set_str(OBJECT(&s->cpus), SIFIVE_U_CPU, "cpu-type", > + object_property_set_str(OBJECT(&s->cpus), cpu_type, "cpu-type", > &error_abort); > object_property_set_int(OBJECT(&s->cpus), ms->smp.cpus, "num-harts", > &error_abort); > @@ -407,10 +424,7 @@ static void riscv_sifive_u_machine_init(MachineClass *mc) > { > mc->desc = "RISC-V Board compatible with SiFive U SDK"; > mc->init = riscv_sifive_u_init; > - /* The real hardware has 5 CPUs, but one of them is a small embedded > power > - * management CPU. > - */ > - mc->max_cpus = 4; > + mc->max_cpus = SIFIVE_U_MANAGEMENT_CPU_COUNT + > SIFIVE_U_COMPUTE_CPU_COUNT; > } > > DEFINE_MACHINE("sifive_u", riscv_sifive_u_machine_init) > diff --git a/include/hw/riscv/sifive_u.h b/include/hw/riscv/sifive_u.h > index 4abc621..650bc4c 100644 > --- a/include/hw/riscv/sifive_u.h > +++ b/include/hw/riscv/sifive_u.h > @@ -68,6 +68,9 @@ enum { > SIFIVE_U_GEM_CLOCK_FREQ = 125000000 > }; > > +#define SIFIVE_U_MANAGEMENT_CPU_COUNT 1 > +#define SIFIVE_U_COMPUTE_CPU_COUNT 4 > + > #define SIFIVE_U_PLIC_HART_CONFIG "MS" > #define SIFIVE_U_PLIC_NUM_SOURCES 54 > #define SIFIVE_U_PLIC_NUM_PRIORITIES 7 > -- > 2.7.4 > >