X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2Ftarget%2Fmips32_pracc.c;h=bae436784af3253a64c7520e2d3b800b6db3b2cf;hb=6663a788a53ee38f2d6950fe7802eae7855e01f3;hp=267a4ffd94c89c24a263ffe17854263daf44a4e4;hpb=374127301ec1d72033b9d573b72c7abdfd61990d;p=fw%2Fopenocd diff --git a/src/target/mips32_pracc.c b/src/target/mips32_pracc.c index 267a4ffd9..bae436784 100644 --- a/src/target/mips32_pracc.c +++ b/src/target/mips32_pracc.c @@ -125,9 +125,9 @@ static int wait_for_pracc_rw(struct mips_ejtag *ejtag_info, uint32_t *ctrl) /* 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; @@ -153,18 +153,22 @@ static int mips32_pracc_exec_read(struct mips32_pracc_context *ctx, uint32_t add 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 { @@ -209,14 +213,18 @@ static int mips32_pracc_exec_write(struct mips32_pracc_context *ctx, uint32_t ad 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 { @@ -231,7 +239,7 @@ int mips32_pracc_exec(struct mips_ejtag *ejtag_info, int code_len, const uint32_ 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; @@ -250,7 +258,7 @@ int mips32_pracc_exec(struct mips_ejtag *ejtag_info, int code_len, const uint32_ 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) @@ -343,10 +351,10 @@ static int mips32_pracc_read_mem32(struct mips_ejtag *ejtag_info, uint32_t addr, int retval = ERROR_OK; int blocksize; - int bytesread; + int wordsread; uint32_t param_in[2]; - bytesread = 0; + wordsread = 0; while (count > 0) { blocksize = count; @@ -357,13 +365,13 @@ static int mips32_pracc_read_mem32(struct mips_ejtag *ejtag_info, uint32_t addr, param_in[1] = blocksize; retval = mips32_pracc_exec(ejtag_info, ARRAY_SIZE(code), code, - ARRAY_SIZE(param_in), param_in, blocksize, &buf[bytesread], 1); + ARRAY_SIZE(param_in), param_in, blocksize, &buf[wordsread], 1); if (retval != ERROR_OK) return retval; count -= blocksize; - addr += blocksize; - bytesread += blocksize; + addr += blocksize*sizeof(uint32_t); + wordsread += blocksize; } return retval; @@ -442,14 +450,17 @@ static int mips32_pracc_read_mem16(struct mips_ejtag *ejtag_info, uint32_t addr, /* 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; @@ -458,17 +469,21 @@ static int mips32_pracc_read_mem16(struct mips_ejtag *ejtag_info, uint32_t addr, 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); + + if (retval != ERROR_OK) + return retval; -/* count -= blocksize; */ -/* addr += blocksize; */ + 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; } @@ -513,14 +528,17 @@ static int mips32_pracc_read_mem8(struct mips_ejtag *ejtag_info, uint32_t addr, /* 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; @@ -529,17 +547,20 @@ static int mips32_pracc_read_mem8(struct mips_ejtag *ejtag_info, uint32_t addr, 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; } @@ -816,6 +837,9 @@ int mips32_pracc_write_mem(struct mips_ejtag *ejtag_info, uint32_t addr, int siz 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)) { @@ -825,9 +849,6 @@ int mips32_pracc_write_mem(struct mips_ejtag *ejtag_info, uint32_t addr, int siz 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;