Skip to content

Commit 17aad9f

Browse files
lbmengalistair23
authored andcommitted
hw/riscv: sifive_u: Support different boot source per MSEL pin state
SiFive FU540 SoC supports booting from several sources, which are controlled using the Mode Select (MSEL[3:0]) pins on the chip. Typically, the boot process runs through several stages before it begins execution of user-provided programs. The SoC supports booting from memory-mapped QSPI flash, which is how start_in_flash property is used for at present. This matches MSEL = 1 configuration (QSPI0). Typical booting flows involve the Zeroth Stage Boot Loader (ZSBL). It's not necessary for QEMU to implement the full ZSBL ROM codes, because we know ZSBL downloads the next stage program into the L2 LIM at address 0x8000000 and executes from there. We can bypass the whole ZSBL execution and use "-bios" to load the next stage program directly if MSEL indicates a ZSBL booting flow. Signed-off-by: Bin Meng <[email protected]> Reviewed-by: Alistair Francis <[email protected]> Message-id: [email protected] Message-Id: <[email protected]> Signed-off-by: Alistair Francis <[email protected]>
1 parent 495134b commit 17aad9f

File tree

2 files changed

+37
-8
lines changed

2 files changed

+37
-8
lines changed

hw/riscv/sifive_u.c

Lines changed: 31 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -405,8 +405,34 @@ static void sifive_u_machine_init(MachineState *machine)
405405
/* create device tree */
406406
create_fdt(s, memmap, machine->ram_size, machine->kernel_cmdline);
407407

408-
riscv_find_and_load_firmware(machine, BIOS_FILENAME,
409-
memmap[SIFIVE_U_DRAM].base, NULL);
408+
if (s->start_in_flash) {
409+
/*
410+
* If start_in_flash property is given, assign s->msel to a value
411+
* that representing booting from QSPI0 memory-mapped flash.
412+
*
413+
* This also means that when both start_in_flash and msel properties
414+
* are given, start_in_flash takes the precedence over msel.
415+
*
416+
* Note this is to keep backward compatibility not to break existing
417+
* users that use start_in_flash property.
418+
*/
419+
s->msel = MSEL_MEMMAP_QSPI0_FLASH;
420+
}
421+
422+
switch (s->msel) {
423+
case MSEL_MEMMAP_QSPI0_FLASH:
424+
start_addr = memmap[SIFIVE_U_FLASH0].base;
425+
break;
426+
case MSEL_L2LIM_QSPI0_FLASH:
427+
case MSEL_L2LIM_QSPI2_SD:
428+
start_addr = memmap[SIFIVE_U_L2LIM].base;
429+
break;
430+
default:
431+
start_addr = memmap[SIFIVE_U_DRAM].base;
432+
break;
433+
}
434+
435+
riscv_find_and_load_firmware(machine, BIOS_FILENAME, start_addr, NULL);
410436

411437
if (machine->kernel_filename) {
412438
uint64_t kernel_entry = riscv_load_kernel(machine->kernel_filename,
@@ -424,13 +450,9 @@ static void sifive_u_machine_init(MachineState *machine)
424450
}
425451
}
426452

427-
if (s->start_in_flash) {
428-
start_addr = memmap[SIFIVE_U_FLASH0].base;
429-
}
430-
431453
/* reset vector */
432454
uint32_t reset_vec[8] = {
433-
0x00000000,
455+
s->msel, /* MSEL pin state */
434456
0x00000297, /* 1: auipc t0, %pcrel_hi(dtb) */
435457
0x01c28593, /* addi a1, t0, %pcrel_lo(1b) */
436458
0xf1402573, /* csrr a0, mhartid */
@@ -502,7 +524,8 @@ static void sifive_u_machine_instance_init(Object *obj)
502524
sifive_u_machine_set_start_in_flash);
503525
object_property_set_description(obj, "start-in-flash",
504526
"Set on to tell QEMU's ROM to jump to "
505-
"flash. Otherwise QEMU will jump to DRAM");
527+
"flash. Otherwise QEMU will jump to DRAM "
528+
"or L2LIM depending on the msel value");
506529

507530
s->msel = 0;
508531
object_property_add(obj, "msel", "uint32",

include/hw/riscv/sifive_u.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,12 @@ enum {
111111
SIFIVE_U_RTCCLK_FREQ = 1000000
112112
};
113113

114+
enum {
115+
MSEL_MEMMAP_QSPI0_FLASH = 1,
116+
MSEL_L2LIM_QSPI0_FLASH = 6,
117+
MSEL_L2LIM_QSPI2_SD = 11
118+
};
119+
114120
#define SIFIVE_U_MANAGEMENT_CPU_COUNT 1
115121
#define SIFIVE_U_COMPUTE_CPU_COUNT 4
116122

0 commit comments

Comments
 (0)