On Mon, Mar 29, 2021 at 1:16 PM Bin Meng <bmeng...@gmail.com> wrote: > > From: Bin Meng <bin.m...@windriver.com> > > At present the Microchip Icicle Kit machine only supports using > '-bios' to load the HSS, and does not support '-kernel' for direct > kernel booting just like other RISC-V machines do. One has to use > U-Boot which is chain-loaded by HSS, to load a kernel for testing. > This is not so convenient. > > Adding '-kernel' support together with the existing '-bios', we > follow the following table to select which payload we execute: > > -bios | -kernel | payload > ------+------------+-------- > N | N | HSS > Y | don't care | HSS > N | Y | kernel > > This ensures backwards compatibility with how we used to expose > '-bios' to users. When '-kernel' is used for direct boot, '-dtb' > must be present to provide a valid device tree for the board, > as we don't generate device tree. > > When direct kernel boot is used, the OpenSBI fw_dynamic BIOS image > is used to boot a payload like U-Boot or OS kernel directly. > > Documentation is updated to describe the direct kernel boot. Note > as of today there is still no PolarFire SoC support in the upstream > Linux kernel hence the document does not include instructions for > that. It will be updated in the future. > > Signed-off-by: Bin Meng <bin.m...@windriver.com>
Reviewed-by: Alistair Francis <alistair.fran...@wdc.com> Alistair > --- > > docs/system/riscv/microchip-icicle-kit.rst | 30 ++++++-- > hw/riscv/microchip_pfsoc.c | 81 +++++++++++++++++++++- > 2 files changed, 103 insertions(+), 8 deletions(-) > > diff --git a/docs/system/riscv/microchip-icicle-kit.rst > b/docs/system/riscv/microchip-icicle-kit.rst > index e803131763..54ced661e3 100644 > --- a/docs/system/riscv/microchip-icicle-kit.rst > +++ b/docs/system/riscv/microchip-icicle-kit.rst > @@ -31,17 +31,37 @@ Boot options > > The ``microchip-icicle-kit`` machine can start using the standard -bios > functionality for loading its BIOS image, aka Hart Software Services (HSS_). > -HSS loads the second stage bootloader U-Boot from an SD card. It does not > -support direct kernel loading via the -kernel option. One has to load kernel > -from U-Boot. > +HSS loads the second stage bootloader U-Boot from an SD card. Then a kernel > +can be loaded from U-Boot. It also supports direct kernel booting via the > +-kernel option along with the device tree blob via -dtb. When direct kernel > +boot is used, the OpenSBI fw_dynamic BIOS image is used to boot a payload > +like U-Boot or OS kernel directly. > + > +The user provided DTB should have the following requirements: > + > +* The /cpus node should contain at least one subnode for E51 and the number > + of subnodes should match QEMU's ``-smp`` option > +* The /memory reg size should match QEMU’s selected ram_size via ``-m`` > +* Should contain a node for the CLINT device with a compatible string > + "riscv,clint0" > + > +QEMU follows below truth table to select which payload to execute: > + > +===== ========== ======= > +-bios -kernel payload > +===== ========== ======= > + N N HSS > + Y don't care HSS > + N Y kernel > +===== ========== ======= > > The memory is set to 1537 MiB by default which is the minimum required high > memory size by HSS. A sanity check on ram size is performed in the machine > init routine to prompt user to increase the RAM size to > 1537 MiB when less > than 1537 MiB ram is detected. > > -Boot the machine > ----------------- > +Running HSS > +----------- > > HSS 2020.12 release is tested at the time of writing. To build an HSS image > that can be booted by the ``microchip-icicle-kit`` machine, type the > following > diff --git a/hw/riscv/microchip_pfsoc.c b/hw/riscv/microchip_pfsoc.c > index c4146b7a6b..1919c09f2f 100644 > --- a/hw/riscv/microchip_pfsoc.c > +++ b/hw/riscv/microchip_pfsoc.c > @@ -53,6 +53,7 @@ > #include "hw/riscv/microchip_pfsoc.h" > #include "hw/intc/sifive_clint.h" > #include "hw/intc/sifive_plic.h" > +#include "sysemu/device_tree.h" > #include "sysemu/sysemu.h" > > /* > @@ -462,6 +463,12 @@ static void > microchip_icicle_kit_machine_init(MachineState *machine) > MemoryRegion *mem_high = g_new(MemoryRegion, 1); > MemoryRegion *mem_high_alias = g_new(MemoryRegion, 1); > uint64_t mem_high_size; > + hwaddr firmware_load_addr; > + const char *firmware_name; > + bool kernel_as_payload = false; > + target_ulong firmware_end_addr, kernel_start_addr; > + uint64_t kernel_entry; > + uint32_t fdt_load_addr; > DriveInfo *dinfo = drive_get_next(IF_SD); > > /* Sanity check on RAM size */ > @@ -506,9 +513,6 @@ static void > microchip_icicle_kit_machine_init(MachineState *machine) > memmap[MICROCHIP_PFSOC_DRAM_HI_ALIAS].base, > mem_high_alias); > > - /* Load the firmware */ > - riscv_find_and_load_firmware(machine, BIOS_FILENAME, RESET_VECTOR, NULL); > - > /* Attach an SD card */ > if (dinfo) { > CadenceSDHCIState *sdhci = &(s->soc.sdhci); > @@ -518,6 +522,77 @@ static void > microchip_icicle_kit_machine_init(MachineState *machine) > &error_fatal); > qdev_realize_and_unref(card, sdhci->bus, &error_fatal); > } > + > + /* > + * We follow the following table to select which payload we execute. > + * > + * -bios | -kernel | payload > + * -------+------------+-------- > + * N | N | HSS > + * Y | don't care | HSS > + * N | Y | kernel > + * > + * This ensures backwards compatibility with how we used to expose -bios > + * to users but allows them to run through direct kernel booting as well. > + * > + * When -kernel is used for direct boot, -dtb must be present to provide > + * a valid device tree for the board, as we don't generate device tree. > + */ > + > + if (machine->kernel_filename && machine->dtb) { > + int fdt_size; > + machine->fdt = load_device_tree(machine->dtb, &fdt_size); > + if (!machine->fdt) { > + error_report("load_device_tree() failed"); > + exit(1); > + } > + > + firmware_name = RISCV64_BIOS_BIN; > + firmware_load_addr = memmap[MICROCHIP_PFSOC_DRAM_LO].base; > + kernel_as_payload = true; > + } > + > + if (!kernel_as_payload) { > + firmware_name = BIOS_FILENAME; > + firmware_load_addr = RESET_VECTOR; > + } > + > + /* Load the firmware */ > + firmware_end_addr = riscv_find_and_load_firmware(machine, firmware_name, > + firmware_load_addr, > NULL); > + > + if (kernel_as_payload) { > + 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(machine->fdt, "/chosen", > + "linux,initrd-start", start); > + qemu_fdt_setprop_cell(machine->fdt, "/chosen", > + "linux,initrd-end", end); > + } > + > + if (machine->kernel_cmdline) { > + qemu_fdt_setprop_string(machine->fdt, "/chosen", > + "bootargs", machine->kernel_cmdline); > + } > + > + /* Compute the fdt load address in dram */ > + fdt_load_addr = riscv_load_fdt(memmap[MICROCHIP_PFSOC_DRAM_LO].base, > + machine->ram_size, machine->fdt); > + /* Load the reset vector */ > + riscv_setup_rom_reset_vec(machine, &s->soc.u_cpus, > firmware_load_addr, > + memmap[MICROCHIP_PFSOC_ENVM_DATA].base, > + memmap[MICROCHIP_PFSOC_ENVM_DATA].size, > + kernel_entry, fdt_load_addr, machine->fdt); > + } > } > > static void microchip_icicle_kit_machine_class_init(ObjectClass *oc, void > *data) > -- > 2.25.1 > >