fields[2].in_handler = NULL;
fields[2].in_handler_priv = NULL;
- jtag_add_dr_scan(3, fields, -1, NULL);
+ jtag_add_dr_scan(3, fields, -1);
fields[0].in_value = reg->value;
- fields[0].in_check_value = check_value;
- fields[0].in_check_mask = check_mask;
+ jtag_set_check_value(fields+0, check_value, check_mask, NULL);
- jtag_add_dr_scan(3, fields, -1, NULL);
+ jtag_add_dr_scan(3, fields, -1);
free(fields[1].out_value);
free(fields[2].out_value);
fields[2].in_handler = NULL;
fields[2].in_handler_priv = NULL;
- jtag_add_dr_scan(3, fields, -1, NULL);
+ jtag_add_dr_scan(3, fields, -1);
free(fields[0].out_value);
free(fields[1].out_value);
}
if (size == 8)
+ {
ERROR("TODO: add support for 64-bit values");
+ return -1;
+ }
else if (size == 4)
*data = target_buffer_get_u32(ctx->target, buf);
else if (size == 2)
*data = target_buffer_get_u16(ctx->target, buf);
else if (size == 1)
*data = buf[0];
+ else
+ return -1;
return 0;
}
u32 old_data_index = ctx->data_index;
u32 old_data_half = ctx->data_half;
u32 old_index = ctx->pipe_index;
+ u32 last_instruction = ctx->last_instruction;
u32 cycles = 0;
+ int current_pc_ok = ctx->pc_ok;
if (ctx->trace_data[ctx->pipe_index].flags & ETMV1_TRIGGER_CYCLE)
{
command_print(cmd_ctx, "--- trigger ---");
}
+
+ /* instructions execute in IE/D or BE/D cycles */
+ if ((pipestat == STAT_IE) || (pipestat == STAT_ID))
+ ctx->last_instruction = ctx->pipe_index;
/* if we don't have a valid pc skip until we reach an indirect branch */
if ((!ctx->pc_ok) && (pipestat != STAT_BE))
{
- if (pipestat == STAT_IE)
- ctx->last_instruction = ctx->pipe_index;
ctx->pipe_index++;
continue;
}
*/
old_data_index = ctx->data_index;
old_data_half = ctx->data_half;
+
+ ctx->last_instruction = ctx->pipe_index;
if ((retval = etmv1_branch_address(ctx)) != 0)
{
{
case 0x0: /* normal PC change */
next_pc = ctx->last_branch;
- ctx->last_instruction = old_index;
break;
case 0x1: /* tracing enabled */
command_print(cmd_ctx, "--- tracing enabled at 0x%8.8x ---", ctx->last_branch);
ctx->current_pc = ctx->last_branch;
ctx->pipe_index++;
- ctx->last_instruction = old_index;
continue;
break;
case 0x2: /* trace restarted after FIFO overflow */
command_print(cmd_ctx, "--- trace restarted after FIFO overflow at 0x%8.8x ---", ctx->last_branch);
ctx->current_pc = ctx->last_branch;
ctx->pipe_index++;
- ctx->last_instruction = old_index;
continue;
break;
case 0x3: /* exit from debug state */
command_print(cmd_ctx, "--- exit from debug state at 0x%8.8x ---", ctx->last_branch);
ctx->current_pc = ctx->last_branch;
ctx->pipe_index++;
- ctx->last_instruction = old_index;
continue;
break;
case 0x4: /* periodic synchronization point */
next_pc = ctx->last_branch;
- ctx->last_instruction = old_index;
+ /* if we had no valid PC prior to this synchronization point,
+ * we have to move on with the next trace cycle
+ */
+ if (!current_pc_ok)
+ {
+ command_print(cmd_ctx, "--- periodic synchronization point at 0x%8.8x ---", next_pc);
+ ctx->current_pc = next_pc;
+ ctx->pipe_index++;
+ continue;
+ }
break;
default: /* reserved */
ERROR("BUG: branch reason code 0x%x is reserved", ctx->last_branch_reason);
if (((ctx->last_branch >= 0x0) && (ctx->last_branch <= 0x20))
|| ((ctx->last_branch >= 0xffff0000) && (ctx->last_branch <= 0xffff0020)))
{
- ctx->last_instruction = old_index;
-
if ((ctx->last_branch & 0xff) == 0x10)
{
command_print(cmd_ctx, "data abort");
}
else if (retval == ERROR_TRACE_INSTRUCTION_UNAVAILABLE)
{
- /* TODO: handle incomplete images */
+ /* TODO: handle incomplete images
+ * for now we just quit the analsysis*/
+ return retval;
}
}
- cycles = old_index - ctx->last_instruction;
- ctx->last_instruction = old_index;
+ cycles = old_index - last_instruction;
}
if ((pipestat == STAT_ID) || (pipestat == STAT_BD))
do {
if ((retval = etmv1_next_packet(ctx, &packet, 0)) != 0)
- return -1;
+ return ERROR_ETM_ANALYSIS_FAILED;
ctx->last_ptr &= ~(0x7f << shift);
ctx->last_ptr |= (packet & 0x7f) << shift;
shift += 7;
{
u32 data;
if (etmv1_data(ctx, 4, &data) != 0)
- return -1;
+ return ERROR_ETM_ANALYSIS_FAILED;
command_print(cmd_ctx, "data: 0x%8.8x", data);
}
}
{
u32 data;
if (etmv1_data(ctx, arm_access_size(&instruction), &data) != 0)
- return -1;
+ return ERROR_ETM_ANALYSIS_FAILED;
command_print(cmd_ctx, "data: 0x%8.8x", data);
}
}
if (arm7_9->etm_ctx->trace_depth > 0)
{
free(arm7_9->etm_ctx->trace_data);
+ arm7_9->etm_ctx->trace_data = NULL;
}
arm7_9->etm_ctx->trace_depth = 0;
}
etm_get_reg(etm_config_reg);
command_print(cmd_ctx, "pairs of address comparators: %i", buf_get_u32(etm_config_reg->value, 0, 4));
command_print(cmd_ctx, "pairs of data comparators: %i", buf_get_u32(etm_config_reg->value, 4, 4));
- command_print(cmd_ctx, "memory map decoders: %i", buf_get_u32(etm_config_reg->value, 8, 4));
- command_print(cmd_ctx, "number of counters: %i", buf_get_u32(etm_config_reg->value, 12, 4));
+ command_print(cmd_ctx, "memory map decoders: %i", buf_get_u32(etm_config_reg->value, 8, 5));
+ command_print(cmd_ctx, "number of counters: %i", buf_get_u32(etm_config_reg->value, 13, 3));
command_print(cmd_ctx, "sequencer %spresent",
(buf_get_u32(etm_config_reg->value, 16, 1) == 1) ? "" : "not ");
command_print(cmd_ctx, "number of ext. inputs: %i", buf_get_u32(etm_config_reg->value, 17, 3));
case 2:
max_port_size = 16;
break;
+ default:
+ ERROR("Illegal max_port_size");
+ exit(-1);
}
command_print(cmd_ctx, "max. port size: %i", max_port_size);
if (image_open(etm_ctx->image, args[0], (argc >= 3) ? args[2] : NULL) != ERROR_OK)
{
- command_print(cmd_ctx, "image opening error: %s", etm_ctx->image->error_str);
free(etm_ctx->image);
etm_ctx->image = NULL;
return ERROR_OK;
if (fileio_open(&file, args[0], FILEIO_WRITE, FILEIO_BINARY) != ERROR_OK)
{
- command_print(cmd_ctx, "file open error: %s", file.error_str);
return ERROR_OK;
}
if (fileio_open(&file, args[0], FILEIO_READ, FILEIO_BINARY) != ERROR_OK)
{
- command_print(cmd_ctx, "file open error: %s", file.error_str);
return ERROR_OK;
}
if (arm7_9->etm_ctx->trace_depth > 0)
{
free(arm7_9->etm_ctx->trace_data);
+ arm7_9->etm_ctx->trace_data = NULL;
}
arm7_9->etm_ctx->trace_depth = 0;
armv4_5_common_t *armv4_5;
arm7_9_common_t *arm7_9;
etm_context_t *etm_ctx;
+ int retval;
target = get_current_target(cmd_ctx);
return ERROR_OK;
}
- etmv1_analyze_trace(etm_ctx, cmd_ctx);
+ if ((retval = etmv1_analyze_trace(etm_ctx, cmd_ctx)) != ERROR_OK)
+ {
+ switch(retval)
+ {
+ case ERROR_ETM_ANALYSIS_FAILED:
+ command_print(cmd_ctx, "further analysis failed (corrupted trace data or just end of data");
+ break;
+ case ERROR_TRACE_INSTRUCTION_UNAVAILABLE:
+ command_print(cmd_ctx, "no instruction for current address available, analysis aborted");
+ break;
+ case ERROR_TRACE_IMAGE_UNAVAILABLE:
+ command_print(cmd_ctx, "no image available for trace analysis");
+ break;
+ default:
+ command_print(cmd_ctx, "unknown error: %i", retval);
+ }
+ }
return ERROR_OK;
}