diff options
Diffstat (limited to 'machine/unprivileged_memory.h')
-rw-r--r-- | machine/unprivileged_memory.h | 38 |
1 files changed, 31 insertions, 7 deletions
diff --git a/machine/unprivileged_memory.h b/machine/unprivileged_memory.h index 03f1e27..5cf2727 100644 --- a/machine/unprivileged_memory.h +++ b/machine/unprivileged_memory.h @@ -2,6 +2,7 @@ #define _RISCV_MISALIGNED_H #include "encoding.h" +#include "bits.h" #include <stdint.h> #define DECLARE_UNPRIVILEGED_LOAD_FUNCTION(type, insn) \ @@ -43,34 +44,57 @@ DECLARE_UNPRIVILEGED_STORE_FUNCTION(uint32_t, sw) DECLARE_UNPRIVILEGED_LOAD_FUNCTION(uint32_t, lwu) DECLARE_UNPRIVILEGED_LOAD_FUNCTION(uint64_t, ld) DECLARE_UNPRIVILEGED_STORE_FUNCTION(uint64_t, sd) +DECLARE_UNPRIVILEGED_LOAD_FUNCTION(uintptr_t, ld) #else DECLARE_UNPRIVILEGED_LOAD_FUNCTION(uint32_t, lw) +DECLARE_UNPRIVILEGED_LOAD_FUNCTION(uintptr_t, lw) + +static inline uint64_t load_uint64_t(const uint64_t* addr, uintptr_t mepc) +{ + return load_uint32_t((uint32_t*)addr, mepc) + + ((uint64_t)load_uint32_t((uint32_t*)addr + 1, mepc) << 32); +} + +static inline void store_uint64_t(uint64_t* addr, uint64_t val, uintptr_t mepc) +{ + store_uint32_t((uint32_t*)addr, val, mepc); + store_uint32_t((uint32_t*)addr + 1, val >> 32, mepc); +} #endif -static uint32_t __attribute__((always_inline)) get_insn(uintptr_t mepc, uintptr_t* mstatus) +static uintptr_t __attribute__((always_inline)) get_insn(uintptr_t mepc, uintptr_t* mstatus) { register uintptr_t __mepc asm ("a2") = mepc; register uintptr_t __mstatus asm ("a3"); - uint32_t val; + uintptr_t val; #ifndef __riscv_compressed asm ("csrrs %[mstatus], mstatus, %[mprv]\n" - "lw %[insn], (%[addr])\n" + STR(LWU) " %[insn], (%[addr])\n" "csrw mstatus, %[mstatus]" : [mstatus] "+&r" (__mstatus), [insn] "=&r" (val) : [mprv] "r" (MSTATUS_MPRV | MSTATUS_MXR), [addr] "r" (__mepc)); #else uintptr_t rvc_mask = 3, tmp; asm ("csrrs %[mstatus], mstatus, %[mprv]\n" + "and %[tmp], %[addr], 2\n" + "bnez %[tmp], 1f\n" + STR(LWU) " %[insn], (%[addr])\n" + "and %[tmp], %[insn], %[rvc_mask]\n" + "beq %[tmp], %[rvc_mask], 2f\n" + "sll %[insn], %[insn], %[xlen_minus_16]\n" + "srl %[insn], %[insn], %[xlen_minus_16]\n" + "j 2f\n" + "1:\n" "lhu %[insn], (%[addr])\n" "and %[tmp], %[insn], %[rvc_mask]\n" - "bne %[tmp], %[rvc_mask], 1f\n" - "lh %[tmp], 2(%[addr])\n" + "bne %[tmp], %[rvc_mask], 2f\n" + "lhu %[tmp], 2(%[addr])\n" "sll %[tmp], %[tmp], 16\n" "add %[insn], %[insn], %[tmp]\n" - "1: csrw mstatus, %[mstatus]" + "2: csrw mstatus, %[mstatus]" : [mstatus] "+&r" (__mstatus), [insn] "=&r" (val), [tmp] "=&r" (tmp) : [mprv] "r" (MSTATUS_MPRV | MSTATUS_MXR), [addr] "r" (__mepc), - [rvc_mask] "r" (rvc_mask)); + [rvc_mask] "r" (rvc_mask), [xlen_minus_16] "i" (__riscv_xlen - 16)); #endif *mstatus = __mstatus; return val; |