aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Waterman <waterman@cs.berkeley.edu>2016-08-25 21:27:10 -0700
committerAndrew Waterman <waterman@cs.berkeley.edu>2016-08-25 21:27:10 -0700
commitbc49f60710d95c577079a9d8f0c7ccc8c5f2c98c (patch)
treeec1a980fd8438fdad782606af1494f0d3520b18f
parentc8149cb261631aadfe6d984cb9b40b88bfb31408 (diff)
downloadspike-bc49f60710d95c577079a9d8f0c7ccc8c5f2c98c.zip
spike-bc49f60710d95c577079a9d8f0c7ccc8c5f2c98c.tar.gz
spike-bc49f60710d95c577079a9d8f0c7ccc8c5f2c98c.tar.bz2
partially update spike to newer debug spec
-rw-r--r--riscv/encoding.h48
-rw-r--r--riscv/execute.cc8
-rw-r--r--riscv/gdbserver.cc4
-rw-r--r--riscv/processor.cc11
-rw-r--r--riscv/processor.h41
5 files changed, 45 insertions, 67 deletions
diff --git a/riscv/encoding.h b/riscv/encoding.h
index e00972e..2a66e51 100644
--- a/riscv/encoding.h
+++ b/riscv/encoding.h
@@ -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)
@@ -57,8 +56,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)
@@ -69,19 +73,18 @@
#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)
@@ -127,23 +130,6 @@
#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
diff --git a/riscv/execute.cc b/riscv/execute.cc
index 0cb70e5..7b42262 100644
--- a/riscv/execute.cc
+++ b/riscv/execute.cc
@@ -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();
}
}
diff --git a/riscv/gdbserver.cc b/riscv/gdbserver.cc
index 9774b30..db88d30 100644
--- a/riscv/gdbserver.cc
+++ b/riscv/gdbserver.cc
@@ -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));
diff --git a/riscv/processor.cc b/riscv/processor.cc
index 7d8c5df..2abbb5a 100644
--- a/riscv/processor.cc
+++ b/riscv/processor.cc
@@ -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;
}
diff --git a/riscv/processor.h b/riscv/processor.h
index 3f8c4de..41d778e 100644
--- a/riscv/processor.h
+++ b/riscv/processor.h
@@ -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;
}