mips32, change in pracc_list for dynamic allocation
pracc_list points to an array with code in the lower half and addr in the upper half. Change it to a struct with an instruction field and an address field. Requiered to make reallocation easier. As a side effect the code is less quirky. Change-Id: Ibf904a33a2f35a7f69284d2a2114f4b4ae79219f Signed-off-by: Salvador Arroyo <sarroyofdez@yahoo.es> Reviewed-on: http://openocd.zylin.com/4019 Tested-by: jenkins Reviewed-by: Freddie Chopin <freddie.chopin@gmail.com>
This commit is contained in:
parent
3414daed26
commit
c8b31aaa15
|
@ -235,18 +235,17 @@ int mips32_pracc_exec(struct mips_ejtag *ejtag_info, struct pracc_queue_info *ct
|
||||||
restart = 1;
|
restart = 1;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ERROR_JTAG_DEVICE_ERROR;
|
return ERROR_JTAG_DEVICE_ERROR;
|
||||||
}
|
}
|
||||||
/* check for store instruction at dmseg */
|
/* 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 != 0) {
|
||||||
if (store_addr > max_store_addr)
|
if (store_addr > max_store_addr)
|
||||||
max_store_addr = store_addr;
|
max_store_addr = store_addr;
|
||||||
store_pending++;
|
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 */
|
if (code_count == ctx->code_count) /* last instruction, start final check */
|
||||||
final_check = 1;
|
final_check = 1;
|
||||||
|
|
||||||
|
@ -306,7 +305,7 @@ inline void pracc_queue_init(struct pracc_queue_info *ctx)
|
||||||
ctx->code_count = 0;
|
ctx->code_count = 0;
|
||||||
ctx->store_count = 0;
|
ctx->store_count = 0;
|
||||||
|
|
||||||
ctx->pracc_list = malloc(2 * ctx->max_code * sizeof(uint32_t));
|
ctx->pracc_list = malloc(ctx->max_code * sizeof(pa_list));
|
||||||
if (ctx->pracc_list == NULL) {
|
if (ctx->pracc_list == NULL) {
|
||||||
LOG_ERROR("Out of memory");
|
LOG_ERROR("Out of memory");
|
||||||
ctx->retval = ERROR_FAIL;
|
ctx->retval = ERROR_FAIL;
|
||||||
|
@ -315,8 +314,8 @@ inline void pracc_queue_init(struct pracc_queue_info *ctx)
|
||||||
|
|
||||||
inline void pracc_add(struct pracc_queue_info *ctx, uint32_t addr, uint32_t instr)
|
inline 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 = instr;
|
||||||
ctx->pracc_list[ctx->code_count++] = instr;
|
ctx->pracc_list[ctx->code_count++].addr = addr;
|
||||||
if (addr)
|
if (addr)
|
||||||
ctx->store_count++;
|
ctx->store_count++;
|
||||||
}
|
}
|
||||||
|
@ -367,16 +366,16 @@ int mips32_pracc_queue_exec(struct mips_ejtag *ejtag_info, struct pracc_queue_in
|
||||||
mips_ejtag_set_instr(ejtag_info, EJTAG_INST_ALL);
|
mips_ejtag_set_instr(ejtag_info, EJTAG_INST_ALL);
|
||||||
|
|
||||||
int scan_count = 0;
|
int scan_count = 0;
|
||||||
for (int i = 0; i != 2 * ctx->code_count; i++) {
|
for (int i = 0; i != 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];
|
|
||||||
|
|
||||||
jtag_add_clocks(num_clocks);
|
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 */
|
int retval = jtag_execute_queue(); /* execute queued scans */
|
||||||
|
@ -385,24 +384,35 @@ int mips32_pracc_queue_exec(struct mips_ejtag *ejtag_info, struct pracc_queue_in
|
||||||
|
|
||||||
uint32_t fetch_addr = MIPS32_PRACC_TEXT; /* start address */
|
uint32_t fetch_addr = MIPS32_PRACC_TEXT; /* start address */
|
||||||
scan_count = 0;
|
scan_count = 0;
|
||||||
for (int i = 0; i != 2 * ctx->code_count; i++) { /* verify every pracc access */
|
for (int i = 0; i != ctx->code_count; i++) { /* verify every pracc access */
|
||||||
uint32_t store_addr = 0;
|
/* check pracc bit */
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
ejtag_ctrl = buf_get_u32(scan_in[scan_count].scan_32.ctrl, 0, 32);
|
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)) {
|
if (!(ejtag_ctrl & EJTAG_CTRL_PRACC)) {
|
||||||
LOG_ERROR("Error: access not pending count: %d", scan_count);
|
LOG_ERROR("Error: access not pending count: %d", scan_count);
|
||||||
retval = ERROR_FAIL;
|
retval = ERROR_FAIL;
|
||||||
goto exit;
|
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)) {
|
if (!(ejtag_ctrl & EJTAG_CTRL_PRNW)) {
|
||||||
LOG_ERROR("Not a store/write access, count: %d", scan_count);
|
LOG_ERROR("Not a store/write access, count: %d", scan_count);
|
||||||
retval = ERROR_FAIL;
|
retval = ERROR_FAIL;
|
||||||
|
@ -410,28 +420,14 @@ int mips32_pracc_queue_exec(struct mips_ejtag *ejtag_info, struct pracc_queue_in
|
||||||
}
|
}
|
||||||
if (addr != store_addr) {
|
if (addr != store_addr) {
|
||||||
LOG_ERROR("Store address mismatch, read: %" PRIx32 " expected: %" PRIx32 " count: %d",
|
LOG_ERROR("Store address mismatch, read: %" PRIx32 " expected: %" PRIx32 " count: %d",
|
||||||
addr, store_addr, scan_count);
|
addr, store_addr, scan_count);
|
||||||
retval = ERROR_FAIL;
|
retval = ERROR_FAIL;
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
int buf_index = (addr - MIPS32_PRACC_PARAM_OUT) / 4;
|
int buf_index = (addr - MIPS32_PRACC_PARAM_OUT) / 4;
|
||||||
buf[buf_index] = buf_get_u32(scan_in[scan_count].scan_32.data, 0, 32);
|
buf[buf_index] = buf_get_u32(scan_in[scan_count].scan_32.data, 0, 32);
|
||||||
|
scan_count++;
|
||||||
} 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++;
|
|
||||||
}
|
}
|
||||||
exit:
|
exit:
|
||||||
free(scan_in);
|
free(scan_in);
|
||||||
|
|
|
@ -42,12 +42,17 @@
|
||||||
#define NEG16(v) (((~(v)) + 1) & 0xFFFF)
|
#define NEG16(v) (((~(v)) + 1) & 0xFFFF)
|
||||||
/*#define NEG18(v) (((~(v)) + 1) & 0x3FFFF)*/
|
/*#define NEG18(v) (((~(v)) + 1) & 0x3FFFF)*/
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint32_t instr;
|
||||||
|
uint32_t addr;
|
||||||
|
} pa_list;
|
||||||
|
|
||||||
struct pracc_queue_info {
|
struct pracc_queue_info {
|
||||||
int retval;
|
int retval;
|
||||||
const int max_code;
|
const int max_code;
|
||||||
int code_count;
|
int code_count;
|
||||||
int store_count;
|
int store_count;
|
||||||
uint32_t *pracc_list; /* Code and store addresses */
|
pa_list *pracc_list; /* Code and store addresses at dmseg */
|
||||||
};
|
};
|
||||||
void pracc_queue_init(struct pracc_queue_info *ctx);
|
void pracc_queue_init(struct pracc_queue_info *ctx);
|
||||||
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);
|
||||||
|
|
|
@ -272,8 +272,8 @@ error:
|
||||||
|
|
||||||
int mips_ejtag_exit_debug(struct mips_ejtag *ejtag_info)
|
int mips_ejtag_exit_debug(struct mips_ejtag *ejtag_info)
|
||||||
{
|
{
|
||||||
uint32_t pracc_list[] = {MIPS32_DRET, 0};
|
pa_list pracc_list = {.instr = MIPS32_DRET, .addr = 0};
|
||||||
struct pracc_queue_info ctx = {.max_code = 1, .pracc_list = pracc_list, .code_count = 1, .store_count = 0};
|
struct pracc_queue_info ctx = {.max_code = 1, .pracc_list = &pracc_list, .code_count = 1, .store_count = 0};
|
||||||
|
|
||||||
/* execute our dret instruction */
|
/* execute our dret instruction */
|
||||||
ctx.retval = mips32_pracc_queue_exec(ejtag_info, &ctx, NULL);
|
ctx.retval = mips32_pracc_queue_exec(ejtag_info, &ctx, NULL);
|
||||||
|
|
Loading…
Reference in New Issue