partially update spike to newer debug spec
authorAndrew Waterman <waterman@cs.berkeley.edu>
Fri, 26 Aug 2016 04:27:10 +0000 (21:27 -0700)
committerAndrew Waterman <waterman@cs.berkeley.edu>
Fri, 26 Aug 2016 04:27:10 +0000 (21:27 -0700)
riscv/encoding.h
riscv/execute.cc
riscv/gdbserver.cc
riscv/processor.cc
riscv/processor.h

index e00972eb6d1a29ca664e67b8406fe74a81ad588d..2a66e51a0f3a595229217136f95c7309633c9ecc 100644 (file)
@@ -37,7 +37,6 @@
 #define DCSR_XDEBUGVER      (3U<<30)
 #define DCSR_NDRESET        (1<<29)
 #define DCSR_FULLRESET      (1<<28)
-#define DCSR_HWBPCOUNT      (0xfff<<16)
 #define DCSR_EBREAKM        (1<<15)
 #define DCSR_EBREAKH        (1<<14)
 #define DCSR_EBREAKS        (1<<13)
 #define DCSR_CAUSE_STEP     4
 #define DCSR_CAUSE_HALT     5
 
+#define MCONTROL_TYPE(xlen)    (0xfULL<<((xlen)-4))
+#define MCONTROL_DMODE(xlen)   (1ULL<<((xlen)-5))
+#define MCONTROL_MASKMAX(xlen) (0x3fULL<<((xlen)-11))
+
 #define MCONTROL_SELECT     (1<<19)
-#define MCONTROL_ACTION     (0x7f<<12)
+#define MCONTROL_TIMING     (1<<18)
+#define MCONTROL_ACTION     (0x3f<<12)
 #define MCONTROL_CHAIN      (1<<11)
 #define MCONTROL_MATCH      (0xf<<7)
 #define MCONTROL_M          (1<<6)
 #define MCONTROL_STORE      (1<<1)
 #define MCONTROL_LOAD       (1<<0)
 
-#define MCONTROL_ACTION_NONE           0
-#define MCONTROL_ACTION_DEBUG_EXCEPTION        1
-#define MCONTROL_ACTION_DEBUG_MODE     2
-#define MCONTROL_ACTION_TRACE_START    3
-#define MCONTROL_ACTION_TRACE_STOP     4
-#define MCONTROL_ACTION_TRACE_EMIT     5
+#define MCONTROL_ACTION_DEBUG_EXCEPTION   0
+#define MCONTROL_ACTION_DEBUG_MODE        1
+#define MCONTROL_ACTION_TRACE_START       2
+#define MCONTROL_ACTION_TRACE_STOP        3
+#define MCONTROL_ACTION_TRACE_EMIT        4
 
-#define MCONTROL_MATCH_EQUAL           0
-#define MCONTROL_MATCH_NAPOT           1
-#define MCONTROL_MATCH_GE              2
-#define MCONTROL_MATCH_LT              3
-#define MCONTROL_MATCH_MASK_LOW                4
-#define MCONTROL_MATCH_MASK_HIGH       5
+#define MCONTROL_MATCH_EQUAL     0
+#define MCONTROL_MATCH_NAPOT     1
+#define MCONTROL_MATCH_GE        2
+#define MCONTROL_MATCH_LT        3
+#define MCONTROL_MATCH_MASK_LOW  4
+#define MCONTROL_MATCH_MASK_HIGH 5
 
 #define MIP_SSIP            (1 << IRQ_S_SOFT)
 #define MIP_HSIP            (1 << IRQ_H_SOFT)
 #define EXT_IO_BASE        0x40000000
 #define DRAM_BASE          0x80000000
 
-// breakpoint control fields
-#define BPCONTROL_X           0x00000001
-#define BPCONTROL_W           0x00000002
-#define BPCONTROL_R           0x00000004
-#define BPCONTROL_U           0x00000008
-#define BPCONTROL_S           0x00000010
-#define BPCONTROL_H           0x00000020
-#define BPCONTROL_M           0x00000040
-#define BPCONTROL_BPMATCH     0x00000780
-#ifdef __riscv64
-# define BPCONTROL_BPAMASKMAX 0x0F80000000000000
-# define BPCONTROL_TDRTYPE    0xF000000000000000
-#else
-# define BPCONTROL_BPAMASKMAX 0x0F800000
-# define BPCONTROL_TDRTYPE    0xF0000000
-#endif
-
 // page table entry (PTE) fields
 #define PTE_V     0x001 // Valid
 #define PTE_R     0x002 // Read
index 0cb70e584e3d9b64635cf48104d27b38e99059e0..7b42262c589a401a848945e08e77085741b4922b 100644 (file)
@@ -169,13 +169,17 @@ miss:
         delete mmu->matched_trigger;
         mmu->matched_trigger = NULL;
       }
-      assert(state.mcontrol[t.index].action != ACTION_NONE);
       switch (state.mcontrol[t.index].action) {
         case ACTION_DEBUG_MODE:
           enter_debug_mode(DCSR_CAUSE_HWBP);
           break;
+        case ACTION_DEBUG_EXCEPTION: {
+          mem_trap_t trap(CAUSE_BREAKPOINT, t.address);
+          take_trap(trap, pc);
+          break;
+        }
         default:
-          assert(0);
+          abort();
       }
     }
 
