Reorganized directory structure
[riscv-isa-sim.git] / riscv / mmu.h
1 #include "decode.h"
2 #include "trap.h"
3
4 class mmu_t
5 {
6 public:
7 mmu_t(char* _mem, size_t _memsz) : mem(_mem), memsz(_memsz) {}
8
9 #define load_func(type) \
10 type##_t load_##type(reg_t addr) { \
11 check_align_and_bounds(addr, sizeof(type##_t), false); \
12 return *(type##_t*)(mem+addr); \
13 }
14
15 #define store_func(type) \
16 void store_##type(reg_t addr, type##_t val) { \
17 check_align_and_bounds(addr, sizeof(type##_t), false); \
18 *(type##_t*)(mem+addr) = val; \
19 }
20
21 insn_t load_insn(reg_t addr)
22 {
23 check_align_and_bounds(addr, sizeof(insn_t), true);
24 return *(insn_t*)(mem+addr);
25 }
26
27 load_func(uint8)
28 load_func(uint16)
29 load_func(uint32)
30 load_func(uint64)
31
32 load_func(int8)
33 load_func(int16)
34 load_func(int32)
35 load_func(int64)
36
37 store_func(uint8)
38 store_func(uint16)
39 store_func(uint32)
40 store_func(uint64)
41
42 reg_t get_badvaddr() { return badvaddr; }
43
44 private:
45 char* mem;
46 size_t memsz;
47 reg_t badvaddr;
48
49 void check_align(reg_t addr, int size, bool fetch)
50 {
51 if(addr & (size-1))
52 {
53 if(fetch)
54 throw trap_instruction_address_misaligned;
55 badvaddr = addr;
56 throw trap_data_address_misaligned;
57 }
58 }
59
60 void check_bounds(reg_t addr, int size, bool fetch)
61 {
62 if(addr >= memsz || addr + size > memsz)
63 {
64 if(fetch)
65 throw trap_instruction_access_fault;
66 badvaddr = addr;
67 throw trap_data_access_fault;
68 }
69 }
70
71 void check_align_and_bounds(reg_t addr, int size, bool fetch)
72 {
73 check_align(addr, size, fetch);
74 check_bounds(addr, size, fetch);
75 }
76 };