#include "hw/char/serial.h"
#include "hw/cpu/cluster.h"
#include "hw/misc/unimp.h"
+#include "hw/sd/sd.h"
#include "hw/ssi/ssi.h"
#include "target/riscv/cpu.h"
#include "hw/riscv/riscv_hart.h"
#define GEM_REVISION 0x10070109
static void create_fdt(SiFiveUState *s, const MemMapEntry *memmap,
- uint64_t mem_size, const char *cmdline, bool is_32_bit)
+ bool is_32_bit)
{
- MachineState *ms = MACHINE(qdev_get_machine());
+ MachineState *ms = MACHINE(s);
+ uint64_t mem_size = ms->ram_size;
void *fdt;
int cpu;
uint32_t *cells;
"sifive,plic-1.0.0", "riscv,plic0"
};
- if (ms->dtb) {
- fdt = s->fdt = load_device_tree(ms->dtb, &s->fdt_size);
- if (!fdt) {
- error_report("load_device_tree() failed");
- exit(1);
- }
- goto update_bootargs;
- } else {
- fdt = s->fdt = create_device_tree(&s->fdt_size);
- if (!fdt) {
- error_report("create_device_tree() failed");
- exit(1);
- }
+ fdt = ms->fdt = create_device_tree(&s->fdt_size);
+ if (!fdt) {
+ error_report("create_device_tree() failed");
+ exit(1);
}
qemu_fdt_setprop_string(fdt, "/", "model", "SiFive HiFive Unleashed A00");
qemu_fdt_setprop_cells(fdt, nodename, "reg",
0x0, memmap[SIFIVE_U_DEV_PLIC].base,
0x0, memmap[SIFIVE_U_DEV_PLIC].size);
- qemu_fdt_setprop_cell(fdt, nodename, "riscv,ndev", 0x35);
+ qemu_fdt_setprop_cell(fdt, nodename, "riscv,ndev",
+ SIFIVE_U_PLIC_NUM_SOURCES - 1);
qemu_fdt_setprop_cell(fdt, nodename, "phandle", plic_phandle);
plic_phandle = qemu_fdt_get_phandle(fdt, nodename);
g_free(cells);
qemu_fdt_setprop_string(fdt, "/aliases", "serial0", nodename);
g_free(nodename);
-
-update_bootargs:
- if (cmdline) {
- qemu_fdt_setprop_string(fdt, "/chosen", "bootargs", cmdline);
- }
}
static void sifive_u_machine_reset(void *opaque, int n, int level)
MemoryRegion *flash0 = g_new(MemoryRegion, 1);
target_ulong start_addr = memmap[SIFIVE_U_DEV_DRAM].base;
target_ulong firmware_end_addr, kernel_start_addr;
+ const char *firmware_name;
uint32_t start_addr_hi32 = 0x00000000;
int i;
uint32_t fdt_load_addr;
uint64_t kernel_entry;
DriveInfo *dinfo;
- DeviceState *flash_dev, *sd_dev;
+ BlockBackend *blk;
+ DeviceState *flash_dev, *sd_dev, *card_dev;
qemu_irq flash_cs, sd_cs;
/* Initialize SoC */
&error_abort);
object_property_set_str(OBJECT(&s->soc), "cpu-type", machine->cpu_type,
&error_abort);
- qdev_realize(DEVICE(&s->soc), NULL, &error_abort);
+ qdev_realize(DEVICE(&s->soc), NULL, &error_fatal);
/* register RAM */
memory_region_add_subregion(system_memory, memmap[SIFIVE_U_DEV_DRAM].base,
qdev_connect_gpio_out(DEVICE(&(s->soc.gpio)), 10,
qemu_allocate_irq(sifive_u_machine_reset, NULL, 0));
- /* create device tree */
- create_fdt(s, memmap, machine->ram_size, machine->kernel_cmdline,
- riscv_is_32bit(&s->soc.u_cpus));
+ /* load/create device tree */
+ if (machine->dtb) {
+ machine->fdt = load_device_tree(machine->dtb, &s->fdt_size);
+ if (!machine->fdt) {
+ error_report("load_device_tree() failed");
+ exit(1);
+ }
+ } else {
+ create_fdt(s, memmap, riscv_is_32bit(&s->soc.u_cpus));
+ }
if (s->start_in_flash) {
/*
break;
}
- if (riscv_is_32bit(&s->soc.u_cpus)) {
- firmware_end_addr = riscv_find_and_load_firmware(machine,
- RISCV32_BIOS_BIN, start_addr, NULL);
- } else {
- firmware_end_addr = riscv_find_and_load_firmware(machine,
- RISCV64_BIOS_BIN, start_addr, NULL);
- }
+ firmware_name = riscv_default_firmware_name(&s->soc.u_cpus);
+ firmware_end_addr = riscv_find_and_load_firmware(machine, firmware_name,
+ start_addr, NULL);
if (machine->kernel_filename) {
kernel_start_addr = riscv_calc_kernel_start_addr(&s->soc.u_cpus,
firmware_end_addr);
- kernel_entry = riscv_load_kernel(machine->kernel_filename,
- kernel_start_addr, NULL);
-
- 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);
- }
+ kernel_entry = riscv_load_kernel(machine, &s->soc.u_cpus,
+ kernel_start_addr, true, NULL);
} else {
/*
* If dynamic firmware is used, it doesn't know where is the next mode
kernel_entry = 0;
}
- /* Compute the fdt load address in dram */
- fdt_load_addr = riscv_load_fdt(memmap[SIFIVE_U_DEV_DRAM].base,
- machine->ram_size, s->fdt);
+ fdt_load_addr = riscv_compute_fdt_addr(memmap[SIFIVE_U_DEV_DRAM].base,
+ memmap[SIFIVE_U_DEV_DRAM].size,
+ machine);
+ riscv_load_fdt(fdt_load_addr, machine->fdt);
+
if (!riscv_is_32bit(&s->soc.u_cpus)) {
start_addr_hi32 = (uint64_t)start_addr >> 32;
}
/* Connect an SPI flash to SPI0 */
flash_dev = qdev_new("is25wp256");
- dinfo = drive_get_next(IF_MTD);
+ dinfo = drive_get(IF_MTD, 0, 0);
if (dinfo) {
qdev_prop_set_drive_err(flash_dev, "drive",
blk_by_legacy_dinfo(dinfo),
sd_cs = qdev_get_gpio_in_named(sd_dev, SSI_GPIO_CS, 0);
sysbus_connect_irq(SYS_BUS_DEVICE(&s->soc.spi2), 1, sd_cs);
+
+ dinfo = drive_get(IF_SD, 0, 0);
+ blk = dinfo ? blk_by_legacy_dinfo(dinfo) : NULL;
+ card_dev = qdev_new(TYPE_SD_CARD_SPI);
+ qdev_prop_set_drive_err(card_dev, "drive", blk, &error_fatal);
+ qdev_realize_and_unref(card_dev,
+ qdev_get_child_bus(sd_dev, "sd-bus"),
+ &error_fatal);
}
static bool sifive_u_machine_get_start_in_flash(Object *obj, Error **errp)
s->start_in_flash = value;
}
-static void sifive_u_machine_get_uint32_prop(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_uint32_prop(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;
s->msel = 0;
- object_property_add(obj, "msel", "uint32",
- sifive_u_machine_get_uint32_prop,
- sifive_u_machine_set_uint32_prop, NULL, &s->msel);
+ object_property_add_uint32_ptr(obj, "msel", &s->msel,
+ OBJ_PROP_FLAG_READWRITE);
object_property_set_description(obj, "msel",
"Mode Select (MSEL[3:0]) pin state");
s->serial = OTP_SERIAL;
- object_property_add(obj, "serial", "uint32",
- sifive_u_machine_get_uint32_prop,
- sifive_u_machine_set_uint32_prop, NULL, &s->serial);
+ object_property_add_uint32_ptr(obj, "serial", &s->serial,
+ OBJ_PROP_FLAG_READWRITE);
object_property_set_description(obj, "serial", "Board serial number");
}
qdev_prop_set_string(DEVICE(&s->u_cpus), "cpu-type", s->cpu_type);
qdev_prop_set_uint64(DEVICE(&s->u_cpus), "resetvec", 0x1004);
- sysbus_realize(SYS_BUS_DEVICE(&s->e_cpus), &error_abort);
- sysbus_realize(SYS_BUS_DEVICE(&s->u_cpus), &error_abort);
+ sysbus_realize(SYS_BUS_DEVICE(&s->e_cpus), &error_fatal);
+ sysbus_realize(SYS_BUS_DEVICE(&s->u_cpus), &error_fatal);
/*
* The cluster must be realized after the RISC-V hart array container,
* as the container's CPU object is only created on realize, and the