RISC-V Proxy Kernel
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

78 lines
1.9 KiB

// See LICENSE for license details.
#include "bbl.h"
#include "mtrap.h"
#include "atomic.h"
#include "vm.h"
#include "bits.h"
#include "config.h"
#include "fdt.h"
#include <string.h>
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>
8 years ago
extern char _payload_start, _payload_end; /* internal payload */
static const void* entry_point;
long disabled_hart_mask;
static uintptr_t dtb_output()
{
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>
8 years ago
/*
* 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;
}
static void filter_dtb(uintptr_t source)
{
uintptr_t dest = dtb_output();
uint32_t size = fdt_size(source);
memcpy((void*)dest, (void*)source, size);
// Remove information from the chained FDT
filter_harts(dest, &disabled_hart_mask);
filter_plic(dest);
filter_compat(dest, "riscv,clint0");
filter_compat(dest, "riscv,debug-013");
}
void boot_other_hart(uintptr_t unused __attribute__((unused)))
{
const void* entry;
do {
entry = entry_point;
mb();
} while (!entry);
long hartid = read_csr(mhartid);
if ((1 << hartid) & disabled_hart_mask) {
while (1) {
__asm__ volatile("wfi");
#ifdef __riscv_div
__asm__ volatile("div x0, x0, x0");
#endif
}
}
enter_supervisor_mode(entry, hartid, dtb_output());
}
void boot_loader(uintptr_t dtb)
{
filter_dtb(dtb);
#ifdef PK_ENABLE_LOGO
print_logo();
#endif
#ifdef PK_PRINT_DEVICE_TREE
fdt_print(dtb_output());
#endif
mb();
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>
8 years ago
/* Use optional FDT preloaded external payload if present */
entry_point = kernel_start ? kernel_start : &_payload_start;
boot_other_hart(0);
}