require_extension('A');
require_rv64;
-p->get_state()->load_reservation = RS1;
+MMU.acquire_load_reservation(RS1);
WRITE_RD(MMU.load_int64(RS1));
require_extension('A');
-p->get_state()->load_reservation = RS1;
+MMU.acquire_load_reservation(RS1);
WRITE_RD(MMU.load_int32(RS1));
require_extension('A');
require_rv64;
-if (RS1 == p->get_state()->load_reservation)
+if (MMU.check_load_reservation(RS1))
{
MMU.store_uint64(RS1, RS2);
WRITE_RD(0);
}
else
WRITE_RD(1);
+
+MMU.yield_load_reservation();
require_extension('A');
-if (RS1 == p->get_state()->load_reservation)
+if (MMU.check_load_reservation(RS1))
{
MMU.store_uint32(RS1, RS2);
WRITE_RD(0);
}
else
WRITE_RD(1);
+
+MMU.yield_load_reservation();
matched_trigger(NULL)
{
flush_tlb();
+ yield_load_reservation();
}
mmu_t::~mmu_t()
amo_func(uint32)
amo_func(uint64)
+ inline void yield_load_reservation()
+ {
+ load_reservation_address = (reg_t)-1;
+ }
+
+ inline void acquire_load_reservation(reg_t vaddr)
+ {
+ reg_t paddr = translate(vaddr, LOAD);
+ 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(vaddr); // disallow LR to I/O space
+ }
+
+ inline bool check_load_reservation(reg_t vaddr)
+ {
+ reg_t paddr = translate(vaddr, STORE);
+ if (auto host_addr = sim->addr_to_mem(paddr))
+ return load_reservation_address == refill_tlb(vaddr, paddr, host_addr, STORE).target_offset + vaddr;
+ else
+ throw trap_store_access_fault(vaddr); // disallow SC to I/O space
+ }
+
static const reg_t ICACHE_ENTRIES = 1024;
inline size_t icache_index(reg_t addr)
simif_t* sim;
processor_t* proc;
memtracer_list_t tracer;
+ reg_t load_reservation_address;
uint16_t fetch_temp;
// implement an instruction cache for simulator performance
misa = max_isa;
prv = PRV_M;
pc = DEFAULT_RSTVEC;
- load_reservation = -1;
tselect = 0;
for (unsigned int i = 0; i < num_triggers; i++)
mcontrol[i].type = 2;
set_csr(CSR_MSTATUS, s);
set_privilege(PRV_M);
}
-
- yield_load_reservation();
}
void processor_t::disasm(insn_t insn)
STEP_STEPPED
} single_step;
- reg_t load_reservation;
-
#ifdef RISCV_ENABLE_COMMITLOG
commit_log_reg_t log_reg_write;
reg_t last_inst_priv;
}
reg_t legalize_privilege(reg_t);
void set_privilege(reg_t);
- void yield_load_reservation() { state.load_reservation = (reg_t)-1; }
void update_histogram(reg_t pc);
const disassembler_t* get_disassembler() { return disassembler; }
if (current_step == INTERLEAVE)
{
current_step = 0;
- procs[current_proc]->yield_load_reservation();
+ procs[current_proc]->get_mmu()->yield_load_reservation();
if (++current_proc == procs.size()) {
current_proc = 0;
clint->increment(INTERLEAVE / INSNS_PER_RTC_TICK);