aboutsummaryrefslogtreecommitdiff
path: root/riscv/mmu.cc
diff options
context:
space:
mode:
authorJerry Zhao <jerryz123@berkeley.edu>2022-12-27 15:38:41 -0800
committerJerry Zhao <jerryz123@berkeley.edu>2023-01-03 10:10:01 -0800
commit25f9028475b3b774be617a197fe76435827258b1 (patch)
tree70b34bfdd106d34e60f692911adad6e12b5fcac2 /riscv/mmu.cc
parentad5fcd96e9731073c58c64e5fa4fecfd3ad5e8a5 (diff)
downloadriscv-isa-sim-25f9028475b3b774be617a197fe76435827258b1.zip
riscv-isa-sim-25f9028475b3b774be617a197fe76435827258b1.tar.gz
riscv-isa-sim-25f9028475b3b774be617a197fe76435827258b1.tar.bz2
Pull pte load/store into methods of mmu_t
Diffstat (limited to 'riscv/mmu.cc')
-rw-r--r--riscv/mmu.cc23
1 files changed, 5 insertions, 18 deletions
diff --git a/riscv/mmu.cc b/riscv/mmu.cc
index ddf277b..0ac0d65 100644
--- a/riscv/mmu.cc
+++ b/riscv/mmu.cc
@@ -42,7 +42,7 @@ void mmu_t::flush_tlb()
flush_icache();
}
-static void throw_access_exception(bool virt, reg_t addr, access_type type)
+void throw_access_exception(bool virt, reg_t addr, access_type type)
{
switch (type) {
case FETCH: throw trap_instruction_access_fault(virt, addr, 0, 0);
@@ -382,12 +382,7 @@ reg_t mmu_t::s2xlate(reg_t gva, reg_t gpa, access_type type, access_type trap_ty
// check that physical address of PTE is legal
auto pte_paddr = base + idx * vm.ptesize;
- auto ppte = sim->addr_to_mem(pte_paddr);
- if (!ppte || !pmp_ok(pte_paddr, vm.ptesize, LOAD, PRV_S)) {
- throw_access_exception(virt, gva, trap_type);
- }
-
- reg_t pte = vm.ptesize == 4 ? from_target(*(target_endian<uint32_t>*)ppte) : from_target(*(target_endian<uint64_t>*)ppte);
+ reg_t pte = pte_load(pte_paddr, gva, virt, trap_type, vm.ptesize);
reg_t ppn = (pte & ~reg_t(PTE_ATTR)) >> PTE_PPN_SHIFT;
bool pbmte = proc->get_state()->menvcfg->read() & MENVCFG_PBMTE;
@@ -418,9 +413,7 @@ reg_t mmu_t::s2xlate(reg_t gva, reg_t gpa, access_type type, access_type trap_ty
#ifdef RISCV_ENABLE_DIRTY
// set accessed and possibly dirty bits.
if ((pte & ad) != ad) {
- if (!pmp_ok(pte_paddr, vm.ptesize, STORE, PRV_S))
- throw_access_exception(virt, gva, trap_type);
- *(target_endian<uint32_t>*)ppte |= to_target((uint32_t)ad);
+ pte_store(pte_paddr, pte | ad, gva, virt, type, vm.ptesize);
}
#else
// take exception if access or possibly dirty bit is not set.
@@ -476,11 +469,7 @@ reg_t mmu_t::walk(reg_t addr, access_type type, reg_t mode, bool virt, bool hlvx
// check that physical address of PTE is legal
auto pte_paddr = s2xlate(addr, base + idx * vm.ptesize, LOAD, type, virt, false);
- auto ppte = sim->addr_to_mem(pte_paddr);
- if (!ppte || !pmp_ok(pte_paddr, vm.ptesize, LOAD, PRV_S))
- throw_access_exception(virt, addr, type);
-
- reg_t pte = vm.ptesize == 4 ? from_target(*(target_endian<uint32_t>*)ppte) : from_target(*(target_endian<uint64_t>*)ppte);
+ reg_t pte = pte_load(pte_paddr, addr, virt, type, vm.ptesize);
reg_t ppn = (pte & ~reg_t(PTE_ATTR)) >> PTE_PPN_SHIFT;
bool pbmte = virt ? (proc->get_state()->henvcfg->read() & HENVCFG_PBMTE) : (proc->get_state()->menvcfg->read() & MENVCFG_PBMTE);
@@ -511,9 +500,7 @@ reg_t mmu_t::walk(reg_t addr, access_type type, reg_t mode, bool virt, bool hlvx
#ifdef RISCV_ENABLE_DIRTY
// set accessed and possibly dirty bits.
if ((pte & ad) != ad) {
- if (!pmp_ok(pte_paddr, vm.ptesize, STORE, PRV_S))
- throw_access_exception(virt, addr, type);
- *(target_endian<uint32_t>*)ppte |= to_target((uint32_t)ad);
+ pte_store(pte_paddr, pte | ad, addr, virt, type, vm.ptesize);
}
#else
// take exception if access or possibly dirty bit is not set.