aboutsummaryrefslogtreecommitdiff
path: root/riscv/mmu.cc
diff options
context:
space:
mode:
authorAndrew Waterman <waterman@cs.berkeley.edu>2015-04-03 21:53:22 -0700
committerAndrew Waterman <waterman@cs.berkeley.edu>2015-04-03 21:53:22 -0700
commitc4350ef6ef6259e48509e125fd2d051969dc6efa (patch)
tree7f6b0900717eea640d687fc677d2cd39c97a9dd2 /riscv/mmu.cc
parentd9d73d80c1b738b3b30eb40d192f61cbdb0e201f (diff)
downloadspike-c4350ef6ef6259e48509e125fd2d051969dc6efa.zip
spike-c4350ef6ef6259e48509e125fd2d051969dc6efa.tar.gz
spike-c4350ef6ef6259e48509e125fd2d051969dc6efa.tar.bz2
Support setting ISA/subsets with --isa flag
Default is RV64IMAFDC. Can do things like --isa=RV32 (which implies IMAFDC) --isa=IM (which implies RV64) --isa=RV64IMAFDXhwacha
Diffstat (limited to 'riscv/mmu.cc')
-rw-r--r--riscv/mmu.cc23
1 files changed, 15 insertions, 8 deletions
diff --git a/riscv/mmu.cc b/riscv/mmu.cc
index 2519f84..e6bbbd4 100644
--- a/riscv/mmu.cc
+++ b/riscv/mmu.cc
@@ -4,6 +4,12 @@
#include "sim.h"
#include "processor.h"
+#define LEVELS(xlen) ((xlen) == 32 ? 2 : 3)
+#define PPN_SHIFT(xlen) ((xlen) == 32 ? 10 : 26)
+#define PTIDXBITS(xlen) ((xlen) == 32 ? 10 : 9)
+#define VPN_BITS(xlen) (PTIDXBITS(xlen) * LEVELS(xlen))
+#define VA_BITS(xlen) (VPN_BITS(xlen) + PGSHIFT)
+
mmu_t::mmu_t(char* _mem, size_t _memsz)
: mem(_mem), memsz(_memsz), proc(NULL)
{
@@ -79,25 +85,26 @@ void* mmu_t::refill_tlb(reg_t addr, reg_t bytes, bool store, bool fetch)
return mem + paddr;
}
-pte_t mmu_t::walk(reg_t addr, bool supervisor, bool store, bool fetch)
+reg_t mmu_t::walk(reg_t addr, bool supervisor, bool store, bool fetch)
{
- reg_t msb_mask = -(reg_t(1) << (VA_BITS-1));
+ reg_t msb_mask = -(reg_t(1) << (VA_BITS(proc->xlen) - 1));
if ((addr & msb_mask) != 0 && (addr & msb_mask) != msb_mask)
return -1; // address isn't properly sign-extended
reg_t base = proc->get_state()->sptbr;
- int ptshift = (LEVELS-1)*PTIDXBITS;
- for (reg_t i = 0; i < LEVELS; i++, ptshift -= PTIDXBITS) {
- reg_t idx = (addr >> (PGSHIFT+ptshift)) & ((1<<PTIDXBITS)-1);
+ int xlen = proc->max_xlen;
+ int ptshift = (LEVELS(xlen) - 1) * PTIDXBITS(xlen);
+ for (reg_t i = 0; i < LEVELS(xlen); i++, ptshift -= PTIDXBITS(xlen)) {
+ reg_t idx = (addr >> (PGSHIFT+ptshift)) & ((1<<PTIDXBITS(xlen))-1);
// check that physical address of PTE is legal
- reg_t pte_addr = base + idx*sizeof(pte_t);
+ reg_t pte_addr = base + idx*sizeof(reg_t);
if (pte_addr >= memsz)
return -1;
- pte_t* ppte = (pte_t*)(mem+pte_addr);
- reg_t ppn = *ppte >> PTE_PPN_SHIFT;
+ reg_t* ppte = (reg_t*)(mem+pte_addr);
+ reg_t ppn = *ppte >> PPN_SHIFT(xlen);
if ((*ppte & PTE_TYPE) == PTE_TYPE_TABLE) { // next level of page table
base = ppn << PGSHIFT;