aboutsummaryrefslogtreecommitdiff
path: root/riscv
diff options
context:
space:
mode:
authorAndrew Waterman <waterman@eecs.berkeley.edu>2012-01-24 00:08:05 -0800
committerAndrew Waterman <waterman@eecs.berkeley.edu>2012-01-24 00:08:05 -0800
commit63bf7dd26ed86a95d0c1080847d8d629a931560a (patch)
tree98dc38d3a58d1aad4db505d1060b8ad9517373c2 /riscv
parented71703766a59469c137d3061321cd9d0f31f4eb (diff)
downloadspike-63bf7dd26ed86a95d0c1080847d8d629a931560a.zip
spike-63bf7dd26ed86a95d0c1080847d8d629a931560a.tar.gz
spike-63bf7dd26ed86a95d0c1080847d8d629a931560a.tar.bz2
check that virtual addresses are sign-extended
Diffstat (limited to 'riscv')
-rw-r--r--riscv/mmu.cc6
-rw-r--r--riscv/mmu.h2
2 files changed, 7 insertions, 1 deletions
diff --git a/riscv/mmu.cc b/riscv/mmu.cc
index 489aeee..aa62b90 100644
--- a/riscv/mmu.cc
+++ b/riscv/mmu.cc
@@ -60,7 +60,11 @@ pte_t mmu_t::walk(reg_t addr)
{
pte_t pte = 0;
- if(!vm_enabled)
+ // the address must be a canonical sign-extended VA_BITS-bit number
+ int shift = 8*sizeof(reg_t) - VA_BITS;
+ if (((sreg_t)addr << shift >> shift) != addr)
+ ;
+ else if(!vm_enabled)
{
if(addr < memsz)
pte = PTE_E | PTE_PERM | ((addr >> PGSHIFT) << PTE_PPN_SHIFT);
diff --git a/riscv/mmu.h b/riscv/mmu.h
index 0c61a77..f6ca972 100644
--- a/riscv/mmu.h
+++ b/riscv/mmu.h
@@ -15,7 +15,9 @@ const reg_t LEVELS = sizeof(pte_t) == sizeof(uint64_t) ? 3 : 2;
const reg_t PGSHIFT = 13;
const reg_t PGSIZE = 1 << PGSHIFT;
const reg_t PTIDXBITS = PGSHIFT - (sizeof(pte_t) == 8 ? 3 : 2);
+const reg_t VPN_BITS = PTIDXBITS * LEVELS;
const reg_t PPN_BITS = 8*sizeof(reg_t) - PGSHIFT;
+const reg_t VA_BITS = VPN_BITS + PGSHIFT;
// page table entry (PTE) fields
#define PTE_T 0x001 // Entry is a page Table descriptor