From a80c695b1961ac40086494920f82e85a085ff358 Mon Sep 17 00:00:00 2001 From: Andrew Waterman Date: Mon, 27 Mar 2017 14:30:22 -0700 Subject: [PATCH] Separate page faults from physical memory access exceptions --- riscv/encoding.h | 18 ++++++++++++------ riscv/mmu.cc | 8 ++++---- riscv/mmu.h | 3 +++ riscv/trap.h | 9 ++++++--- 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 -- 2.30.2