|
|
@@ -74,6 +74,8 @@ Nico Coesel |
|
|
|
#include "config.h" |
|
|
|
#endif |
|
|
|
|
|
|
|
#include <helper/time_support.h> |
|
|
|
|
|
|
|
#include "mips32.h" |
|
|
|
#include "mips32_pracc.h" |
|
|
|
|
|
|
@@ -111,16 +113,34 @@ static int mips32_pracc_write_u32(struct mips_ejtag *ejtag_info, |
|
|
|
static int wait_for_pracc_rw(struct mips_ejtag *ejtag_info, uint32_t *ctrl) |
|
|
|
{ |
|
|
|
uint32_t ejtag_ctrl; |
|
|
|
long long then = timeval_ms(); |
|
|
|
int timeout; |
|
|
|
|
|
|
|
/* wait for the PrAcc to become "1" */ |
|
|
|
mips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL); |
|
|
|
ejtag_ctrl = ejtag_info->ejtag_ctrl; |
|
|
|
|
|
|
|
int retval; |
|
|
|
if ((retval = jtag_execute_queue()) != ERROR_OK) |
|
|
|
{ |
|
|
|
LOG_ERROR("fastdata load failed"); |
|
|
|
return retval; |
|
|
|
} |
|
|
|
|
|
|
|
while (1) |
|
|
|
{ |
|
|
|
mips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL); |
|
|
|
ejtag_ctrl = ejtag_info->ejtag_ctrl; |
|
|
|
mips_ejtag_drscan_32(ejtag_info, &ejtag_ctrl); |
|
|
|
retval = mips_ejtag_drscan_32(ejtag_info, &ejtag_ctrl); |
|
|
|
if (retval != ERROR_OK) |
|
|
|
return retval; |
|
|
|
|
|
|
|
if (ejtag_ctrl & EJTAG_CTRL_PRACC) |
|
|
|
break; |
|
|
|
LOG_DEBUG("DEBUGMODULE: No memory access in progress!"); |
|
|
|
return ERROR_JTAG_DEVICE_ERROR; |
|
|
|
|
|
|
|
if ( (timeout = timeval_ms()-then) > 1000 ) |
|
|
|
{ |
|
|
|
LOG_DEBUG("DEBUGMODULE: No memory access in progress!"); |
|
|
|
return ERROR_JTAG_DEVICE_ERROR; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
*ctrl = ejtag_ctrl; |
|
|
@@ -175,7 +195,6 @@ static int mips32_pracc_exec_read(struct mips32_pracc_context *ctx, uint32_t add |
|
|
|
mips_ejtag_set_instr(ctx->ejtag_info, EJTAG_INST_CONTROL); |
|
|
|
mips_ejtag_drscan_32(ctx->ejtag_info, &ejtag_ctrl); |
|
|
|
|
|
|
|
jtag_add_clocks(5); |
|
|
|
return jtag_execute_queue(); |
|
|
|
} |
|
|
|
|
|
|
@@ -184,17 +203,18 @@ static int mips32_pracc_exec_write(struct mips32_pracc_context *ctx, uint32_t ad |
|
|
|
uint32_t ejtag_ctrl,data; |
|
|
|
int offset; |
|
|
|
struct mips_ejtag *ejtag_info = ctx->ejtag_info; |
|
|
|
int retval; |
|
|
|
|
|
|
|
mips_ejtag_set_instr(ctx->ejtag_info, EJTAG_INST_DATA); |
|
|
|
mips_ejtag_drscan_32(ctx->ejtag_info, &data); |
|
|
|
retval = mips_ejtag_drscan_32(ctx->ejtag_info, &data); |
|
|
|
if (retval != ERROR_OK) |
|
|
|
return retval; |
|
|
|
|
|
|
|
/* Clear access pending bit */ |
|
|
|
ejtag_ctrl = ejtag_info->ejtag_ctrl & ~EJTAG_CTRL_PRACC; |
|
|
|
mips_ejtag_set_instr(ctx->ejtag_info, EJTAG_INST_CONTROL); |
|
|
|
mips_ejtag_drscan_32(ctx->ejtag_info, &ejtag_ctrl); |
|
|
|
|
|
|
|
jtag_add_clocks(5); |
|
|
|
int retval; |
|
|
|
retval = jtag_execute_queue(); |
|
|
|
if (retval != ERROR_OK) |
|
|
|
return retval; |
|
|
@@ -250,7 +270,9 @@ int mips32_pracc_exec(struct mips_ejtag *ejtag_info, int code_len, const uint32_ |
|
|
|
|
|
|
|
address = data = 0; |
|
|
|
mips_ejtag_set_instr(ejtag_info, EJTAG_INST_ADDRESS); |
|
|
|
mips_ejtag_drscan_32(ejtag_info, &address); |
|
|
|
retval = mips_ejtag_drscan_32(ejtag_info, &address); |
|
|
|
if (retval != ERROR_OK) |
|
|
|
return retval; |
|
|
|
|
|
|
|
/* Check for read or write */ |
|
|
|
if (ejtag_ctrl & EJTAG_CTRL_PRNW) |
|
|
@@ -1018,11 +1040,17 @@ int mips32_pracc_fastdata_xfer(struct mips_ejtag *ejtag_info, struct working_are |
|
|
|
/* next fetch to dmseg should be in FASTDATA_AREA, check */ |
|
|
|
address = 0; |
|
|
|
mips_ejtag_set_instr(ejtag_info, EJTAG_INST_ADDRESS); |
|
|
|
mips_ejtag_drscan_32(ejtag_info, &address); |
|
|
|
retval = mips_ejtag_drscan_32(ejtag_info, &address); |
|
|
|
if (retval != ERROR_OK) |
|
|
|
return retval; |
|
|
|
|
|
|
|
if (address != MIPS32_PRACC_FASTDATA_AREA) |
|
|
|
return ERROR_FAIL; |
|
|
|
|
|
|
|
/* wait PrAcc pending bit for FASTDATA write */ |
|
|
|
if ((retval = wait_for_pracc_rw(ejtag_info, &ejtag_ctrl)) != ERROR_OK) |
|
|
|
return retval; |
|
|
|
|
|
|
|
/* Send the load start address */ |
|
|
|
val = addr; |
|
|
|
mips_ejtag_set_instr(ejtag_info, EJTAG_INST_FASTDATA); |
|
|
@@ -1030,12 +1058,10 @@ int mips32_pracc_fastdata_xfer(struct mips_ejtag *ejtag_info, struct working_are |
|
|
|
|
|
|
|
/* Send the load end address */ |
|
|
|
val = addr + (count - 1) * 4; |
|
|
|
mips_ejtag_set_instr(ejtag_info, EJTAG_INST_FASTDATA); |
|
|
|
mips_ejtag_fastdata_scan(ejtag_info, 1, &val); |
|
|
|
|
|
|
|
for (i = 0; i < count; i++) |
|
|
|
{ |
|
|
|
/* Send the data out using fastdata (clears the access pending bit) */ |
|
|
|
if ((retval = mips_ejtag_fastdata_scan(ejtag_info, write_t, buf++)) != ERROR_OK) |
|
|
|
return retval; |
|
|
|
} |
|
|
@@ -1051,7 +1077,9 @@ int mips32_pracc_fastdata_xfer(struct mips_ejtag *ejtag_info, struct working_are |
|
|
|
|
|
|
|
address = 0; |
|
|
|
mips_ejtag_set_instr(ejtag_info, EJTAG_INST_ADDRESS); |
|
|
|
mips_ejtag_drscan_32(ejtag_info, &address); |
|
|
|
retval = mips_ejtag_drscan_32(ejtag_info, &address); |
|
|
|
if (retval != ERROR_OK) |
|
|
|
return retval; |
|
|
|
|
|
|
|
if (address != MIPS32_PRACC_TEXT) |
|
|
|
LOG_ERROR("mini program did not return to start"); |
|
|
|