aboutsummaryrefslogtreecommitdiff
path: root/bbl
diff options
context:
space:
mode:
authorMichael Clark <michaeljclark@mac.com>2018-05-21 13:29:31 +1200
committerMichael Clark <michaeljclark@mac.com>2018-05-22 21:41:18 +1200
commit474ee5a81880dcf60789e7c2a3054b3afb34c3ca (patch)
tree343a134219be59ee0347343a5ea415707d711ab3 /bbl
parent9ffedde3d747a9b6f559041cc69478df6d647135 (diff)
downloadpk-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.ac9
-rw-r--r--bbl/bbl.c16
-rw-r--r--bbl/payload.S8
3 files changed, 27 insertions, 6 deletions
diff --git a/bbl/bbl.ac b/bbl/bbl.ac
index 80d3b06..55ff50b 100644
--- a/bbl/bbl.ac
+++ b/bbl/bbl.ac
@@ -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])],
diff --git a/bbl/bbl.c b/bbl/bbl.c
index 1b96a9d..93746ff 100644
--- a/bbl/bbl.c
+++ b/bbl/bbl.c
@@ -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: