From f643d661e1573b7da8a603c23a49b08552c60543 Mon Sep 17 00:00:00 2001 From: Jonathan Neuschäfer Date: Mon, 22 Aug 2016 19:37:15 +0200 Subject: arch/riscv: Add functions to read/write memory on behalf of supervisor/user mode MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 Reviewed-on: https://review.coreboot.org/16260 Tested-by: build bot (Jenkins) Reviewed-by: Ronald G. Minnich --- src/arch/riscv/include/vm.h | 47 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) (limited to 'src') 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 #include +#include #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 -- cgit v1.2.3