diff options
author | Andrew Waterman <andrew@sifive.com> | 2019-10-16 16:24:11 -0700 |
---|---|---|
committer | Andrew Waterman <andrew@sifive.com> | 2019-10-16 16:24:45 -0700 |
commit | e10f44738b87a2b5249fccc58bb2e06d24ee1728 (patch) | |
tree | c5bc45b3b60dc10fab09a90f7df6cb3b21562bba | |
parent | bbe881f3c5435d02eeb7c28515bfb301470f2875 (diff) | |
download | spike-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.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()) |