From bc49f60710d95c577079a9d8f0c7ccc8c5f2c98c Mon Sep 17 00:00:00 2001 From: Andrew Waterman Date: Thu, 25 Aug 2016 21:27:10 -0700 Subject: [PATCH] partially update spike to newer debug spec --- riscv/encoding.h | 48 ++++++++++++++++------------------------------ riscv/execute.cc | 8 ++++++-- riscv/gdbserver.cc | 4 +++- riscv/processor.cc | 11 +++-------- riscv/processor.h | 41 ++++++++++++++++----------------------- 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; } -- 2.30.2