[sim] added icache simulator (disabled by default)
[riscv-isa-sim.git] / riscv / mmu.h
1 #include "decode.h"
2 #include "trap.h"
3
4 class processor_t;
5
6 class mmu_t
7 {
8 public:
9 mmu_t(char* _mem, size_t _memsz) : mem(_mem), memsz(_memsz), badvaddr(0) {}
10
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); \
15 }
16
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; \
21 }
22
23 insn_t load_insn(reg_t addr, bool rvc)
24 {
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);
29
30 insn_t insn;
31 insn.bits = lo | ((uint32_t)hi << 16);
32
33 return insn;
34 #else
35 check_align_and_bounds(addr, 4, false, true);
36 return *(insn_t*)(mem+addr);
37 #endif
38 }
39
40 load_func(uint8)
41 load_func(uint16)
42 load_func(uint32)
43 load_func(uint64)
44
45 load_func(int8)
46 load_func(int16)
47 load_func(int32)
48 load_func(int64)
49
50 store_func(uint8)
51 store_func(uint16)
52 store_func(uint32)
53 store_func(uint64)
54
55 reg_t get_badvaddr() { return badvaddr; }
56
57 private:
58 char* mem;
59 size_t memsz;
60 reg_t badvaddr;
61
62 void check_align(reg_t addr, int size, bool store, bool fetch)
63 {
64 if(addr & (size-1))
65 {
66 badvaddr = addr;
67 if(fetch)
68 throw trap_instruction_address_misaligned;
69 if(store)
70 throw trap_store_address_misaligned;
71 throw trap_load_address_misaligned;
72 }
73 }
74
75 void check_bounds(reg_t addr, int size, bool store, bool fetch)
76 {
77 if(addr >= memsz || addr + size > memsz)
78 {
79 badvaddr = addr;
80 if(fetch)
81 throw trap_instruction_access_fault;
82 throw store ? trap_store_access_fault : trap_load_access_fault;
83 }
84 }
85
86 void check_align_and_bounds(reg_t addr, int size, bool store, bool fetch)
87 {
88 check_align(addr, size, store, fetch);
89 check_bounds(addr, size, store, fetch);
90 }
91
92 friend class processor_t;
93 };