index 9774b30fb1318d3bbc403716468a6474e2df51cf..db88d30dfddab67d1b60157243caafab6b9bcb64 100644 (file)
@@ -1086,7 +1086,9 @@ class hardware_breakpoint_insert_op_t : public operation_t
             }
 
             if (type == 2 &&
-                get_field(mcontrol, MCONTROL_ACTION) == MCONTROL_ACTION_NONE) {
+                !get_field(mcontrol, MCONTROL_EXECUTE) &&
+                !get_field(mcontrol, MCONTROL_LOAD) &&
+                !get_field(mcontrol, MCONTROL_STORE)) {
               // Found an unused trigger.
               gs.dr_write_load(0, S0, SLOT_DATA1);
               gs.dr_write32(1, csrw(S0, CSR_TDATA0));
index 7d8c5df64e9cb6f78d3b57c810983d5c22aec2cd..2abbb5ad248ef22314ec9838eca3e36c415bbc43 100644 (file)
@@ -119,11 +119,8 @@ void state_t::reset()
   mtvec = DEFAULT_MTVEC;
   load_reservation = -1;
   tselect = 0;
-  for (unsigned int i = 0; i < num_triggers; i++) {
+  for (unsigned int i = 0; i < num_triggers; i++)
     mcontrol[i].type = 2;
-    mcontrol[i].action = ACTION_NONE;
-    tdata1[i] = 0;
-  }
 }
 
 void processor_t::set_debug(bool value)
@@ -516,8 +513,8 @@ reg_t processor_t::get_csr(int which)
       if (state.tselect < state.num_triggers) {
         reg_t v = 0;
         mcontrol_t *mc = &state.mcontrol[state.tselect];
-        v = set_field(v, 0xfL << (xlen-4), mc->type);
-        v = set_field(v, 0x3fL << (xlen-10), mc->maskmax);
+        v = set_field(v, MCONTROL_TYPE(xlen), mc->type);
+        v = set_field(v, MCONTROL_MASKMAX(xlen), mc->maskmax);
         v = set_field(v, MCONTROL_SELECT, mc->select);
         v = set_field(v, MCONTROL_ACTION, mc->action);
         v = set_field(v, MCONTROL_CHAIN, mc->chain);
@@ -679,8 +676,6 @@ void processor_t::trigger_updated()
   mmu->check_triggers_store = false;
 
   for (unsigned i = 0; i < state.num_triggers; i++) {
-    if (state.mcontrol[i].action == ACTION_NONE)
-      continue;
     if (state.mcontrol[i].execute) {
       mmu->check_triggers_fetch = true;
     }
index 3f8c4def59b4e71be280bc1d0a8629cbe74beacc..41d778e589263a1cbfb43ad51fb0263c65e0343f 100644 (file)
@@ -45,7 +45,6 @@ typedef struct
 
 typedef enum
 {
-  ACTION_NONE = MCONTROL_ACTION_NONE,
   ACTION_DEBUG_EXCEPTION = MCONTROL_ACTION_DEBUG_EXCEPTION,
   ACTION_DEBUG_MODE = MCONTROL_ACTION_DEBUG_MODE,
   ACTION_TRACE_START = MCONTROL_ACTION_TRACE_START,
@@ -198,18 +197,22 @@ public:
     if (state.dcsr.cause)
       return -1;
 
-    bool chain_ok = false;
+    bool chain_ok = true;
 
     for (unsigned int i = 0; i < state.num_triggers; i++) {
-      if (state.mcontrol[i].action == ACTION_NONE ||
-          (operation == OPERATION_EXECUTE && !state.mcontrol[i].execute) ||
+      if (!chain_ok) {
+        chain_ok |= !state.mcontrol[i].chain;
+        continue;
+      }
+
+      if ((operation == OPERATION_EXECUTE && !state.mcontrol[i].execute) ||
           (operation == OPERATION_STORE && !state.mcontrol[i].store) ||
           (operation == OPERATION_LOAD && !state.mcontrol[i].load) ||
           (state.prv == PRV_M && !state.mcontrol[i].m) ||
           (state.prv == PRV_H && !state.mcontrol[i].h) ||
           (state.prv == PRV_S && !state.mcontrol[i].s) ||
           (state.prv == PRV_U && !state.mcontrol[i].u)) {
-        goto next;
+        continue;
       }
 
       reg_t value;
@@ -228,54 +231,42 @@ public:
       switch (state.mcontrol[i].match) {
         case MATCH_EQUAL:
           if (value != state.tdata1[i])
-            goto next;
+            continue;
           break;
         case MATCH_NAPOT:
           {
             reg_t mask = ~((1 << cto(state.tdata1[i])) - 1);
             if ((value & mask) != (state.tdata1[i] & mask))
-              goto next;
+              continue;
           }
           break;
         case MATCH_GE:
           if (value < state.tdata1[i])
-            goto next;
+            continue;
           break;
         case MATCH_LT:
           if (value >= state.tdata1[i])
-            goto next;
+            continue;
           break;
         case MATCH_MASK_LOW:
           {
             reg_t mask = state.tdata1[i] >> (xlen/2);
             if ((value & mask) != (state.tdata1[i] & mask))
-              goto next;
+              continue;
           }
           break;
         case MATCH_MASK_HIGH:
           {
             reg_t mask = state.tdata1[i] >> (xlen/2);
             if (((value >> (xlen/2)) & mask) != (state.tdata1[i] & mask))
-              goto next;
+              continue;
           }
           break;
       }
 
-      if (state.mcontrol[i].chain && !chain_ok) {
-        goto next;
-      }
-
-      // We got here, so this trigger matches. But if the next trigger has
-      // chain set, then we can't perform the action.
-      if (i+1 < state.num_triggers && state.mcontrol[i+1].chain) {
-        chain_ok = true;
-        continue;
-      } else {
+      if (!state.mcontrol[i].chain)
         return i;
-      }
-
-next:
-      chain_ok = false;
+      chain_ok = true;
     }
     return -1;
   }