aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--riscv/execute.cc2
-rw-r--r--riscv/insns/c_ebreak.h2
-rw-r--r--riscv/insns/ebreak.h2
-rw-r--r--riscv/mmu.cc18
-rw-r--r--riscv/mmu.h20
-rw-r--r--riscv/processor.h2
-rw-r--r--riscv/trap.h42
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