diff options
-rw-r--r-- | riscv/mmu.h | 1 | ||||
-rw-r--r-- | riscv/sim.cc | 11 |
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()) |