aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAaron Durbin <adurbin@rivosinc.com>2023-01-27 10:34:49 -0800
committerAaron Durbin <adurbin@rivosinc.com>2023-01-27 10:37:20 -0800
commit8cabd4a29b183973078da0f7766b4d5f2005eeba (patch)
treeb481afa80c447710897b8e5fa3c369768686caee
parent7ccd0fd3002b297d8bda4b4cd1ec2a6b7987111c (diff)
downloadspike-8cabd4a29b183973078da0f7766b4d5f2005eeba.zip
spike-8cabd4a29b183973078da0f7766b4d5f2005eeba.tar.gz
spike-8cabd4a29b183973078da0f7766b4d5f2005eeba.tar.bz2
Use Svadu control bits to drive A/D updates
The Svadu (https://github.com/riscv/riscv-svadu) extension updates the A/D bits of PTEs: 1. In S/HS mode when menvcfg.hade=1 2. In G-stage page tables when menvcfg.hade=1 3. In VS mode when henvcfg.hade=1 To enable this behavior the 'svadu' ISA string is needed. This newly added behavior supplants the --mmu-dirty flag. However, that flag is not yet removed.
-rw-r--r--riscv/mmu.cc6
1 files changed, 4 insertions, 2 deletions
diff --git a/riscv/mmu.cc b/riscv/mmu.cc
index e5f8a1f..fc80dfa 100644
--- a/riscv/mmu.cc
+++ b/riscv/mmu.cc
@@ -388,6 +388,7 @@ reg_t mmu_t::s2xlate(reg_t gva, reg_t gpa, access_type type, access_type trap_ty
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;
+ bool hade = proc->get_state()->menvcfg->read() & MENVCFG_HADE;
if (pte & PTE_RSVD) {
break;
@@ -415,7 +416,7 @@ reg_t mmu_t::s2xlate(reg_t gva, reg_t gpa, access_type type, access_type trap_ty
reg_t ad = PTE_A | ((type == STORE) * PTE_D);
if ((pte & ad) != ad) {
- if (proc->cfg->dirty_enabled) {
+ if (hade) {
// set accessed and possibly dirty bits
pte_store(pte_paddr, pte | ad, gva, virt, type, vm.ptesize);
} else {
@@ -476,6 +477,7 @@ reg_t mmu_t::walk(reg_t addr, access_type type, reg_t mode, bool virt, bool hlvx
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);
+ bool hade = virt ? (proc->get_state()->henvcfg->read() & HENVCFG_HADE) : (proc->get_state()->menvcfg->read() & MENVCFG_HADE);
if (pte & PTE_RSVD) {
break;
@@ -503,7 +505,7 @@ reg_t mmu_t::walk(reg_t addr, access_type type, reg_t mode, bool virt, bool hlvx
reg_t ad = PTE_A | ((type == STORE) * PTE_D);
if ((pte & ad) != ad) {
- if (proc->cfg->dirty_enabled) {
+ if (hade) {
// set accessed and possibly dirty bits.
pte_store(pte_paddr, pte | ad, addr, virt, type, vm.ptesize);
} else {