restart = 1;
continue;
}
-
return ERROR_JTAG_DEVICE_ERROR;
}
/* check for store instruction at dmseg */
- uint32_t store_addr = ctx->pracc_list[ctx->max_code + code_count];
+ uint32_t store_addr = ctx->pracc_list[code_count].addr;
if (store_addr != 0) {
if (store_addr > max_store_addr)
max_store_addr = store_addr;
store_pending++;
}
- instr = ctx->pracc_list[code_count++];
+ instr = ctx->pracc_list[code_count++].instr;
if (code_count == ctx->code_count) /* last instruction, start final check */
final_check = 1;
ctx->retval = ERROR_OK;
ctx->code_count = 0;
ctx->store_count = 0;
-
- ctx->pracc_list = malloc(2 * ctx->max_code * sizeof(uint32_t));
- if (ctx->pracc_list == NULL) {
- LOG_ERROR("Out of memory");
- ctx->retval = ERROR_FAIL;
- }
+ ctx->max_code = 0;
+ ctx->pracc_list = NULL;
}
-inline void pracc_add(struct pracc_queue_info *ctx, uint32_t addr, uint32_t instr)
+void pracc_add(struct pracc_queue_info *ctx, uint32_t addr, uint32_t instr)
{
- ctx->pracc_list[ctx->max_code + ctx->code_count] = addr;
- ctx->pracc_list[ctx->code_count++] = instr;
+ if (ctx->retval != ERROR_OK) /* On previous out of memory, return */
+ return;
+ if (ctx->code_count == ctx->max_code) {
+ void *p = realloc(ctx->pracc_list, sizeof(pa_list) * (ctx->max_code + PRACC_BLOCK));
+ if (p) {
+ ctx->max_code += PRACC_BLOCK;
+ ctx->pracc_list = p;
+ } else {
+ ctx->retval = ERROR_FAIL; /* Out of memory */
+ return;
+ }
+ }
+ ctx->pracc_list[ctx->code_count].instr = instr;
+ ctx->pracc_list[ctx->code_count++].addr = addr;
if (addr)
ctx->store_count++;
}
-inline void pracc_add_li32(struct pracc_queue_info *ctx, uint32_t reg_num, uint32_t data, bool optimize)
+void pracc_add_li32(struct pracc_queue_info *ctx, uint32_t reg_num, uint32_t data, bool optimize)
{
if (LOWER16(data) == 0 && optimize)
pracc_add(ctx, 0, MIPS32_LUI(reg_num, UPPER16(data))); /* load only upper value */
inline void pracc_queue_free(struct pracc_queue_info *ctx)
{
- if (ctx->code_count > ctx->max_code) /* Only for internal check, will be erased */
- LOG_ERROR("Internal error, code count: %d > max code: %d", ctx->code_count, ctx->max_code);
if (ctx->pracc_list != NULL)
free(ctx->pracc_list);
}
int mips32_pracc_queue_exec(struct mips_ejtag *ejtag_info, struct pracc_queue_info *ctx, uint32_t *buf)
{
+ if (ctx->retval != ERROR_OK) {
+ LOG_ERROR("Out of memory");
+ return ERROR_FAIL;
+ }
+
if (ejtag_info->mode == 0)
return mips32_pracc_exec(ejtag_info, ctx, buf);
mips_ejtag_set_instr(ejtag_info, EJTAG_INST_ALL);
int scan_count = 0;
- for (int i = 0; i != 2 * ctx->code_count; i++) {
- uint32_t data = 0;
- if (i & 1u) { /* Check store address from previous instruction, if not the first */
- if (i < 2 || 0 == ctx->pracc_list[ctx->max_code + (i / 2) - 1])
- continue;
- } else
- data = ctx->pracc_list[i / 2];
-
+ for (int i = 0; i != ctx->code_count; i++) {
jtag_add_clocks(num_clocks);
- mips_ejtag_add_scan_96(ejtag_info, ejtag_ctrl, data, scan_in[scan_count++].scan_96);
+ mips_ejtag_add_scan_96(ejtag_info, ejtag_ctrl, ctx->pracc_list[i].instr,
+ scan_in[scan_count++].scan_96);
+
+ /* Check store address from previous instruction, if not the first */
+ if (i > 0 && ctx->pracc_list[i - 1].addr) {
+ jtag_add_clocks(num_clocks);
+ mips_ejtag_add_scan_96(ejtag_info, ejtag_ctrl, 0, scan_in[scan_count++].scan_96);
+ }
}
int retval = jtag_execute_queue(); /* execute queued scans */
uint32_t fetch_addr = MIPS32_PRACC_TEXT; /* start address */
scan_count = 0;
- for (int i = 0; i != 2 * ctx->code_count; i++) { /* verify every pracc access */
- uint32_t store_addr = 0;
- if (i & 1u) { /* Read store addres from previous instruction, if not the first */
- store_addr = ctx->pracc_list[ctx->max_code + (i / 2) - 1];
- if (i < 2 || 0 == store_addr)
- continue;
- }
-
+ for (int i = 0; i != ctx->code_count; i++) { /* verify every pracc access */
+ /* check pracc bit */
ejtag_ctrl = buf_get_u32(scan_in[scan_count].scan_32.ctrl, 0, 32);
+ uint32_t addr = buf_get_u32(scan_in[scan_count].scan_32.addr, 0, 32);
if (!(ejtag_ctrl & EJTAG_CTRL_PRACC)) {
LOG_ERROR("Error: access not pending count: %d", scan_count);
retval = ERROR_FAIL;
goto exit;
}
+ if (ejtag_ctrl & EJTAG_CTRL_PRNW) {
+ LOG_ERROR("Not a fetch/read access, count: %d", scan_count);
+ retval = ERROR_FAIL;
+ goto exit;
+ }
+ if (addr != fetch_addr) {
+ LOG_ERROR("Fetch addr mismatch, read: %" PRIx32 " expected: %" PRIx32 " count: %d",
+ addr, fetch_addr, scan_count);
+ retval = ERROR_FAIL;
+ goto exit;
+ }
+ fetch_addr += 4;
+ scan_count++;
- uint32_t addr = buf_get_u32(scan_in[scan_count].scan_32.addr, 0, 32);
+ /* check if previous intrucction is a store instruction at dmesg */
+ if (i > 0 && ctx->pracc_list[i - 1].addr) {
+ uint32_t store_addr = ctx->pracc_list[i - 1].addr;
+ ejtag_ctrl = buf_get_u32(scan_in[scan_count].scan_32.ctrl, 0, 32);
+ addr = buf_get_u32(scan_in[scan_count].scan_32.addr, 0, 32);
- if (store_addr != 0) {
if (!(ejtag_ctrl & EJTAG_CTRL_PRNW)) {
LOG_ERROR("Not a store/write access, count: %d", scan_count);
retval = ERROR_FAIL;
}
if (addr != store_addr) {
LOG_ERROR("Store address mismatch, read: %" PRIx32 " expected: %" PRIx32 " count: %d",
- addr, store_addr, scan_count);
+ addr, store_addr, scan_count);
retval = ERROR_FAIL;
goto exit;
}
int buf_index = (addr - MIPS32_PRACC_PARAM_OUT) / 4;
buf[buf_index] = buf_get_u32(scan_in[scan_count].scan_32.data, 0, 32);
-
- } else {
- if (ejtag_ctrl & EJTAG_CTRL_PRNW) {
- LOG_ERROR("Not a fetch/read access, count: %d", scan_count);
- retval = ERROR_FAIL;
- goto exit;
- }
- if (addr != fetch_addr) {
- LOG_ERROR("Fetch addr mismatch, read: %" PRIx32 " expected: %" PRIx32 " count: %d",
- addr, fetch_addr, scan_count);
- retval = ERROR_FAIL;
- goto exit;
- }
- fetch_addr += 4;
+ scan_count++;
}
- scan_count++;
}
exit:
free(scan_in);
int mips32_pracc_read_u32(struct mips_ejtag *ejtag_info, uint32_t addr, uint32_t *buf)
{
- struct pracc_queue_info ctx = {.max_code = 8};
+ struct pracc_queue_info ctx;
pracc_queue_init(&ctx);
- if (ctx.retval != ERROR_OK)
- goto exit;
pracc_add(&ctx, 0, MIPS32_LUI(15, PRACC_UPPER_BASE_ADDR)); /* $15 = MIPS32_PRACC_BASE_ADDR */
pracc_add(&ctx, 0, MIPS32_LUI(8, UPPER16((addr + 0x8000)))); /* load $8 with modified upper address */
pracc_add(&ctx, 0, MIPS32_MFC0(15, 31, 0)); /* move COP0 DeSave to $15 */
ctx.retval = mips32_pracc_queue_exec(ejtag_info, &ctx, buf);
-exit:
pracc_queue_free(&ctx);
return ctx.retval;
}
return mips32_pracc_read_u32(ejtag_info, addr, (uint32_t *)buf);
uint32_t *data = NULL;
- struct pracc_queue_info ctx = {.max_code = 256 * 3 + 8 + 1}; /* alloc memory for the worst case */
+ struct pracc_queue_info ctx;
pracc_queue_init(&ctx);
- if (ctx.retval != ERROR_OK)
- goto exit;
if (size != 4) {
data = malloc(256 * sizeof(uint32_t));
int mips32_cp0_read(struct mips_ejtag *ejtag_info, uint32_t *val, uint32_t cp0_reg, uint32_t cp0_sel)
{
- struct pracc_queue_info ctx = {.max_code = 7};
+ struct pracc_queue_info ctx;
pracc_queue_init(&ctx);
- if (ctx.retval != ERROR_OK)
- goto exit;
pracc_add(&ctx, 0, MIPS32_LUI(15, PRACC_UPPER_BASE_ADDR)); /* $15 = MIPS32_PRACC_BASE_ADDR */
pracc_add(&ctx, 0, MIPS32_MFC0(8, cp0_reg, cp0_sel)); /* move cp0 reg / sel to $8 */
pracc_add(&ctx, 0, MIPS32_ORI(8, 8, LOWER16(ejtag_info->reg8))); /* restore lower 16 bits of $8 */
ctx.retval = mips32_pracc_queue_exec(ejtag_info, &ctx, val);
-exit:
pracc_queue_free(&ctx);
return ctx.retval;
}
int mips32_cp0_write(struct mips_ejtag *ejtag_info, uint32_t val, uint32_t cp0_reg, uint32_t cp0_sel)
{
- struct pracc_queue_info ctx = {.max_code = 6};
+ struct pracc_queue_info ctx;
pracc_queue_init(&ctx);
- if (ctx.retval != ERROR_OK)
- goto exit;
pracc_add_li32(&ctx, 15, val, 0); /* Load val to $15 */
pracc_add(&ctx, 0, MIPS32_MFC0(15, 31, 0)); /* restore $15 from DeSave */
ctx.retval = mips32_pracc_queue_exec(ejtag_info, &ctx, NULL);
-exit:
pracc_queue_free(&ctx);
return ctx.retval;
}
static int mips32_pracc_synchronize_cache(struct mips_ejtag *ejtag_info,
uint32_t start_addr, uint32_t end_addr, int cached, int rel)
{
- struct pracc_queue_info ctx = {.max_code = 256 * 2 + 5};
+ struct pracc_queue_info ctx;
pracc_queue_init(&ctx);
- if (ctx.retval != ERROR_OK)
- goto exit;
+
/** Find cache line size in bytes */
uint32_t clsiz;
if (rel) { /* Release 2 (rel = 1) */
static int mips32_pracc_write_mem_generic(struct mips_ejtag *ejtag_info,
uint32_t addr, int size, int count, const void *buf)
{
- struct pracc_queue_info ctx = {.max_code = 128 * 3 + 5 + 1}; /* alloc memory for the worst case */
+ struct pracc_queue_info ctx;
pracc_queue_init(&ctx);
- if (ctx.retval != ERROR_OK)
- goto exit;
const uint32_t *buf32 = buf;
const uint16_t *buf16 = buf;
MIPS32_MTC0(1, 24, 0), /* move $1 to depc (pc) */
};
- struct pracc_queue_info ctx = {.max_code = 37 * 2 + 7 + 1};
+ struct pracc_queue_info ctx;
pracc_queue_init(&ctx);
- if (ctx.retval != ERROR_OK)
- goto exit;
/* load registers 2 to 31 with li32, optimize */
for (int i = 2; i < 32; i++)
ejtag_info->reg8 = regs[8];
ejtag_info->reg9 = regs[9];
-exit:
pracc_queue_free(&ctx);
return ctx.retval;
}
MIPS32_MFC0(8, 24, 0), /* move depc (pc) to $8 */
};
- struct pracc_queue_info ctx = {.max_code = 49};
+ struct pracc_queue_info ctx;
pracc_queue_init(&ctx);
- if (ctx.retval != ERROR_OK)
- goto exit;
pracc_add(&ctx, 0, MIPS32_MTC0(1, 31, 0)); /* move $1 to COP0 DeSave */
pracc_add(&ctx, 0, MIPS32_LUI(1, PRACC_UPPER_BASE_ADDR)); /* $1 = MIP32_PRACC_BASE_ADDR */
ejtag_info->reg8 = regs[8]; /* reg8 is saved but not restored, next called function should restore it */
ejtag_info->reg9 = regs[9];
-exit:
pracc_queue_free(&ctx);
return ctx.retval;
}