X-Git-Url: https://review.openocd.org/gitweb?p=openocd.git;a=blobdiff_plain;f=src%2Ftarget%2Fmips32_pracc.c;h=af60d321638652aad0a52a573add2aceacbfb7d9;hp=19ba886c5b72bf4d6a20e907a31b678e6fd1fd33;hb=f6315d5e5b7b71515ef051711e5f818a42d6b3b3;hpb=b48a94f05da3a887f1978da01db77b79513d4aa9 diff --git a/src/target/mips32_pracc.c b/src/target/mips32_pracc.c index 19ba886c5b..af60d32163 100644 --- a/src/target/mips32_pracc.c +++ b/src/target/mips32_pracc.c @@ -74,6 +74,8 @@ Nico Coesel #include "config.h" #endif +#include + #include "mips32.h" #include "mips32_pracc.h" @@ -90,19 +92,55 @@ struct mips32_pracc_context struct mips_ejtag *ejtag_info; }; +static int mips32_pracc_read_mem8(struct mips_ejtag *ejtag_info, + uint32_t addr, int count, uint8_t *buf); +static int mips32_pracc_read_mem16(struct mips_ejtag *ejtag_info, + uint32_t addr, int count, uint16_t *buf); +static int mips32_pracc_read_mem32(struct mips_ejtag *ejtag_info, + uint32_t addr, int count, uint32_t *buf); +static int mips32_pracc_read_u32(struct mips_ejtag *ejtag_info, + uint32_t addr, uint32_t *buf); + +static int mips32_pracc_write_mem8(struct mips_ejtag *ejtag_info, + uint32_t addr, int count, uint8_t *buf); +static int mips32_pracc_write_mem16(struct mips_ejtag *ejtag_info, + uint32_t addr, int count, uint16_t *buf); +static int mips32_pracc_write_mem32(struct mips_ejtag *ejtag_info, + uint32_t addr, int count, uint32_t *buf); +static int mips32_pracc_write_u32(struct mips_ejtag *ejtag_info, + uint32_t addr, uint32_t *buf); + 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!\n"); - 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; @@ -150,17 +188,14 @@ static int mips32_pracc_exec_read(struct mips32_pracc_context *ctx, uint32_t add /* Send the data out */ mips_ejtag_set_instr(ctx->ejtag_info, EJTAG_INST_DATA); - mips_ejtag_drscan_32(ctx->ejtag_info, &data); + mips_ejtag_drscan_32_out(ctx->ejtag_info, data); /* Clear the access pending bit (let the processor eat!) */ 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); + mips_ejtag_drscan_32_out(ctx->ejtag_info, ejtag_ctrl); - jtag_add_clocks(5); - jtag_execute_queue(); - - return ERROR_OK; + return jtag_execute_queue(); } static int mips32_pracc_exec_write(struct mips32_pracc_context *ctx, uint32_t address) @@ -168,17 +203,21 @@ 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); + mips_ejtag_drscan_32_out(ctx->ejtag_info, ejtag_ctrl); - jtag_add_clocks(5); - jtag_execute_queue(); + retval = jtag_execute_queue(); + if (retval != ERROR_OK) + return retval; if ((address >= MIPS32_PRACC_PARAM_IN) && (address <= MIPS32_PRACC_PARAM_IN + ctx->num_iparam * 4)) @@ -231,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) @@ -284,7 +325,7 @@ int mips32_pracc_read_mem(struct mips_ejtag *ejtag_info, uint32_t addr, int size return ERROR_OK; } -int mips32_pracc_read_mem32(struct mips_ejtag *ejtag_info, uint32_t addr, int count, uint32_t *buf) +static int mips32_pracc_read_mem32(struct mips_ejtag *ejtag_info, uint32_t addr, int count, uint32_t *buf) { static const uint32_t code[] = { /* start: */ @@ -354,7 +395,7 @@ int mips32_pracc_read_mem32(struct mips_ejtag *ejtag_info, uint32_t addr, int co return retval; } -int mips32_pracc_read_u32(struct mips_ejtag *ejtag_info, uint32_t addr, uint32_t *buf) +static int mips32_pracc_read_u32(struct mips_ejtag *ejtag_info, uint32_t addr, uint32_t *buf) { static const uint32_t code[] = { /* start: */ @@ -387,7 +428,7 @@ int mips32_pracc_read_u32(struct mips_ejtag *ejtag_info, uint32_t addr, uint32_t return retval; } -int mips32_pracc_read_mem16(struct mips_ejtag *ejtag_info, uint32_t addr, int count, uint16_t *buf) +static int mips32_pracc_read_mem16(struct mips_ejtag *ejtag_info, uint32_t addr, int count, uint16_t *buf) { static const uint32_t code[] = { /* start: */ @@ -430,13 +471,10 @@ int mips32_pracc_read_mem16(struct mips_ejtag *ejtag_info, uint32_t addr, int co uint32_t *param_out = malloc(count * sizeof(uint32_t)); int i; -// int retval; + int retval = ERROR_OK; int blocksize; - int bytesread; uint32_t param_in[2]; - bytesread = 0; - //while (count > 0) { blocksize = count; @@ -446,12 +484,11 @@ int mips32_pracc_read_mem16(struct mips_ejtag *ejtag_info, uint32_t addr, int co param_in[0] = addr; param_in[1] = blocksize; - mips32_pracc_exec(ejtag_info, ARRAY_SIZE(code), code, \ + retval = mips32_pracc_exec(ejtag_info, ARRAY_SIZE(code), code, ARRAY_SIZE(param_in), param_in, count, param_out, 1); // count -= blocksize; // addr += blocksize; -// bytesread += blocksize; } for (i = 0; i < count; i++) @@ -461,10 +498,10 @@ int mips32_pracc_read_mem16(struct mips_ejtag *ejtag_info, uint32_t addr, int co free(param_out); - return ERROR_OK; + return retval; } -int mips32_pracc_read_mem8(struct mips_ejtag *ejtag_info, uint32_t addr, int count, uint8_t *buf) +static int mips32_pracc_read_mem8(struct mips_ejtag *ejtag_info, uint32_t addr, int count, uint8_t *buf) { static const uint32_t code[] = { /* start: */ @@ -507,13 +544,10 @@ int mips32_pracc_read_mem8(struct mips_ejtag *ejtag_info, uint32_t addr, int cou uint32_t *param_out = malloc(count * sizeof(uint32_t)); int i; -// int retval; + int retval = ERROR_OK; int blocksize; - int bytesread; uint32_t param_in[2]; - bytesread = 0; - // while (count > 0) { blocksize = count; @@ -523,12 +557,11 @@ int mips32_pracc_read_mem8(struct mips_ejtag *ejtag_info, uint32_t addr, int cou param_in[0] = addr; param_in[1] = blocksize; - mips32_pracc_exec(ejtag_info, ARRAY_SIZE(code), code, \ + retval = mips32_pracc_exec(ejtag_info, ARRAY_SIZE(code), code, ARRAY_SIZE(param_in), param_in, count, param_out, 1); // count -= blocksize; // addr += blocksize; -// bytesread += blocksize; } for (i = 0; i < count; i++) @@ -538,7 +571,7 @@ int mips32_pracc_read_mem8(struct mips_ejtag *ejtag_info, uint32_t addr, int cou free(param_out); - return ERROR_OK; + return retval; } int mips32_pracc_write_mem(struct mips_ejtag *ejtag_info, uint32_t addr, int size, int count, void *buf) @@ -559,7 +592,7 @@ int mips32_pracc_write_mem(struct mips_ejtag *ejtag_info, uint32_t addr, int siz return ERROR_OK; } -int mips32_pracc_write_mem32(struct mips_ejtag *ejtag_info, uint32_t addr, int count, uint32_t *buf) +static int mips32_pracc_write_mem32(struct mips_ejtag *ejtag_info, uint32_t addr, int count, uint32_t *buf) { static const uint32_t code[] = { /* start: */ @@ -600,15 +633,16 @@ int mips32_pracc_write_mem32(struct mips_ejtag *ejtag_info, uint32_t addr, int c memcpy(¶m_in[2], buf, count * sizeof(uint32_t)); - mips32_pracc_exec(ejtag_info, ARRAY_SIZE(code), code, \ + int retval; + retval = mips32_pracc_exec(ejtag_info, ARRAY_SIZE(code), code, count + 2, param_in, 0, NULL, 1); free(param_in); - return ERROR_OK; + return retval; } -int mips32_pracc_write_u32(struct mips_ejtag *ejtag_info, uint32_t addr, uint32_t *buf) +static int mips32_pracc_write_u32(struct mips_ejtag *ejtag_info, uint32_t addr, uint32_t *buf) { static const uint32_t code[] = { /* start: */ @@ -634,13 +668,11 @@ int mips32_pracc_write_u32(struct mips_ejtag *ejtag_info, uint32_t addr, uint32_ param_in[0] = addr; param_in[1] = *buf; - mips32_pracc_exec(ejtag_info, ARRAY_SIZE(code), code, \ + return mips32_pracc_exec(ejtag_info, ARRAY_SIZE(code), code, ARRAY_SIZE(param_in), param_in, 0, NULL, 1); - - return ERROR_OK; } -int mips32_pracc_write_mem16(struct mips_ejtag *ejtag_info, uint32_t addr, int count, uint16_t *buf) +static int mips32_pracc_write_mem16(struct mips_ejtag *ejtag_info, uint32_t addr, int count, uint16_t *buf) { static const uint32_t code[] = { /* start: */ @@ -690,15 +722,16 @@ int mips32_pracc_write_mem16(struct mips_ejtag *ejtag_info, uint32_t addr, int c param_in[i + 2] = buf[i]; } - mips32_pracc_exec(ejtag_info, ARRAY_SIZE(code), code, \ + int retval; + retval = mips32_pracc_exec(ejtag_info, ARRAY_SIZE(code), code, count + 2, param_in, 0, NULL, 1); free(param_in); - return ERROR_OK; + return retval; } -int mips32_pracc_write_mem8(struct mips_ejtag *ejtag_info, uint32_t addr, int count, uint8_t *buf) +static int mips32_pracc_write_mem8(struct mips_ejtag *ejtag_info, uint32_t addr, int count, uint8_t *buf) { static const uint32_t code[] = { /* start: */ @@ -749,7 +782,7 @@ int mips32_pracc_write_mem8(struct mips_ejtag *ejtag_info, uint32_t addr, int co param_in[i + 2] = buf[i]; } - retval = mips32_pracc_exec(ejtag_info, ARRAY_SIZE(code), code, \ + retval = mips32_pracc_exec(ejtag_info, ARRAY_SIZE(code), code, count + 2, param_in, 0, NULL, 1); free(param_in); @@ -821,7 +854,7 @@ int mips32_pracc_write_regs(struct mips_ejtag *ejtag_info, uint32_t *regs) int retval; - retval = mips32_pracc_exec(ejtag_info, ARRAY_SIZE(code), code, \ + retval = mips32_pracc_exec(ejtag_info, ARRAY_SIZE(code), code, MIPS32NUMCOREREGS, regs, 0, NULL, 1); return retval; @@ -896,7 +929,7 @@ int mips32_pracc_read_regs(struct mips_ejtag *ejtag_info, uint32_t *regs) int retval; - retval = mips32_pracc_exec(ejtag_info, ARRAY_SIZE(code), code, \ + retval = mips32_pracc_exec(ejtag_info, ARRAY_SIZE(code), code, 0, NULL, MIPS32NUMCOREREGS, regs, 1); return retval; @@ -910,7 +943,7 @@ int mips32_pracc_read_regs(struct mips_ejtag *ejtag_info, uint32_t *regs) * 3. data ... */ int mips32_pracc_fastdata_xfer(struct mips_ejtag *ejtag_info, struct working_area *source, - int write, uint32_t addr, int count, uint32_t *buf) + int write_t, uint32_t addr, int count, uint32_t *buf) { uint32_t handler_code[] = { /* caution when editing, table is modified below */ @@ -955,7 +988,7 @@ int mips32_pracc_fastdata_xfer(struct mips_ejtag *ejtag_info, struct working_are if (source->size < MIPS32_FASTDATA_HANDLER_SIZE) return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; - if (write) + if (write_t) { handler_code[8] = MIPS32_LW(11,0,8); /* load data from probe at fastdata area */ handler_code[9] = MIPS32_SW(11,0,9); /* store data to RAM @ r9 */ @@ -967,7 +1000,12 @@ int mips32_pracc_fastdata_xfer(struct mips_ejtag *ejtag_info, struct working_are } /* write program into RAM */ - mips32_pracc_write_mem32(ejtag_info, source->address, ARRAY_SIZE(handler_code), handler_code); + if (write_t != ejtag_info->fast_access_save) + { + mips32_pracc_write_mem32(ejtag_info, source->address, ARRAY_SIZE(handler_code), handler_code); + /* save previous operation to speed to any consecutive read/writes */ + ejtag_info->fast_access_save = write_t; + } LOG_DEBUG("%s using 0x%.8" PRIx32 " for write handler", __func__, source->address); @@ -980,12 +1018,12 @@ int mips32_pracc_fastdata_xfer(struct mips_ejtag *ejtag_info, struct working_are return retval; mips_ejtag_set_instr(ejtag_info, EJTAG_INST_DATA); - mips_ejtag_drscan_32(ejtag_info, &jmp_code[i]); + mips_ejtag_drscan_32_out(ejtag_info, jmp_code[i]); /* Clear the access pending bit (let the processor eat!) */ ejtag_ctrl = ejtag_info->ejtag_ctrl & ~EJTAG_CTRL_PRACC; mips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL); - mips_ejtag_drscan_32(ejtag_info, &ejtag_ctrl); + mips_ejtag_drscan_32_out(ejtag_info, ejtag_ctrl); } if ((retval = wait_for_pracc_rw(ejtag_info, &ejtag_ctrl)) != ERROR_OK) @@ -994,11 +1032,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); @@ -1006,13 +1050,11 @@ 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, buf++)) != ERROR_OK) + if ((retval = mips_ejtag_fastdata_scan(ejtag_info, write_t, buf++)) != ERROR_OK) return retval; } @@ -1027,7 +1069,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");