aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTim Newsome <tim@sifive.com>2018-08-10 14:55:28 -0700
committerAndrew Waterman <aswaterman@gmail.com>2018-08-10 14:55:28 -0700
commitbed0a54fdaedf09a4c6523a2a116b59d021fb12b (patch)
tree979e52e17acb6deef8bf2c5d17580f6b60141c3e
parent1ff2a70ec87c0a418ca38cdff9b14fc29e4b1ecb (diff)
downloadriscv-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.cc8
-rw-r--r--riscv/mmu.h12
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) {