- added support for error handlers to JTAG scan commands (jtag_[plain_][ir|dr]_scan)

- catch apparently broken JTAG IR scan after ARM926EJ-S CP15 operations
- added "arm7_9 dump_etb" command


git-svn-id: svn://svn.berlios.de/openocd/trunk@142 b42882b7-edfa-0310-969c-e2dbd0fdcd60
__archive__
drath 2007-04-25 20:15:59 +00:00
parent 04dc98916d
commit 22bc5194ae
25 changed files with 462 additions and 182 deletions

View File

@ -357,6 +357,10 @@ int command_run_line(command_context_t *context, char *line)
if (!*line) if (!*line)
return ERROR_OK; return ERROR_OK;
/* ignore comments */
if (*line && (line[0] == '#'))
return ERROR_OK;
if (context->echo) if (context->echo)
{ {
command_print(context, "%s", line); command_print(context, "%s", line);

View File

@ -331,6 +331,12 @@ int amt_jtagaccel_execute_queue(void)
int scan_size; int scan_size;
enum scan_type type; enum scan_type type;
u8 *buffer; u8 *buffer;
int retval;
/* return ERROR_OK, unless a jtag_read_buffer returns a failed check
* that wasn't handled by a caller-provided error handler
*/
retval = ERROR_OK;
while (cmd) while (cmd)
{ {
@ -379,7 +385,7 @@ int amt_jtagaccel_execute_queue(void)
type = jtag_scan_type(cmd->cmd.scan); type = jtag_scan_type(cmd->cmd.scan);
amt_jtagaccel_scan(cmd->cmd.scan->ir_scan, type, buffer, scan_size); amt_jtagaccel_scan(cmd->cmd.scan->ir_scan, type, buffer, scan_size);
if (jtag_read_buffer(buffer, cmd->cmd.scan) != ERROR_OK) if (jtag_read_buffer(buffer, cmd->cmd.scan) != ERROR_OK)
return ERROR_JTAG_QUEUE_FAILED; retval = ERROR_JTAG_QUEUE_FAILED;
if (buffer) if (buffer)
free(buffer); free(buffer);
break; break;
@ -396,7 +402,7 @@ int amt_jtagaccel_execute_queue(void)
cmd = cmd->next; cmd = cmd->next;
} }
return ERROR_OK; return retval;
} }
#if PARPORT_USE_GIVEIO == 1 #if PARPORT_USE_GIVEIO == 1

View File

@ -182,6 +182,7 @@ int bitbang_execute_queue(void)
int scan_size; int scan_size;
enum scan_type type; enum scan_type type;
u8 *buffer; u8 *buffer;
int retval;
if (!bitbang_interface) if (!bitbang_interface)
{ {
@ -189,6 +190,11 @@ int bitbang_execute_queue(void)
exit(-1); exit(-1);
} }
/* return ERROR_OK, unless a jtag_read_buffer returns a failed check
* that wasn't handled by a caller-provided error handler
*/
retval = ERROR_OK;
while (cmd) while (cmd)
{ {
switch (cmd->type) switch (cmd->type)
@ -234,7 +240,7 @@ int bitbang_execute_queue(void)
break; break;
case JTAG_SCAN: case JTAG_SCAN:
#ifdef _DEBUG_JTAG_IO_ #ifdef _DEBUG_JTAG_IO_
DEBUG("scan end in %i", cmd->cmd.scan->end_state); DEBUG("%s scan end in %i", (cmd->cmd.scan->ir_scan) ? "IR" : "DR", cmd->cmd.scan->end_state);
#endif #endif
if (cmd->cmd.scan->end_state != -1) if (cmd->cmd.scan->end_state != -1)
bitbang_end_state(cmd->cmd.scan->end_state); bitbang_end_state(cmd->cmd.scan->end_state);
@ -242,7 +248,7 @@ int bitbang_execute_queue(void)
type = jtag_scan_type(cmd->cmd.scan); type = jtag_scan_type(cmd->cmd.scan);
bitbang_scan(cmd->cmd.scan->ir_scan, type, buffer, scan_size); bitbang_scan(cmd->cmd.scan->ir_scan, type, buffer, scan_size);
if (jtag_read_buffer(buffer, cmd->cmd.scan) != ERROR_OK) if (jtag_read_buffer(buffer, cmd->cmd.scan) != ERROR_OK)
return ERROR_JTAG_QUEUE_FAILED; retval = ERROR_JTAG_QUEUE_FAILED;
if (buffer) if (buffer)
free(buffer); free(buffer);
break; break;
@ -259,6 +265,6 @@ int bitbang_execute_queue(void)
cmd = cmd->next; cmd = cmd->next;
} }
return ERROR_OK; return retval;
} }

View File

@ -403,6 +403,11 @@ int ft2232_send_and_recv(jtag_command_t *first, jtag_command_t *last)
ft2232_expect_read = 0; ft2232_expect_read = 0;
ft2232_read_pointer = 0; ft2232_read_pointer = 0;
/* return ERROR_OK, unless a jtag_read_buffer returns a failed check
* that wasn't handled by a caller-provided error handler
*/
retval = ERROR_OK;
cmd = first; cmd = first;
while (cmd != last) while (cmd != last)
{ {
@ -415,7 +420,8 @@ int ft2232_send_and_recv(jtag_command_t *first, jtag_command_t *last)
scan_size = jtag_scan_size(cmd->cmd.scan); scan_size = jtag_scan_size(cmd->cmd.scan);
buffer = calloc(CEIL(scan_size, 8), 1); buffer = calloc(CEIL(scan_size, 8), 1);
ft2232_read_scan(type, buffer, scan_size); ft2232_read_scan(type, buffer, scan_size);
jtag_read_buffer(buffer, cmd->cmd.scan); if (jtag_read_buffer(buffer, cmd->cmd.scan) != ERROR_OK)
retval = ERROR_JTAG_QUEUE_FAILED;
free(buffer); free(buffer);
} }
break; break;
@ -427,7 +433,7 @@ int ft2232_send_and_recv(jtag_command_t *first, jtag_command_t *last)
ft2232_buffer_size = 0; ft2232_buffer_size = 0;
return ERROR_OK; return retval;
} }
void ft2232_add_pathmove(pathmove_command_t *cmd) void ft2232_add_pathmove(pathmove_command_t *cmd)
@ -1039,6 +1045,12 @@ int ft2232_execute_queue()
int i; int i;
int predicted_size = 0; int predicted_size = 0;
int require_send = 0; int require_send = 0;
int retval;
/* return ERROR_OK, unless ft2232_send_and_recv reports a failed check
* that wasn't handled by a caller-provided error handler
*/
retval = ERROR_OK;
ft2232_buffer_size = 0; ft2232_buffer_size = 0;
ft2232_expect_read = 0; ft2232_expect_read = 0;
@ -1060,7 +1072,8 @@ int ft2232_execute_queue()
predicted_size = 3; predicted_size = 3;
if (ft2232_buffer_size + predicted_size + 1 > FT2232_BUFFER_SIZE) if (ft2232_buffer_size + predicted_size + 1 > FT2232_BUFFER_SIZE)
{ {
ft2232_send_and_recv(first_unsent, cmd); if (ft2232_send_and_recv(first_unsent, cmd) != ERROR_OK)
retval = ERROR_JTAG_QUEUE_FAILED;
require_send = 0; require_send = 0;
first_unsent = cmd; first_unsent = cmd;
} }
@ -1084,7 +1097,8 @@ int ft2232_execute_queue()
predicted_size += 3; predicted_size += 3;
if (ft2232_buffer_size + predicted_size + 1 > FT2232_BUFFER_SIZE) if (ft2232_buffer_size + predicted_size + 1 > FT2232_BUFFER_SIZE)
{ {
ft2232_send_and_recv(first_unsent, cmd); if (ft2232_send_and_recv(first_unsent, cmd) != ERROR_OK)
retval = ERROR_JTAG_QUEUE_FAILED;
require_send = 0; require_send = 0;
first_unsent = cmd; first_unsent = cmd;
} }
@ -1135,7 +1149,8 @@ int ft2232_execute_queue()
predicted_size = 3; predicted_size = 3;
if (ft2232_buffer_size + predicted_size + 1 > FT2232_BUFFER_SIZE) if (ft2232_buffer_size + predicted_size + 1 > FT2232_BUFFER_SIZE)
{ {
ft2232_send_and_recv(first_unsent, cmd); if (ft2232_send_and_recv(first_unsent, cmd) != ERROR_OK)
retval = ERROR_JTAG_QUEUE_FAILED;
require_send = 0; require_send = 0;
first_unsent = cmd; first_unsent = cmd;
} }
@ -1159,7 +1174,8 @@ int ft2232_execute_queue()
predicted_size = 3 * CEIL(cmd->cmd.pathmove->num_states, 7); predicted_size = 3 * CEIL(cmd->cmd.pathmove->num_states, 7);
if (ft2232_buffer_size + predicted_size + 1 > FT2232_BUFFER_SIZE) if (ft2232_buffer_size + predicted_size + 1 > FT2232_BUFFER_SIZE)
{ {
ft2232_send_and_recv(first_unsent, cmd); if (ft2232_send_and_recv(first_unsent, cmd) != ERROR_OK)
retval = ERROR_JTAG_QUEUE_FAILED;
require_send = 0; require_send = 0;
first_unsent = cmd; first_unsent = cmd;
} }
@ -1178,7 +1194,8 @@ int ft2232_execute_queue()
DEBUG("oversized ft2232 scan (predicted_size > FT2232_BUFFER_SIZE)"); DEBUG("oversized ft2232 scan (predicted_size > FT2232_BUFFER_SIZE)");
/* unsent commands before this */ /* unsent commands before this */
if (first_unsent != cmd) if (first_unsent != cmd)
ft2232_send_and_recv(first_unsent, cmd); if (ft2232_send_and_recv(first_unsent, cmd) != ERROR_OK)
retval = ERROR_JTAG_QUEUE_FAILED;
/* current command */ /* current command */
if (cmd->cmd.scan->end_state != -1) if (cmd->cmd.scan->end_state != -1)
@ -1193,7 +1210,8 @@ int ft2232_execute_queue()
else if (ft2232_buffer_size + predicted_size + 1 > FT2232_BUFFER_SIZE) else if (ft2232_buffer_size + predicted_size + 1 > FT2232_BUFFER_SIZE)
{ {
DEBUG("ft2232 buffer size reached, sending queued commands (first_unsent: %p, cmd: %p)", first_unsent, cmd); DEBUG("ft2232 buffer size reached, sending queued commands (first_unsent: %p, cmd: %p)", first_unsent, cmd);
ft2232_send_and_recv(first_unsent, cmd); if (ft2232_send_and_recv(first_unsent, cmd) != ERROR_OK)
retval = ERROR_JTAG_QUEUE_FAILED;
require_send = 0; require_send = 0;
first_unsent = cmd; first_unsent = cmd;
} }
@ -1210,7 +1228,8 @@ int ft2232_execute_queue()
#endif #endif
break; break;
case JTAG_SLEEP: case JTAG_SLEEP:
ft2232_send_and_recv(first_unsent, cmd); if (ft2232_send_and_recv(first_unsent, cmd) != ERROR_OK)
retval = ERROR_JTAG_QUEUE_FAILED;
first_unsent = cmd->next; first_unsent = cmd->next;
jtag_sleep(cmd->cmd.sleep->us); jtag_sleep(cmd->cmd.sleep->us);
#ifdef _DEBUG_JTAG_IO_ #ifdef _DEBUG_JTAG_IO_
@ -1225,9 +1244,10 @@ int ft2232_execute_queue()
} }
if (require_send > 0) if (require_send > 0)
ft2232_send_and_recv(first_unsent, cmd); if (ft2232_send_and_recv(first_unsent, cmd) != ERROR_OK)
retval = ERROR_JTAG_QUEUE_FAILED;
return ERROR_OK; return retval;
} }
#if BUILD_FT2232_FTD2XX == 1 #if BUILD_FT2232_FTD2XX == 1

View File

