projects
/
riscv-isa-sim.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
Put simif_t declaration in its own file. (#209)
[riscv-isa-sim.git]
/
riscv
/
mmu.cc
diff --git
a/riscv/mmu.cc
b/riscv/mmu.cc
index 76a6ab1d4f685cf142a83d03a87f68847529e266..3a0bd39b89471470cef1155f201a646b673cbfab 100644
(file)
--- a/
riscv/mmu.cc
+++ b/
riscv/mmu.cc
@@
-1,10
+1,10
@@
// See LICENSE for license details.
#include "mmu.h"
// See LICENSE for license details.
#include "mmu.h"
-#include "sim.h"
+#include "sim
if
.h"
#include "processor.h"
#include "processor.h"
-mmu_t::mmu_t(sim_t* sim, processor_t* proc)
+mmu_t::mmu_t(sim
if
_t* sim, processor_t* proc)
: sim(sim), proc(proc),
check_triggers_fetch(false),
check_triggers_load(false),
: sim(sim), proc(proc),
check_triggers_fetch(false),
check_triggers_load(false),
@@
-159,11
+159,11
@@
tlb_entry_t mmu_t::refill_tlb(reg_t vaddr, reg_t paddr, char* host_addr, access_
reg_t mmu_t::walk(reg_t addr, access_type type, reg_t mode)
{
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()->s
ptbr
);
+ vm_info vm = decode_vm_info(proc->max_xlen, mode, proc->get_state()->s
atp
);
if (vm.levels == 0)
return addr & ((reg_t(2) << (proc->xlen-1))-1); // zero-extend from xlen
if (vm.levels == 0)
return addr & ((reg_t(2) << (proc->xlen-1))-1); // zero-extend from xlen
- bool s
upervisor
= mode == PRV_S;
+ bool s
_mode
= mode == PRV_S;
bool sum = get_field(proc->state.mstatus, MSTATUS_SUM);
bool mxr = get_field(proc->state.mstatus, MSTATUS_MXR);
bool sum = get_field(proc->state.mstatus, MSTATUS_SUM);
bool mxr = get_field(proc->state.mstatus, MSTATUS_MXR);
@@
-182,14
+182,14
@@
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)
// 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;
if (PTE_TABLE(pte)) { // next level of page table
base = ppn << PGSHIFT;
reg_t pte = vm.ptesize == 4 ? *(uint32_t*)ppte : *(uint64_t*)ppte;
reg_t ppn = pte >> PTE_PPN_SHIFT;
if (PTE_TABLE(pte)) { // next level of page table
base = ppn << PGSHIFT;
- } else if ((pte & PTE_U) ? s
upervisor && !sum : !supervisor
) {
+ } else if ((pte & PTE_U) ? s
_mode && (type == FETCH || !sum) : !s_mode
) {
break;
} else if (!(pte & PTE_V) || (!(pte & PTE_R) && (pte & PTE_W))) {
break;
break;
} else if (!(pte & PTE_V) || (!(pte & PTE_R) && (pte & PTE_W))) {
break;
@@
-223,6
+223,14
@@
fail:
case STORE: throw trap_store_page_fault(addr);
default: abort();
}
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)
}
void mmu_t::register_memtracer(memtracer_t* t)