diff options
-rw-r--r-- | riscv/insns/lr_d.h | 4 | ||||
-rw-r--r-- | riscv/insns/lr_w.h | 4 | ||||
-rw-r--r-- | riscv/mmu.cc | 6 | ||||
-rw-r--r-- | riscv/mmu.h | 17 |
4 files changed, 14 insertions, 17 deletions
diff --git a/riscv/insns/lr_d.h b/riscv/insns/lr_d.h index 6dd8d67..214daff 100644 --- a/riscv/insns/lr_d.h +++ b/riscv/insns/lr_d.h @@ -1,5 +1,3 @@ require_extension('A'); require_rv64; -auto res = MMU.load_int64(RS1, true); -MMU.acquire_load_reservation(RS1); -WRITE_RD(res); +WRITE_RD(MMU.load_reserved<int64_t>(RS1)); diff --git a/riscv/insns/lr_w.h b/riscv/insns/lr_w.h index 185be53..354590f 100644 --- a/riscv/insns/lr_w.h +++ b/riscv/insns/lr_w.h @@ -1,4 +1,2 @@ require_extension('A'); -auto res = MMU.load_int32(RS1, true); -MMU.acquire_load_reservation(RS1); -WRITE_RD(res); +WRITE_RD(MMU.load_reserved<int32_t>(RS1)); diff --git a/riscv/mmu.cc b/riscv/mmu.cc index de82a77..0c858ae 100644 --- a/riscv/mmu.cc +++ b/riscv/mmu.cc @@ -190,7 +190,11 @@ void mmu_t::load_slow_path_intrapage(reg_t addr, reg_t len, uint8_t* bytes, uint tracer.trace(paddr, len, LOAD); else if (xlate_flags == 0) refill_tlb(addr, paddr, host_addr, LOAD); - } else if (!mmio_load(paddr, len, bytes)) { + + if (xlate_flags & RISCV_XLATE_LR) { + load_reservation_address = paddr; + } + } else if ((xlate_flags & RISCV_XLATE_LR) || !mmio_load(paddr, len, bytes)) { throw trap_load_access_fault((proc) ? proc->state.v : false, addr, 0, 0); } } diff --git a/riscv/mmu.h b/riscv/mmu.h index 70a644d..bbe473b 100644 --- a/riscv/mmu.h +++ b/riscv/mmu.h @@ -49,8 +49,9 @@ public: mmu_t(simif_t* sim, processor_t* proc); ~mmu_t(); -#define RISCV_XLATE_VIRT (1U << 0) +#define RISCV_XLATE_VIRT (1U << 0) #define RISCV_XLATE_VIRT_HLVX (1U << 1) +#define RISCV_XLATE_LR (1U << 2) #ifndef RISCV_ENABLE_COMMITLOG # define READ_MEM(addr, size) ((void)(addr), (void)(size)) @@ -78,6 +79,11 @@ public: return from_target(res); } + template<typename T> + T load_reserved(reg_t addr) { + return load<T>(addr, true, RISCV_XLATE_LR); + } + // template for functions that load an aligned value from memory #define load_func(type, prefix, xlate_flags) \ type##_t ALWAYS_INLINE prefix##_##type(reg_t addr, bool require_alignment = false) { return load<type##_t>(addr, require_alignment, xlate_flags); } @@ -222,15 +228,6 @@ public: load_reservation_address = (reg_t)-1; } - inline void acquire_load_reservation(reg_t vaddr) - { - reg_t paddr = translate(vaddr, 1, LOAD, 0); - if (auto host_addr = sim->addr_to_mem(paddr)) - load_reservation_address = refill_tlb(vaddr, paddr, host_addr, LOAD).target_offset + vaddr; - else - throw trap_load_access_fault((proc) ? proc->state.v : false, vaddr, 0, 0); // disallow LR to I/O space - } - inline bool check_load_reservation(reg_t vaddr, size_t size) { if (vaddr & (size-1)) { |