aboutsummaryrefslogtreecommitdiff
path: root/riscv/mmu.cc
diff options
context:
space:
mode:
authorAndrew Waterman <waterman@cs.berkeley.edu>2013-07-26 20:25:18 -0700
committerAndrew Waterman <waterman@cs.berkeley.edu>2013-07-26 20:25:18 -0700
commit7a16302b4d8049d80bb56a0cd00cc226170c1ca7 (patch)
tree687db59f4bf0adf02d16875bc29c46d15db6f8ea /riscv/mmu.cc
parentb357c97b249cdb13cc08f0893d73994662b5be8d (diff)
downloadspike-7a16302b4d8049d80bb56a0cd00cc226170c1ca7.zip
spike-7a16302b4d8049d80bb56a0cd00cc226170c1ca7.tar.gz
spike-7a16302b4d8049d80bb56a0cd00cc226170c1ca7.tar.bz2
New supervisor mode
Diffstat (limited to 'riscv/mmu.cc')
-rw-r--r--riscv/mmu.cc26
1 files changed, 13 insertions, 13 deletions
diff --git a/riscv/mmu.cc b/riscv/mmu.cc
index 8b63a43..01cbb97 100644
--- a/riscv/mmu.cc
+++ b/riscv/mmu.cc
@@ -40,9 +40,9 @@ reg_t mmu_t::refill_tlb(reg_t addr, reg_t bytes, bool store, bool fetch)
reg_t pte_perm = pte & PTE_PERM;
if (proc == NULL || (proc->sr & SR_S))
pte_perm = (pte_perm/(PTE_SX/PTE_UX)) & PTE_PERM;
- pte_perm |= pte & PTE_E;
+ pte_perm |= pte & PTE_V;
- reg_t perm = (fetch ? PTE_UX : store ? PTE_UW : PTE_UR) | PTE_E;
+ reg_t perm = (fetch ? PTE_UX : store ? PTE_UW : PTE_UR) | PTE_V;
if(unlikely((pte_perm & perm) != perm))
{
if (fetch)
@@ -53,7 +53,7 @@ reg_t mmu_t::refill_tlb(reg_t addr, reg_t bytes, bool store, bool fetch)
}
reg_t pgoff = addr & (PGSIZE-1);
- reg_t pgbase = pte >> PTE_PPN_SHIFT << PGSHIFT;
+ reg_t pgbase = pte >> PGSHIFT << PGSHIFT;
reg_t paddr = pgbase + pgoff;
if (unlikely(tracer.interested_in_range(pgbase, pgbase + PGSIZE, store, fetch)))
@@ -80,7 +80,7 @@ pte_t mmu_t::walk(reg_t addr)
else if (proc == NULL || !(proc->sr & SR_VM))
{
if(addr < memsz)
- pte = PTE_E | PTE_PERM | ((addr >> PGSHIFT) << PTE_PPN_SHIFT);
+ pte = PTE_V | PTE_PERM | ((addr >> PGSHIFT) << PGSHIFT);
}
else
{
@@ -97,23 +97,23 @@ pte_t mmu_t::walk(reg_t addr)
break;
ptd = *(pte_t*)(mem+pte_addr);
- if(ptd & PTE_E)
+
+ if (!(ptd & PTE_V)) // invalid mapping
+ break;
+ else if (ptd & PTE_T) // next level of page table
+ base = (ptd >> PGSHIFT) << PGSHIFT;
+ else // the actual PTE
{
// if this PTE is from a larger PT, fake a leaf
// PTE so the TLB will work right
reg_t vpn = addr >> PGSHIFT;
- ptd |= (vpn & ((1<<(ptshift))-1)) << PTE_PPN_SHIFT;
+ ptd |= (vpn & ((1<<(ptshift))-1)) << PGSHIFT;
- // fault if physical addr is invalid
- reg_t ppn = ptd >> PTE_PPN_SHIFT;
- if((ppn << PGSHIFT) + (addr & (PGSIZE-1)) < memsz)
+ // fault if physical addr is out of range
+ if (((ptd >> PGSHIFT) << PGSHIFT) < memsz)
pte = ptd;
break;
}
- else if(!(ptd & PTE_T))
- break;
-
- base = (ptd >> PTE_PPN_SHIFT) << PGSHIFT;
}
}