diff options
-rw-r--r-- | riscv/execute.cc | 2 | ||||
-rw-r--r-- | riscv/insns/c_ebreak.h | 2 | ||||
-rw-r--r-- | riscv/insns/ebreak.h | 2 | ||||
-rw-r--r-- | riscv/mmu.cc | 18 | ||||
-rw-r--r-- | riscv/mmu.h | 20 | ||||
-rw-r--r-- | riscv/processor.h | 2 | ||||
-rw-r--r-- | riscv/trap.h | 42 |
7 files changed, 60 insertions, 28 deletions
diff --git a/riscv/execute.cc b/riscv/execute.cc index 4ed2753..a6c7f10 100644 --- a/riscv/execute.cc +++ b/riscv/execute.cc @@ -347,7 +347,7 @@ void processor_t::step(size_t n) enter_debug_mode(DCSR_CAUSE_HWBP); break; case ACTION_DEBUG_EXCEPTION: { - mem_trap_t trap(CAUSE_BREAKPOINT, t.address); + insn_trap_t trap(CAUSE_BREAKPOINT, t.address); take_trap(trap, pc); break; } diff --git a/riscv/insns/c_ebreak.h b/riscv/insns/c_ebreak.h index a17200f..1c36b24 100644 --- a/riscv/insns/c_ebreak.h +++ b/riscv/insns/c_ebreak.h @@ -1,2 +1,2 @@ require_extension('C'); -throw trap_breakpoint(); +throw trap_breakpoint(0); diff --git a/riscv/insns/ebreak.h b/riscv/insns/ebreak.h index c22776c..f123f95 100644 --- a/riscv/insns/ebreak.h +++ b/riscv/insns/ebreak.h @@ -1 +1 @@ -throw trap_breakpoint(); +throw trap_breakpoint(0); diff --git a/riscv/mmu.cc b/riscv/mmu.cc index b038f23..78abd39 100644 --- a/riscv/mmu.cc +++ b/riscv/mmu.cc @@ -37,9 +37,9 @@ void mmu_t::flush_tlb() static void throw_access_exception(reg_t addr, access_type type) { switch (type) { - case FETCH: throw trap_instruction_access_fault(addr); - case LOAD: throw trap_load_access_fault(addr); - case STORE: throw trap_store_access_fault(addr); + case FETCH: throw trap_instruction_access_fault(addr, 0, 0); + case LOAD: throw trap_load_access_fault(addr, 0, 0); + case STORE: throw trap_store_access_fault(addr, 0, 0); default: abort(); } } @@ -69,7 +69,7 @@ tlb_entry_t mmu_t::fetch_slow_path(reg_t vaddr) return refill_tlb(vaddr, paddr, host_addr, FETCH); } else { if (!mmio_load(paddr, sizeof fetch_temp, (uint8_t*)&fetch_temp)) - throw trap_instruction_access_fault(vaddr); + throw trap_instruction_access_fault(vaddr, 0, 0); tlb_entry_t entry = {(char*)&fetch_temp - vaddr, paddr - vaddr}; return entry; } @@ -137,7 +137,7 @@ void mmu_t::load_slow_path(reg_t addr, reg_t len, uint8_t* bytes) else refill_tlb(addr, paddr, host_addr, LOAD); } else if (!mmio_load(paddr, len, bytes)) { - throw trap_load_access_fault(addr); + throw trap_load_access_fault(addr, 0, 0); } if (!matched_trigger) { @@ -166,7 +166,7 @@ void mmu_t::store_slow_path(reg_t addr, reg_t len, const uint8_t* bytes) else refill_tlb(addr, paddr, host_addr, STORE); } else if (!mmio_store(paddr, len, bytes)) { - throw trap_store_access_fault(addr); + throw trap_store_access_fault(addr, 0, 0); } } @@ -350,9 +350,9 @@ reg_t mmu_t::walk(reg_t addr, access_type type, reg_t mode) } switch (type) { - case FETCH: throw trap_instruction_page_fault(addr); - case LOAD: throw trap_load_page_fault(addr); - case STORE: throw trap_store_page_fault(addr); + case FETCH: throw trap_instruction_page_fault(addr, 0, 0); + case LOAD: throw trap_load_page_fault(addr, 0, 0); + case STORE: throw trap_store_page_fault(addr, 0, 0); default: abort(); } } diff --git a/riscv/mmu.h b/riscv/mmu.h index f89d139..edf38ed 100644 --- a/riscv/mmu.h +++ b/riscv/mmu.h @@ -66,7 +66,7 @@ public: res += (reg_t)load_uint8(addr + i) << (i * 8); return res; #else - throw trap_load_address_misaligned(addr); + throw trap_load_address_misaligned(addr, 0, 0); #endif } @@ -76,7 +76,7 @@ public: for (size_t i = 0; i < size; i++) store_uint8(addr + i, data >> (i * 8)); #else - throw trap_store_address_misaligned(addr); + throw trap_store_address_misaligned(addr, 0, 0); #endif } @@ -165,17 +165,17 @@ public: template<typename op> \ type##_t amo_##type(reg_t addr, op f) { \ if (addr & (sizeof(type##_t)-1)) \ - throw trap_store_address_misaligned(addr); \ + throw trap_store_address_misaligned(addr, 0, 0); \ try { \ auto lhs = load_##type(addr); \ store_##type(addr, f(lhs)); \ return lhs; \ } catch (trap_load_page_fault& t) { \ /* AMO faults should be reported as store faults */ \ - throw trap_store_page_fault(t.get_tval()); \ + throw trap_store_page_fault(t.get_tval(), t.get_tval2(), t.get_tinst()); \ } catch (trap_load_access_fault& t) { \ /* AMO faults should be reported as store faults */ \ - throw trap_store_access_fault(t.get_tval()); \ + throw trap_store_access_fault(t.get_tval(), t.get_tval2(), t.get_tinst()); \ } \ } @@ -183,7 +183,7 @@ public: { #ifndef RISCV_ENABLE_MISALIGNED if (unlikely(addr & (sizeof(float128_t)-1))) - throw trap_store_address_misaligned(addr); + throw trap_store_address_misaligned(addr, 0, 0); #endif store_uint64(addr, val.v[0]); store_uint64(addr + 8, val.v[1]); @@ -193,7 +193,7 @@ public: { #ifndef RISCV_ENABLE_MISALIGNED if (unlikely(addr & (sizeof(float128_t)-1))) - throw trap_load_address_misaligned(addr); + throw trap_load_address_misaligned(addr, 0, 0); #endif return (float128_t){load_uint64(addr), load_uint64(addr + 8)}; } @@ -219,19 +219,19 @@ public: if (auto host_addr = sim->addr_to_mem(paddr)) load_reservation_address = refill_tlb(vaddr, paddr, host_addr, LOAD).target_offset + vaddr; else - throw trap_load_access_fault(vaddr); // disallow LR to I/O space + throw trap_load_access_fault(vaddr, 0, 0); // disallow LR to I/O space } inline bool check_load_reservation(reg_t vaddr, size_t size) { if (vaddr & (size-1)) - throw trap_store_address_misaligned(vaddr); + throw trap_store_address_misaligned(vaddr, 0, 0); reg_t paddr = translate(vaddr, 1, STORE); if (auto host_addr = sim->addr_to_mem(paddr)) return load_reservation_address == refill_tlb(vaddr, paddr, host_addr, STORE).target_offset + vaddr; else - throw trap_store_access_fault(vaddr); // disallow SC to I/O space + throw trap_store_access_fault(vaddr, 0, 0); // disallow SC to I/O space } static const reg_t ICACHE_ENTRIES = 1024; diff --git a/riscv/processor.h b/riscv/processor.h index 68e13d8..a679eaa 100644 --- a/riscv/processor.h +++ b/riscv/processor.h @@ -284,7 +284,7 @@ public: } void check_pc_alignment(reg_t pc) { if (unlikely(pc & ~pc_alignment_mask())) - throw trap_instruction_address_misaligned(pc); + throw trap_instruction_address_misaligned(pc, 0, 0); } reg_t legalize_privilege(reg_t); void set_privilege(reg_t); diff --git a/riscv/trap.h b/riscv/trap.h index ac048eb..824af6f 100644 --- a/riscv/trap.h +++ b/riscv/trap.h @@ -13,18 +13,23 @@ class trap_t public: trap_t(reg_t which) : which(which) {} virtual const char* name(); + virtual bool has_gva() { return false; } virtual bool has_tval() { return false; } virtual reg_t get_tval() { return 0; } + virtual bool has_tval2() { return false; } + virtual reg_t get_tval2() { return 0; } + virtual bool has_tinst() { return false; } + virtual reg_t get_tinst() { return 0; } reg_t cause() { return which; } private: char _name[16]; reg_t which; }; -class mem_trap_t : public trap_t +class insn_trap_t : public trap_t { public: - mem_trap_t(reg_t which, reg_t tval) + insn_trap_t(reg_t which, reg_t tval) : trap_t(which), tval(tval) {} bool has_tval() override { return true; } reg_t get_tval() override { return tval; } @@ -32,22 +37,45 @@ class mem_trap_t : public trap_t reg_t tval; }; +class mem_trap_t : public trap_t +{ + public: + mem_trap_t(reg_t which, bool gva, reg_t tval, reg_t tval2, reg_t tinst) + : trap_t(which), gva(gva), tval(tval), tval2(tval2), tinst(tinst) {} + bool has_gva() override { return gva; } + bool has_tval() override { return true; } + reg_t get_tval() override { return tval; } + bool has_tval2() override { return true; } + reg_t get_tval2() override { return tval2; } + bool has_tinst() override { return true; } + reg_t get_tinst() override { return tinst; } + private: + bool gva; + reg_t tval, tval2, tinst; +}; + #define DECLARE_TRAP(n, x) class trap_##x : public trap_t { \ public: \ trap_##x() : trap_t(n) {} \ const char* name() { return "trap_"#x; } \ }; +#define DECLARE_INST_TRAP(n, x) class trap_##x : public insn_trap_t { \ + public: \ + trap_##x(reg_t tval) : insn_trap_t(n, tval) {} \ + const char* name() { return "trap_"#x; } \ +}; + #define DECLARE_MEM_TRAP(n, x) class trap_##x : public mem_trap_t { \ public: \ - trap_##x(reg_t tval) : mem_trap_t(n, tval) {} \ + trap_##x(reg_t tval, reg_t tval2, reg_t tinst) : mem_trap_t(n, true, tval, tval2, tinst) {} \ const char* name() { return "trap_"#x; } \ }; DECLARE_MEM_TRAP(CAUSE_MISALIGNED_FETCH, instruction_address_misaligned) DECLARE_MEM_TRAP(CAUSE_FETCH_ACCESS, instruction_access_fault) -DECLARE_MEM_TRAP(CAUSE_ILLEGAL_INSTRUCTION, illegal_instruction) -DECLARE_TRAP(CAUSE_BREAKPOINT, breakpoint) +DECLARE_INST_TRAP(CAUSE_ILLEGAL_INSTRUCTION, illegal_instruction) +DECLARE_INST_TRAP(CAUSE_BREAKPOINT, breakpoint) DECLARE_MEM_TRAP(CAUSE_MISALIGNED_LOAD, load_address_misaligned) DECLARE_MEM_TRAP(CAUSE_MISALIGNED_STORE, store_address_misaligned) DECLARE_MEM_TRAP(CAUSE_LOAD_ACCESS, load_access_fault) @@ -59,5 +87,9 @@ DECLARE_TRAP(CAUSE_MACHINE_ECALL, machine_ecall) DECLARE_MEM_TRAP(CAUSE_FETCH_PAGE_FAULT, instruction_page_fault) DECLARE_MEM_TRAP(CAUSE_LOAD_PAGE_FAULT, load_page_fault) DECLARE_MEM_TRAP(CAUSE_STORE_PAGE_FAULT, store_page_fault) +DECLARE_MEM_TRAP(CAUSE_FETCH_GUEST_PAGE_FAULT, instruction_guest_page_fault) +DECLARE_MEM_TRAP(CAUSE_LOAD_GUEST_PAGE_FAULT, load_guest_page_fault) +DECLARE_INST_TRAP(CAUSE_VIRTUAL_INSTRUCTION, virtual_instruction) +DECLARE_MEM_TRAP(CAUSE_STORE_GUEST_PAGE_FAULT, store_guest_page_fault) #endif |