|
|
@@ -190,49 +190,32 @@ void mips_ejtag_drscan_8_out(struct mips_ejtag *ejtag_info, uint8_t data) |
|
|
|
jtag_add_dr_scan(tap, 1, &field, TAP_IDLE); |
|
|
|
} |
|
|
|
|
|
|
|
static int mips_ejtag_step_enable(struct mips_ejtag *ejtag_info) |
|
|
|
/* Set (to enable) or clear (to disable stepping) the SSt bit (bit 8) in Cp0 Debug reg (reg 23, sel 0) */ |
|
|
|
int mips_ejtag_config_step(struct mips_ejtag *ejtag_info, int enable_step) |
|
|
|
{ |
|
|
|
static const uint32_t code[] = { |
|
|
|
MIPS32_MTC0(1, 31, 0), /* move $1 to COP0 DeSave */ |
|
|
|
MIPS32_MFC0(1, 23, 0), /* move COP0 Debug to $1 */ |
|
|
|
MIPS32_ORI(1, 1, 0x0100), /* set SSt bit in debug reg */ |
|
|
|
MIPS32_MTC0(1, 23, 0), /* move $1 to COP0 Debug */ |
|
|
|
MIPS32_B(NEG16(5)), |
|
|
|
MIPS32_MFC0(1, 31, 0), /* move COP0 DeSave to $1 */ |
|
|
|
}; |
|
|
|
int code_len = enable_step ? 6 : 7; |
|
|
|
|
|
|
|
return mips32_pracc_exec(ejtag_info, ARRAY_SIZE(code), code, |
|
|
|
0, NULL, 0, NULL, 1); |
|
|
|
} |
|
|
|
uint32_t *code = malloc(code_len * sizeof(uint32_t)); |
|
|
|
if (code == NULL) { |
|
|
|
LOG_ERROR("Out of memory"); |
|
|
|
return ERROR_FAIL; |
|
|
|
} |
|
|
|
uint32_t *code_p = code; |
|
|
|
|
|
|
|
static int mips_ejtag_step_disable(struct mips_ejtag *ejtag_info) |
|
|
|
{ |
|
|
|
static const uint32_t code[] = { |
|
|
|
MIPS32_MTC0(15, 31, 0), /* move $15 to COP0 DeSave */ |
|
|
|
MIPS32_LUI(15, UPPER16(MIPS32_PRACC_STACK)), /* $15 = MIPS32_PRACC_STACK */ |
|
|
|
MIPS32_ORI(15, 15, LOWER16(MIPS32_PRACC_STACK)), |
|
|
|
MIPS32_SW(1, 0, 15), /* sw $1,($15) */ |
|
|
|
MIPS32_SW(2, 0, 15), /* sw $2,($15) */ |
|
|
|
MIPS32_MFC0(1, 23, 0), /* move COP0 Debug to $1 */ |
|
|
|
MIPS32_LUI(2, 0xFFFF), /* $2 = 0xfffffeff */ |
|
|
|
MIPS32_ORI(2, 2, 0xFEFF), |
|
|
|
MIPS32_AND(1, 1, 2), |
|
|
|
MIPS32_MTC0(1, 23, 0), /* move $1 to COP0 Debug */ |
|
|
|
MIPS32_LW(2, 0, 15), |
|
|
|
MIPS32_LW(1, 0, 15), |
|
|
|
MIPS32_B(NEG16(13)), |
|
|
|
MIPS32_MFC0(15, 31, 0), /* move COP0 DeSave to $15 */ |
|
|
|
}; |
|
|
|
*code_p++ = MIPS32_MTC0(1, 31, 0); /* move $1 to COP0 DeSave */ |
|
|
|
*code_p++ = MIPS32_MFC0(1, 23, 0), /* move COP0 Debug to $1 */ |
|
|
|
*code_p++ = MIPS32_ORI(1, 1, 0x0100); /* set SSt bit in debug reg */ |
|
|
|
if (!enable_step) |
|
|
|
*code_p++ = MIPS32_XORI(1, 1, 0x0100); /* clear SSt bit in debug reg */ |
|
|
|
|
|
|
|
return mips32_pracc_exec(ejtag_info, ARRAY_SIZE(code), code, |
|
|
|
0, NULL, 0, NULL, 1); |
|
|
|
} |
|
|
|
*code_p++ = MIPS32_MTC0(1, 23, 0); /* move $1 to COP0 Debug */ |
|
|
|
*code_p++ = MIPS32_B(NEG16((code_len - 1))); /* jump to start */ |
|
|
|
*code_p = MIPS32_MFC0(1, 31, 0); /* move COP0 DeSave to $1 */ |
|
|
|
|
|
|
|
int mips_ejtag_config_step(struct mips_ejtag *ejtag_info, int enable_step) |
|
|
|
{ |
|
|
|
if (enable_step) |
|
|
|
return mips_ejtag_step_enable(ejtag_info); |
|
|
|
return mips_ejtag_step_disable(ejtag_info); |
|
|
|
int retval = mips32_pracc_exec(ejtag_info, code_len, code, 0, NULL, 0, NULL, 1); |
|
|
|
|
|
|
|
free(code); |
|
|
|
return retval; |
|
|
|
} |
|
|
|
|
|
|
|
int mips_ejtag_enter_debug(struct mips_ejtag *ejtag_info) |
|
|
|