9 mmu_t(char* _mem
, size_t _memsz
) : mem(_mem
), memsz(_memsz
), badvaddr(0) {}
11 #define load_func(type) \
12 type##_t load_##type(reg_t addr) { \
13 check_align_and_bounds(addr, sizeof(type##_t), false, false); \
14 return *(type##_t*)(mem+addr); \
17 #define store_func(type) \
18 void store_##type(reg_t addr, type##_t val) { \
19 check_align_and_bounds(addr, sizeof(type##_t), true, false); \
20 *(type##_t*)(mem+addr) = val; \
23 insn_t
load_insn(reg_t addr
, bool rvc
)
25 #ifdef RISCV_ENABLE_RVC
26 check_align_and_bounds(addr
, rvc
? 2 : 4, false, true);
27 uint16_t lo
= *(uint16_t*)(mem
+addr
);
28 uint16_t hi
= *(uint16_t*)(mem
+addr
+2);
31 insn
.bits
= lo
| ((uint32_t)hi
<< 16);
35 check_align_and_bounds(addr
, 4, false, true);
36 return *(insn_t
*)(mem
+addr
);
55 reg_t
get_badvaddr() { return badvaddr
; }
62 void check_align(reg_t addr
, int size
, bool store
, bool fetch
)
68 throw trap_instruction_address_misaligned
;
70 throw trap_store_address_misaligned
;
71 throw trap_load_address_misaligned
;
75 void check_bounds(reg_t addr
, int size
, bool store
, bool fetch
)
77 if(addr
>= memsz
|| addr
+ size
> memsz
)
81 throw trap_instruction_access_fault
;
82 throw store
? trap_store_access_fault
: trap_load_access_fault
;
86 void check_align_and_bounds(reg_t addr
, int size
, bool store
, bool fetch
)
88 check_align(addr
, size
, store
, fetch
);
89 check_bounds(addr
, size
, store
, fetch
);
92 friend class processor_t
;