@ -360,6 +360,12 @@ int gw16012_execute_queue(void)
int scan_size; int scan_size;
enum scan_type type; enum scan_type type;
u8 *buffer; u8 *buffer;
int retval;
/* return ERROR_OK, unless a jtag_read_buffer returns a failed check
* that wasn't handled by a caller-provided error handler
*/
retval = ERROR_OK;
while (cmd) while (cmd)
{ {
@ -415,7 +421,7 @@ int gw16012_execute_queue(void)
#endif #endif
gw16012_scan(cmd->cmd.scan->ir_scan, type, buffer, scan_size); gw16012_scan(cmd->cmd.scan->ir_scan, type, buffer, scan_size);
if (jtag_read_buffer(buffer, cmd->cmd.scan) != ERROR_OK) if (jtag_read_buffer(buffer, cmd->cmd.scan) != ERROR_OK)
return ERROR_JTAG_QUEUE_FAILED; retval = ERROR_JTAG_QUEUE_FAILED;
if (buffer) if (buffer)
free(buffer); free(buffer);
break; break;
@ -432,7 +438,7 @@ int gw16012_execute_queue(void)
cmd = cmd->next; cmd = cmd->next;
} }
return ERROR_OK; return retval;
} }
#if PARPORT_USE_GIVEIO == 1 #if PARPORT_USE_GIVEIO == 1

View File

