diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/arch/riscv/boot.c | 23 | ||||
-rw-r--r-- | src/arch/riscv/bootblock.S | 9 | ||||
-rw-r--r-- | src/arch/riscv/include/arch/boot.h | 21 | ||||
-rw-r--r-- | src/arch/riscv/payload.S | 30 | ||||
-rw-r--r-- | src/arch/riscv/stages.c | 11 |
5 files changed, 78 insertions, 16 deletions
diff --git a/src/arch/riscv/boot.c b/src/arch/riscv/boot.c index b73f3cade4..d7233fe3da 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 43bca907bb..0b5a2b2961 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 0000000000..24c1bedebf --- /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 a189adf1db..1b8cb96110 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 053fd7634c..80754762bd 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(); } |