Jonathan Neuschäfer has uploaded this change for review. ( https://review.coreboot.org/23797
Change subject: arch/riscv: Pass the bootrom-provided FDT to the payload ......................................................................
arch/riscv: Pass the bootrom-provided FDT to the payload
The RISC-V boot protocol foresees that at every stage boundary (bootrom to boot loader, boot loader -> OS), register a0 contains the Hart ID and a1 contains the physical address of the Flattened Device Tree that the stage shall use.
As a first step, pass the bootrom-provided FDT to the payload, unmodified.
Change-Id: I468bc64a47153d564087235f1c7e2d10e3d7a658 Signed-off-by: Jonathan Neuschäfer j.neuschaefer@gmx.net --- M src/arch/riscv/boot.c M src/arch/riscv/bootblock.S A src/arch/riscv/include/arch/boot.h M src/arch/riscv/payload.S M src/arch/riscv/stages.c 5 files changed, 78 insertions(+), 16 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/97/23797/1
diff --git a/src/arch/riscv/boot.c b/src/arch/riscv/boot.c index b73f3ca..d7233fe 100644 --- a/src/arch/riscv/boot.c +++ b/src/arch/riscv/boot.c @@ -15,20 +15,35 @@
#include <program_loading.h> #include <vm.h> +#include <arch/boot.h> #include <arch/encoding.h> #include <rules.h> #include <console/console.h>
+/* + * A pointer to the Flattened Device Tree passed to coreboot by the boot ROM. + * Presumably this FDT is also in ROM. + * + * This pointer is only used in ramstage! + */ +const void *rom_fdt; + void arch_prog_run(struct prog *prog) { void (*doit)(void *) = prog_entry(prog); - void riscvpayload(const char *configstring, void *payload); - const char *config = NULL; + void riscvpayload(const void *fdt, void *payload);
if (ENV_RAMSTAGE && prog_type(prog) == PROG_PAYLOAD) { - printk(BIOS_SPEW, "Config string: '%s'\n", config); + /* + * FIXME: This is wrong and will crash. Linux can't (in early + * boot) access memory that's before its own loading address. + * We need to copy the FDT to a place where Linux can access it. + */ + const void *fdt = rom_fdt; + + printk(BIOS_SPEW, "FDT is at %p\n", fdt); printk(BIOS_SPEW, "OK, let's go\n"); - riscvpayload(config, doit); + riscvpayload(fdt, doit); }
doit(prog_entry_arg(prog)); diff --git a/src/arch/riscv/bootblock.S b/src/arch/riscv/bootblock.S index 43bca90..0b5a2b2 100644 --- a/src/arch/riscv/bootblock.S +++ b/src/arch/riscv/bootblock.S @@ -25,7 +25,14 @@ .globl _start _start:
- + # The boot ROM may pass the following arguments to coreboot: + # a0: the value of mhartid + # a1: a pointer to the flattened devicetree + # + # Preserve only the FDT pointer. We can query mhartid ourselves at any + # time. + # + csrw mscratch, a1
# N.B. This only works on low 4G of the address space # and the stack must be page-aligned. diff --git a/src/arch/riscv/include/arch/boot.h b/src/arch/riscv/include/arch/boot.h new file mode 100644 index 0000000..24c1bed --- /dev/null +++ b/src/arch/riscv/include/arch/boot.h @@ -0,0 +1,21 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2018 Jonathan Neuschäfer + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef ARCH_RISCV_INCLUDE_ARCH_BOOT_H +#define ARCH_RISCV_INCLUDE_ARCH_BOOT_H + +extern const void *rom_fdt; + +#endif diff --git a/src/arch/riscv/payload.S b/src/arch/riscv/payload.S index a189adf..1b8cb96 100644 --- a/src/arch/riscv/payload.S +++ b/src/arch/riscv/payload.S @@ -1,6 +1,9 @@ /* * This file is part of the coreboot project. * + * Copyright (C) 2016 Google Inc + * Copyright (C) 2018 Jonathan Neuschäfer + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; version 2 of the License. @@ -11,17 +14,22 @@ * GNU General Public License for more details. */
-// "return" to a payload pointed to by a1 with -// an M-mode pointer (or, to upper levels, physical address) -// to the config string in a0. +// "return" to a payload. a0: FDT, a1: entry point .global riscvpayload riscvpayload: - mv t0,a1 - csrw mepc, t0 - csrr t0, mstatus - li t1, ~(3<<11) - and t0, t0, t1 - li t2, (1<<11) - or t0, t0, t2 - csrw mstatus, t0 + /* Load the entry point */ + mv t0, a1 + csrw mepc, t0 + csrr t0, mstatus + + /* Set mstatus.MPP (the previous privilege mode) to supervisor mode */ + li t1, ~(3<<11) + and t0, t0, t1 + li t2, (1<<11) + or t0, t0, t2 + csrw mstatus, t0 + + /* Pass the right arguments and jump! */ + mv a1, a0 + csrr a0, mhartid mret diff --git a/src/arch/riscv/stages.c b/src/arch/riscv/stages.c index 053fd76..8075476 100644 --- a/src/arch/riscv/stages.c +++ b/src/arch/riscv/stages.c @@ -24,9 +24,20 @@ * linker script. */
+#include <arch/boot.h> +#include <arch/encoding.h> #include <arch/stages.h> +#include <rules.h>
void stage_entry(void) { + /* + * Save the FDT pointer before entering ramstage, because mscratch + * might be overwritten in the trap handler, and there is code in + * ramstage that generates misaligned access faults. + */ + if (ENV_RAMSTAGE) + rom_fdt = (const void *)read_csr(mscratch); + main(); }