Fix 2 trigger corner cases. (#229)
authorTim Newsome <tim@sifive.com>
Fri, 10 Aug 2018 21:55:28 +0000 (14:55 -0700)
committerAndrew Waterman <aswaterman@gmail.com>
Fri, 10 Aug 2018 21:55:28 +0000 (14:55 -0700)
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.

riscv/execute.cc
riscv/mmu.h

index b110d093d51a8950b376d37e137b3e9c4c48dfff..e639e90462cf9063404f5cfde99b712ad201b94f 100644 (file)
@@ -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)) {
index 715d8397338a10174878df55aff05531e623155b..f66eb00fd6d6fb0556d62532a47271f0ce1ffbb9 100644 (file)
@@ -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) {