[coreboot-gerrit] New patch to review for coreboot: arch/riscv: Add functions to read/write memory on behalf of supervisor/user mode

Jonathan Neuschäfer (j.neuschaefer@gmx.net) gerrit at coreboot.org
Fri Aug 19 12:46:14 CEST 2016


Jonathan Neuschäfer (j.neuschaefer at gmx.net) just uploaded a new patch set to gerrit, which you can find at https://review.coreboot.org/16260

-gerrit

commit f01cdd6a71314df27e9634abddec09da3f0820da
Author: Jonathan Neuschäfer <j.neuschaefer at gmx.net>
Date:   Fri Aug 19 12:10:20 2016 +0200

    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 at gmx.net>
---
 src/arch/riscv/include/vm.h | 47 +++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 47 insertions(+)

diff --git a/src/arch/riscv/include/vm.h b/src/arch/riscv/include/vm.h
index cd82b0a..a32efc5 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



More information about the coreboot-gerrit mailing list