aboutsummaryrefslogtreecommitdiff
path: root/src/arch/riscv/payload.c
diff options
context:
space:
mode:
authorXiang Wang <wxjstz@126.com>2019-03-28 12:19:30 +0800
committerMartin Roth <martinroth@google.com>2019-08-03 17:17:24 +0000
commita6f9eab44ab0590ca7da33da0b042a8fce8da0f1 (patch)
treeda04d80fb1c25357e757e3baa2e4480fdc026dd2 /src/arch/riscv/payload.c
parentc989e0bd56ae19770af91e30cbbf9dc5c9717da8 (diff)
riscv: add support for OpenSBI
Call OpenSBI in M-Mode and use it to set up SBI and to lockdown the platform. It will also jump to the specified payload when done. This behaviour is similar to BL31 on aarch31. The payload is 41KiB in size on qemu. Tested on qemu-riscv: Required to boot a kernel as OpenSBI's instruction emulation feature is required on that virtual machine. Tested on SiFive/unleashed: The earlycon is working. No console after regular serial driver should take over, which might be related to kernel config. Change-Id: I2a178595bd2aa2e1f114cbc69e8eadd46955b54d Signed-off-by: Xiang Wang <merle@hardenedlinux.org> Signed-off-by: Patrick Rudolph <patrick.rudolph@9elements.com> Reviewed-on: https://review.coreboot.org/c/coreboot/+/32394 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Philipp Deppenwiese <zaolin.daisuki@gmail.com>
Diffstat (limited to 'src/arch/riscv/payload.c')
-rw-r--r--src/arch/riscv/payload.c26
1 files changed, 26 insertions, 0 deletions
diff --git a/src/arch/riscv/payload.c b/src/arch/riscv/payload.c
index 903e8a6ab6..297d30d2a5 100644
--- a/src/arch/riscv/payload.c
+++ b/src/arch/riscv/payload.c
@@ -15,18 +15,44 @@
* GNU General Public License for more details.
*/
+#include <program_loading.h>
#include <stdint.h>
#include <arch/boot.h>
#include <arch/encoding.h>
+#include <arch/smp/atomic.h>
#include <console/console.h>
#include <vm.h>
+/* Run OpenSBI and let OpenSBI hand over control to the payload */
+void run_payload_opensbi(struct prog *prog, void *fdt, struct prog *opensbi, int payload_mode)
+{
+ int hart_id = read_csr(mhartid);
+ uintptr_t status = read_csr(mstatus);
+ status = INSERT_FIELD(status, MSTATUS_MPIE, 0);
+
+ /*
+ * In case of OpenSBI we always run it in M-Mode.
+ * OpenSBI will switch to payload_mode when done.
+ */
+
+ status = INSERT_FIELD(status, MSTATUS_MPP, PRV_M);
+ /* Trap vector base address point to the payload */
+ write_csr(mtvec, prog_entry(opensbi));
+ /* disable M-Mode interrupt */
+ write_csr(mie, 0);
+ write_csr(mstatus, status);
+
+ run_opensbi(hart_id, fdt, prog_entry(opensbi), prog_entry(prog), payload_mode);
+}
+
+/* Runs the payload without OpenSBI integration */
void run_payload(struct prog *prog, void *fdt, int payload_mode)
{
void (*doit)(int hart_id, void *fdt) = prog_entry(prog);
int hart_id = read_csr(mhartid);
uintptr_t status = read_csr(mstatus);
status = INSERT_FIELD(status, MSTATUS_MPIE, 0);
+
switch (payload_mode) {
case RISCV_PAYLOAD_MODE_U:
status = INSERT_FIELD(status, MSTATUS_MPP, PRV_U);