@ -191,11 +191,12 @@ jtag_interface_t *jtag = NULL;
char* jtag_interface = NULL; char* jtag_interface = NULL;
int jtag_speed = -1; int jtag_speed = -1;
/* forward declarations */ /* forward declarations */
int jtag_add_ir_scan(int num_fields, scan_field_t *fields, enum tap_state endstate); int jtag_add_ir_scan(int num_fields, scan_field_t *fields, enum tap_state endstate, error_handler_t *error_handler);
int jtag_add_dr_scan(int num_fields, scan_field_t *fields, enum tap_state endstate); int jtag_add_dr_scan(int num_fields, scan_field_t *fields, enum tap_state endstate, error_handler_t *error_handler);
int jtag_add_plain_ir_scan(int num_fields, scan_field_t *fields, enum tap_state endstate); int jtag_add_plain_ir_scan(int num_fields, scan_field_t *fields, enum tap_state endstate, error_handler_t *error_handler);
int jtag_add_plain_dr_scan(int num_fields, scan_field_t *fields, enum tap_state endstate); int jtag_add_plain_dr_scan(int num_fields, scan_field_t *fields, enum tap_state endstate, error_handler_t *error_handler);
int jtag_add_statemove(enum tap_state endstate); int jtag_add_statemove(enum tap_state endstate);
int jtag_add_pathmove(int num_states, enum tap_state *path); int jtag_add_pathmove(int num_states, enum tap_state *path);
int jtag_add_runtest(int num_cycles, enum tap_state endstate); int jtag_add_runtest(int num_cycles, enum tap_state endstate);
@ -364,13 +365,12 @@ void cmd_queue_free()
cmd_queue_pages = NULL; cmd_queue_pages = NULL;
} }
int jtag_add_ir_scan(int num_fields, scan_field_t *fields, enum tap_state state) int jtag_add_ir_scan(int num_fields, scan_field_t *fields, enum tap_state state, error_handler_t *error_handler)
{ {
jtag_command_t **last_cmd; jtag_command_t **last_cmd;
jtag_device_t *device; jtag_device_t *device;
int i, j; int i, j;
int scan_size = 0; int scan_size = 0;
/* int changed = 0; */
if (jtag_trst == 1) if (jtag_trst == 1)
{ {
@ -378,26 +378,6 @@ int jtag_add_ir_scan(int num_fields, scan_field_t *fields, enum tap_state state)
return ERROR_JTAG_TRST_ASSERTED; return ERROR_JTAG_TRST_ASSERTED;
} }
/*
for (i=0; i<num_fields; i++)
{
device = jtag_get_device(fields[i].device);
if (device)
{
if (buf_cmp(device->cur_instr, fields[i].out_value, device->ir_length))
changed = 1;
}
else
{
ERROR("inexistant device specified for ir scan");
return ERROR_INVALID_ARGUMENTS;
}
}
if (!changed)
return ERROR_OK;
*/
last_cmd = jtag_get_last_command_p(); last_cmd = jtag_get_last_command_p();
/* allocate memory for a new list member */ /* allocate memory for a new list member */
@ -412,6 +392,15 @@ int jtag_add_ir_scan(int num_fields, scan_field_t *fields, enum tap_state state)
(*last_cmd)->cmd.scan->num_fields = jtag_num_devices; /* one field per device */ (*last_cmd)->cmd.scan->num_fields = jtag_num_devices; /* one field per device */
(*last_cmd)->cmd.scan->fields = cmd_queue_alloc(jtag_num_devices * sizeof(scan_field_t)); (*last_cmd)->cmd.scan->fields = cmd_queue_alloc(jtag_num_devices * sizeof(scan_field_t));
(*last_cmd)->cmd.scan->end_state = state; (*last_cmd)->cmd.scan->end_state = state;
if (error_handler)
{
(*last_cmd)->cmd.scan->error_handler = cmd_queue_alloc(sizeof(error_handler_t));
*(*last_cmd)->cmd.scan->error_handler = *error_handler;
}
else
{
(*last_cmd)->cmd.scan->error_handler = NULL;
}
if (state != -1) if (state != -1)
cmd_queue_end_state = state; cmd_queue_end_state = state;
@ -475,7 +464,7 @@ int jtag_add_ir_scan(int num_fields, scan_field_t *fields, enum tap_state state)
return ERROR_OK; return ERROR_OK;
} }
int jtag_add_plain_ir_scan(int num_fields, scan_field_t *fields, enum tap_state state) int jtag_add_plain_ir_scan(int num_fields, scan_field_t *fields, enum tap_state state, error_handler_t *error_handler)
{ {
jtag_command_t **last_cmd; jtag_command_t **last_cmd;
int i; int i;
@ -500,6 +489,15 @@ int jtag_add_plain_ir_scan(int num_fields, scan_field_t *fields, enum tap_state
(*last_cmd)->cmd.scan->num_fields = num_fields; (*last_cmd)->cmd.scan->num_fields = num_fields;
(*last_cmd)->cmd.scan->fields = cmd_queue_alloc(num_fields * sizeof(scan_field_t)); (*last_cmd)->cmd.scan->fields = cmd_queue_alloc(num_fields * sizeof(scan_field_t));
(*last_cmd)->cmd.scan->end_state = state; (*last_cmd)->cmd.scan->end_state = state;
if (error_handler)
{
(*last_cmd)->cmd.scan->error_handler = cmd_queue_alloc(sizeof(error_handler_t));
*(*last_cmd)->cmd.scan->error_handler = *error_handler;
}
else
{
(*last_cmd)->cmd.scan->error_handler = NULL;
}
if (state != -1) if (state != -1)
cmd_queue_end_state = state; cmd_queue_end_state = state;
@ -529,7 +527,7 @@ int jtag_add_plain_ir_scan(int num_fields, scan_field_t *fields, enum tap_state
return ERROR_OK; return ERROR_OK;
} }
int jtag_add_dr_scan(int num_fields, scan_field_t *fields, enum tap_state state) int jtag_add_dr_scan(int num_fields, scan_field_t *fields, enum tap_state state, error_handler_t *error_handler)
{ {
int i, j; int i, j;
int bypass_devices = 0; int bypass_devices = 0;
@ -564,6 +562,15 @@ int jtag_add_dr_scan(int num_fields, scan_field_t *fields, enum tap_state state)
(*last_cmd)->cmd.scan->num_fields = num_fields + bypass_devices; (*last_cmd)->cmd.scan->num_fields = num_fields + bypass_devices;
(*last_cmd)->cmd.scan->fields = cmd_queue_alloc((num_fields + bypass_devices) * sizeof(scan_field_t)); (*last_cmd)->cmd.scan->fields = cmd_queue_alloc((num_fields + bypass_devices) * sizeof(scan_field_t));
(*last_cmd)->cmd.scan->end_state = state; (*last_cmd)->cmd.scan->end_state = state;
if (error_handler)
{
(*last_cmd)->cmd.scan->error_handler = cmd_queue_alloc(sizeof(error_handler_t));
*(*last_cmd)->cmd.scan->error_handler = *error_handler;
}
else
{
(*last_cmd)->cmd.scan->error_handler = NULL;
}
if (state != -1) if (state != -1)
cmd_queue_end_state = state; cmd_queue_end_state = state;
@ -628,7 +635,7 @@ int jtag_add_dr_scan(int num_fields, scan_field_t *fields, enum tap_state state)
return ERROR_OK; return ERROR_OK;
} }
int jtag_add_plain_dr_scan(int num_fields, scan_field_t *fields, enum tap_state state) int jtag_add_plain_dr_scan(int num_fields, scan_field_t *fields, enum tap_state state, error_handler_t *error_handler)
{ {
int i; int i;
jtag_command_t **last_cmd = jtag_get_last_command_p(); jtag_command_t **last_cmd = jtag_get_last_command_p();
@ -651,6 +658,15 @@ int jtag_add_plain_dr_scan(int num_fields, scan_field_t *fields, enum tap_state
(*last_cmd)->cmd.scan->num_fields = num_fields; (*last_cmd)->cmd.scan->num_fields = num_fields;
(*last_cmd)->cmd.scan->fields = cmd_queue_alloc(num_fields * sizeof(scan_field_t)); (*last_cmd)->cmd.scan->fields = cmd_queue_alloc(num_fields * sizeof(scan_field_t));
(*last_cmd)->cmd.scan->end_state = state; (*last_cmd)->cmd.scan->end_state = state;
if (error_handler)
{
(*last_cmd)->cmd.scan->error_handler = cmd_queue_alloc(sizeof(error_handler_t));
*(*last_cmd)->cmd.scan->error_handler = *error_handler;
}
else
{
(*last_cmd)->cmd.scan->error_handler = NULL;
}
if (state != -1) if (state != -1)
cmd_queue_end_state = state; cmd_queue_end_state = state;
@ -1009,7 +1025,10 @@ int jtag_read_buffer(u8 *buffer, scan_command_t *cmd)
{ {
int i; int i;
int bit_count = 0; int bit_count = 0;
int retval = ERROR_OK; int retval;
/* we return ERROR_OK, unless a check fails, or a handler reports a problem */
retval = ERROR_OK;
for (i=0; i < cmd->num_fields; i++) for (i=0; i < cmd->num_fields; i++)
{ {
@ -1028,7 +1047,6 @@ int jtag_read_buffer(u8 *buffer, scan_command_t *cmd)
free(char_buf); free(char_buf);
#endif #endif
if (cmd->fields[i].in_value) if (cmd->fields[i].in_value)
{ {
buf_cpy(captured, cmd->fields[i].in_value, num_bits); buf_cpy(captured, cmd->fields[i].in_value, num_bits);
@ -1037,7 +1055,6 @@ int jtag_read_buffer(u8 *buffer, scan_command_t *cmd)
{ {
if (cmd->fields[i].in_handler(cmd->fields[i].in_value, cmd->fields[i].in_handler_priv) != ERROR_OK) if (cmd->fields[i].in_handler(cmd->fields[i].in_value, cmd->fields[i].in_handler_priv) != ERROR_OK)
{ {
/* TODO: error reporting */
WARNING("in_handler reported a failed check"); WARNING("in_handler reported a failed check");
retval = ERROR_JTAG_QUEUE_FAILED; retval = ERROR_JTAG_QUEUE_FAILED;
} }
@ -1049,27 +1066,63 @@ int jtag_read_buffer(u8 *buffer, scan_command_t *cmd)
{ {
if (cmd->fields[i].in_handler(captured, cmd->fields[i].in_handler_priv) != ERROR_OK) if (cmd->fields[i].in_handler(captured, cmd->fields[i].in_handler_priv) != ERROR_OK)
{ {
/* TODO: error reporting */ /* We're going to call the error:handler later, but if the in_handler
* reported an error we report this failure upstream
*/
WARNING("in_handler reported a failed check"); WARNING("in_handler reported a failed check");
retval = ERROR_JTAG_QUEUE_FAILED; retval = ERROR_JTAG_QUEUE_FAILED;
} }
} }
if (cmd->fields[i].in_check_value) if (cmd->fields[i].in_check_value)
{ {
if ((cmd->fields[i].in_check_mask && buf_cmp_mask(captured, cmd->fields[i].in_check_value, cmd->fields[i].in_check_mask, num_bits)) int compare_failed = 0;
|| (!cmd->fields[i].in_check_mask && buf_cmp(captured, cmd->fields[i].in_check_mask, num_bits)))
if (cmd->fields[i].in_check_mask)
compare_failed = buf_cmp_mask(captured, cmd->fields[i].in_check_value, cmd->fields[i].in_check_mask, num_bits);
else
compare_failed = buf_cmp(captured, cmd->fields[i].in_check_value, num_bits);
if (compare_failed)
{ {
char *captured_char = buf_to_str(captured, (num_bits > 64) ? 64 : num_bits, 16); char *captured_char = buf_to_str(captured, (num_bits > 64) ? 64 : num_bits, 16);
char *in_check_value_char = buf_to_str(cmd->fields[i].in_check_value, (num_bits > 64) ? 64 : num_bits, 16); char *in_check_value_char = buf_to_str(cmd->fields[i].in_check_value, (num_bits > 64) ? 64 : num_bits, 16);
char *in_check_mask_char = buf_to_str(cmd->fields[i].in_check_mask, (num_bits > 64) ? 64 : num_bits, 16);
/* TODO: error reporting */ if (cmd->error_handler)
WARNING("value captured during scan didn't pass the requested check: captured: 0x%s check_value: 0x%s check_mask: 0x%s", captured_char, in_check_value_char, in_check_mask_char); {
retval = ERROR_JTAG_QUEUE_FAILED; /* ask the error handler if once has been specified if this is a real problem */
if (cmd->error_handler->error_handler(captured, cmd->error_handler->error_handler_priv) != ERROR_OK)
retval = ERROR_JTAG_QUEUE_FAILED;
else
compare_failed = 0;
}
else
{
/* if there wasn't a handler specified, we report a failure */
retval = ERROR_JTAG_QUEUE_FAILED;
}
/* An error handler could have caught the failing check
* only report a problem when there wasn't a handler, or if the handler
* acknowledged the error
*/
if (compare_failed)
{
if (cmd->fields[i].in_check_mask)
{
char *in_check_mask_char;
in_check_mask_char = buf_to_str(cmd->fields[i].in_check_mask, (num_bits > 64) ? 64 : num_bits, 16);
WARNING("value captured during scan didn't pass the requested check: captured: 0x%s check_value: 0x%s check_mask: 0x%s", captured_char, in_check_value_char, in_check_mask_char);
free(in_check_mask_char);
}
else
{
WARNING("value captured during scan didn't pass the requested check: captured: 0x%s check_value: 0x%s", captured_char, in_check_value_char);
}
}
free(captured_char); free(captured_char);
free(in_check_value_char); free(in_check_value_char);
free(in_check_mask_char);
} }
} }
free(captured); free(captured);
@ -1167,7 +1220,7 @@ int jtag_examine_chain()
buf_set_u32(idcode_buffer, 0, 32, 0x000000FF); buf_set_u32(idcode_buffer, 0, 32, 0x000000FF);
} }
jtag_add_plain_dr_scan(1, &field, TAP_TLR); jtag_add_plain_dr_scan(1, &field, TAP_TLR, NULL);
jtag_execute_queue(); jtag_execute_queue();
for (i = 0; i < JTAG_MAX_CHAIN_SIZE * 4; i++) for (i = 0; i < JTAG_MAX_CHAIN_SIZE * 4; i++)
@ -1262,7 +1315,7 @@ int jtag_validate_chain()
field.in_handler = NULL; field.in_handler = NULL;
field.in_handler_priv = NULL; field.in_handler_priv = NULL;
jtag_add_plain_ir_scan(1, &field, TAP_TLR); jtag_add_plain_ir_scan(1, &field, TAP_TLR, NULL);
jtag_execute_queue(); jtag_execute_queue();
device = jtag_devices; device = jtag_devices;
@ -1589,17 +1642,19 @@ int handle_endstate_command(struct command_context_s *cmd_ctx, char *cmd, char *
if (argc < 1) if (argc < 1)
{ {
command_print(cmd_ctx, "usage: endstate <tap_state>"); command_print(cmd_ctx, "usage: endstate <tap_state>");
return ERROR_OK;
} }
else
for (state = 0; state < 16; state++)
{ {
if (strcmp(args[0], tap_state_strings[state]) == 0) for (state = 0; state < 16; state++)
{ {
jtag_add_end_state(state); if (strcmp(args[0], tap_state_strings[state]) == 0)
jtag_execute_queue(); {
jtag_add_end_state(state);
jtag_execute_queue();
}
} }
} }
command_print(cmd_ctx, "current endstate: %s", tap_state_strings[end_state]);
return ERROR_OK; return ERROR_OK;
} }
@ -1721,7 +1776,7 @@ int handle_irscan_command(struct command_context_s *cmd_ctx, char *cmd, char **a
fields[i].in_handler_priv = NULL; fields[i].in_handler_priv = NULL;
} }
jtag_add_ir_scan(argc / 2, fields, -1); jtag_add_ir_scan(argc / 2, fields, -1, NULL);
jtag_execute_queue(); jtag_execute_queue();
for (i = 0; i < argc / 2; i++) for (i = 0; i < argc / 2; i++)
@ -1781,7 +1836,7 @@ int handle_drscan_command(struct command_context_s *cmd_ctx, char *cmd, char **a
} }
} }
jtag_add_dr_scan(num_fields, fields, -1); jtag_add_dr_scan(num_fields, fields, -1, NULL);
jtag_execute_queue(); jtag_execute_queue();
for (i = 0; i < argc / 2; i++) for (i = 0; i < argc / 2; i++)

View File

@ -61,6 +61,12 @@ extern enum tap_state cur_state; /* current TAP state */
#define TAP_MOVE(from, to) tap_move[tap_move_map[from]][tap_move_map[to]] #define TAP_MOVE(from, to) tap_move[tap_move_map[from]][tap_move_map[to]]
typedef struct error_handler_s
{
int (*error_handler)(u8 *in_value, void *priv); /* handle failed checks */
void *error_handler_priv; /* additional information for the check_handler */
} error_handler_t;
typedef struct scan_field_s typedef struct scan_field_s
{ {
int device; /* ordinal device number this instruction refers to */ int device; /* ordinal device number this instruction refers to */
@ -86,6 +92,7 @@ typedef struct scan_command_s
int num_fields; /* number of fields in *fields array */ int num_fields; /* number of fields in *fields array */
scan_field_t *fields; /* pointer to an array of data scan fields */ scan_field_t *fields; /* pointer to an array of data scan fields */
enum tap_state end_state; /* TAP state in which JTAG commands should finish */ enum tap_state end_state; /* TAP state in which JTAG commands should finish */
error_handler_t *error_handler;
} scan_command_t; } scan_command_t;
typedef struct statemove_command_s typedef struct statemove_command_s
@ -239,10 +246,10 @@ extern int jtag_init(struct command_context_s *cmd_ctx);
extern int jtag_register_commands(struct command_context_s *cmd_ctx); extern int jtag_register_commands(struct command_context_s *cmd_ctx);
/* JTAG interface */ /* JTAG interface */
extern int jtag_add_ir_scan(int num_fields, scan_field_t *fields, enum tap_state endstate); extern int jtag_add_ir_scan(int num_fields, scan_field_t *fields, enum tap_state endstate, error_handler_t *error_handler);
extern int jtag_add_dr_scan(int num_fields, scan_field_t *fields, enum tap_state endstate); extern int jtag_add_dr_scan(int num_fields, scan_field_t *fields, enum tap_state endstate, error_handler_t *error_handler);
extern int jtag_add_plain_ir_scan(int num_fields, scan_field_t *fields, enum tap_state endstate); extern int jtag_add_plain_ir_scan(int num_fields, scan_field_t *fields, enum tap_state endstate, error_handler_t *error_handler);
extern int jtag_add_plain_dr_scan(int num_fields, scan_field_t *fields, enum tap_state endstate); extern int jtag_add_plain_dr_scan(int num_fields, scan_field_t *fields, enum tap_state endstate, error_handler_t *error_handler);
extern int jtag_add_statemove(enum tap_state endstate); extern int jtag_add_statemove(enum tap_state endstate);
extern int jtag_add_pathmove(int num_states, enum tap_state *path); extern int jtag_add_pathmove(int num_states, enum tap_state *path);
extern int jtag_add_runtest(int num_cycles, enum tap_state endstate); extern int jtag_add_runtest(int num_cycles, enum tap_state endstate);

View File

@ -18,7 +18,7 @@
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/ ***************************************************************************/
#define OPENOCD_VERSION "Open On-Chip Debugger (2007-04-11 16:20 CEST)" #define OPENOCD_VERSION "Open On-Chip Debugger (2007-04-25 22:15 CEST)"
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
#include "config.h" #include "config.h"

View File

@ -62,7 +62,7 @@ int virtex2_set_instr(int chain_pos, u32 new_instr)
field.in_handler = NULL; field.in_handler = NULL;
field.in_handler_priv = NULL; field.in_handler_priv = NULL;
jtag_add_ir_scan(1, &field, TAP_RTI); jtag_add_ir_scan(1, &field, TAP_RTI, NULL);
free(field.out_value); free(field.out_value);
} }
@ -94,7 +94,7 @@ int virtex2_send_32(struct pld_device_s *pld_device, int num_words, u32 *words)
virtex2_set_instr(virtex2_info->chain_pos, 0x5); /* CFG_IN */ virtex2_set_instr(virtex2_info->chain_pos, 0x5); /* CFG_IN */
jtag_add_dr_scan(1, &scan_field, TAP_PD); jtag_add_dr_scan(1, &scan_field, TAP_PD, NULL);
free(values); free(values);
@ -127,7 +127,7 @@ int virtex2_receive_32(struct pld_device_s *pld_device, int num_words, u32 *word
while (num_words--) while (num_words--)
{ {
scan_field.in_handler_priv = words++; scan_field.in_handler_priv = words++;
jtag_add_dr_scan(1, &scan_field, TAP_PD); jtag_add_dr_scan(1, &scan_field, TAP_PD, NULL);
} }
return ERROR_OK; return ERROR_OK;
@ -189,7 +189,7 @@ int virtex2_load(struct pld_device_s *pld_device, char *filename)
field.num_bits = bit_file.length * 8; field.num_bits = bit_file.length * 8;
field.out_value = bit_file.data; field.out_value = bit_file.data;
jtag_add_dr_scan(1, &field, TAP_PD); jtag_add_dr_scan(1, &field, TAP_PD, NULL);
jtag_execute_queue(); jtag_execute_queue();
jtag_add_statemove(TAP_TLR); jtag_add_statemove(TAP_TLR);

View File

@ -97,7 +97,7 @@ int arm720t_scan_cp15(target_t *target, u32 out, u32 *in, int instruction, int c
jtag_add_end_state(TAP_PD); jtag_add_end_state(TAP_PD);
arm_jtag_scann(jtag_info, 0xf); arm_jtag_scann(jtag_info, 0xf);
arm_jtag_set_instr(jtag_info, jtag_info->intest_instr); arm_jtag_set_instr(jtag_info, jtag_info->intest_instr, NULL);
fields[0].device = jtag_info->chain_pos; fields[0].device = jtag_info->chain_pos;
fields[0].num_bits = 1; fields[0].num_bits = 1;
@ -126,7 +126,7 @@ int arm720t_scan_cp15(target_t *target, u32 out, u32 *in, int instruction, int c
fields[1].in_check_value = NULL; fields[1].in_check_value = NULL;
fields[1].in_check_mask = NULL; fields[1].in_check_mask = NULL;
jtag_add_dr_scan(2, fields, -1); jtag_add_dr_scan(2, fields, -1, NULL);
if (clock) if (clock)
jtag_add_runtest(0, -1); jtag_add_runtest(0, -1);

View File

@ -55,7 +55,6 @@ int handle_arm7_9_dbgrq_command(struct command_context_s *cmd_ctx, char *cmd, ch
int handle_arm7_9_fast_memory_access_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc); int handle_arm7_9_fast_memory_access_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
int handle_arm7_9_dcc_downloads_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc); int handle_arm7_9_dcc_downloads_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
int handle_arm7_9_etm_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc); int handle_arm7_9_etm_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
int handle_arm7_9_etb_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
int arm7_9_reinit_embeddedice(target_t *target) int arm7_9_reinit_embeddedice(target_t *target)
{ {
@ -545,7 +544,7 @@ int arm7_9_execute_sys_speed(struct target_s *target)
/* set RESTART instruction */ /* set RESTART instruction */
jtag_add_end_state(TAP_RTI); jtag_add_end_state(TAP_RTI);
arm_jtag_set_instr(jtag_info, 0x4); arm_jtag_set_instr(jtag_info, 0x4, NULL);
for (timeout=0; timeout<50; timeout++) for (timeout=0; timeout<50; timeout++)
{ {
@ -578,7 +577,7 @@ int arm7_9_execute_fast_sys_speed(struct target_s *target)
/* set RESTART instruction */ /* set RESTART instruction */
jtag_add_end_state(TAP_RTI); jtag_add_end_state(TAP_RTI);
arm_jtag_set_instr(jtag_info, 0x4); arm_jtag_set_instr(jtag_info, 0x4, NULL);
/* check for DBGACK and SYSCOMP set (others don't care) */ /* check for DBGACK and SYSCOMP set (others don't care) */
buf_set_u32(check_value, 0, 32, 0x9); buf_set_u32(check_value, 0, 32, 0x9);
@ -1308,7 +1307,7 @@ int arm7_9_restart_core(struct target_s *target)
/* set RESTART instruction */ /* set RESTART instruction */
jtag_add_end_state(TAP_RTI); jtag_add_end_state(TAP_RTI);
arm_jtag_set_instr(jtag_info, 0x4); arm_jtag_set_instr(jtag_info, 0x4, NULL);
jtag_add_runtest(1, TAP_RTI); jtag_add_runtest(1, TAP_RTI);
if ((jtag_execute_queue()) != ERROR_OK) if ((jtag_execute_queue()) != ERROR_OK)
@ -2098,7 +2097,6 @@ int arm7_9_register_commands(struct command_context_s *cmd_ctx)
arm7_9_cmd = register_command(cmd_ctx, NULL, "arm7_9", NULL, COMMAND_ANY, "arm7/9 specific commands"); arm7_9_cmd = register_command(cmd_ctx, NULL, "arm7_9", NULL, COMMAND_ANY, "arm7/9 specific commands");
register_command(cmd_ctx, arm7_9_cmd, "etm", handle_arm7_9_etm_command, COMMAND_CONFIG, NULL); register_command(cmd_ctx, arm7_9_cmd, "etm", handle_arm7_9_etm_command, COMMAND_CONFIG, NULL);
register_command(cmd_ctx, arm7_9_cmd, "etb", handle_arm7_9_etb_command, COMMAND_CONFIG, NULL);
register_command(cmd_ctx, arm7_9_cmd, "write_xpsr", handle_arm7_9_write_xpsr_command, COMMAND_EXEC, "write program status register <value> <not cpsr|spsr>"); register_command(cmd_ctx, arm7_9_cmd, "write_xpsr", handle_arm7_9_write_xpsr_command, COMMAND_EXEC, "write program status register <value> <not cpsr|spsr>");
register_command(cmd_ctx, arm7_9_cmd, "write_xpsr_im8", handle_arm7_9_write_xpsr_im8_command, COMMAND_EXEC, "write program status register <8bit immediate> <rotate> <not cpsr|spsr>"); register_command(cmd_ctx, arm7_9_cmd, "write_xpsr_im8", handle_arm7_9_write_xpsr_im8_command, COMMAND_EXEC, "write program status register <8bit immediate> <rotate> <not cpsr|spsr>");
@ -2117,6 +2115,7 @@ int arm7_9_register_commands(struct command_context_s *cmd_ctx)
COMMAND_ANY, "use DCC downloads for larger memory writes <enable|disable>"); COMMAND_ANY, "use DCC downloads for larger memory writes <enable|disable>");
armv4_5_register_commands(cmd_ctx); armv4_5_register_commands(cmd_ctx);
etb_register_commands(cmd_ctx, arm7_9_cmd);
return ERROR_OK; return ERROR_OK;
} }

View File

@ -134,6 +134,7 @@ void arm7_9_disable_eice_step(target_t *target);
int arm7_9_execute_sys_speed(struct target_s *target); int arm7_9_execute_sys_speed(struct target_s *target);
int arm7_9_init_arch_info(target_t *target, arm7_9_common_t *arm7_9); int arm7_9_init_arch_info(target_t *target, arm7_9_common_t *arm7_9);
int arm7_9_get_arch_pointers(target_t *target, armv4_5_common_t **armv4_5_p, arm7_9_common_t **arm7_9_p);
#endif /* ARM7_9_COMMON_H */ #endif /* ARM7_9_COMMON_H */

View File

@ -124,9 +124,9 @@ int arm7tdmi_examine_debug_reason(target_t *target)
fields[1].in_handler_priv = NULL; fields[1].in_handler_priv = NULL;
arm_jtag_scann(&arm7_9->jtag_info, 0x1); arm_jtag_scann(&arm7_9->jtag_info, 0x1);
arm_jtag_set_instr(&arm7_9->jtag_info, arm7_9->jtag_info.intest_instr); arm_jtag_set_instr(&arm7_9->jtag_info, arm7_9->jtag_info.intest_instr, NULL);
jtag_add_dr_scan(2, fields, TAP_PD); jtag_add_dr_scan(2, fields, TAP_PD, NULL);
jtag_execute_queue(); jtag_execute_queue();
fields[0].in_value = NULL; fields[0].in_value = NULL;
@ -134,7 +134,7 @@ int arm7tdmi_examine_debug_reason(target_t *target)
fields[1].in_value = NULL; fields[1].in_value = NULL;
fields[1].out_value = databus; fields[1].out_value = databus;
jtag_add_dr_scan(2, fields, TAP_PD); jtag_add_dr_scan(2, fields, TAP_PD, NULL);
if (breakpoint & 1) if (breakpoint & 1)
target->debug_reason = DBG_REASON_WATCHPOINT; target->debug_reason = DBG_REASON_WATCHPOINT;
@ -157,7 +157,7 @@ int arm7tdmi_clock_out(arm_jtag_t *jtag_info, u32 out, u32 *in, int breakpoint)
jtag_add_end_state(TAP_PD); jtag_add_end_state(TAP_PD);
arm_jtag_scann(jtag_info, 0x1); arm_jtag_scann(jtag_info, 0x1);
arm_jtag_set_instr(jtag_info, jtag_info->intest_instr); arm_jtag_set_instr(jtag_info, jtag_info->intest_instr, NULL);
fields[0].device = jtag_info->chain_pos; fields[0].device = jtag_info->chain_pos;
fields[0].num_bits = 1; fields[0].num_bits = 1;
@ -187,7 +187,7 @@ int arm7tdmi_clock_out(arm_jtag_t *jtag_info, u32 out, u32 *in, int breakpoint)
fields[1].in_check_value = NULL; fields[1].in_check_value = NULL;
fields[1].in_check_mask = NULL; fields[1].in_check_mask = NULL;
jtag_add_dr_scan(2, fields, -1); jtag_add_dr_scan(2, fields, -1, NULL);
jtag_add_runtest(0, -1); jtag_add_runtest(0, -1);
@ -214,7 +214,7 @@ int arm7tdmi_clock_data_in(arm_jtag_t *jtag_info, u32 *in)
jtag_add_end_state(TAP_PD); jtag_add_end_state(TAP_PD);
arm_jtag_scann(jtag_info, 0x1); arm_jtag_scann(jtag_info, 0x1);
arm_jtag_set_instr(jtag_info, jtag_info->intest_instr); arm_jtag_set_instr(jtag_info, jtag_info->intest_instr, NULL);
fields[0].device = jtag_info->chain_pos; fields[0].device = jtag_info->chain_pos;
fields[0].num_bits = 1; fields[0].num_bits = 1;
@ -236,7 +236,7 @@ int arm7tdmi_clock_data_in(arm_jtag_t *jtag_info, u32 *in)
fields[1].in_check_value = NULL; fields[1].in_check_value = NULL;
fields[1].in_check_mask = NULL; fields[1].in_check_mask = NULL;
jtag_add_dr_scan(2, fields, -1); jtag_add_dr_scan(2, fields, -1, NULL);
jtag_add_runtest(0, -1); jtag_add_runtest(0, -1);
@ -268,7 +268,7 @@ int arm7tdmi_clock_data_in_endianness(arm_jtag_t *jtag_info, void *in, int size,
jtag_add_end_state(TAP_PD); jtag_add_end_state(TAP_PD);
arm_jtag_scann(jtag_info, 0x1); arm_jtag_scann(jtag_info, 0x1);
arm_jtag_set_instr(jtag_info, jtag_info->intest_instr); arm_jtag_set_instr(jtag_info, jtag_info->intest_instr, NULL);
fields[0].device = jtag_info->chain_pos; fields[0].device = jtag_info->chain_pos;
fields[0].num_bits = 1; fields[0].num_bits = 1;
@ -301,7 +301,7 @@ int arm7tdmi_clock_data_in_endianness(arm_jtag_t *jtag_info, void *in, int size,
fields[1].in_check_value = NULL; fields[1].in_check_value = NULL;
fields[1].in_check_mask = NULL; fields[1].in_check_mask = NULL;
jtag_add_dr_scan(2, fields, -1); jtag_add_dr_scan(2, fields, -1, NULL);
jtag_add_runtest(0, -1); jtag_add_runtest(0, -1);

View File

@ -103,7 +103,7 @@ int arm920t_read_cp15_physical(target_t *target, int reg_addr, u32 *value)
jtag_add_end_state(TAP_RTI); jtag_add_end_state(TAP_RTI);
arm_jtag_scann(jtag_info, 0xf); arm_jtag_scann(jtag_info, 0xf);
arm_jtag_set_instr(jtag_info, jtag_info->intest_instr); arm_jtag_set_instr(jtag_info, jtag_info->intest_instr, NULL);
fields[0].device = jtag_info->chain_pos; fields[0].device = jtag_info->chain_pos;
fields[0].num_bits = 1; fields[0].num_bits = 1;
@ -145,12 +145,12 @@ int arm920t_read_cp15_physical(target_t *target, int reg_addr, u32 *value)
fields[3].in_handler = NULL; fields[3].in_handler = NULL;
fields[3].in_handler_priv = NULL; fields[3].in_handler_priv = NULL;
jtag_add_dr_scan(4, fields, -1); jtag_add_dr_scan(4, fields, -1, NULL);
fields[1].in_handler_priv = value; fields[1].in_handler_priv = value;
fields[1].in_handler = arm_jtag_buf_to_u32; fields[1].in_handler = arm_jtag_buf_to_u32;
jtag_add_dr_scan(4, fields, -1); jtag_add_dr_scan(4, fields, -1, NULL);
#ifdef _DEBUG_INSTRUCTION_EXECUTION_ #ifdef _DEBUG_INSTRUCTION_EXECUTION_
jtag_execute_queue(); jtag_execute_queue();
@ -175,7 +175,7 @@ int arm920t_write_cp15_physical(target_t *target, int reg_addr, u32 value)
jtag_add_end_state(TAP_RTI); jtag_add_end_state(TAP_RTI);
arm_jtag_scann(jtag_info, 0xf); arm_jtag_scann(jtag_info, 0xf);
arm_jtag_set_instr(jtag_info, jtag_info->intest_instr); arm_jtag_set_instr(jtag_info, jtag_info->intest_instr, NULL);
fields[0].device = jtag_info->chain_pos; fields[0].device = jtag_info->chain_pos;
fields[0].num_bits = 1; fields[0].num_bits = 1;
@ -217,7 +217,7 @@ int arm920t_write_cp15_physical(target_t *target, int reg_addr, u32 value)
fields[3].in_handler = NULL; fields[3].in_handler = NULL;
fields[3].in_handler_priv = NULL; fields[3].in_handler_priv = NULL;
jtag_add_dr_scan(4, fields, -1); jtag_add_dr_scan(4, fields, -1, NULL);
#ifdef _DEBUG_INSTRUCTION_EXECUTION_ #ifdef _DEBUG_INSTRUCTION_EXECUTION_
DEBUG("addr: 0x%x value: %8.8x", reg_addr, value); DEBUG("addr: 0x%x value: %8.8x", reg_addr, value);
@ -239,7 +239,7 @@ int arm920t_execute_cp15(target_t *target, u32 cp15_opcode, u32 arm_opcode)
jtag_add_end_state(TAP_RTI); jtag_add_end_state(TAP_RTI);
arm_jtag_scann(jtag_info, 0xf); arm_jtag_scann(jtag_info, 0xf);
arm_jtag_set_instr(jtag_info, jtag_info->intest_instr); arm_jtag_set_instr(jtag_info, jtag_info->intest_instr, NULL);
buf_set_u32(cp15_opcode_buf, 0, 32, cp15_opcode); buf_set_u32(cp15_opcode_buf, 0, 32, cp15_opcode);
@ -283,7 +283,7 @@ int arm920t_execute_cp15(target_t *target, u32 cp15_opcode, u32 arm_opcode)
fields[3].in_handler = NULL; fields[3].in_handler = NULL;
fields[3].in_handler_priv = NULL; fields[3].in_handler_priv = NULL;
jtag_add_dr_scan(4, fields, -1); jtag_add_dr_scan(4, fields, -1, NULL);
arm9tdmi_clock_out(jtag_info, arm_opcode, 0, NULL, 0); arm9tdmi_clock_out(jtag_info, arm_opcode, 0, NULL, 0);
arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 1); arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 1);

View File

@ -28,7 +28,7 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#if 0 #if 1
#define _DEBUG_INSTRUCTION_EXECUTION_ #define _DEBUG_INSTRUCTION_EXECUTION_
#endif #endif
@ -91,6 +91,22 @@ target_type_t arm926ejs_target =
.quit = arm926ejs_quit .quit = arm926ejs_quit
}; };
int arm926ejs_catch_broken_irscan(u8 *in_value, void *priv)
{
/* The ARM926EJ-S' instruction register is 4 bits wide */
*in_value &= 0xf;
if ((*in_value == 0x0f) || (*in_value == 0x00))
{
DEBUG("caught ARM926EJ-S invalid Capture-IR result after CP15 access");
return ERROR_OK;
}
else
{
return ERROR_JTAG_QUEUE_FAILED;
}
}
int arm926ejs_read_cp15(target_t *target, u32 address, u32 *value) int arm926ejs_read_cp15(target_t *target, u32 address, u32 *value)
{ {
armv4_5_common_t *armv4_5 = target->arch_info; armv4_5_common_t *armv4_5 = target->arch_info;
@ -100,12 +116,13 @@ int arm926ejs_read_cp15(target_t *target, u32 address, u32 *value)
u8 address_buf[2]; u8 address_buf[2];
u8 nr_w_buf = 0; u8 nr_w_buf = 0;
u8 access = 1; u8 access = 1;
error_handler_t error_handler;
buf_set_u32(address_buf, 0, 14, address); buf_set_u32(address_buf, 0, 14, address);
jtag_add_end_state(TAP_RTI); jtag_add_end_state(TAP_RTI);
arm_jtag_scann(jtag_info, 0xf); arm_jtag_scann(jtag_info, 0xf);
arm_jtag_set_instr(jtag_info, jtag_info->intest_instr); arm_jtag_set_instr(jtag_info, jtag_info->intest_instr, NULL);
fields[0].device = jtag_info->chain_pos; fields[0].device = jtag_info->chain_pos;
fields[0].num_bits = 32; fields[0].num_bits = 32;
@ -147,17 +164,17 @@ int arm926ejs_read_cp15(target_t *target, u32 address, u32 *value)
fields[3].in_handler = NULL; fields[3].in_handler = NULL;
fields[3].in_handler_priv = NULL; fields[3].in_handler_priv = NULL;
jtag_add_dr_scan(4, fields, -1); jtag_add_dr_scan(4, fields, -1, NULL);
/* rescan with NOP, to wait for the access to complete */
access = 0;
fields[0].in_handler_priv = value; fields[0].in_handler_priv = value;
fields[0].in_handler = arm_jtag_buf_to_u32; fields[0].in_handler = arm_jtag_buf_to_u32;
do do
{ {
jtag_add_dr_scan(4, fields, -1); /* rescan with NOP, to wait for the access to complete */
access = 0;
nr_w_buf = 0;
jtag_add_dr_scan(4, fields, -1, NULL);
jtag_execute_queue(); jtag_execute_queue();
} while (buf_get_u32(&access, 0, 1) != 1); } while (buf_get_u32(&access, 0, 1) != 1);
@ -165,6 +182,11 @@ int arm926ejs_read_cp15(target_t *target, u32 address, u32 *value)
DEBUG("addr: 0x%x value: %8.8x", address, *value); DEBUG("addr: 0x%x value: %8.8x", address, *value);
#endif #endif
error_handler.error_handler = arm926ejs_catch_broken_irscan;
error_handler.error_handler_priv = NULL;
arm_jtag_set_instr(jtag_info, 0xc, &error_handler);
return ERROR_OK; return ERROR_OK;
} }
@ -178,13 +200,14 @@ int arm926ejs_write_cp15(target_t *target, u32 address, u32 value)
u8 address_buf[2]; u8 address_buf[2];
u8 nr_w_buf = 1; u8 nr_w_buf = 1;
u8 access = 1; u8 access = 1;
error_handler_t error_handler;
buf_set_u32(address_buf, 0, 14, address); buf_set_u32(address_buf, 0, 14, address);
buf_set_u32(value_buf, 0, 32, value); buf_set_u32(value_buf, 0, 32, value);
jtag_add_end_state(TAP_RTI); jtag_add_end_state(TAP_RTI);
arm_jtag_scann(jtag_info, 0xf); arm_jtag_scann(jtag_info, 0xf);
arm_jtag_set_instr(jtag_info, jtag_info->intest_instr); arm_jtag_set_instr(jtag_info, jtag_info->intest_instr, NULL);
fields[0].device = jtag_info->chain_pos; fields[0].device = jtag_info->chain_pos;
fields[0].num_bits = 32; fields[0].num_bits = 32;
@ -226,14 +249,14 @@ int arm926ejs_write_cp15(target_t *target, u32 address, u32 value)
fields[3].in_handler = NULL; fields[3].in_handler = NULL;
fields[3].in_handler_priv = NULL; fields[3].in_handler_priv = NULL;
jtag_add_dr_scan(4, fields, -1); jtag_add_dr_scan(4, fields, -1, NULL);
/* rescan with NOP, to wait for the access to complete */
access = 0;
do do
{ {
jtag_add_dr_scan(4, fields, -1); /* rescan with NOP, to wait for the access to complete */
access = 0;
nr_w_buf = 0;
jtag_add_dr_scan(4, fields, -1, NULL);
jtag_execute_queue(); jtag_execute_queue();
} while (buf_get_u32(&access, 0, 1) != 1); } while (buf_get_u32(&access, 0, 1) != 1);
@ -241,6 +264,11 @@ int arm926ejs_write_cp15(target_t *target, u32 address, u32 value)
DEBUG("addr: 0x%x value: %8.8x", address, value); DEBUG("addr: 0x%x value: %8.8x", address, value);
#endif #endif
error_handler.error_handler = arm926ejs_catch_broken_irscan;
error_handler.error_handler_priv = NULL;
arm_jtag_set_instr(jtag_info, 0xf, &error_handler);
return ERROR_OK; return ERROR_OK;
} }
@ -430,7 +458,6 @@ void arm926ejs_post_debug_entry(target_t *target)
arm926ejs_read_cp15(target, ARM926EJS_CP15_ADDR(7, 0, 15, 0), &cache_dbg_ctrl); arm926ejs_read_cp15(target, ARM926EJS_CP15_ADDR(7, 0, 15, 0), &cache_dbg_ctrl);
cache_dbg_ctrl |= 0x7; cache_dbg_ctrl |= 0x7;
arm926ejs_write_cp15(target, ARM926EJS_CP15_ADDR(7, 0, 15, 0), cache_dbg_ctrl); arm926ejs_write_cp15(target, ARM926EJS_CP15_ADDR(7, 0, 15, 0), cache_dbg_ctrl);
} }
void arm926ejs_pre_restore_context(target_t *target) void arm926ejs_pre_restore_context(target_t *target)
@ -641,6 +668,11 @@ int arm926ejs_init_arch_info(target_t *target, arm926ejs_common_t *arm926ejs, in
arm7_9->examine_debug_reason = arm926ejs_examine_debug_reason; arm7_9->examine_debug_reason = arm926ejs_examine_debug_reason;
/* The ARM926EJ-S implements the ARMv5TE architecture which
* has the BKPT instruction, so we don't have to use a watchpoint comparator
*/
arm7_9->sw_bkpts_enabled = 1;
return ERROR_OK; return ERROR_OK;
} }

