diff options
author | Michael Clark <michaeljclark@mac.com> | 2018-05-21 13:29:31 +1200 |
---|---|---|
committer | Michael Clark <michaeljclark@mac.com> | 2018-05-22 21:41:18 +1200 |
commit | 474ee5a81880dcf60789e7c2a3054b3afb34c3ca (patch) | |
tree | 343a134219be59ee0347343a5ea415707d711ab3 /bbl | |
parent | 9ffedde3d747a9b6f559041cc69478df6d647135 (diff) | |
download | pk-474ee5a81880dcf60789e7c2a3054b3afb34c3ca.zip pk-474ee5a81880dcf60789e7c2a3054b3afb34c3ca.tar.gz pk-474ee5a81880dcf60789e7c2a3054b3afb34c3ca.tar.bz2 |
RISC-V: Support separate firmware and kernel payload
Support for separate firmware and kernel payload is added
by updating BBL to read optional preloaded kernel address
attributes from device-tree using a similar mechanism to
that used to pass init ramdisk addresses to linux kernel.
chosen {
riscv,kernel-start = <0x00000000 0x80200000>;
riscv,kernel-end = <0x00000000 0x80590634>;
};
These attributes are added by QEMU and read by BBL when combining
-bios <firmware-image> and -kernel <kernel-image> options. e.g.
$ qemu-system-riscv64 -machine virt -bios bbl -kernel vmlinux
With this change, bbl can be compiled without --with-payload
and the dummy payload alignment is altered to make the memory
footprint of the firmware-only bbl smaller. The dummy payload
message is updated to indicate the alternative load method.
This load method could also be supported by a first stage boot
loader that reads seperate firmware and kernel from SPI flash.
The main advantage of this new mechanism is that it eases kernel
development by avoiding the riscv-pk packaging step after kernel
builds, makes building per repository artefacts for CI simpler,
and mimics bootloaders on other platforms that can load a kernel
image file directly. Ultimately BBL should use an SPI driver to
load the kernel image however this mechanism supports use cases
such such as QEMU's -bios, -kernel and -initrd options following
examples from other platforms that pass kernel entry to firmware
via device-tree.
Cc: Palmer Dabbelt <palmer@sifive.com>
Cc: Alistair Francis <Alistair.Francis@wdc.com>
Signed-off-by: Michael Clark <mjc@sifive.com>
Diffstat (limited to 'bbl')
-rw-r--r-- | bbl/bbl.ac | 9 | ||||
-rw-r--r-- | bbl/bbl.c | 16 | ||||
-rw-r--r-- | bbl/payload.S | 8 |
3 files changed, 27 insertions, 6 deletions
@@ -4,8 +4,13 @@ AS_IF([test "x$enable_logo" == "xyes"], [ ]) AC_ARG_WITH([payload], AS_HELP_STRING([--with-payload], [Set ELF payload for bbl]), - [AC_SUBST([BBL_PAYLOAD], $with_payload, [Kernel payload for bbl])], - [AC_SUBST([BBL_PAYLOAD], [dummy_payload], [Kernel payload for bbl])]) + [ + AC_SUBST([BBL_PAYLOAD], $with_payload, [Kernel payload for bbl]) + AC_DEFINE(RELAXED_ALIGNMENT,[0],[Use relaxed payload alignment]) + ], [ + AC_SUBST([BBL_PAYLOAD], [dummy_payload], [Kernel payload for bbl]) + AC_DEFINE(RELAXED_ALIGNMENT,[1],[Use relaxed payload alignment]) + ]) AC_ARG_WITH([logo], AS_HELP_STRING([--with-logo], [Specify a better logo]), [AC_SUBST([BBL_LOGO_FILE], $with_logo, [Logo for bbl])], @@ -7,13 +7,21 @@ #include "fdt.h" #include <string.h> +extern char _payload_start, _payload_end; /* internal payload */ static const void* entry_point; long disabled_hart_mask; static uintptr_t dtb_output() { - extern char _payload_end; - uintptr_t end = (uintptr_t) &_payload_end; + /* + * Place DTB after the payload, either the internal payload or a + * preloaded external payload specified in device-tree, if present. + * + * Note: linux kernel calls __va(dtb) to get the device-tree virtual + * address. The kernel's virtual mapping begins at its load address, + * thus mandating device-tree is in physical memory after the kernel. + */ + uintptr_t end = kernel_end ? (uintptr_t)kernel_end : (uintptr_t)&_payload_end; return (end + MEGAPAGE_SIZE - 1) / MEGAPAGE_SIZE * MEGAPAGE_SIZE; } @@ -53,7 +61,6 @@ void boot_other_hart(uintptr_t unused __attribute__((unused))) void boot_loader(uintptr_t dtb) { - extern char _payload_start; filter_dtb(dtb); #ifdef PK_ENABLE_LOGO print_logo(); @@ -62,6 +69,7 @@ void boot_loader(uintptr_t dtb) fdt_print(dtb_output()); #endif mb(); - entry_point = &_payload_start; + /* Use optional FDT preloaded external payload if present */ + entry_point = kernel_start ? kernel_start : &_payload_start; boot_other_hart(0); } diff --git a/bbl/payload.S b/bbl/payload.S index 6a175aa..b6797aa 100644 --- a/bbl/payload.S +++ b/bbl/payload.S @@ -1,7 +1,15 @@ +#include "config.h" #include "encoding.h" .section ".payload","a",@progbits + +#if RELAXED_ALIGNMENT + /* align payload minimally */ + .align 3 +#else + /* align payload to megapage */ .align RISCV_PGSHIFT + RISCV_PGLEVEL_BITS +#endif .globl _payload_start, _payload_end _payload_start: |