summaryrefslogtreecommitdiff
path: root/src/arch
diff options
context:
space:
mode:
authorJonathan Neuschäfer <j.neuschaefer@gmx.net>2016-08-22 19:37:15 +0200
committerRonald G. Minnich <rminnich@gmail.com>2016-08-23 23:48:54 +0200
commitf643d661e1573b7da8a603c23a49b08552c60543 (patch)
treea440ca539a3f45100730494e97b224921d8307f9 /src/arch
parentcafb10c67257f4845280a7a1c995a0a1965e490d (diff)
arch/riscv: Add functions to read/write memory on behalf of supervisor/user mode
Normally machine-mode code operates completely within physical address space. When emulating less privileged memory accesses (e.g. when the hardware doesn't support unaligned read/write), it is useful to access memory through the MMU (and with virtual addresses); this patch implements this functionality using the MPRV bit. Change-Id: Ic3b3301f348769faf3ee3ef2a78935dfbcbd15fd Signed-off-by: Jonathan Neuschäfer <j.neuschaefer@gmx.net> Reviewed-on: https://review.coreboot.org/16260 Tested-by: build bot (Jenkins) Reviewed-by: Ronald G. Minnich <rminnich@gmail.com>
Diffstat (limited to 'src/arch')
-rw-r--r--src/arch/riscv/include/vm.h47
1 files changed, 47 insertions, 0 deletions
diff --git a/src/arch/riscv/include/vm.h b/src/arch/riscv/include/vm.h
index cc26b13d21..bee2ed4215 100644
--- a/src/arch/riscv/include/vm.h
+++ b/src/arch/riscv/include/vm.h
@@ -30,6 +30,7 @@
#include <string.h>
#include <stdint.h>
+#include <arch/encoding.h>
#define SUPERPAGE_SIZE ((uintptr_t)(RISCV_PGSIZE << RISCV_PGLEVEL_BITS))
#define VM_CHOICE VM_SV39
@@ -70,4 +71,50 @@ void mstatus_init(void); // need to setup mstatus so we know we have virtual mem
void flush_tlb(void);
+
+#define DEFINE_MPRV_READ(name, type, insn) \
+ static inline type name(type *p); \
+ static inline type name(type *p) \
+ { \
+ int mprv = MSTATUS_MPRV; \
+ type value; \
+ asm ( \
+ "csrs mstatus, %1\n" \
+ STRINGIFY(insn) " %0, 0(%2)\n" \
+ "csrc mstatus, %1\n" \
+ : "=r"(value) : "r"(mprv), "r"(p) : "memory" \
+ ); \
+ return value; \
+ }
+
+#define DEFINE_MPRV_WRITE(name, type, insn) \
+ static inline void name(type *p, type value); \
+ static inline void name(type *p, type value) \
+ { \
+ int mprv = MSTATUS_MPRV; \
+ asm ( \
+ "csrs mstatus, %0\n" \
+ STRINGIFY(insn) " %1, 0(%2)\n" \
+ "csrc mstatus, %0\n" \
+ :: "r"(mprv), "r"(value), "r"(p) : "memory" \
+ ); \
+ }
+
+DEFINE_MPRV_READ(mprv_read_u8, uint8_t, lbu)
+DEFINE_MPRV_READ(mprv_read_u16, uint16_t, lhu)
+DEFINE_MPRV_READ(mprv_read_u32, uint32_t, lwu)
+DEFINE_MPRV_READ(mprv_read_u64, uint32_t, ld)
+DEFINE_MPRV_READ(mprv_read_long, long, ld)
+DEFINE_MPRV_READ(mprv_read_ulong, unsigned long, ld)
+DEFINE_MPRV_WRITE(mprv_write_u8, uint8_t, sb)
+DEFINE_MPRV_WRITE(mprv_write_u16, uint16_t, sh)
+DEFINE_MPRV_WRITE(mprv_write_u32, uint32_t, sw)
+DEFINE_MPRV_WRITE(mprv_write_u64, uint64_t, sd)
+DEFINE_MPRV_WRITE(mprv_write_long, long, sd)
+DEFINE_MPRV_WRITE(mprv_write_ulong, unsigned long, sd)
+
+#undef DEFINE_MPRV_READ
+#undef DEFINE_MPRV_WRITE
+
+
#endif