diff options
-rw-r--r-- | riscv/mmu.cc | 35 | ||||
-rw-r--r-- | riscv/mmu.h | 14 | ||||
-rw-r--r-- | riscv/sim.cc | 26 | ||||
-rw-r--r-- | riscv/sim.h | 8 | ||||
-rw-r--r-- | riscv/simif.h | 11 |
5 files changed, 50 insertions, 44 deletions
diff --git a/riscv/mmu.cc b/riscv/mmu.cc index ddf277b..ce3e5ca 100644 --- a/riscv/mmu.cc +++ b/riscv/mmu.cc @@ -128,37 +128,37 @@ reg_t reg_from_bytes(size_t len, const uint8_t* bytes) abort(); } -bool mmu_t::mmio_ok(reg_t addr, access_type UNUSED type) +bool mmu_t::mmio_ok(reg_t paddr, access_type UNUSED type) { // Disallow access to debug region when not in debug mode - if (addr >= DEBUG_START && addr <= DEBUG_END && proc && !proc->state.debug_mode) + if (paddr >= DEBUG_START && paddr <= DEBUG_END && proc && !proc->state.debug_mode) return false; return true; } -bool mmu_t::mmio_fetch(reg_t addr, size_t len, uint8_t* bytes) +bool mmu_t::mmio_fetch(reg_t paddr, size_t len, uint8_t* bytes) { - if (!mmio_ok(addr, FETCH)) + if (!mmio_ok(paddr, FETCH)) return false; - return sim->mmio_fetch(addr, len, bytes); + return sim->mmio_fetch(paddr, len, bytes); } -bool mmu_t::mmio_load(reg_t addr, size_t len, uint8_t* bytes) +bool mmu_t::mmio_load(reg_t paddr, size_t len, uint8_t* bytes) { - if (!mmio_ok(addr, LOAD)) + if (!mmio_ok(paddr, LOAD)) return false; - return sim->mmio_load(addr, len, bytes); + return sim->mmio_load(paddr, len, bytes); } -bool mmu_t::mmio_store(reg_t addr, size_t len, const uint8_t* bytes) +bool mmu_t::mmio_store(reg_t paddr, size_t len, const uint8_t* bytes) { - if (!mmio_ok(addr, STORE)) + if (!mmio_ok(paddr, STORE)) return false; - return sim->mmio_store(addr, len, bytes); + return sim->mmio_store(paddr, len, bytes); } void mmu_t::check_triggers(triggers::operation_t operation, reg_t address, std::optional<reg_t> data) @@ -192,6 +192,10 @@ void mmu_t::load_slow_path_intrapage(reg_t addr, reg_t len, uint8_t* bytes, uint reg_t paddr = translate(addr, len, LOAD, xlate_flags); + if ((xlate_flags & RISCV_XLATE_LR) && !sim->reservable(paddr)) { + throw trap_load_access_fault((proc) ? proc->state.v : false, addr, 0, 0); + } + if (auto host_addr = sim->addr_to_mem(paddr)) { memcpy(bytes, host_addr, len); if (tracer.interested_in_range(paddr, paddr + PGSIZE, LOAD)) @@ -199,12 +203,13 @@ void mmu_t::load_slow_path_intrapage(reg_t addr, reg_t len, uint8_t* bytes, uint else if (xlate_flags == 0) refill_tlb(addr, paddr, host_addr, LOAD); - if (xlate_flags & RISCV_XLATE_LR) { - load_reservation_address = paddr; - } - } else if ((xlate_flags & RISCV_XLATE_LR) || !mmio_load(paddr, len, bytes)) { + } else if (!mmio_load(paddr, len, bytes)) { throw trap_load_access_fault((proc) ? proc->state.v : false, addr, 0, 0); } + + if (xlate_flags & RISCV_XLATE_LR) { + load_reservation_address = paddr; + } } void mmu_t::load_slow_path(reg_t addr, reg_t len, uint8_t* bytes, uint32_t xlate_flags) diff --git a/riscv/mmu.h b/riscv/mmu.h index cc00010..723b08e 100644 --- a/riscv/mmu.h +++ b/riscv/mmu.h @@ -163,7 +163,7 @@ public: void clean_inval(reg_t addr, bool clean, bool inval) { convert_load_traps_to_store_traps({ const reg_t paddr = translate(addr, blocksz, LOAD, 0) & ~(blocksz - 1); - if (sim->addr_to_mem(paddr)) { + if (sim->reservable(paddr)) { if (tracer.interested_in_range(paddr, paddr + PGSIZE, LOAD)) tracer.clean_invalidate(paddr, blocksz, clean, inval); } else { @@ -185,10 +185,10 @@ public: } reg_t paddr = translate(vaddr, 1, STORE, 0); - if (sim->addr_to_mem(paddr)) + if (sim->reservable(paddr)) return load_reservation_address == paddr; else - throw trap_store_access_fault((proc) ? proc->state.v : false, vaddr, 0, 0); // disallow SC to I/O space + throw trap_store_access_fault((proc) ? proc->state.v : false, vaddr, 0, 0); } template<typename T> @@ -347,10 +347,10 @@ private: void load_slow_path_intrapage(reg_t addr, reg_t len, uint8_t* bytes, uint32_t xlate_flags); void store_slow_path(reg_t addr, reg_t len, const uint8_t* bytes, uint32_t xlate_flags, bool actually_store, bool require_alignment); void store_slow_path_intrapage(reg_t addr, reg_t len, const uint8_t* bytes, uint32_t xlate_flags, bool actually_store); - bool mmio_fetch(reg_t addr, size_t len, uint8_t* bytes); - bool mmio_load(reg_t addr, size_t len, uint8_t* bytes); - bool mmio_store(reg_t addr, size_t len, const uint8_t* bytes); - bool mmio_ok(reg_t addr, access_type type); + bool mmio_fetch(reg_t paddr, size_t len, uint8_t* bytes); + bool mmio_load(reg_t paddr, size_t len, uint8_t* bytes); + bool mmio_store(reg_t paddr, size_t len, const uint8_t* bytes); + bool mmio_ok(reg_t paddr, access_type type); void check_triggers(triggers::operation_t operation, reg_t address, std::optional<reg_t> data = std::nullopt); reg_t translate(reg_t addr, reg_t len, access_type type, uint32_t xlate_flags); diff --git a/riscv/sim.cc b/riscv/sim.cc index 361008b..84ff98c 100644 --- a/riscv/sim.cc +++ b/riscv/sim.cc @@ -309,18 +309,18 @@ 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) +bool sim_t::mmio_load(reg_t paddr, size_t len, uint8_t* bytes) { - if (addr + len < addr || !paddr_ok(addr + len - 1)) + if (paddr + len < paddr || !paddr_ok(paddr + len - 1)) return false; - return bus.load(addr, len, bytes); + return bus.load(paddr, len, bytes); } -bool sim_t::mmio_store(reg_t addr, size_t len, const uint8_t* bytes) +bool sim_t::mmio_store(reg_t paddr, size_t len, const uint8_t* bytes) { - if (addr + len < addr || !paddr_ok(addr + len - 1)) + if (paddr + len < paddr || !paddr_ok(paddr + len - 1)) return false; - return bus.store(addr, len, bytes); + return bus.store(paddr, len, bytes); } void sim_t::make_dtb() @@ -402,19 +402,19 @@ void sim_t::set_rom() bus.add_device(DEFAULT_RSTVEC, boot_rom.get()); } -char* sim_t::addr_to_mem(reg_t addr) { - if (!paddr_ok(addr)) +char* sim_t::addr_to_mem(reg_t paddr) { + if (!paddr_ok(paddr)) return NULL; - auto desc = bus.find_device(addr); + auto desc = bus.find_device(paddr); if (auto mem = dynamic_cast<mem_t*>(desc.second)) - if (addr - desc.first < mem->size()) - return mem->contents(addr - desc.first); + if (paddr - desc.first < mem->size()) + return mem->contents(paddr - desc.first); return NULL; } -const char* sim_t::get_symbol(uint64_t addr) +const char* sim_t::get_symbol(uint64_t paddr) { - return htif_t::get_symbol(addr); + return htif_t::get_symbol(paddr); } // htif diff --git a/riscv/sim.h b/riscv/sim.h index 2c348b3..21b1616 100644 --- a/riscv/sim.h +++ b/riscv/sim.h @@ -94,13 +94,13 @@ private: remote_bitbang_t* remote_bitbang; // memory-mapped I/O routines - char* addr_to_mem(reg_t addr); - bool mmio_load(reg_t addr, size_t len, uint8_t* bytes); - bool mmio_store(reg_t addr, size_t len, const uint8_t* bytes); + char* addr_to_mem(reg_t paddr); + bool mmio_load(reg_t paddr, size_t len, uint8_t* bytes); + bool mmio_store(reg_t paddr, size_t len, const uint8_t* bytes); void make_dtb(); void set_rom(); - const char* get_symbol(uint64_t addr); + const char* get_symbol(uint64_t paddr); // presents a prompt for introspection into the simulation void interactive(); diff --git a/riscv/simif.h b/riscv/simif.h index 61815e5..c756b9c 100644 --- a/riscv/simif.h +++ b/riscv/simif.h @@ -10,15 +10,16 @@ class simif_t { public: // should return NULL for MMIO addresses - virtual char* addr_to_mem(reg_t addr) = 0; + virtual char* addr_to_mem(reg_t paddr) = 0; + virtual bool reservable(reg_t paddr) { return addr_to_mem(paddr); } // used for MMIO addresses - virtual bool mmio_fetch(reg_t addr, size_t len, uint8_t* bytes) { return mmio_load(addr, len, bytes); }; - virtual bool mmio_load(reg_t addr, size_t len, uint8_t* bytes) = 0; - virtual bool mmio_store(reg_t addr, size_t len, const uint8_t* bytes) = 0; + virtual bool mmio_fetch(reg_t paddr, size_t len, uint8_t* bytes) { return mmio_load(paddr, len, bytes); } + virtual bool mmio_load(reg_t paddr, size_t len, uint8_t* bytes) = 0; + virtual bool mmio_store(reg_t paddr, size_t len, const uint8_t* bytes) = 0; // Callback for processors to let the simulation know they were reset. virtual void proc_reset(unsigned id) = 0; - virtual const char* get_symbol(uint64_t addr) = 0; + virtual const char* get_symbol(uint64_t paddr) = 0; virtual ~simif_t() = default; |