/* wait for the PrAcc to become "1" */
mips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL);
- ejtag_ctrl = ejtag_info->ejtag_ctrl;
while (1) {
+ ejtag_ctrl = ejtag_info->ejtag_ctrl;
retval = mips_ejtag_drscan_32(ejtag_info, &ejtag_ctrl);
if (retval != ERROR_OK)
return retval;
uint32_t ejtag_ctrl, data;
if ((address >= MIPS32_PRACC_PARAM_IN)
- && (address <= MIPS32_PRACC_PARAM_IN + ctx->num_iparam * 4)) {
+ && (address < MIPS32_PRACC_PARAM_IN + ctx->num_iparam * 4)) {
offset = (address - MIPS32_PRACC_PARAM_IN) / 4;
data = ctx->local_iparam[offset];
} else if ((address >= MIPS32_PRACC_PARAM_OUT)
- && (address <= MIPS32_PRACC_PARAM_OUT + ctx->num_oparam * 4)) {
+ && (address < MIPS32_PRACC_PARAM_OUT + ctx->num_oparam * 4)) {
offset = (address - MIPS32_PRACC_PARAM_OUT) / 4;
data = ctx->local_oparam[offset];
} else if ((address >= MIPS32_PRACC_TEXT)
- && (address <= MIPS32_PRACC_TEXT + ctx->code_len * 4)) {
+ && (address < MIPS32_PRACC_TEXT + ctx->code_len * 4)) {
offset = (address - MIPS32_PRACC_TEXT) / 4;
data = ctx->code[offset];
} else if (address == MIPS32_PRACC_STACK) {
+ if (ctx->stack_offset <= 0) {
+ LOG_ERROR("Error: Pracc stack out of bounds");
+ return ERROR_JTAG_DEVICE_ERROR;
+ }
/* save to our debug stack */
data = ctx->stack[--ctx->stack_offset];
} else {
return retval;
if ((address >= MIPS32_PRACC_PARAM_IN)
- && (address <= MIPS32_PRACC_PARAM_IN + ctx->num_iparam * 4)) {
+ && (address < MIPS32_PRACC_PARAM_IN + ctx->num_iparam * 4)) {
offset = (address - MIPS32_PRACC_PARAM_IN) / 4;
ctx->local_iparam[offset] = data;
} else if ((address >= MIPS32_PRACC_PARAM_OUT)
- && (address <= MIPS32_PRACC_PARAM_OUT + ctx->num_oparam * 4)) {
+ && (address < MIPS32_PRACC_PARAM_OUT + ctx->num_oparam * 4)) {
offset = (address - MIPS32_PRACC_PARAM_OUT) / 4;
ctx->local_oparam[offset] = data;
} else if (address == MIPS32_PRACC_STACK) {
+ if (ctx->stack_offset >= 32) {
+ LOG_ERROR("Error: Pracc stack out of bounds");
+ return ERROR_JTAG_DEVICE_ERROR;
+ }
/* save data onto our stack */
ctx->stack[ctx->stack_offset++] = data;
} else {
int num_param_in, uint32_t *param_in, int num_param_out, uint32_t *param_out, int cycle)
{
uint32_t ejtag_ctrl;
- uint32_t address, data;
+ uint32_t address;
struct mips32_pracc_context ctx;
int retval;
int pass = 0;
if (retval != ERROR_OK)
return retval;
- address = data = 0;
+ address = 0;
mips_ejtag_set_instr(ejtag_info, EJTAG_INST_ADDRESS);
retval = mips_ejtag_drscan_32(ejtag_info, &address);
if (retval != ERROR_OK)
static int mips32_pracc_read_u32(struct mips_ejtag *ejtag_info, uint32_t addr, uint32_t *buf)
{
- static const uint32_t code[] = {
- /* start: */
- 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(8, 0, 15), /* sw $8,($15) */
-
- MIPS32_LW(8, NEG16(MIPS32_PRACC_STACK-MIPS32_PRACC_PARAM_IN), 15), /* load R8 @ param_in[0] = address */
+ uint32_t code[] = {
+ /* start: */
+ MIPS32_MTC0(15, 31, 0), /* move $15 to COP0 DeSave */
+ MIPS32_LUI(15, PRACC_UPPER_BASE_ADDR), /* $15 = MIPS32_PRACC_BASE_ADDR */
+ MIPS32_SW(8, PRACC_STACK_OFFSET, 15), /* sw $8,PRACC_STACK_OFFSET($15) */
- MIPS32_LW(8, 0, 8), /* lw $8,0($8), Load $8 with the word @mem[$8] */
- MIPS32_SW(8, NEG16(MIPS32_PRACC_STACK - MIPS32_PRACC_PARAM_OUT), 15), /* store R8 @ param_out[0] */
+ MIPS32_LUI(8, UPPER16((addr + 0x8000))), /* load $8 with modified upper address */
+ MIPS32_LW(8, LOWER16(addr), 8), /* lw $8, LOWER16(addr)($8) */
+ MIPS32_SW(8, PRACC_OUT_OFFSET, 15), /* sw $8,PRACC_OUT_OFFSET($15) */
- MIPS32_LW(8, 0, 15), /* lw $8,($15) */
- MIPS32_B(NEG16(9)), /* b start */
- MIPS32_MFC0(15, 31, 0), /* move COP0 DeSave to $15 */
+ MIPS32_LW(8, PRACC_STACK_OFFSET, 15), /* lw $8,PRACC_STACK_OFFSET($15) */
+ MIPS32_B(NEG16(8)), /* b start */
+ MIPS32_MFC0(15, 31, 0), /* move COP0 DeSave to $15 */
};
- int retval = ERROR_OK;
- uint32_t param_in[1];
-
- param_in[0] = addr;
-
- retval = mips32_pracc_exec(ejtag_info, ARRAY_SIZE(code), code,
- ARRAY_SIZE(param_in), param_in, 1, buf, 1);
- if (retval != ERROR_OK)
- return retval;
-
- return retval;
+ return mips32_pracc_exec(ejtag_info, ARRAY_SIZE(code), code, 0, NULL, 1, buf, 1);
}
static int mips32_pracc_read_mem16(struct mips_ejtag *ejtag_info, uint32_t addr, int count, uint16_t *buf)
/* TODO remove array */
uint32_t *param_out = malloc(count * sizeof(uint32_t));
- int i;
+ if (param_out == NULL) {
+ LOG_ERROR("Out of memory");
+ return ERROR_FAIL;
+ }
int retval = ERROR_OK;
int blocksize;
+ int hwordsread = 0;
uint32_t param_in[2];
- /*while (count > 0) */
- {
+ while (count > 0) {
blocksize = count;
if (count > 0x400)
blocksize = 0x400;
param_in[1] = blocksize;
retval = mips32_pracc_exec(ejtag_info, ARRAY_SIZE(code), code,
- ARRAY_SIZE(param_in), param_in, count, param_out, 1);
+ ARRAY_SIZE(param_in), param_in, blocksize, ¶m_out[hwordsread], 1);
-/* count -= blocksize; */
-/* addr += blocksize; */
+ if (retval != ERROR_OK)
+ return retval;
+
+ count -= blocksize;
+ addr += blocksize*sizeof(uint16_t);
+ hwordsread += blocksize;
}
- for (i = 0; i < count; i++)
+ int i;
+ for (i = 0; i < hwordsread; i++)
buf[i] = param_out[i];
free(param_out);
-
return retval;
}
/* TODO remove array */
uint32_t *param_out = malloc(count * sizeof(uint32_t));
- int i;
+ if (param_out == NULL) {
+ LOG_ERROR("Out of memory");
+ return ERROR_FAIL;
+ }
int retval = ERROR_OK;
int blocksize;
uint32_t param_in[2];
+ int bytesread = 0;
-/* while (count > 0) */
- {
+ while (count > 0) {
blocksize = count;
if (count > 0x400)
blocksize = 0x400;
param_in[1] = blocksize;
retval = mips32_pracc_exec(ejtag_info, ARRAY_SIZE(code), code,
- ARRAY_SIZE(param_in), param_in, count, param_out, 1);
+ ARRAY_SIZE(param_in), param_in, count, ¶m_out[bytesread], 1);
-/* count -= blocksize; */
-/* addr += blocksize; */
- }
+ if (retval != ERROR_OK)
+ return retval;
- for (i = 0; i < count; i++)
+ count -= blocksize;
+ addr += blocksize;
+ bytesread += blocksize;
+ }
+ int i;
+ for (i = 0; i < bytesread; i++)
buf[i] = param_out[i];
free(param_out);
-
return retval;
}
{
/**
* Do not make this code static, but regenerate it every time,
- * as 5th element has to be changed to add parameters
+ * as 3th element has to be changed to add parameters
*/
uint32_t code[] = {
- /* start: */
- 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(8, 0, 15), /* sw $8,($15) */
- MIPS32_SW(9, 0, 15), /* sw $9,($15) */
-
- /* 5 */ MIPS32_MFC0(8, 0, 0), /* move COP0 [cp0_reg select] to $8 */
+ /* start: */
+ MIPS32_MTC0(15, 31, 0), /* move $15 to COP0 DeSave */
+ MIPS32_LUI(15, PRACC_UPPER_BASE_ADDR), /* $15 = MIPS32_PRACC_BASE_ADDR */
+ MIPS32_SW(8, PRACC_STACK_OFFSET, 15), /* sw $8,PRACC_STACK_OFFSET($15) */
- MIPS32_LUI(9, UPPER16(MIPS32_PRACC_PARAM_OUT)), /* $11 = MIPS32_PRACC_PARAM_OUT */
- MIPS32_ORI(9, 9, LOWER16(MIPS32_PRACC_PARAM_OUT)),
- MIPS32_SW(8, 0, 9), /* sw $8,0($9) */
+ /* 3 */ MIPS32_MFC0(8, 0, 0), /* move COP0 [cp0_reg select] to $8 */
+ MIPS32_SW(8, PRACC_OUT_OFFSET, 15), /* sw $8,PRACC_OUT_OFFSET($15) */
- MIPS32_LW(9, 0, 15), /* lw $9,($15) */
- MIPS32_LW(8, 0, 15), /* lw $8,($15) */
- MIPS32_B(NEG16(12)), /* b start */
- MIPS32_MFC0(15, 31, 0), /* move COP0 DeSave to $15 */
+ MIPS32_LW(8, PRACC_STACK_OFFSET, 15), /* lw $8,PRACC_STACK_OFFSET($15) */
+ MIPS32_B(NEG16(7)), /* b start */
+ MIPS32_MFC0(15, 31, 0), /* move COP0 DeSave to $15 */
};
/**
* MIPS32_MTC0 is implemented via MIPS32_R_INST macro.
* In order to insert our parameters, we must change rd and funct fields.
*/
- code[5] |= (cp0_reg << 11) | cp0_sel; /* change rd and funct of MIPS32_R_INST macro */
+ code[3] |= (cp0_reg << 11) | cp0_sel; /* change rd and funct of MIPS32_R_INST macro */
- /* TODO remove array */
- uint32_t *param_out = val;
- int retval;
-
- retval = mips32_pracc_exec(ejtag_info, ARRAY_SIZE(code), code, 0, NULL, 1, param_out, 1);
-
- return retval;
+ return mips32_pracc_exec(ejtag_info, ARRAY_SIZE(code), code, 0, NULL, 1, val, 1);
}
-int mips32_cp0_write(struct mips_ejtag *ejtag_info,
- uint32_t val, uint32_t cp0_reg, uint32_t cp0_sel)
+int mips32_cp0_write(struct mips_ejtag *ejtag_info, uint32_t val, uint32_t cp0_reg, uint32_t cp0_sel)
{
uint32_t code[] = {
/* start: */
- 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(8, 0, 15), /* sw $8,($15) */
- MIPS32_SW(9, 0, 15), /* sw $9,($15) */
-
- MIPS32_LUI(8, UPPER16(MIPS32_PRACC_PARAM_IN)), /* $8 = MIPS32_PRACC_PARAM_IN */
- MIPS32_ORI(8, 8, LOWER16(MIPS32_PRACC_PARAM_IN)),
- MIPS32_LW(9, 0, 8), /* Load write val to $9 */
+ MIPS32_MTC0(15, 31, 0), /* move $15 to COP0 DeSave */
+ MIPS32_LUI(15, UPPER16(val)), /* Load val to $15 */
+ MIPS32_ORI(15, 15, LOWER16(val)),
- /* 8 */ MIPS32_MTC0(9, 0, 0), /* move $9 to COP0 [cp0_reg select] */
+ /* 3 */ MIPS32_MTC0(15, 0, 0), /* move $15 to COP0 [cp0_reg select] */
- MIPS32_LW(9, 0, 15), /* lw $9,($15) */
- MIPS32_LW(8, 0, 15), /* lw $8,($15) */
- MIPS32_B(NEG16(12)), /* b start */
- MIPS32_MFC0(15, 31, 0), /* move COP0 DeSave to $15 */
+ MIPS32_B(NEG16(5)), /* b start */
+ MIPS32_MFC0(15, 31, 0), /* move COP0 DeSave to $15 */
};
/**
* Note that MIPS32_MTC0 macro is implemented via MIPS32_R_INST macro.
* In order to insert our parameters, we must change rd and funct fields.
*/
- code[8] |= (cp0_reg << 11) | cp0_sel; /* change rd and funct fields of MIPS32_R_INST macro */
-
- /* TODO remove array */
- uint32_t *param_in = malloc(1 * sizeof(uint32_t));
- int retval;
- param_in[0] = val;
-
- retval = mips32_pracc_exec(ejtag_info, ARRAY_SIZE(code), code, 1, param_in, 0, NULL, 1);
+ code[3] |= (cp0_reg << 11) | cp0_sel; /* change rd and funct fields of MIPS32_R_INST macro */
- free(param_in);
-
- return retval;
+ return mips32_pracc_exec(ejtag_info, ARRAY_SIZE(code), code, 0, NULL, 0, NULL, 1);
}
/**
uint32_t conf = 0;
int cached = 0;
+ if ((KSEGX(addr) == KSEG1) || ((addr >= 0xff200000) && (addr <= 0xff3fffff)))
+ return retval; /*Nothing to do*/
+
mips32_cp0_read(ejtag_info, &conf, 16, 0);
switch (KSEGX(addr)) {
case KSEG0:
cached = (conf & MIPS32_CONFIG0_K0_MASK) >> MIPS32_CONFIG0_K0_SHIFT;
break;
- case KSEG1:
- /* uncachable segment - nothing to do */
- break;
case KSEG2:
case KSEG3:
cached = (conf & MIPS32_CONFIG0_K23_MASK) >> MIPS32_CONFIG0_K23_SHIFT;