10 mmu_t(char* _mem
, size_t _memsz
)
11 : mem(_mem
), memsz(_memsz
), badvaddr(0),
12 icsim(NULL
), dcsim(NULL
), itlbsim(NULL
), dtlbsim(NULL
)
16 void set_icsim(icsim_t
* _icsim
) { icsim
= _icsim
; }
17 void set_dcsim(icsim_t
* _dcsim
) { dcsim
= _dcsim
; }
18 void set_itlbsim(icsim_t
* _itlbsim
) { itlbsim
= _itlbsim
; }
19 void set_dtlbsim(icsim_t
* _dtlbsim
) { dtlbsim
= _dtlbsim
; }
21 #ifdef RISCV_ENABLE_ICSIM
22 # define dcsim_tick(dcsim, dtlbsim, addr, size, st) \
23 do { if(dcsim) (dcsim)->tick(addr, size, st); \
24 if(dtlbsim) (dtlbsim)->tick(addr, sizeof(reg_t), false); } while(0)
26 # define dcsim_tick(dcsim, dtlbsim, addr, size, st)
29 #define load_func(type) \
30 type##_t load_##type(reg_t addr) { \
31 check_align_and_bounds(addr, sizeof(type##_t), false, false); \
32 dcsim_tick(dcsim, dtlbsim, addr, sizeof(type##_t), false); \
33 return *(type##_t*)(mem+addr); \
36 #define store_func(type) \
37 void store_##type(reg_t addr, type##_t val) { \
38 check_align_and_bounds(addr, sizeof(type##_t), true, false); \
39 dcsim_tick(dcsim, dtlbsim, addr, sizeof(type##_t), true); \
40 *(type##_t*)(mem+addr) = val; \
43 insn_t
load_insn(reg_t addr
, bool rvc
)
45 #ifdef RISCV_ENABLE_RVC
46 check_align_and_bounds(addr
, rvc
? 2 : 4, false, true);
47 uint16_t lo
= *(uint16_t*)(mem
+addr
);
48 uint16_t hi
= *(uint16_t*)(mem
+addr
+2);
51 insn
.bits
= lo
| ((uint32_t)hi
<< 16);
53 #ifdef RISCV_ENABLE_ICSIM
55 icsim
->tick(addr
, insn_length(insn
), false);
57 itlbsim
->tick(addr
, sizeof(reg_t
), false);
62 check_align_and_bounds(addr
, 4, false, true);
63 return *(insn_t
*)(mem
+addr
);
82 reg_t
get_badvaddr() { return badvaddr
; }
94 void check_align(reg_t addr
, int size
, bool store
, bool fetch
)
100 throw trap_instruction_address_misaligned
;
102 throw trap_store_address_misaligned
;
103 throw trap_load_address_misaligned
;
107 void check_bounds(reg_t addr
, int size
, bool store
, bool fetch
)
109 if(addr
>= memsz
|| addr
+ size
> memsz
)
113 throw trap_instruction_access_fault
;
114 throw store
? trap_store_access_fault
: trap_load_access_fault
;
118 void check_align_and_bounds(reg_t addr
, int size
, bool store
, bool fetch
)
120 check_align(addr
, size
, store
, fetch
);
121 check_bounds(addr
, size
, store
, fetch
);
124 friend class processor_t
;