#define MCONTROL_STORE (1<<1)
#define MCONTROL_LOAD (1<<0)
+#define MCONTROL_TYPE_NONE 0
+#define MCONTROL_TYPE_MATCH 2
+
#define MCONTROL_ACTION_DEBUG_EXCEPTION 0
#define MCONTROL_ACTION_DEBUG_MODE 1
#define MCONTROL_ACTION_TRACE_START 2
#define CSR_MSTIME_DELTA 0x705
#define CSR_MSINSTRET_DELTA 0x706
#define CSR_TSELECT 0x7a0
-#define CSR_TDATA0 0x7a1
-#define CSR_TDATA1 0x7a2
-#define CSR_TDATA2 0x7a3
+#define CSR_TDATA1 0x7a1
+#define CSR_TDATA2 0x7a2
+#define CSR_TDATA3 0x7a3
#define CSR_DCSR 0x7b0
#define CSR_DPC 0x7b1
#define CSR_DSCRATCH 0x7b2
DECLARE_CSR(mstime_delta, CSR_MSTIME_DELTA)
DECLARE_CSR(msinstret_delta, CSR_MSINSTRET_DELTA)
DECLARE_CSR(tselect, CSR_TSELECT)
-DECLARE_CSR(tdata0, CSR_TDATA0)
DECLARE_CSR(tdata1, CSR_TDATA1)
DECLARE_CSR(tdata2, CSR_TDATA2)
+DECLARE_CSR(tdata3, CSR_TDATA3)
DECLARE_CSR(dcsr, CSR_DCSR)
DECLARE_CSR(dpc, CSR_DPC)
DECLARE_CSR(dscratch, CSR_DSCRATCH)
return true;
}
- gs.dr_write32(0, csrr(S0, CSR_TDATA0));
+ gs.dr_write32(0, csrr(S0, CSR_TDATA1));
gs.dr_write_store(1, S0, SLOT_DATA0);
gs.dr_write_jump(2);
state = STATE_CHECK_MCONTROL;
!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));
+ gs.dr_write32(1, csrw(S0, CSR_TDATA1));
gs.dr_write_jump(2);
mcontrol = set_field(0, MCONTROL_ACTION, MCONTROL_ACTION_DEBUG_MODE);
mcontrol = set_field(mcontrol, MCONTROL_MATCH, MCONTROL_MATCH_EQUAL);
case STATE_WRITE_ADDRESS:
{
gs.dr_write_load(0, S0, SLOT_DATA1);
- gs.dr_write32(1, csrw(S0, CSR_TDATA1));
+ gs.dr_write32(1, csrw(S0, CSR_TDATA2));
gs.dr_write_jump(2);
gs.dr_write(SLOT_DATA1, bp.vaddr);
gs.set_interrupt(0);
bool perform_step(unsigned int step) {
gs.dr_write32(0, addi(S0, ZERO, bp.index));
gs.dr_write32(1, csrw(S0, CSR_TSELECT));
- gs.dr_write32(2, csrw(ZERO, CSR_TDATA0));
+ gs.dr_write32(2, csrw(ZERO, CSR_TDATA1));
gs.dr_write_jump(3);
gs.set_interrupt(0);
return true;
case CSR_MCAUSE: state.mcause = val; break;
case CSR_MBADADDR: state.mbadaddr = val; break;
case CSR_TSELECT: state.tselect = val; break;
- case CSR_TDATA0:
+ case CSR_TDATA1:
if (state.tselect < state.num_triggers) {
mcontrol_t *mc = &state.mcontrol[state.tselect];
+ mc->dmode = get_field(val, MCONTROL_DMODE(xlen));
mc->select = get_field(val, MCONTROL_SELECT);
mc->action = (mcontrol_action_t) get_field(val, MCONTROL_ACTION);
mc->chain = get_field(val, MCONTROL_CHAIN);
trigger_updated();
}
break;
- case CSR_TDATA1:
+ case CSR_TDATA2:
if (state.tselect < state.num_triggers) {
state.tdata1[state.tselect] = val;
}
case CSR_MEDELEG: return state.medeleg;
case CSR_MIDELEG: return state.mideleg;
case CSR_TSELECT: return state.tselect;
- case CSR_TDATA0:
+ case CSR_TDATA1:
if (state.tselect < state.num_triggers) {
reg_t v = 0;
mcontrol_t *mc = &state.mcontrol[state.tselect];
v = set_field(v, MCONTROL_TYPE(xlen), mc->type);
+ v = set_field(v, MCONTROL_DMODE(xlen), mc->dmode);
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);
return 0;
}
break;
- case CSR_TDATA1:
+ case CSR_TDATA2:
if (state.tselect < state.num_triggers) {
return state.tdata1[state.tselect];
} else {
uint8_t type;
uint8_t maskmax;
bool select;
+ bool dmode;
mcontrol_action_t action;
bool chain;
mcontrol_match_t match;