aboutsummaryrefslogtreecommitdiff
path: root/riscv/mmu.cc
diff options
context:
space:
mode:
authorRyan Buchner <ryan.buchner@arilinc.com>2022-05-07 22:33:16 -0700
committerRyan Buchner <ryan.buchner@arilinc.com>2022-05-11 10:33:22 -0700
commit996634f0be06099401eec5165428b3ecc4a72fb6 (patch)
tree8d7e86580b7d05173dde056a5f058be4232c7137 /riscv/mmu.cc
parentea70a9359daf5780b815b68aa9cdc7b2a71d2f8c (diff)
downloadspike-996634f0be06099401eec5165428b3ecc4a72fb6.zip
spike-996634f0be06099401eec5165428b3ecc4a72fb6.tar.gz
spike-996634f0be06099401eec5165428b3ecc4a72fb6.tar.bz2
Switch from checking for SVPBMT extension to checking *ENVCFG values during tablewalks
Fix issue #990.
Diffstat (limited to 'riscv/mmu.cc')
-rw-r--r--riscv/mmu.cc6
1 files changed, 4 insertions, 2 deletions
diff --git a/riscv/mmu.cc b/riscv/mmu.cc
index 2918f0b..3868c70 100644
--- a/riscv/mmu.cc
+++ b/riscv/mmu.cc
@@ -294,12 +294,13 @@ reg_t mmu_t::s2xlate(reg_t gva, reg_t gpa, access_type type, access_type trap_ty
reg_t pte = vm.ptesize == 4 ? from_target(*(target_endian<uint32_t>*)ppte) : from_target(*(target_endian<uint64_t>*)ppte);
reg_t ppn = (pte & ~reg_t(PTE_ATTR)) >> PTE_PPN_SHIFT;
+ bool pbmte = proc->get_state()->menvcfg->read() & MENVCFG_PBMTE;
if (pte & PTE_RSVD) {
break;
} else if (!proc->extension_enabled(EXT_SVNAPOT) && (pte & PTE_N)) {
break;
- } else if (!proc->extension_enabled(EXT_SVPBMT) && (pte & PTE_PBMT)) {
+ } else if (!pbmte && (pte & PTE_PBMT)) {
break;
} else if (PTE_TABLE(pte)) { // next level of page table
if (pte & (PTE_D | PTE_A | PTE_U | PTE_N | PTE_PBMT))
@@ -384,12 +385,13 @@ reg_t mmu_t::walk(reg_t addr, access_type type, reg_t mode, bool virt, bool hlvx
reg_t pte = vm.ptesize == 4 ? from_target(*(target_endian<uint32_t>*)ppte) : from_target(*(target_endian<uint64_t>*)ppte);
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);
if (pte & PTE_RSVD) {
break;
} else if (!proc->extension_enabled(EXT_SVNAPOT) && (pte & PTE_N)) {
break;
- } else if (!proc->extension_enabled(EXT_SVPBMT) && (pte & PTE_PBMT)) {
+ } else if (!pbmte && (pte & PTE_PBMT)) {
break;
} else if (PTE_TABLE(pte)) { // next level of page table
if (pte & (PTE_D | PTE_A | PTE_U | PTE_N | PTE_PBMT))