aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Waterman <andrew@sifive.com>2017-03-27 14:30:22 -0700
committerAndrew Waterman <andrew@sifive.com>2017-03-27 14:30:22 -0700
commita80c695b1961ac40086494920f82e85a085ff358 (patch)
treed7c938bdfb5aa80542e8a1f9a68421ec730ca703
parent1fa2174178a5432443f114dfc059ba19c53b1fae (diff)
downloadspike-a80c695b1961ac40086494920f82e85a085ff358.zip
spike-a80c695b1961ac40086494920f82e85a085ff358.tar.gz
spike-a80c695b1961ac40086494920f82e85a085ff358.tar.bz2
Separate page faults from physical memory access exceptions
-rw-r--r--riscv/encoding.h18
-rw-r--r--riscv/mmu.cc8
-rw-r--r--riscv/mmu.h3
-rw-r--r--riscv/trap.h9
4 files changed, 25 insertions, 13 deletions
diff --git a/riscv/encoding.h b/riscv/encoding.h
index a7066b7..b07d976 100644
--- a/riscv/encoding.h
+++ b/riscv/encoding.h
@@ -958,17 +958,20 @@
#define CSR_MHPMCOUNTER30H 0xb9e
#define CSR_MHPMCOUNTER31H 0xb9f
#define CAUSE_MISALIGNED_FETCH 0x0
-#define CAUSE_FAULT_FETCH 0x1
+#define CAUSE_FETCH_ACCESS 0x1
#define CAUSE_ILLEGAL_INSTRUCTION 0x2
#define CAUSE_BREAKPOINT 0x3
#define CAUSE_MISALIGNED_LOAD 0x4
-#define CAUSE_FAULT_LOAD 0x5
+#define CAUSE_LOAD_ACCESS 0x5
#define CAUSE_MISALIGNED_STORE 0x6
-#define CAUSE_FAULT_STORE 0x7
+#define CAUSE_STORE_ACCESS 0x7
#define CAUSE_USER_ECALL 0x8
#define CAUSE_SUPERVISOR_ECALL 0x9
#define CAUSE_HYPERVISOR_ECALL 0xa
#define CAUSE_MACHINE_ECALL 0xb
+#define CAUSE_FETCH_PAGE_FAULT 0xc
+#define CAUSE_LOAD_PAGE_FAULT 0xd
+#define CAUSE_STORE_PAGE_FAULT 0xf
#endif
#ifdef DECLARE_INSN
DECLARE_INSN(beq, MATCH_BEQ, MASK_BEQ)
@@ -1450,15 +1453,18 @@ DECLARE_CSR(mhpmcounter31h, CSR_MHPMCOUNTER31H)
#endif
#ifdef DECLARE_CAUSE
DECLARE_CAUSE("misaligned fetch", CAUSE_MISALIGNED_FETCH)
-DECLARE_CAUSE("fault fetch", CAUSE_FAULT_FETCH)
+DECLARE_CAUSE("fetch access", CAUSE_FETCH_ACCESS)
DECLARE_CAUSE("illegal instruction", CAUSE_ILLEGAL_INSTRUCTION)
DECLARE_CAUSE("breakpoint", CAUSE_BREAKPOINT)
DECLARE_CAUSE("misaligned load", CAUSE_MISALIGNED_LOAD)
-DECLARE_CAUSE("fault load", CAUSE_FAULT_LOAD)
+DECLARE_CAUSE("load access", CAUSE_LOAD_ACCESS)
DECLARE_CAUSE("misaligned store", CAUSE_MISALIGNED_STORE)
-DECLARE_CAUSE("fault store", CAUSE_FAULT_STORE)
+DECLARE_CAUSE("store access", CAUSE_STORE_ACCESS)
DECLARE_CAUSE("user_ecall", CAUSE_USER_ECALL)
DECLARE_CAUSE("supervisor_ecall", CAUSE_SUPERVISOR_ECALL)
DECLARE_CAUSE("hypervisor_ecall", CAUSE_HYPERVISOR_ECALL)
DECLARE_CAUSE("machine_ecall", CAUSE_MACHINE_ECALL)
+DECLARE_CAUSE("fetch page fault", CAUSE_FETCH_PAGE_FAULT)
+DECLARE_CAUSE("load page fault", CAUSE_LOAD_PAGE_FAULT)
+DECLARE_CAUSE("store page fault", CAUSE_STORE_PAGE_FAULT)
#endif
diff --git a/riscv/mmu.cc b/riscv/mmu.cc
index 0b28f2f..8df38e5 100644
--- a/riscv/mmu.cc
+++ b/riscv/mmu.cc
@@ -180,7 +180,7 @@ reg_t mmu_t::walk(reg_t addr, access_type type, reg_t mode)
// check that physical address of PTE is legal
reg_t pte_addr = base + idx * vm.ptesize;
if (!sim->addr_is_mem(pte_addr))
- break;
+ throw trap_load_access_fault(addr);
void* ppte = sim->addr_to_mem(pte_addr);
reg_t pte = vm.ptesize == 4 ? *(uint32_t*)ppte : *(uint64_t*)ppte;
@@ -215,9 +215,9 @@ reg_t mmu_t::walk(reg_t addr, access_type type, reg_t mode)
fail:
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_page_fault(addr);
+ case LOAD: throw trap_load_page_fault(addr);
+ case STORE: throw trap_store_page_fault(addr);
default: abort();
}
}
diff --git a/riscv/mmu.h b/riscv/mmu.h
index 9365457..66454be 100644
--- a/riscv/mmu.h
+++ b/riscv/mmu.h
@@ -115,6 +115,9 @@ public:
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_badaddr()); \
} catch (trap_load_access_fault& t) { \
/* AMO faults should be reported as store faults */ \
throw trap_store_access_fault(t.get_badaddr()); \
diff --git a/riscv/trap.h b/riscv/trap.h
index 7f35c5f..a289a68 100644
--- a/riscv/trap.h
+++ b/riscv/trap.h
@@ -45,16 +45,19 @@ class mem_trap_t : public trap_t
};
DECLARE_MEM_TRAP(CAUSE_MISALIGNED_FETCH, instruction_address_misaligned)
-DECLARE_MEM_TRAP(CAUSE_FAULT_FETCH, instruction_access_fault)
+DECLARE_MEM_TRAP(CAUSE_FETCH_ACCESS, instruction_access_fault)
DECLARE_TRAP(CAUSE_ILLEGAL_INSTRUCTION, illegal_instruction)
DECLARE_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_FAULT_LOAD, load_access_fault)
-DECLARE_MEM_TRAP(CAUSE_FAULT_STORE, store_access_fault)
+DECLARE_MEM_TRAP(CAUSE_LOAD_ACCESS, load_access_fault)
+DECLARE_MEM_TRAP(CAUSE_STORE_ACCESS, store_access_fault)
DECLARE_TRAP(CAUSE_USER_ECALL, user_ecall)
DECLARE_TRAP(CAUSE_SUPERVISOR_ECALL, supervisor_ecall)
DECLARE_TRAP(CAUSE_HYPERVISOR_ECALL, hypervisor_ecall)
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)
#endif