diff --git a/riscv/mmu.cc b/riscv/mmu.cc index d04e3e25..ce3e5ca2 100644 --- a/riscv/mmu.cc +++ b/riscv/mmu.cc @@ -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 8789c8cc..723b08e9 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 diff --git a/riscv/simif.h b/riscv/simif.h index 2c5bb27f..c756b9cd 100644 --- a/riscv/simif.h +++ b/riscv/simif.h @@ -11,6 +11,7 @@ class simif_t public: // should return NULL for MMIO addresses 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 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;