aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHesham Almatary <Hesham.Almatary@cl.cam.ac.uk>2018-05-14 17:11:33 +0100
committerHesham Almatary <Hesham.Almatary@cl.cam.ac.uk>2018-07-12 10:58:55 +0100
commit72672f9a393e10e5444f733cba287a9744cd4033 (patch)
tree34ebae81163c3b0039959b763076e3abada606d7
parent2d85b4c38e216f8e9ceea595b87a999f2bf5d9df (diff)
downloadriscv-pk-72672f9a393e10e5444f733cba287a9744cd4033.zip
riscv-pk-72672f9a393e10e5444f733cba287a9744cd4033.tar.gz
riscv-pk-72672f9a393e10e5444f733cba287a9744cd4033.tar.bz2
bbl: boot payload in machine mode when --enable-boot-machine is passed
-rw-r--r--bbl/bbl.c4
-rw-r--r--machine/mentry.S5
-rw-r--r--machine/minit.c26
-rw-r--r--machine/mtrap.h2
4 files changed, 37 insertions, 0 deletions
diff --git a/bbl/bbl.c b/bbl/bbl.c
index 6363d0a..08e44af 100644
--- a/bbl/bbl.c
+++ b/bbl/bbl.c
@@ -58,7 +58,11 @@ void boot_other_hart(uintptr_t unused __attribute__((unused)))
}
}
+#ifdef BBL_BOOT_MACHINE
+ enter_machine_mode(entry, hartid, dtb_output());
+#else /* Run bbl in supervisor mode */
enter_supervisor_mode(entry, hartid, dtb_output());
+#endif
}
void boot_loader(uintptr_t dtb)
diff --git a/machine/mentry.S b/machine/mentry.S
index ede40bb..99e1b72 100644
--- a/machine/mentry.S
+++ b/machine/mentry.S
@@ -2,6 +2,7 @@
#include "mtrap.h"
#include "bits.h"
+#include "config.h"
.data
.align 6
@@ -18,7 +19,11 @@ trap_table:
.word bad_trap
.word mcall_trap
.word bad_trap
+#ifdef BBL_BOOT_MACHINE
+ .word mcall_trap
+#else
.word bad_trap
+#endif /* BBL_BOOT_MACHINE */
.word bad_trap
#define TRAP_FROM_MACHINE_MODE_VECTOR 13
.word __trap_from_machine_mode
diff --git a/machine/minit.c b/machine/minit.c
index a411978..de75192 100644
--- a/machine/minit.c
+++ b/machine/minit.c
@@ -95,7 +95,9 @@ static void hart_init()
{
mstatus_init();
fp_init();
+#ifndef BBL_BOOT_MACHINE
delegate_traps();
+#endif /* BBL_BOOT_MACHINE */
}
static void plic_init()
@@ -213,3 +215,27 @@ void enter_supervisor_mode(void (*fn)(uintptr_t), uintptr_t arg0, uintptr_t arg1
asm volatile ("mret" : : "r" (a0), "r" (a1));
__builtin_unreachable();
}
+
+void enter_machine_mode(void (*fn)(uintptr_t, uintptr_t), uintptr_t arg0, uintptr_t arg1)
+{
+ // Set up a PMP to permit access to all of memory.
+ // Ignore the illegal-instruction trap if PMPs aren't supported.
+ uintptr_t pmpc = PMP_NAPOT | PMP_R | PMP_W | PMP_X;
+ asm volatile ("la t0, 1f\n\t"
+ "csrrw t0, mtvec, t0\n\t"
+ "csrw pmpaddr0, %1\n\t"
+ "csrw pmpcfg0, %0\n\t"
+ ".align 2\n\t"
+ "1: csrw mtvec, t0"
+ : : "r" (pmpc), "r" (-1UL) : "t0");
+
+ uintptr_t mstatus = read_csr(mstatus);
+ mstatus = INSERT_FIELD(mstatus, MSTATUS_MPIE, 0);
+ write_csr(mstatus, mstatus);
+ write_csr(mscratch, MACHINE_STACK_TOP() - MENTRY_FRAME_SIZE);
+
+ /* Jump to the payload's entry point */
+ fn(arg0, arg1);
+
+ __builtin_unreachable();
+}
diff --git a/machine/mtrap.h b/machine/mtrap.h
index 4b9e569..a5bcea2 100644
--- a/machine/mtrap.h
+++ b/machine/mtrap.h
@@ -67,6 +67,8 @@ void putstring(const char* s);
void enter_supervisor_mode(void (*fn)(uintptr_t), uintptr_t arg0, uintptr_t arg1)
__attribute__((noreturn));
+void enter_machine_mode(void (*fn)(uintptr_t, uintptr_t), uintptr_t arg0, uintptr_t arg1)
+ __attribute__((noreturn));
void boot_loader(uintptr_t dtb);
void boot_other_hart(uintptr_t dtb);