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>
This commit is contained in:
parent
cafb10c672
commit
f643d661e1
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue