From 18e688c5427a1171eb6bf65669e40a2c50cc58c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonathan=20Neusch=C3=A4fer?= Date: Mon, 22 Aug 2016 19:37:15 +0200 Subject: [PATCH] UPSTREAM: 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. BUG=None BRANCH=None TEST=None Signed-off-by: Jonathan Neuschfer Reviewed-on: https://review.coreboot.org/16260 Tested-by: build bot (Jenkins) Reviewed-by: Ronald G. Minnich Change-Id: Ic3b3301f348769faf3ee3ef2a78935dfbcbd15fd Reviewed-on: https://chromium-review.googlesource.com/374466 Commit-Ready: Furquan Shaikh Tested-by: Furquan Shaikh Reviewed-by: Furquan Shaikh --- 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 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