diff options
author | Tim Newsome <tim@sifive.com> | 2018-08-10 14:55:28 -0700 |
---|---|---|
committer | Andrew Waterman <aswaterman@gmail.com> | 2018-08-10 14:55:28 -0700 |
commit | bed0a54fdaedf09a4c6523a2a116b59d021fb12b (patch) | |
tree | 979e52e17acb6deef8bf2c5d17580f6b60141c3e | |
parent | 1ff2a70ec87c0a418ca38cdff9b14fc29e4b1ecb (diff) | |
download | riscv-isa-sim-bed0a54fdaedf09a4c6523a2a116b59d021fb12b.zip riscv-isa-sim-bed0a54fdaedf09a4c6523a2a116b59d021fb12b.tar.gz riscv-isa-sim-bed0a54fdaedf09a4c6523a2a116b59d021fb12b.tar.bz2 |
Fix 2 trigger corner cases. (#229)
1. When hitting a trigger during a single step, dcsr.cause must reflect
the trigger not the step.
2. Also check for triggers on accesses that require a slow path fetch.
-rw-r--r-- | riscv/execute.cc | 8 | ||||
-rw-r--r-- | riscv/mmu.h | 12 |
2 files changed, 14 insertions, 6 deletions
diff --git a/riscv/execute.cc b/riscv/execute.cc index b110d09..e639e90 100644 --- a/riscv/execute.cc +++ b/riscv/execute.cc @@ -130,9 +130,11 @@ void processor_t::step(size_t n) { if (unlikely(!state.serialized && state.single_step == state.STEP_STEPPED)) { state.single_step = state.STEP_NONE; - enter_debug_mode(DCSR_CAUSE_STEP); - // enter_debug_mode changed state.pc, so we can't just continue. - break; + if (state.dcsr.cause == DCSR_CAUSE_NONE) { + enter_debug_mode(DCSR_CAUSE_STEP); + // enter_debug_mode changed state.pc, so we can't just continue. + break; + } } if (unlikely(state.single_step == state.STEP_STEPPING)) { diff --git a/riscv/mmu.h b/riscv/mmu.h index 715d839..f66eb00 100644 --- a/riscv/mmu.h +++ b/riscv/mmu.h @@ -318,14 +318,20 @@ private: reg_t vpn = addr >> PGSHIFT; if (likely(tlb_insn_tag[vpn % TLB_ENTRIES] == vpn)) return tlb_data[vpn % TLB_ENTRIES]; + tlb_entry_t result; + if (unlikely(tlb_insn_tag[vpn % TLB_ENTRIES] != (vpn | TLB_CHECK_TRIGGERS))) { + result = fetch_slow_path(addr); + } else { + result = tlb_data[vpn % TLB_ENTRIES]; + } if (unlikely(tlb_insn_tag[vpn % TLB_ENTRIES] == (vpn | TLB_CHECK_TRIGGERS))) { uint16_t* ptr = (uint16_t*)(tlb_data[vpn % TLB_ENTRIES].host_offset + addr); int match = proc->trigger_match(OPERATION_EXECUTE, addr, *ptr); - if (match >= 0) + if (match >= 0) { throw trigger_matched_t(match, OPERATION_EXECUTE, addr, *ptr); - return tlb_data[vpn % TLB_ENTRIES]; + } } - return fetch_slow_path(addr); + return result; } inline const uint16_t* translate_insn_addr_to_host(reg_t addr) { |