Fix 2 trigger corner cases. (#229)
[riscv-isa-sim.git] / riscv / mmu.cc
index eca8a8339968ef6880cba51dd08272b85a2e72a0..021f587eaac5ac23c42ae0fa8b88c93c4ca27ec5 100644 (file)
@@ -1,7 +1,7 @@
 // See LICENSE for license details.
 
 #include "mmu.h"
-#include "sim.h"
+#include "simif.h"
 #include "processor.h"
 
 mmu_t::mmu_t(simif_t* sim, processor_t* proc)
@@ -12,6 +12,7 @@ mmu_t::mmu_t(simif_t* sim, processor_t* proc)
   matched_trigger(NULL)
 {
   flush_tlb();
+  yield_load_reservation();
 }
 
 mmu_t::~mmu_t()
@@ -182,7 +183,7 @@ reg_t mmu_t::walk(reg_t addr, access_type type, reg_t mode)
     // check that physical address of PTE is legal
     auto ppte = sim->addr_to_mem(base + idx * vm.ptesize);
     if (!ppte)
-      throw trap_load_access_fault(addr);
+      goto fail_access;
 
     reg_t pte = vm.ptesize == 4 ? *(uint32_t*)ppte : *(uint64_t*)ppte;
     reg_t ppn = pte >> PTE_PPN_SHIFT;
@@ -223,6 +224,14 @@ fail:
     case STORE: throw trap_store_page_fault(addr);
     default: abort();
   }
+
+fail_access:
+  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);
+    default: abort();
+  }
 }
 
 void mmu_t::register_memtracer(memtracer_t* t)