Skip to content

Commit

Permalink
Merge remote-tracking branch 'remotes/alistair/tags/pull-riscv-to-app…
Browse files Browse the repository at this point in the history
…ly-20200429-2' into staging

RISC-V pull request for 5.1

This is the first pull request for the 5.1 development period. It
contains all of the patches that were sent during the 5.0 timeframe.

This is an assortment of fixes for RISC-V, including fixes for the
Hypervisor extension, the Spike machine and an update to OpenSBI.

# gpg: Signature made Wed 29 Apr 2020 21:17:17 BST
# gpg:                using RSA key F6C4AC46D4934868D3B8CE8F21E10D29DF977054
# gpg: Good signature from "Alistair Francis <alistair@alistair23.me>" [full]
# Primary key fingerprint: F6C4 AC46 D493 4868 D3B8  CE8F 21E1 0D29 DF97 7054

* remotes/alistair/tags/pull-riscv-to-apply-20200429-2:
  hw/riscv/spike: Allow more than one CPUs
  hw/riscv/spike: Allow loading firmware separately using -bios option
  hw/riscv: Add optional symbol callback ptr to riscv_load_firmware()
  roms: opensbi: Upgrade from v0.6 to v0.7
  linux-user/riscv: fix up struct target_ucontext definition
  target/riscv: Add a sifive-e34 cpu type
  riscv: sifive_e: Support changing CPU type
  hw/riscv: Generate correct "mmu-type" for 32-bit machines
  riscv: Fix Stage2 SV32 page table walk
  riscv: AND stage-1 and stage-2 protection flags
  riscv: Don't use stage-2 PTE lookup protection flags
  riscv/sifive_u: Add a serial property to the sifive_u machine
  riscv/sifive_u: Add a serial property to the sifive_u SoC
  riscv/sifive_u: Fix up file ordering

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
  • Loading branch information
pm215 committed Apr 29, 2020
2 parents 648db19 + 31e6d70 commit 1573603
Show file tree
Hide file tree
Showing 16 changed files with 159 additions and 80 deletions.
13 changes: 8 additions & 5 deletions hw/riscv/boot.c
Expand Up @@ -36,7 +36,8 @@

void riscv_find_and_load_firmware(MachineState *machine,
const char *default_machine_firmware,
hwaddr firmware_load_addr)
hwaddr firmware_load_addr,
symbol_fn_t sym_cb)
{
char *firmware_filename = NULL;

Expand Down Expand Up @@ -76,7 +77,7 @@ void riscv_find_and_load_firmware(MachineState *machine,

if (firmware_filename) {
/* If not "none" load the firmware */
riscv_load_firmware(firmware_filename, firmware_load_addr);
riscv_load_firmware(firmware_filename, firmware_load_addr, sym_cb);
g_free(firmware_filename);
}
}
Expand All @@ -96,12 +97,14 @@ char *riscv_find_firmware(const char *firmware_filename)
}