View File

@ -253,7 +253,7 @@ int arm966e_read_cp15(target_t *target, int reg_addr, u32 *value)
jtag_add_end_state(TAP_RTI); jtag_add_end_state(TAP_RTI);
arm_jtag_scann(jtag_info, 0xf); arm_jtag_scann(jtag_info, 0xf);
arm_jtag_set_instr(jtag_info, jtag_info->intest_instr); arm_jtag_set_instr(jtag_info, jtag_info->intest_instr, NULL);
fields[0].device = jtag_info->chain_pos; fields[0].device = jtag_info->chain_pos;
fields[0].num_bits = 32; fields[0].num_bits = 32;
@ -285,11 +285,11 @@ int arm966e_read_cp15(target_t *target, int reg_addr, u32 *value)
fields[2].in_handler = NULL; fields[2].in_handler = NULL;
fields[2].in_handler_priv = NULL; fields[2].in_handler_priv = NULL;
jtag_add_dr_scan(3, fields, -1); jtag_add_dr_scan(3, fields, -1, NULL);
fields[0].in_value = (u8*)value; fields[0].in_value = (u8*)value;
jtag_add_dr_scan(3, fields, -1); jtag_add_dr_scan(3, fields, -1, NULL);
return ERROR_OK; return ERROR_OK;
} }
@ -305,7 +305,7 @@ int arm966e_write_cp15(target_t *target, int reg_addr, u32 value)
jtag_add_end_state(TAP_RTI); jtag_add_end_state(TAP_RTI);
arm_jtag_scann(jtag_info, 0xf); arm_jtag_scann(jtag_info, 0xf);
arm_jtag_set_instr(jtag_info, jtag_info->intest_instr); arm_jtag_set_instr(jtag_info, jtag_info->intest_instr, NULL);
fields[0].device = jtag_info->chain_pos; fields[0].device = jtag_info->chain_pos;
fields[0].num_bits = 32; fields[0].num_bits = 32;
@ -337,7 +337,7 @@ int arm966e_write_cp15(target_t *target, int reg_addr, u32 value)
fields[2].in_handler = NULL; fields[2].in_handler = NULL;
fields[2].in_handler_priv = NULL; fields[2].in_handler_priv = NULL;
jtag_add_dr_scan(3, fields, -1); jtag_add_dr_scan(3, fields, -1, NULL);
return ERROR_OK; return ERROR_OK;
} }

