diff options
author | Jonathan Neuschäfer <j.neuschaefer@gmx.net> | 2016-08-22 19:37:15 +0200 |
---|---|---|
committer | Ronald G. Minnich <rminnich@gmail.com> | 2016-08-23 23:48:54 +0200 |
commit | f643d661e1573b7da8a603c23a49b08552c60543 (patch) | |
tree | a440ca539a3f45100730494e97b224921d8307f9 /src/arch/riscv | |
parent | cafb10c67257f4845280a7a1c995a0a1965e490d (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/riscv')
-rw-r--r-- | src/arch/riscv/include/vm.h | 47 |
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 |