All of lore.kernel.org
 help / color / mirror / Atom feed
From: Bin Meng <bmeng.cn@gmail.com>
To: Alistair Francis <Alistair.Francis@wdc.com>,
	qemu-devel@nongnu.org, qemu-riscv@nongnu.org
Cc: Bin Meng <bin.meng@windriver.com>
Subject: [PATCH 8/8] hw/riscv: microchip_pfsoc: Support direct kernel boot
Date: Tue, 30 Mar 2021 01:08:18 +0800	[thread overview]
Message-ID: <20210329170818.23139-8-bmeng.cn@gmail.com> (raw)
In-Reply-To: <20210329170818.23139-1-bmeng.cn@gmail.com>

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>
---

 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



  parent reply	other threads:[~2021-03-29 17:18 UTC|newest]

Thread overview: 25+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-03-29 17:08 [PATCH 1/8] hw/riscv: sifive_u: Switch to use qemu_fdt_setprop_string_array() helper Bin Meng
2021-03-29 17:08 ` [PATCH 2/8] hw/riscv: virt: " Bin Meng
2021-03-31 15:41   ` Alistair Francis
2021-03-31 15:41     ` Alistair Francis
2021-03-29 17:08 ` [PATCH 3/8] hw/riscv: Support the official CLINT DT bindings Bin Meng
2021-03-31 15:42   ` Alistair Francis
2021-03-31 15:42     ` Alistair Francis
2021-03-29 17:08 ` [PATCH 4/8] hw/riscv: Support the official PLIC " Bin Meng
2021-03-31 15:43   ` Alistair Francis
2021-03-31 15:43     ` Alistair Francis
2021-03-29 17:08 ` [PATCH 5/8] docs/system/riscv: Correct the indentation level of supported devices Bin Meng
2021-03-31 15:44   ` Alistair Francis
2021-03-31 15:44     ` Alistair Francis
2021-03-29 17:08 ` [PATCH 6/8] docs/system/riscv: sifive_u: Document '-dtb' usage Bin Meng
2021-03-31 15:46   ` Alistair Francis
2021-03-31 15:46     ` Alistair Francis
2021-03-29 17:08 ` [PATCH 7/8] hw/riscv: Use macros for BIOS image names Bin Meng
2021-03-31 15:44   ` Alistair Francis
2021-03-31 15:44     ` Alistair Francis
2021-03-29 17:08 ` Bin Meng [this message]
2021-03-31 15:50   ` [PATCH 8/8] hw/riscv: microchip_pfsoc: Support direct kernel boot Alistair Francis
2021-03-31 15:50     ` Alistair Francis
2021-03-31 15:40 ` [PATCH 1/8] hw/riscv: sifive_u: Switch to use qemu_fdt_setprop_string_array() helper Alistair Francis
2021-03-31 15:40   ` Alistair Francis
2021-03-31 16:07 ` Richard Henderson

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20210329170818.23139-8-bmeng.cn@gmail.com \
    --to=bmeng.cn@gmail.com \
    --cc=Alistair.Francis@wdc.com \
    --cc=bin.meng@windriver.com \
    --cc=qemu-devel@nongnu.org \
    --cc=qemu-riscv@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.