View File

@ -98,6 +98,15 @@ arm9tdmi_vector_t arm9tdmi_vectors[] =
{0, 0}, {0, 0},
}; };
int arm9tdmi_jtag_error_handler(u8 *in_value, void *priv)
{
char *caller = priv;
DEBUG("caller: %s", caller);
return ERROR_OK;
}
int arm9tdmi_examine_debug_reason(target_t *target) int arm9tdmi_examine_debug_reason(target_t *target)
{ {
/* get pointers to arch-specific information */ /* get pointers to arch-specific information */
@ -108,6 +117,7 @@ int arm9tdmi_examine_debug_reason(target_t *target)
if ((target->debug_reason != DBG_REASON_DBGRQ) if ((target->debug_reason != DBG_REASON_DBGRQ)
&& (target->debug_reason != DBG_REASON_SINGLESTEP)) && (target->debug_reason != DBG_REASON_SINGLESTEP))
{ {
error_handler_t error_handler;
scan_field_t fields[3]; scan_field_t fields[3];
u8 databus[4]; u8 databus[4];
u8 instructionbus[4]; u8 instructionbus[4];
@ -146,9 +156,11 @@ int arm9tdmi_examine_debug_reason(target_t *target)
fields[2].in_handler_priv = NULL; fields[2].in_handler_priv = NULL;
arm_jtag_scann(&arm7_9->jtag_info, 0x1); arm_jtag_scann(&arm7_9->jtag_info, 0x1);
arm_jtag_set_instr(&arm7_9->jtag_info, arm7_9->jtag_info.intest_instr); error_handler.error_handler = arm9tdmi_jtag_error_handler;
error_handler.error_handler_priv = "arm9tdmi_examine_debug_reason";
arm_jtag_set_instr(&arm7_9->jtag_info, arm7_9->jtag_info.intest_instr, &error_handler);
jtag_add_dr_scan(3, fields, TAP_PD); jtag_add_dr_scan(3, fields, TAP_PD, NULL);
jtag_execute_queue(); jtag_execute_queue();
fields[0].in_value = NULL; fields[0].in_value = NULL;
@ -158,7 +170,7 @@ int arm9tdmi_examine_debug_reason(target_t *target)
fields[2].in_value = NULL; fields[2].in_value = NULL;
fields[2].out_value = instructionbus; fields[2].out_value = instructionbus;
jtag_add_dr_scan(3, fields, TAP_PD); jtag_add_dr_scan(3, fields, TAP_PD, NULL);
if (debug_reason & 0x4) if (debug_reason & 0x4)
if (debug_reason & 0x2) if (debug_reason & 0x2)
@ -175,6 +187,7 @@ int arm9tdmi_examine_debug_reason(target_t *target)
/* put an instruction in the ARM9TDMI pipeline or write the data bus, and optionally read data */ /* put an instruction in the ARM9TDMI pipeline or write the data bus, and optionally read data */
int arm9tdmi_clock_out(arm_jtag_t *jtag_info, u32 instr, u32 out, u32 *in, int sysspeed) int arm9tdmi_clock_out(arm_jtag_t *jtag_info, u32 instr, u32 out, u32 *in, int sysspeed)
{ {
error_handler_t error_handler;
scan_field_t fields[3]; scan_field_t fields[3];
u8 out_buf[4]; u8 out_buf[4];
u8 instr_buf[4]; u8 instr_buf[4];
@ -190,7 +203,11 @@ int arm9tdmi_clock_out(arm_jtag_t *jtag_info, u32 instr, u32 out, u32 *in, int s
jtag_add_end_state(TAP_PD); jtag_add_end_state(TAP_PD);
arm_jtag_scann(jtag_info, 0x1); arm_jtag_scann(jtag_info, 0x1);
arm_jtag_set_instr(jtag_info, jtag_info->intest_instr);
error_handler.error_handler = arm9tdmi_jtag_error_handler;
error_handler.error_handler_priv = "arm9tdmi_clock_out";
arm_jtag_set_instr(jtag_info, jtag_info->intest_instr, &error_handler);
fields[0].device = jtag_info->chain_pos; fields[0].device = jtag_info->chain_pos;
fields[0].num_bits = 32; fields[0].num_bits = 32;
@ -230,7 +247,7 @@ int arm9tdmi_clock_out(arm_jtag_t *jtag_info, u32 instr, u32 out, u32 *in, int s
fields[2].in_handler = NULL; fields[2].in_handler = NULL;
fields[2].in_handler_priv = NULL; fields[2].in_handler_priv = NULL;
jtag_add_dr_scan(3, fields, -1); jtag_add_dr_scan(3, fields, -1, NULL);
jtag_add_runtest(0, -1); jtag_add_runtest(0, -1);
@ -254,10 +271,15 @@ int arm9tdmi_clock_out(arm_jtag_t *jtag_info, u32 instr, u32 out, u32 *in, int s
int arm9tdmi_clock_data_in(arm_jtag_t *jtag_info, u32 *in) int arm9tdmi_clock_data_in(arm_jtag_t *jtag_info, u32 *in)
{ {
scan_field_t fields[3]; scan_field_t fields[3];
error_handler_t error_handler;
jtag_add_end_state(TAP_PD); jtag_add_end_state(TAP_PD);
arm_jtag_scann(jtag_info, 0x1); arm_jtag_scann(jtag_info, 0x1);
arm_jtag_set_instr(jtag_info, jtag_info->intest_instr);
error_handler.error_handler = arm9tdmi_jtag_error_handler;
error_handler.error_handler_priv = "arm9tdmi_clock_data_in_endianness";
arm_jtag_set_instr(jtag_info, jtag_info->intest_instr, &error_handler);
fields[0].device = jtag_info->chain_pos; fields[0].device = jtag_info->chain_pos;
fields[0].num_bits = 32; fields[0].num_bits = 32;
@ -289,7 +311,7 @@ int arm9tdmi_clock_data_in(arm_jtag_t *jtag_info, u32 *in)
fields[2].in_handler = NULL; fields[2].in_handler = NULL;
fields[2].in_handler_priv = NULL; fields[2].in_handler_priv = NULL;
jtag_add_dr_scan(3, fields, -1); jtag_add_dr_scan(3, fields, -1, NULL);
jtag_add_runtest(0, -1); jtag_add_runtest(0, -1);
@ -318,10 +340,15 @@ int arm9tdmi_clock_data_in(arm_jtag_t *jtag_info, u32 *in)
int arm9tdmi_clock_data_in_endianness(arm_jtag_t *jtag_info, void *in, int size, int be) int arm9tdmi_clock_data_in_endianness(arm_jtag_t *jtag_info, void *in, int size, int be)
{ {
scan_field_t fields[3]; scan_field_t fields[3];
error_handler_t error_handler;
jtag_add_end_state(TAP_PD); jtag_add_end_state(TAP_PD);
arm_jtag_scann(jtag_info, 0x1); arm_jtag_scann(jtag_info, 0x1);
arm_jtag_set_instr(jtag_info, jtag_info->intest_instr);
error_handler.error_handler = arm9tdmi_jtag_error_handler;
error_handler.error_handler_priv = "arm9tdmi_clock_data_in_endianness";
arm_jtag_set_instr(jtag_info, jtag_info->intest_instr, &error_handler);
fields[0].device = jtag_info->chain_pos; fields[0].device = jtag_info->chain_pos;
fields[0].num_bits = 32; fields[0].num_bits = 32;
@ -364,7 +391,7 @@ int arm9tdmi_clock_data_in_endianness(arm_jtag_t *jtag_info, void *in, int size,
fields[2].in_handler = NULL; fields[2].in_handler = NULL;
fields[2].in_handler_priv = NULL; fields[2].in_handler_priv = NULL;
jtag_add_dr_scan(3, fields, -1); jtag_add_dr_scan(3, fields, -1, NULL);
jtag_add_runtest(0, -1); jtag_add_runtest(0, -1);

View File

@ -29,7 +29,18 @@
#include <stdlib.h> #include <stdlib.h>
int arm_jtag_set_instr(arm_jtag_t *jtag_info, u32 new_instr) #if 0
#define _ARM_JTAG_SCAN_N_CHECK_
#endif
int arm_jtag_set_instr_error_handler(u8 *in_value, void *priv)
{
ERROR("setting the new JTAG instruction failed, debugging is likely to be broken");
return ERROR_OK;
}
int arm_jtag_set_instr(arm_jtag_t *jtag_info, u32 new_instr, error_handler_t *caller_error_handler)
{ {
jtag_device_t *device = jtag_get_device(jtag_info->chain_pos); jtag_device_t *device = jtag_get_device(jtag_info->chain_pos);
@ -48,7 +59,18 @@ int arm_jtag_set_instr(arm_jtag_t *jtag_info, u32 new_instr)
field.in_handler = NULL; field.in_handler = NULL;
field.in_handler_priv = NULL; field.in_handler_priv = NULL;
jtag_add_ir_scan(1, &field, -1); if (caller_error_handler)
{
jtag_add_ir_scan(1, &field, -1, caller_error_handler);
}
else
{
error_handler_t error_handler;
error_handler.error_handler = arm_jtag_set_instr_error_handler;
error_handler.error_handler_priv = NULL;
jtag_add_ir_scan(1, &field, -1, &error_handler);
}
free(field.out_value); free(field.out_value);
} }
@ -60,6 +82,9 @@ int arm_jtag_scann(arm_jtag_t *jtag_info, u32 new_scan_chain)
{ {
if(jtag_info->cur_scan_chain != new_scan_chain) if(jtag_info->cur_scan_chain != new_scan_chain)
{ {
#ifdef _ARM_JTAG_SCAN_N_CHECK_
u8 scan_n_check_value = 0x10;
#endif
scan_field_t field; scan_field_t field;
field.device = jtag_info->chain_pos; field.device = jtag_info->chain_pos;
@ -67,15 +92,18 @@ int arm_jtag_scann(arm_jtag_t *jtag_info, u32 new_scan_chain)
field.out_value = calloc(CEIL(field.num_bits, 8), 1); field.out_value = calloc(CEIL(field.num_bits, 8), 1);
buf_set_u32(field.out_value, 0, field.num_bits, new_scan_chain); buf_set_u32(field.out_value, 0, field.num_bits, new_scan_chain);
field.out_mask = NULL; field.out_mask = NULL;
//field.in_value = &scan_n_capture;
field.in_value = NULL; field.in_value = NULL;
#ifdef _ARM_JTAG_SCAN_N_CHECK_
field.in_check_value = &scan_n_check_value;
#else
field.in_check_value = NULL; field.in_check_value = NULL;
#endif
field.in_check_mask = NULL; field.in_check_mask = NULL;
field.in_handler = NULL; field.in_handler = NULL;
field.in_handler_priv = NULL; field.in_handler_priv = NULL;
arm_jtag_set_instr(jtag_info, jtag_info->scann_instr); arm_jtag_set_instr(jtag_info, jtag_info->scann_instr, NULL);
jtag_add_dr_scan(1, &field, -1); jtag_add_dr_scan(1, &field, -1, NULL);
jtag_info->cur_scan_chain = new_scan_chain; jtag_info->cur_scan_chain = new_scan_chain;

View File

@ -21,6 +21,7 @@
#define ARM_JTAG #define ARM_JTAG
#include "types.h" #include "types.h"
#include "jtag.h"
typedef struct arm_jtag_s typedef struct arm_jtag_s
{ {
@ -33,7 +34,7 @@ typedef struct arm_jtag_s
u32 intest_instr; u32 intest_instr;
} arm_jtag_t; } arm_jtag_t;
extern int arm_jtag_set_instr(arm_jtag_t *jtag_info, u32 new_instr); extern int arm_jtag_set_instr(arm_jtag_t *jtag_info, u32 new_instr, error_handler_t *error_handler);
extern int arm_jtag_scann(arm_jtag_t *jtag_info, u32 new_scan_chain); extern int arm_jtag_scann(arm_jtag_t *jtag_info, u32 new_scan_chain);
extern int arm_jtag_setup_connection(arm_jtag_t *jtag_info); extern int arm_jtag_setup_connection(arm_jtag_t *jtag_info);

View File

@ -86,6 +86,15 @@ int embeddedice_set_reg_w_exec(reg_t *reg, u8 *buf);
int embeddedice_write_reg(reg_t *reg, u32 value); int embeddedice_write_reg(reg_t *reg, u32 value);
int embeddedice_read_reg(reg_t *reg); int embeddedice_read_reg(reg_t *reg);
int embeddedice_jtag_error_handler(u8 *in_value, void *priv)
{
char *caller = priv;
DEBUG("caller: %s", caller);
return ERROR_OK;
}
reg_cache_t* embeddedice_build_reg_cache(target_t *target, arm7_9_common_t *arm7_9) reg_cache_t* embeddedice_build_reg_cache(target_t *target, arm7_9_common_t *arm7_9)
{ {
reg_cache_t *reg_cache = malloc(sizeof(reg_cache_t)); reg_cache_t *reg_cache = malloc(sizeof(reg_cache_t));
@ -214,12 +223,17 @@ int embeddedice_read_reg_w_check(reg_t *reg, u8* check_value, u8* check_mask)
embeddedice_reg_t *ice_reg = reg->arch_info; embeddedice_reg_t *ice_reg = reg->arch_info;
u8 reg_addr = ice_reg->addr & 0x1f; u8 reg_addr = ice_reg->addr & 0x1f;
scan_field_t fields[3]; scan_field_t fields[3];
error_handler_t error_handler;
DEBUG("%i", ice_reg->addr); DEBUG("%i", ice_reg->addr);
jtag_add_end_state(TAP_RTI); jtag_add_end_state(TAP_RTI);
arm_jtag_scann(ice_reg->jtag_info, 0x2); arm_jtag_scann(ice_reg->jtag_info, 0x2);
arm_jtag_set_instr(ice_reg->jtag_info, ice_reg->jtag_info->intest_instr);
error_handler.error_handler = embeddedice_jtag_error_handler;
error_handler.error_handler_priv = "embeddedice_read_reg_w_check";
arm_jtag_set_instr(ice_reg->jtag_info, ice_reg->jtag_info->intest_instr, &error_handler);
fields[0].device = ice_reg->jtag_info->chain_pos; fields[0].device = ice_reg->jtag_info->chain_pos;
fields[0].num_bits = 32; fields[0].num_bits = 32;
@ -253,7 +267,7 @@ int embeddedice_read_reg_w_check(reg_t *reg, u8* check_value, u8* check_mask)
fields[2].in_handler = NULL; fields[2].in_handler = NULL;
fields[2].in_handler_priv = NULL; fields[2].in_handler_priv = NULL;
jtag_add_dr_scan(3, fields, -1); jtag_add_dr_scan(3, fields, -1, NULL);
fields[0].in_value = reg->value; fields[0].in_value = reg->value;
fields[0].in_check_value = check_value; fields[0].in_check_value = check_value;
@ -265,7 +279,7 @@ int embeddedice_read_reg_w_check(reg_t *reg, u8* check_value, u8* check_mask)
*/ */
buf_set_u32(fields[1].out_value, 0, 5, embeddedice_reg_arch_info[EICE_COMMS_CTRL]); buf_set_u32(fields[1].out_value, 0, 5, embeddedice_reg_arch_info[EICE_COMMS_CTRL]);
jtag_add_dr_scan(3, fields, -1); jtag_add_dr_scan(3, fields, -1, NULL);
free(fields[1].out_value); free(fields[1].out_value);
free(fields[2].out_value); free(fields[2].out_value);
@ -310,12 +324,17 @@ int embeddedice_write_reg(reg_t *reg, u32 value)
embeddedice_reg_t *ice_reg = reg->arch_info; embeddedice_reg_t *ice_reg = reg->arch_info;
u8 reg_addr = ice_reg->addr & 0x1f; u8 reg_addr = ice_reg->addr & 0x1f;
scan_field_t fields[3]; scan_field_t fields[3];
error_handler_t error_handler;
DEBUG("%i: 0x%8.8x", ice_reg->addr, value); DEBUG("%i: 0x%8.8x", ice_reg->addr, value);
jtag_add_end_state(TAP_RTI); jtag_add_end_state(TAP_RTI);
arm_jtag_scann(ice_reg->jtag_info, 0x2); arm_jtag_scann(ice_reg->jtag_info, 0x2);
arm_jtag_set_instr(ice_reg->jtag_info, ice_reg->jtag_info->intest_instr);
error_handler.error_handler = embeddedice_jtag_error_handler;
error_handler.error_handler_priv = "embeddedice_write_reg";
arm_jtag_set_instr(ice_reg->jtag_info, ice_reg->jtag_info->intest_instr, NULL);
fields[0].device = ice_reg->jtag_info->chain_pos; fields[0].device = ice_reg->jtag_info->chain_pos;
fields[0].num_bits = 32; fields[0].num_bits = 32;
@ -350,7 +369,7 @@ int embeddedice_write_reg(reg_t *reg, u32 value)
fields[2].in_handler = NULL; fields[2].in_handler = NULL;
fields[2].in_handler_priv = NULL; fields[2].in_handler_priv = NULL;
jtag_add_dr_scan(3, fields, -1); jtag_add_dr_scan(3, fields, -1, NULL);
free(fields[0].out_value); free(fields[0].out_value);
free(fields[1].out_value); free(fields[1].out_value);

View File

@ -21,6 +21,7 @@
#include "config.h" #include "config.h"
#endif #endif
#include "arm7_9_common.h"
#include "etb.h" #include "etb.h"
#include "log.h" #include "log.h"
@ -54,6 +55,9 @@ int etb_set_reg_w_exec(reg_t *reg, u8 *buf);
int etb_write_reg(reg_t *reg, u32 value); int etb_write_reg(reg_t *reg, u32 value);
int etb_read_reg(reg_t *reg); int etb_read_reg(reg_t *reg);
int handle_arm7_9_etb_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
int handle_arm7_9_etb_dump_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
int etb_set_instr(etb_t *etb, u32 new_instr) int etb_set_instr(etb_t *etb, u32 new_instr)
{ {
jtag_device_t *device = jtag_get_device(etb->chain_pos); jtag_device_t *device = jtag_get_device(etb->chain_pos);
@ -73,7 +77,7 @@ int etb_set_instr(etb_t *etb, u32 new_instr)
field.in_handler = NULL; field.in_handler = NULL;
field.in_handler_priv = NULL; field.in_handler_priv = NULL;
jtag_add_ir_scan(1, &field, -1); jtag_add_ir_scan(1, &field, -1, NULL);
free(field.out_value); free(field.out_value);
} }
@ -100,7 +104,7 @@ int etb_scann(etb_t *etb, u32 new_scan_chain)
/* select INTEST instruction */ /* select INTEST instruction */
etb_set_instr(etb, 0x2); etb_set_instr(etb, 0x2);
jtag_add_dr_scan(1, &field, -1); jtag_add_dr_scan(1, &field, -1, NULL);
etb->cur_scan_chain = new_scan_chain; etb->cur_scan_chain = new_scan_chain;
@ -212,13 +216,17 @@ int etb_read_reg_w_check(reg_t *reg, u8* check_value, u8* check_mask)
fields[2].in_handler = NULL; fields[2].in_handler = NULL;
fields[2].in_handler_priv = NULL; fields[2].in_handler_priv = NULL;
jtag_add_dr_scan(3, fields, -1); jtag_add_dr_scan(3, fields, -1, NULL);
/* read the identification register in the second run, to make sure we
* don't read the ETB data register twice, skipping every second entry
*/
buf_set_u32(fields[1].out_value, 0, 7, 0x0);
fields[0].in_value = reg->value; fields[0].in_value = reg->value;
fields[0].in_check_value = check_value; fields[0].in_check_value = check_value;
fields[0].in_check_mask = check_mask; fields[0].in_check_mask = check_mask;
jtag_add_dr_scan(3, fields, -1); jtag_add_dr_scan(3, fields, -1, NULL);
free(fields[1].out_value); free(fields[1].out_value);
free(fields[2].out_value); free(fields[2].out_value);
@ -303,7 +311,7 @@ int etb_write_reg(reg_t *reg, u32 value)
fields[2].in_handler = NULL; fields[2].in_handler = NULL;
fields[2].in_handler_priv = NULL; fields[2].in_handler_priv = NULL;
jtag_add_dr_scan(3, fields, -1); jtag_add_dr_scan(3, fields, -1, NULL);
free(fields[0].out_value); free(fields[0].out_value);
free(fields[1].out_value); free(fields[1].out_value);
@ -317,3 +325,57 @@ int etb_store_reg(reg_t *reg)
return etb_write_reg(reg, buf_get_u32(reg->value, 0, reg->size)); return etb_write_reg(reg, buf_get_u32(reg->value, 0, reg->size));
} }
int etb_register_commands(struct command_context_s *cmd_ctx, command_t *arm7_9_cmd)
{
register_command(cmd_ctx, arm7_9_cmd, "etb", handle_arm7_9_etb_command, COMMAND_CONFIG, NULL);
register_command(cmd_ctx, arm7_9_cmd, "etb_dump", handle_arm7_9_etb_dump_command, COMMAND_EXEC, "dump current ETB content");
return ERROR_OK;
}
int handle_arm7_9_etb_dump_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
{
int retval;
target_t *target = get_current_target(cmd_ctx);
armv4_5_common_t *armv4_5;
arm7_9_common_t *arm7_9;
int i;
if (arm7_9_get_arch_pointers(target, &armv4_5, &arm7_9) != ERROR_OK)
{
command_print(cmd_ctx, "current target isn't an ARM7/ARM9 target");
return ERROR_OK;
}
if (!arm7_9->etb)
{
command_print(cmd_ctx, "no ETB configured for current target");
return ERROR_OK;
}
if (!(arm7_9->etb->RAM_depth && arm7_9->etb->RAM_width))
{
/* identify ETB RAM depth and width */
etb_read_reg(&arm7_9->etb->reg_cache->reg_list[ETB_RAM_DEPTH]);
etb_read_reg(&arm7_9->etb->reg_cache->reg_list[ETB_RAM_WIDTH]);
jtag_execute_queue();
arm7_9->etb->RAM_depth = buf_get_u32(arm7_9->etb->reg_cache->reg_list[ETB_RAM_DEPTH].value, 0, 32);
arm7_9->etb->RAM_width = buf_get_u32(arm7_9->etb->reg_cache->reg_list[ETB_RAM_WIDTH].value, 0, 32);
}
/* always start reading from the beginning of the buffer */
etb_write_reg(&arm7_9->etb->reg_cache->reg_list[ETB_RAM_READ_POINTER], 0x0);
for (i = 0; i < arm7_9->etb->RAM_depth; i++)
{
u32 trace_data;
etb_read_reg(&arm7_9->etb->reg_cache->reg_list[ETB_RAM_DATA]);
jtag_execute_queue();
trace_data = buf_get_u32(arm7_9->etb->reg_cache->reg_list[ETB_RAM_DATA].value, 0, 32);
command_print(cmd_ctx, "%8.8i: %i %2.2x %2.2x %2.2x (0x%8.8x)",
i, (trace_data >> 19) & 1, (trace_data >> 11) & 0xff, (trace_data >> 3) & 0xff, trace_data & 0x7, trace_data);
}
return ERROR_OK;
}

View File

@ -20,6 +20,7 @@
#ifndef ETB_H #ifndef ETB_H
#define ETB_H #define ETB_H
#include "command.h"
#include "target.h" #include "target.h"
#include "register.h" #include "register.h"
#include "arm_jtag.h" #include "arm_jtag.h"
@ -43,6 +44,10 @@ typedef struct etb_s
int chain_pos; int chain_pos;
int cur_scan_chain; int cur_scan_chain;
reg_cache_t *reg_cache; reg_cache_t *reg_cache;
/* ETB parameters */
int RAM_depth;
int RAM_width;
} etb_t; } etb_t;
typedef struct etb_reg_s typedef struct etb_reg_s
@ -59,4 +64,6 @@ extern int etb_store_reg(reg_t *reg);
extern int etb_set_reg(reg_t *reg, u32 value); extern int etb_set_reg(reg_t *reg, u32 value);
extern int etb_set_reg_w_exec(reg_t *reg, u8 *buf); extern int etb_set_reg_w_exec(reg_t *reg, u8 *buf);
extern int etb_register_commands(struct command_context_s *cmd_ctx, command_t *arm7_9_cmd);
#endif /* ETB_H */ #endif /* ETB_H */

View File

@ -64,8 +64,8 @@ int etm_reg_arch_info[] =
int etm_reg_arch_size_info[] = int etm_reg_arch_size_info[] =
{ {
32, 32, 17, 8, 3, 9, 32, 17, 32, 32, 17, 8, 3, 9, 32, 16,
26, 16, 25, 8, 17, 32, 32, 17, 17, 26, 25, 8, 17, 32, 32, 17,
32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
@ -271,7 +271,7 @@ int etm_read_reg_w_check(reg_t *reg, u8* check_value, u8* check_mask)
jtag_add_end_state(TAP_RTI); jtag_add_end_state(TAP_RTI);
arm_jtag_scann(etm_reg->jtag_info, 0x6); arm_jtag_scann(etm_reg->jtag_info, 0x6);
arm_jtag_set_instr(etm_reg->jtag_info, etm_reg->jtag_info->intest_instr); arm_jtag_set_instr(etm_reg->jtag_info, etm_reg->jtag_info->intest_instr, NULL);
fields[0].device = etm_reg->jtag_info->chain_pos; fields[0].device = etm_reg->jtag_info->chain_pos;
fields[0].num_bits = 32; fields[0].num_bits = 32;
@ -305,13 +305,13 @@ int etm_read_reg_w_check(reg_t *reg, u8* check_value, u8* check_mask)
fields[2].in_handler = NULL; fields[2].in_handler = NULL;
fields[2].in_handler_priv = NULL; fields[2].in_handler_priv = NULL;
jtag_add_dr_scan(3, fields, -1); jtag_add_dr_scan(3, fields, -1, NULL);
fields[0].in_value = reg->value; fields[0].in_value = reg->value;
fields[0].in_check_value = check_value; fields[0].in_check_value = check_value;
fields[0].in_check_mask = check_mask; fields[0].in_check_mask = check_mask;
jtag_add_dr_scan(3, fields, -1); jtag_add_dr_scan(3, fields, -1, NULL);
free(fields[1].out_value); free(fields[1].out_value);
free(fields[2].out_value); free(fields[2].out_value);
@ -361,7 +361,7 @@ int etm_write_reg(reg_t *reg, u32 value)
jtag_add_end_state(TAP_RTI); jtag_add_end_state(TAP_RTI);
arm_jtag_scann(etm_reg->jtag_info, 0x6); arm_jtag_scann(etm_reg->jtag_info, 0x6);
arm_jtag_set_instr(etm_reg->jtag_info, etm_reg->jtag_info->intest_instr); arm_jtag_set_instr(etm_reg->jtag_info, etm_reg->jtag_info->intest_instr, NULL);
fields[0].device = etm_reg->jtag_info->chain_pos; fields[0].device = etm_reg->jtag_info->chain_pos;
fields[0].num_bits = 32; fields[0].num_bits = 32;
@ -396,7 +396,7 @@ int etm_write_reg(reg_t *reg, u32 value)
fields[2].in_handler = NULL; fields[2].in_handler = NULL;
fields[2].in_handler_priv = NULL; fields[2].in_handler_priv = NULL;
jtag_add_dr_scan(3, fields, -1); jtag_add_dr_scan(3, fields, -1, NULL);
free(fields[0].out_value); free(fields[0].out_value);
free(fields[1].out_value); free(fields[1].out_value);

View File

@ -210,7 +210,7 @@ int xscale_jtag_set_instr(int chain_pos, u32 new_instr)
field.in_handler = NULL; field.in_handler = NULL;
field.in_handler_priv = NULL; field.in_handler_priv = NULL;
jtag_add_ir_scan(1, &field, -1); jtag_add_ir_scan(1, &field, -1, NULL);
free(field.out_value); free(field.out_value);
} }
@ -288,7 +288,7 @@ int xscale_read_dcsr(target_t *target)
fields[2].in_handler = NULL; fields[2].in_handler = NULL;
fields[2].in_handler_priv = NULL; fields[2].in_handler_priv = NULL;
jtag_add_dr_scan(3, fields, -1); jtag_add_dr_scan(3, fields, -1, NULL);
if ((retval = jtag_execute_queue()) != ERROR_OK) if ((retval = jtag_execute_queue()) != ERROR_OK)
{ {
@ -308,7 +308,7 @@ int xscale_read_dcsr(target_t *target)
jtag_add_end_state(TAP_RTI); jtag_add_end_state(TAP_RTI);
jtag_add_dr_scan(3, fields, -1); jtag_add_dr_scan(3, fields, -1, NULL);
return ERROR_OK; return ERROR_OK;
} }
@ -383,7 +383,7 @@ int xscale_receive(target_t *target, u32 *buffer, int num_words)
fields[1].in_handler_priv = (u8*)&field1[i]; fields[1].in_handler_priv = (u8*)&field1[i];
jtag_add_pathmove(3, path); jtag_add_pathmove(3, path);
jtag_add_dr_scan(3, fields, TAP_RTI); jtag_add_dr_scan(3, fields, TAP_RTI, NULL);
words_scheduled++; words_scheduled++;
} }
@ -487,7 +487,7 @@ int xscale_read_tx(target_t *target, int consume)
else else
jtag_add_statemove(TAP_PD); jtag_add_statemove(TAP_PD);
jtag_add_dr_scan(3, fields, TAP_RTI); jtag_add_dr_scan(3, fields, TAP_RTI, NULL);
if ((retval = jtag_execute_queue()) != ERROR_OK) if ((retval = jtag_execute_queue()) != ERROR_OK)
{ {
@ -567,7 +567,7 @@ int xscale_write_rx(target_t *target)
do do
{ {
DEBUG("polling RX"); DEBUG("polling RX");
jtag_add_dr_scan(3, fields, TAP_RTI); jtag_add_dr_scan(3, fields, TAP_RTI, NULL);
if ((retval = jtag_execute_queue()) != ERROR_OK) if ((retval = jtag_execute_queue()) != ERROR_OK)
{ {
@ -585,7 +585,7 @@ int xscale_write_rx(target_t *target)
/* set rx_valid */ /* set rx_valid */
field2 = 0x1; field2 = 0x1;
jtag_add_dr_scan(3, fields, TAP_RTI); jtag_add_dr_scan(3, fields, TAP_RTI, NULL);
if ((retval = jtag_execute_queue()) != ERROR_OK) if ((retval = jtag_execute_queue()) != ERROR_OK)
{ {
@ -671,7 +671,7 @@ int xscale_send(target_t *target, u8 *buffer, int count, int size)
exit(-1); exit(-1);
} }
jtag_add_dr_scan(3, fields, TAP_RTI); jtag_add_dr_scan(3, fields, TAP_RTI, NULL);
buffer += size; buffer += size;
} }
@ -750,7 +750,7 @@ int xscale_write_dcsr(target_t *target, int hold_rst, int ext_dbg_brk)
fields[2].in_handler = NULL; fields[2].in_handler = NULL;
fields[2].in_handler_priv = NULL; fields[2].in_handler_priv = NULL;
jtag_add_dr_scan(3, fields, -1); jtag_add_dr_scan(3, fields, -1, NULL);
if ((retval = jtag_execute_queue()) != ERROR_OK) if ((retval = jtag_execute_queue()) != ERROR_OK)
{ {
@ -822,7 +822,7 @@ int xscale_load_ic(target_t *target, int mini, u32 va, u32 buffer[8])
fields[1].in_handler = NULL; fields[1].in_handler = NULL;
fields[1].in_handler_priv = NULL; fields[1].in_handler_priv = NULL;
jtag_add_dr_scan(2, fields, -1); jtag_add_dr_scan(2, fields, -1, NULL);
fields[0].num_bits = 32; fields[0].num_bits = 32;
fields[0].out_value = packet; fields[0].out_value = packet;
@ -834,7 +834,7 @@ int xscale_load_ic(target_t *target, int mini, u32 va, u32 buffer[8])
{ {
buf_set_u32(packet, 0, 32, buffer[word]); buf_set_u32(packet, 0, 32, buffer[word]);
cmd = parity(*((u32*)packet)); cmd = parity(*((u32*)packet));
jtag_add_dr_scan(2, fields, -1); jtag_add_dr_scan(2, fields, -1, NULL);
} }
jtag_execute_queue(); jtag_execute_queue();
@ -880,7 +880,7 @@ int xscale_invalidate_ic_line(target_t *target, u32 va)
fields[1].in_handler = NULL; fields[1].in_handler = NULL;
fields[1].in_handler_priv = NULL; fields[1].in_handler_priv = NULL;
jtag_add_dr_scan(2, fields, -1); jtag_add_dr_scan(2, fields, -1, NULL);
return ERROR_OK; return ERROR_OK;
} }

View File

@ -188,9 +188,9 @@ int handle_xsvf_command(struct command_context_s *cmd_ctx, char *cmd, char **arg
field.in_handler = NULL; field.in_handler = NULL;
field.in_handler_priv = NULL; field.in_handler_priv = NULL;
if (device == -1) if (device == -1)
jtag_add_plain_ir_scan(1, &field, TAP_PI); jtag_add_plain_ir_scan(1, &field, TAP_PI, NULL);
else else
jtag_add_ir_scan(1, &field, TAP_PI); jtag_add_ir_scan(1, &field, TAP_PI, NULL);
if (jtag_execute_queue() != ERROR_OK) if (jtag_execute_queue() != ERROR_OK)
{ {
tdo_mismatch = 1; tdo_mismatch = 1;
@ -231,9 +231,9 @@ int handle_xsvf_command(struct command_context_s *cmd_ctx, char *cmd, char **arg
field.in_handler = NULL; field.in_handler = NULL;
field.in_handler_priv = NULL; field.in_handler_priv = NULL;
if (device == -1) if (device == -1)
jtag_add_plain_dr_scan(1, &field, TAP_PD); jtag_add_plain_dr_scan(1, &field, TAP_PD, NULL);
else else
jtag_add_dr_scan(1, &field, TAP_PD); jtag_add_dr_scan(1, &field, TAP_PD, NULL);
if (jtag_execute_queue() != ERROR_OK) if (jtag_execute_queue() != ERROR_OK)
{ {
tdo_mismatch = 1; tdo_mismatch = 1;
@ -308,9 +308,9 @@ int handle_xsvf_command(struct command_context_s *cmd_ctx, char *cmd, char **arg
field.in_handler = NULL; field.in_handler = NULL;
field.in_handler_priv = NULL; field.in_handler_priv = NULL;
if (device == -1) if (device == -1)
jtag_add_plain_dr_scan(1, &field, TAP_PD); jtag_add_plain_dr_scan(1, &field, TAP_PD, NULL);
else else
jtag_add_dr_scan(1, &field, TAP_PD); jtag_add_dr_scan(1, &field, TAP_PD, NULL);
if (jtag_execute_queue() != ERROR_OK) if (jtag_execute_queue() != ERROR_OK)
{ {
tdo_mismatch = 1; tdo_mismatch = 1;
@ -434,9 +434,9 @@ int handle_xsvf_command(struct command_context_s *cmd_ctx, char *cmd, char **arg
field.in_handler = NULL; field.in_handler = NULL;
field.in_handler_priv = NULL; field.in_handler_priv = NULL;
if (device == -1) if (device == -1)
jtag_add_plain_ir_scan(1, &field, xsvf_to_tap[xendir]); jtag_add_plain_ir_scan(1, &field, xsvf_to_tap[xendir], NULL);
else else
jtag_add_ir_scan(1, &field, xsvf_to_tap[xendir]); jtag_add_ir_scan(1, &field, xsvf_to_tap[xendir], NULL);
} }
free(ir_buf); free(ir_buf);
} }