target_ulong riscv_load_firmware(const char *firmware_filename,
hwaddr firmware_load_addr)
hwaddr firmware_load_addr,
symbol_fn_t sym_cb)
{
uint64_t firmware_entry, firmware_start, firmware_end;

if (load_elf(firmware_filename, NULL, NULL, NULL, &firmware_entry,
&firmware_start, &firmware_end, NULL, 0, EM_RISCV, 1, 0) > 0) {
if (load_elf_ram_sym(firmware_filename, NULL, NULL, NULL,
&firmware_entry, &firmware_start, &firmware_end, NULL,
0, EM_RISCV, 1, 0, NULL, true, sym_cb) > 0) {
return firmware_entry;
}

Expand Down
5 changes: 3 additions & 2 deletions hw/riscv/sifive_e.c
Expand Up @@ -123,8 +123,6 @@ static void riscv_sifive_e_soc_init(Object *obj)
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_E_CPU, "cpu-type",
&error_abort);
object_property_set_int(OBJECT(&s->cpus), ms->smp.cpus, "num-harts",
&error_abort);
sysbus_init_child_obj(obj, "riscv.sifive.e.gpio0",
Expand All @@ -141,6 +139,8 @@ static void riscv_sifive_e_soc_realize(DeviceState *dev, Error **errp)
SiFiveESoCState *s = RISCV_E_SOC(dev);
MemoryRegion *sys_mem = get_system_memory();

object_property_set_str(OBJECT(&s->cpus), ms->cpu_type, "cpu-type",
&error_abort);
object_property_set_bool(OBJECT(&s->cpus), true, "realized",
&error_abort);

Expand Down Expand Up @@ -219,6 +219,7 @@ static void riscv_sifive_e_machine_init(MachineClass *mc)
mc->desc = "RISC-V Board compatible with SiFive E SDK";
mc->init = riscv_sifive_e_init;
mc->max_cpus = 1;
mc->default_cpu_type = SIFIVE_E_CPU;
}

DEFINE_MACHINE("sifive_e", riscv_sifive_e_machine_init)
Expand Down
142 changes: 86 additions & 56 deletions hw/riscv/sifive_u.c
Expand Up @@ -34,6 +34,7 @@
#include "qemu/log.h"
#include "qemu/error-report.h"
#include "qapi/error.h"
#include "qapi/visitor.h"
#include "hw/boards.h"
#include "hw/loader.h"
#include "hw/sysbus.h"
Expand Down Expand Up @@ -159,7 +160,11 @@ static void create_fdt(SiFiveUState *s, const struct MemmapEntry *memmap,
qemu_fdt_add_subnode(fdt, nodename);
/* cpu 0 is the management hart that does not have mmu */
if (cpu != 0) {
#if defined(TARGET_RISCV32)
qemu_fdt_setprop_string(fdt, nodename, "mmu-type", "riscv,sv32");
#else
qemu_fdt_setprop_string(fdt, nodename, "mmu-type", "riscv,sv48");
#endif
isa = riscv_isa_string(&s->soc.u_cpus.harts[cpu - 1]);
} else {
isa = riscv_isa_string(&s->soc.e_cpus.harts[0]);
Expand Down Expand Up @@ -312,7 +317,7 @@ static void create_fdt(SiFiveUState *s, const struct MemmapEntry *memmap,
g_free(nodename);
}

static void riscv_sifive_u_init(MachineState *machine)
static void sifive_u_machine_init(MachineState *machine)
{
const struct MemmapEntry *memmap = sifive_u_memmap;
SiFiveUState *s = RISCV_U_MACHINE(machine);
Expand All @@ -326,6 +331,8 @@ static void riscv_sifive_u_init(MachineState *machine)
object_initialize_child(OBJECT(machine), "soc", &s->soc,
sizeof(s->soc), TYPE_RISCV_U_SOC,
&error_abort, NULL);
object_property_set_uint(OBJECT(&s->soc), s->serial, "serial",
&error_abort);
object_property_set_bool(OBJECT(&s->soc), true, "realized",
&error_abort);

Expand All @@ -345,7 +352,7 @@ static void riscv_sifive_u_init(MachineState *machine)
create_fdt(s, memmap, machine->ram_size, machine->kernel_cmdline);

riscv_find_and_load_firmware(machine, BIOS_FILENAME,
memmap[SIFIVE_U_DRAM].base);
memmap[SIFIVE_U_DRAM].base, NULL);

if (machine->kernel_filename) {
uint64_t kernel_entry = riscv_load_kernel(machine->kernel_filename,
Expand Down Expand Up @@ -403,6 +410,76 @@ static void riscv_sifive_u_init(MachineState *machine)
&address_space_memory);
}

static bool sifive_u_machine_get_start_in_flash(Object *obj, Error **errp)
{
SiFiveUState *s = RISCV_U_MACHINE(obj);

return s->start_in_flash;
}

static void sifive_u_machine_set_start_in_flash(Object *obj, bool value, Error **errp)
{
SiFiveUState *s = RISCV_U_MACHINE(obj);

s->start_in_flash = value;
}

static void sifive_u_machine_get_serial(Object *obj, Visitor *v, const char *name,
void *opaque, Error **errp)
{
visit_type_uint32(v, name, (uint32_t *)opaque, errp);
}

static void sifive_u_machine_set_serial(Object *obj, Visitor *v, const char *name,
void *opaque, Error **errp)
{
visit_type_uint32(v, name, (uint32_t *)opaque, errp);
}

static void sifive_u_machine_instance_init(Object *obj)
{
SiFiveUState *s = RISCV_U_MACHINE(obj);

s->start_in_flash = false;
object_property_add_bool(obj, "start-in-flash", sifive_u_machine_get_start_in_flash,
sifive_u_machine_set_start_in_flash, NULL);
object_property_set_description(obj, "start-in-flash",
"Set on to tell QEMU's ROM to jump to "
"flash. Otherwise QEMU will jump to DRAM",
NULL);

s->serial = OTP_SERIAL;
object_property_add(obj, "serial", "uint32", sifive_u_machine_get_serial,
sifive_u_machine_set_serial, NULL, &s->serial, NULL);
object_property_set_description(obj, "serial", "Board serial number", NULL);
}

static void sifive_u_machine_class_init(ObjectClass *oc, void *data)
{
MachineClass *mc = MACHINE_CLASS(oc);

mc->desc = "RISC-V Board compatible with SiFive U SDK";
mc->init = sifive_u_machine_init;
mc->max_cpus = SIFIVE_U_MANAGEMENT_CPU_COUNT + SIFIVE_U_COMPUTE_CPU_COUNT;
mc->min_cpus = SIFIVE_U_MANAGEMENT_CPU_COUNT + 1;
mc->default_cpus = mc->min_cpus;
}

static const TypeInfo sifive_u_machine_typeinfo = {
.name = MACHINE_TYPE_NAME("sifive_u"),
.parent = TYPE_MACHINE,
.class_init = sifive_u_machine_class_init,
.instance_init = sifive_u_machine_instance_init,
.instance_size = sizeof(SiFiveUState),
};

static void sifive_u_machine_init_register_types(void)
{
type_register_static(&sifive_u_machine_typeinfo);
}

type_init(sifive_u_machine_init_register_types)

static void riscv_sifive_u_soc_init(Object *obj)
{
MachineState *ms = MACHINE(qdev_get_machine());
Expand Down Expand Up @@ -438,38 +515,10 @@ static void riscv_sifive_u_soc_init(Object *obj)
TYPE_SIFIVE_U_PRCI);
sysbus_init_child_obj(obj, "otp", &s->otp, sizeof(s->otp),
TYPE_SIFIVE_U_OTP);
qdev_prop_set_uint32(DEVICE(&s->otp), "serial", OTP_SERIAL);
sysbus_init_child_obj(obj, "gem", &s->gem, sizeof(s->gem),
TYPE_CADENCE_GEM);
}

static bool sifive_u_get_start_in_flash(Object *obj, Error **errp)
{
SiFiveUState *s = RISCV_U_MACHINE(obj);

return s->start_in_flash;
}

static void sifive_u_set_start_in_flash(Object *obj, bool value, Error **errp)
{
SiFiveUState *s = RISCV_U_MACHINE(obj);

s->start_in_flash = value;
}

static void riscv_sifive_u_machine_instance_init(Object *obj)
{
SiFiveUState *s = RISCV_U_MACHINE(obj);

s->start_in_flash = false;
object_property_add_bool(obj, "start-in-flash", sifive_u_get_start_in_flash,
sifive_u_set_start_in_flash, NULL);
object_property_set_description(obj, "start-in-flash",
"Set on to tell QEMU's ROM to jump to "
"flash. Otherwise QEMU will jump to DRAM",
NULL);
}

static void riscv_sifive_u_soc_realize(DeviceState *dev, Error **errp)
{
MachineState *ms = MACHINE(qdev_get_machine());
Expand Down Expand Up @@ -558,6 +607,7 @@ static void riscv_sifive_u_soc_realize(DeviceState *dev, Error **errp)
object_property_set_bool(OBJECT(&s->prci), true, "realized", &err);
sysbus_mmio_map(SYS_BUS_DEVICE(&s->prci), 0, memmap[SIFIVE_U_PRCI].base);

qdev_prop_set_uint32(DEVICE(&s->otp), "serial", s->serial);
object_property_set_bool(OBJECT(&s->otp), true, "realized", &err);
sysbus_mmio_map(SYS_BUS_DEVICE(&s->otp), 0, memmap[SIFIVE_U_OTP].base);

Expand All @@ -584,10 +634,16 @@ static void riscv_sifive_u_soc_realize(DeviceState *dev, Error **errp)
memmap[SIFIVE_U_GEM_MGMT].base, memmap[SIFIVE_U_GEM_MGMT].size);
}

static Property riscv_sifive_u_soc_props[] = {
DEFINE_PROP_UINT32("serial", SiFiveUSoCState, serial, OTP_SERIAL),
DEFINE_PROP_END_OF_LIST()
};

static void riscv_sifive_u_soc_class_init(ObjectClass *oc, void *data)
{
DeviceClass *dc = DEVICE_CLASS(oc);

device_class_set_props(dc, riscv_sifive_u_soc_props);
dc->realize = riscv_sifive_u_soc_realize;
/* Reason: Uses serial_hds in realize function, thus can't be used twice */
dc->user_creatable = false;
Expand All @@ -607,29 +663,3 @@ static void riscv_sifive_u_soc_register_types(void)
}

type_init(riscv_sifive_u_soc_register_types)

static void riscv_sifive_u_machine_class_init(ObjectClass *oc, void *data)
{
MachineClass *mc = MACHINE_CLASS(oc);

mc->desc = "RISC-V Board compatible with SiFive U SDK";
mc->init = riscv_sifive_u_init;
mc->max_cpus = SIFIVE_U_MANAGEMENT_CPU_COUNT + SIFIVE_U_COMPUTE_CPU_COUNT;
mc->min_cpus = SIFIVE_U_MANAGEMENT_CPU_COUNT + 1;
mc->default_cpus = mc->min_cpus;
}

static const TypeInfo riscv_sifive_u_machine_typeinfo = {
.name = MACHINE_TYPE_NAME("sifive_u"),
.parent = TYPE_MACHINE,
.class_init = riscv_sifive_u_machine_class_init,
.instance_init = riscv_sifive_u_machine_instance_init,
.instance_size = sizeof(SiFiveUState),
};

static void riscv_sifive_u_machine_init_register_types(void)
{
type_register_static(&riscv_sifive_u_machine_typeinfo);
}

type_init(riscv_sifive_u_machine_init_register_types)
30 changes: 28 additions & 2 deletions hw/riscv/spike.c
Expand Up @@ -45,6 +45,12 @@

#include <libfdt.h>

#if defined(TARGET_RISCV32)
# define BIOS_FILENAME "opensbi-riscv32-spike-fw_jump.elf"
#else
# define BIOS_FILENAME "opensbi-riscv64-spike-fw_jump.elf"
#endif

static const struct MemmapEntry {
hwaddr base;
hwaddr size;
Expand Down Expand Up @@ -102,7 +108,11 @@ static void create_fdt(SpikeState *s, const struct MemmapEntry *memmap,
char *intc = g_strdup_printf("/cpus/cpu@%d/interrupt-controller", cpu);
char *isa = riscv_isa_string(&s->soc.harts[cpu]);
qemu_fdt_add_subnode(fdt, nodename);
#if defined(TARGET_RISCV32)
qemu_fdt_setprop_string(fdt, nodename, "mmu-type", "riscv,sv32");
#else
qemu_fdt_setprop_string(fdt, nodename, "mmu-type", "riscv,sv48");
#endif
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");
Expand Down Expand Up @@ -183,8 +193,24 @@ static void spike_board_init(MachineState *machine)
memory_region_add_subregion(system_memory, memmap[SPIKE_MROM].base,
mask_rom);

riscv_find_and_load_firmware(machine, BIOS_FILENAME,
memmap[SPIKE_DRAM].base,
htif_symbol_callback);

if (machine->kernel_filename) {
riscv_load_kernel(machine->kernel_filename, htif_symbol_callback);
uint64_t kernel_entry = riscv_load_kernel(machine->kernel_filename,
htif_symbol_callback);

if (machine->initrd_filename) {
hwaddr start;
hwaddr end = riscv_load_initrd(machine->initrd_filename,
machine->ram_size, kernel_entry,
&start);
qemu_fdt_setprop_cell(s->fdt, "/chosen",
"linux,initrd-start", start);
qemu_fdt_setprop_cell(s->fdt, "/chosen", "linux,initrd-end",
end);
}
}

/* reset vector */
Expand Down Expand Up @@ -450,7 +476,7 @@ static void spike_machine_init(MachineClass *mc)
{
mc->desc = "RISC-V Spike Board";
mc->init = spike_board_init;
mc->max_cpus = 1;
mc->max_cpus = 8;
mc->is_default = true;
mc->default_cpu_type = SPIKE_V1_10_0_CPU;
}
Expand Down
6 changes: 5 additions & 1 deletion hw/riscv/virt.c
Expand Up @@ -229,7 +229,11 @@ static void create_fdt(RISCVVirtState *s, const struct MemmapEntry *memmap,
char *intc = g_strdup_printf("/cpus/cpu@%d/interrupt-controller", cpu);
char *isa = riscv_isa_string(&s->soc.harts[cpu]);
qemu_fdt_add_subnode(fdt, nodename);
#if defined(TARGET_RISCV32)
qemu_fdt_setprop_string(fdt, nodename, "mmu-type", "riscv,sv32");
#else
qemu_fdt_setprop_string(fdt, nodename, "mmu-type", "riscv,sv48");
#endif
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");
Expand Down Expand Up @@ -507,7 +511,7 @@ static void riscv_virt_board_init(MachineState *machine)
mask_rom);

riscv_find_and_load_firmware(machine, BIOS_FILENAME,
memmap[VIRT_DRAM].base);
memmap[VIRT_DRAM].base, NULL);

if (machine->kernel_filename) {
uint64_t kernel_entry = riscv_load_kernel(machine->kernel_filename,
Expand Down
6 changes: 4 additions & 2 deletions include/hw/riscv/boot.h
Expand Up @@ -24,10 +24,12 @@

void riscv_find_and_load_firmware(MachineState *machine,
const char *default_machine_firmware,
hwaddr firmware_load_addr);
hwaddr firmware_load_addr,
symbol_fn_t sym_cb);
char *riscv_find_firmware(const char *firmware_filename);
target_ulong riscv_load_firmware(const char *firmware_filename,
hwaddr firmware_load_addr);
hwaddr firmware_load_addr,
symbol_fn_t sym_cb);
target_ulong riscv_load_kernel(const char *kernel_filename,
symbol_fn_t sym_cb);
hwaddr riscv_load_initrd(const char *filename, uint64_t mem_size,
Expand Down
3 changes: 3 additions & 0 deletions include/hw/riscv/sifive_u.h
Expand Up @@ -42,6 +42,8 @@ typedef struct SiFiveUSoCState {
SiFiveUPRCIState prci;
SiFiveUOTPState otp;
CadenceGEMState gem;

uint32_t serial;
} SiFiveUSoCState;

#define TYPE_RISCV_U_MACHINE MACHINE_TYPE_NAME("sifive_u")
Expand All @@ -59,6 +61,7 @@ typedef struct SiFiveUState {
int fdt_size;

bool start_in_flash;
uint32_t serial;
} SiFiveUState;

enum {
Expand Down

0 comments on commit 1573603

Please sign in to comment.