aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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())