// See LICENSE for license details.
#include "mmu.h"
-#include "sim.h"
+#include "simif.h"
#include "processor.h"
-mmu_t::mmu_t(sim_t* sim, processor_t* proc)
+mmu_t::mmu_t(simif_t* sim, processor_t* proc)
: sim(sim), proc(proc),
check_triggers_fetch(false),
check_triggers_load(false),
matched_trigger(NULL)
{
flush_tlb();
+ yield_load_reservation();
}
mmu_t::~mmu_t()
reg_t mmu_t::walk(reg_t addr, access_type type, reg_t mode)
{
- vm_info vm = decode_vm_info(proc->max_xlen, mode, proc->get_state()->sptbr);
+ vm_info vm = decode_vm_info(proc->max_xlen, mode, proc->get_state()->satp);
if (vm.levels == 0)
return addr & ((reg_t(2) << (proc->xlen-1))-1); // zero-extend from xlen
// 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;
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)