aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Waterman <andrew@sifive.com>2019-10-16 16:24:11 -0700
committerAndrew Waterman <andrew@sifive.com>2019-10-16 16:24:45 -0700
commite10f44738b87a2b5249fccc58bb2e06d24ee1728 (patch)
treec5bc45b3b60dc10fab09a90f7df6cb3b21562bba
parentbbe881f3c5435d02eeb7c28515bfb301470f2875 (diff)
downloadspike-e10f44738b87a2b5249fccc58bb2e06d24ee1728.zip
spike-e10f44738b87a2b5249fccc58bb2e06d24ee1728.tar.gz
spike-e10f44738b87a2b5249fccc58bb2e06d24ee1728.tar.bz2
Enforce 2^56-bit physical address limit
It's very difficult to encounter this (need to manually place a device or memory at very high addresses), but it is technically a Spike bug.
-rw-r--r--riscv/mmu.h1
-rw-r--r--riscv/sim.cc11
2 files changed, 10 insertions, 2 deletions
diff --git a/riscv/mmu.h b/riscv/mmu.h
index 9826cf1..c7e047a 100644
--- a/riscv/mmu.h
+++ b/riscv/mmu.h
@@ -17,6 +17,7 @@
#define PGSHIFT 12
const reg_t PGSIZE = 1 << PGSHIFT;
const reg_t PGMASK = ~(PGSIZE-1);
+#define MAX_PADDR_BITS 56 // imposed by Sv39 / Sv48
struct insn_fetch_t
{
diff --git a/riscv/sim.cc b/riscv/sim.cc
index dce17dd..cffc037 100644
--- a/riscv/sim.cc
+++ b/riscv/sim.cc
@@ -157,16 +157,21 @@ void sim_t::set_procs_debug(bool value)
procs[i]->set_debug(value);
}
+static bool paddr_ok(reg_t addr)
+{
+ return (addr >> MAX_PADDR_BITS) == 0;
+}
+
bool sim_t::mmio_load(reg_t addr, size_t len, uint8_t* bytes)
{
- if (addr + len < addr)
+ if (addr + len < addr || !paddr_ok(addr + len - 1))
return false;
return bus.load(addr, len, bytes);
}
bool sim_t::mmio_store(reg_t addr, size_t len, const uint8_t* bytes)
{
- if (addr + len < addr)
+ if (addr + len < addr || !paddr_ok(addr + len - 1))
return false;
return bus.store(addr, len, bytes);
}
@@ -204,6 +209,8 @@ void sim_t::make_dtb()
}
char* sim_t::addr_to_mem(reg_t addr) {
+ if (!paddr_ok(addr))
+ return NULL;
auto desc = bus.find_device(addr);
if (auto mem = dynamic_cast<mem_t*>(desc.second))
if (addr - desc.first < mem->size())