qemu-riscv
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH 8/8] hw/riscv: microchip_pfsoc: Support direct kernel boot


From: Alistair Francis
Subject: Re: [PATCH 8/8] hw/riscv: microchip_pfsoc: Support direct kernel boot
Date: Wed, 31 Mar 2021 11:50:23 -0400

On Mon, Mar 29, 2021 at 1:16 PM Bin Meng <bmeng.cn@gmail.com> wrote:
>
> From: Bin Meng <bin.meng@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.meng@windriver.com>

Reviewed-by: Alistair Francis <alistair.francis@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
>
>



reply via email to

[Prev in Thread] Current Thread [Next in Thread]