diff options
author | Ryan Buchner <ryan.buchner@arilinc.com> | 2022-05-07 22:33:16 -0700 |
---|---|---|
committer | Ryan Buchner <ryan.buchner@arilinc.com> | 2022-05-11 10:33:22 -0700 |
commit | 996634f0be06099401eec5165428b3ecc4a72fb6 (patch) | |
tree | 8d7e86580b7d05173dde056a5f058be4232c7137 /riscv/mmu.cc | |
parent | ea70a9359daf5780b815b68aa9cdc7b2a71d2f8c (diff) | |
download | spike-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.cc | 6 |
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)) |