From 2e01a1ad1930aabb9e3bc7a0e3eb98b2b3331b1c Mon Sep 17 00:00:00 2001 From: mifi Date: Mon, 7 Jan 2008 17:11:11 +0000 Subject: [PATCH] - added gdb flash fixes patch https://lists.berlios.de/pipermail/openocd-development/2007-December/000548.html - added synthesize in_check_mask/value and error handler patch https://lists.berlios.de/pipermail/openocd-development/2008-January/000554.html (thanks to oyvind harboe for these patches) git-svn-id: svn://svn.berlios.de/openocd/trunk@248 b42882b7-edfa-0310-969c-e2dbd0fdcd60 --- src/jtag/bitq.c | 24 +--- src/jtag/jtag.c | 230 ++++++++++++++++++------------------- src/jtag/jtag.h | 12 +- src/server/gdb_server.c | 27 +++-- src/target/arm7_9_common.c | 18 ++- src/target/arm_jtag.c | 14 ++- src/target/embeddedice.c | 3 +- src/target/etb.c | 6 +- src/target/etm.c | 3 +- src/target/xscale.c | 79 +++++-------- src/xsvf/xsvf.c | 10 +- 11 files changed, 196 insertions(+), 230 deletions(-) diff --git a/src/jtag/bitq.c b/src/jtag/bitq.c index 9d1f43dc..a4ec626f 100644 --- a/src/jtag/bitq.c +++ b/src/jtag/bitq.c @@ -69,7 +69,7 @@ void bitq_in_proc(void) while (bitq_in_state.field_idxcmd.scan->num_fields) { field=&bitq_in_state.cmd->cmd.scan->fields[bitq_in_state.field_idx]; - if (field->in_check_value || field->in_value || field->in_handler) { + if ( field->in_value || field->in_handler) { if (bitq_in_state.bit_pos==0) { /* initialize field scanning */ @@ -115,26 +115,6 @@ void bitq_in_proc(void) bitq_in_state.bit_pos++; } - if (field->in_check_value) { - /* match scanned in value */ - for (in_idx=0; in_idx*8num_bits; in_idx++) { - if (field->in_check_mask) in_mask=field->in_check_mask[in_idx]; - else in_mask=0xff; - if (field->num_bits-in_idx*8<8) in_mask>>=8-(field->num_bits-in_idx*8); - if (field->in_check_value[in_idx]&in_mask!=in_buff[in_idx]&in_mask) { - char *captured_char = buf_to_str(in_buff, (field->num_bits > 64) ? 64 : field->num_bits, 16); - char *in_check_value_char = buf_to_str(field->in_check_value, (field->num_bits > 64) ? 64 : field->num_bits, 16); - char *in_check_mask_char = buf_to_str(field->in_check_mask, (field->num_bits > 64) ? 64 : field->num_bits, 16); - /* TODO: error reporting */ - 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); - bitq_in_state.status=ERROR_JTAG_QUEUE_FAILED; - free(captured_char); - free(in_check_value_char); - free(in_check_mask_char); - break; /* leave the comparison loop upon first mismatch */ - } - } - } if (field->in_handler && bitq_in_state.status==ERROR_OK) { bitq_in_state.status=(*field->in_handler)(in_buff, field->in_handler_priv); @@ -237,7 +217,7 @@ void bitq_scan_field(scan_field_t *field, int pause) u8 *out_ptr; u8 out_mask; - if (field->in_check_value || field->in_value || field->in_handler) tdo_req=1; + if ( field->in_value || field->in_handler) tdo_req=1; else tdo_req=0; if (field->out_value==NULL) { diff --git a/src/jtag/jtag.c b/src/jtag/jtag.c index a34a16fd..bc5e88fb 100644 --- a/src/jtag/jtag.c +++ b/src/jtag/jtag.c @@ -209,10 +209,6 @@ int jtag_speed = -1; /* forward declarations */ -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, error_handler_t *error_handler); -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, error_handler_t *error_handler); int jtag_add_statemove(enum tap_state endstate); int jtag_add_pathmove(int num_states, enum tap_state *path); int jtag_add_runtest(int num_cycles, enum tap_state endstate); @@ -381,7 +377,7 @@ void cmd_queue_free() cmd_queue_pages = NULL; } -int jtag_add_ir_scan(int num_fields, scan_field_t *fields, enum tap_state state, error_handler_t *error_handler) +int jtag_add_ir_scan(int num_fields, scan_field_t *fields, enum tap_state state, void *dummy_anachronism) { jtag_command_t **last_cmd; jtag_device_t *device; @@ -408,15 +404,6 @@ 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->fields = cmd_queue_alloc(jtag_num_devices * sizeof(scan_field_t)); (*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) cmd_queue_end_state = state; @@ -437,18 +424,12 @@ int jtag_add_ir_scan(int num_fields, scan_field_t *fields, enum tap_state state, (*last_cmd)->cmd.scan->fields[i].device = i; (*last_cmd)->cmd.scan->fields[i].num_bits = scan_size; (*last_cmd)->cmd.scan->fields[i].in_value = NULL; + (*last_cmd)->cmd.scan->fields[i].in_handler = NULL; + (*last_cmd)->cmd.scan->fields[i].in_handler_priv = NULL; if (jtag_verify_capture_ir) { - (*last_cmd)->cmd.scan->fields[i].in_check_value = buf_cpy(device->expected, cmd_queue_alloc(CEIL(scan_size, 8)), scan_size); - (*last_cmd)->cmd.scan->fields[i].in_check_mask = buf_cpy(device->expected_mask, cmd_queue_alloc(CEIL(scan_size, 8)), scan_size); - } - else - { - (*last_cmd)->cmd.scan->fields[i].in_check_value = NULL; - (*last_cmd)->cmd.scan->fields[i].in_check_mask = NULL; + jtag_set_check_value((*last_cmd)->cmd.scan->fields+i, device->expected, device->expected_mask, NULL); } - (*last_cmd)->cmd.scan->fields[i].in_handler = NULL; - (*last_cmd)->cmd.scan->fields[i].in_handler_priv = NULL; /* search the list */ for (j=0; j < num_fields; j++) @@ -480,7 +461,7 @@ int jtag_add_ir_scan(int num_fields, scan_field_t *fields, enum tap_state state, return ERROR_OK; } -int jtag_add_plain_ir_scan(int num_fields, scan_field_t *fields, enum tap_state state, error_handler_t *error_handler) +int jtag_add_plain_ir_scan(int num_fields, scan_field_t *fields, enum tap_state state, void *dummy_anachronism) { jtag_command_t **last_cmd; int i; @@ -505,15 +486,6 @@ 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->fields = cmd_queue_alloc(num_fields * sizeof(scan_field_t)); (*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) cmd_queue_end_state = state; @@ -535,15 +507,15 @@ int jtag_add_plain_ir_scan(int num_fields, scan_field_t *fields, enum tap_state (*last_cmd)->cmd.scan->fields[i].out_value = buf_cpy(fields[i].out_value, cmd_queue_alloc(num_bytes), num_bits); (*last_cmd)->cmd.scan->fields[i].out_mask = buf_cpy(fields[i].out_mask, cmd_queue_alloc(num_bytes), num_bits); (*last_cmd)->cmd.scan->fields[i].in_value = fields[i].in_value; - (*last_cmd)->cmd.scan->fields[i].in_check_value = buf_cpy(fields[i].in_check_value, cmd_queue_alloc(num_bytes), num_bits); - (*last_cmd)->cmd.scan->fields[i].in_check_mask = buf_cpy(fields[i].in_check_mask, cmd_queue_alloc(num_bytes), num_bits); + (*last_cmd)->cmd.scan->fields[i].in_check_value = fields[i].in_check_value; + (*last_cmd)->cmd.scan->fields[i].in_check_mask = fields[i].in_check_mask; (*last_cmd)->cmd.scan->fields[i].in_handler = NULL; (*last_cmd)->cmd.scan->fields[i].in_handler_priv = NULL; } return ERROR_OK; } -int jtag_add_dr_scan(int num_fields, scan_field_t *fields, enum tap_state state, error_handler_t *error_handler) +int jtag_add_dr_scan(int num_fields, scan_field_t *fields, enum tap_state state, void *dummy_anachronism) { int i, j; int bypass_devices = 0; @@ -578,15 +550,6 @@ 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->fields = cmd_queue_alloc((num_fields + bypass_devices) * sizeof(scan_field_t)); (*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) cmd_queue_end_state = state; @@ -614,8 +577,8 @@ int jtag_add_dr_scan(int num_fields, scan_field_t *fields, enum tap_state state, (*last_cmd)->cmd.scan->fields[field_count].out_value = buf_cpy(fields[j].out_value, cmd_queue_alloc(CEIL(scan_size, 8)), scan_size); (*last_cmd)->cmd.scan->fields[field_count].out_mask = buf_cpy(fields[j].out_mask, cmd_queue_alloc(CEIL(scan_size, 8)), scan_size); (*last_cmd)->cmd.scan->fields[field_count].in_value = fields[j].in_value; - (*last_cmd)->cmd.scan->fields[field_count].in_check_value = buf_cpy(fields[j].in_check_value, cmd_queue_alloc(CEIL(scan_size, 8)), scan_size); - (*last_cmd)->cmd.scan->fields[field_count].in_check_mask = buf_cpy(fields[j].in_check_mask, cmd_queue_alloc(CEIL(scan_size, 8)), scan_size); + (*last_cmd)->cmd.scan->fields[field_count].in_check_value = fields[j].in_check_value; + (*last_cmd)->cmd.scan->fields[field_count].in_check_mask = fields[j].in_check_mask; (*last_cmd)->cmd.scan->fields[field_count].in_handler = fields[j].in_handler; (*last_cmd)->cmd.scan->fields[field_count++].in_handler_priv = fields[j].in_handler_priv; } @@ -651,7 +614,7 @@ int jtag_add_dr_scan(int num_fields, scan_field_t *fields, enum tap_state state, return ERROR_OK; } -int jtag_add_plain_dr_scan(int num_fields, scan_field_t *fields, enum tap_state state, error_handler_t *error_handler) +int jtag_add_plain_dr_scan(int num_fields, scan_field_t *fields, enum tap_state state, void *dummy_anachronism) { int i; jtag_command_t **last_cmd = jtag_get_last_command_p(); @@ -674,15 +637,6 @@ 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->fields = cmd_queue_alloc(num_fields * sizeof(scan_field_t)); (*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) cmd_queue_end_state = state; @@ -704,8 +658,8 @@ int jtag_add_plain_dr_scan(int num_fields, scan_field_t *fields, enum tap_state (*last_cmd)->cmd.scan->fields[i].out_value = buf_cpy(fields[i].out_value, cmd_queue_alloc(num_bytes), num_bits); (*last_cmd)->cmd.scan->fields[i].out_mask = buf_cpy(fields[i].out_mask, cmd_queue_alloc(num_bytes), num_bits); (*last_cmd)->cmd.scan->fields[i].in_value = fields[i].in_value; - (*last_cmd)->cmd.scan->fields[i].in_check_value = buf_cpy(fields[i].in_check_value, cmd_queue_alloc(num_bytes), num_bits); - (*last_cmd)->cmd.scan->fields[i].in_check_mask = buf_cpy(fields[i].in_check_mask, cmd_queue_alloc(num_bytes), num_bits); + (*last_cmd)->cmd.scan->fields[i].in_check_value = fields[i].in_check_value; + (*last_cmd)->cmd.scan->fields[i].in_check_mask = fields[i].in_check_mask; (*last_cmd)->cmd.scan->fields[i].in_handler = fields[i].in_handler; (*last_cmd)->cmd.scan->fields[i].in_handler_priv = fields[i].in_handler_priv; } @@ -1037,6 +991,8 @@ int jtag_build_buffer(scan_command_t *cmd, u8 **buffer) } +extern int jtag_check_value(u8 *captured, void *priv); + int jtag_read_buffer(u8 *buffer, scan_command_t *cmd) { int i; @@ -1048,10 +1004,10 @@ int jtag_read_buffer(u8 *buffer, scan_command_t *cmd) for (i=0; i < cmd->num_fields; i++) { - /* if neither in_value, in_check_value nor in_handler + /* if neither in_value nor in_handler * are specified we don't have to examine this field */ - if (cmd->fields[i].in_value || cmd->fields[i].in_check_value || cmd->fields[i].in_handler) + if (cmd->fields[i].in_value || cmd->fields[i].in_handler) { int num_bits = cmd->fields[i].num_bits; u8 *captured = buf_set_buf(buffer, bit_count, malloc(CEIL(num_bits, 8)), 0, num_bits); @@ -1064,13 +1020,30 @@ int jtag_read_buffer(u8 *buffer, scan_command_t *cmd) free(char_buf); #endif + void *priv=cmd->fields[i].in_handler_priv; + if (cmd->fields[i].in_handler==&jtag_check_value) + { + /* Yuk! we want to pass in the pointer to cmd->fields[i] which is not known + * when jtag_check_value is invoked + * + * Not pretty, but this is part of synthesizing check_mask via in_handler + * with a minimum of code impact. + * + * A cleaner change would be to modify the in_handler to always take field + * as an argument. Perhaps later... + * + * Change in_handler to be varargs and have fields+i as the first vararg? + * + */ + priv=cmd->fields+i; + } if (cmd->fields[i].in_value) { buf_cpy(captured, cmd->fields[i].in_value, num_bits); if (cmd->fields[i].in_handler) { - 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, priv) != ERROR_OK) { WARNING("in_handler reported a failed check"); retval = ERROR_JTAG_QUEUE_FAILED; @@ -1081,7 +1054,7 @@ int jtag_read_buffer(u8 *buffer, scan_command_t *cmd) /* no in_value specified, but a handler takes care of the scanned data */ if (cmd->fields[i].in_handler && (!cmd->fields[i].in_value)) { - if (cmd->fields[i].in_handler(captured, cmd->fields[i].in_handler_priv) != ERROR_OK) + if (cmd->fields[i].in_handler(captured, priv) != ERROR_OK) { /* We're going to call the error:handler later, but if the in_handler * reported an error we report this failure upstream @@ -1091,58 +1064,6 @@ int jtag_read_buffer(u8 *buffer, scan_command_t *cmd) } } - if (cmd->fields[i].in_check_value) - { - int compare_failed = 0; - - 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) - { - if (cmd->error_handler) - { - /* 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) - { - 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); - - 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(in_check_value_char); - } - - } - } free(captured); } bit_count += cmd->fields[i].num_bits; @@ -1151,6 +1072,83 @@ int jtag_read_buffer(u8 *buffer, scan_command_t *cmd) return retval; } +int jtag_check_value(u8 *captured, void *priv) +{ + int retval=ERROR_OK; + scan_field_t *field=(scan_field_t *)priv; + int num_bits = field->num_bits; + + int compare_failed = 0; + + if (field->in_check_mask) + compare_failed = buf_cmp_mask(captured, field->in_check_value, field->in_check_mask, num_bits); + else + compare_failed = buf_cmp(captured, field->in_check_value, num_bits); + + if (compare_failed) + { + if (field->in_handler_error_handler.error_handler) + { + /* ask the error handler if once has been specified if this is a real problem */ + if (field->in_handler_error_handler.error_handler(captured, field->in_handler_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) + { + char *captured_char = buf_to_str(captured, (num_bits > 64) ? 64 : num_bits, 16); + char *in_check_value_char = buf_to_str(field->in_check_value, (num_bits > 64) ? 64 : num_bits, 16); + + if (field->in_check_mask) + { + char *in_check_mask_char; + in_check_mask_char = buf_to_str(field->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(in_check_value_char); + } + + } + return retval; +} + +/* + set up checking of this field using the in_handler. The values passed in must be valid until + after jtag_execute() has completed. + */ +void jtag_set_check_value(scan_field_t *field, u8 *value, u8 *mask, error_handler_t *in_error_handler) +{ + if (value) + field->in_handler=jtag_check_value; + else + field->in_handler=NULL; /* No check, e.g. embeddedice uses value==NULL to indicate no check */ + field->in_handler_priv=NULL; /* this will be filled in at the invocation site to point to the field duplicate */ + field->in_check_value=value; + field->in_check_mask=mask; + if (in_error_handler) + field->in_handler_error_handler=*in_error_handler; + else + field->in_handler_error_handler.error_handler=NULL; +} + enum scan_type jtag_scan_type(scan_command_t *cmd) { int i; @@ -1158,7 +1156,7 @@ enum scan_type jtag_scan_type(scan_command_t *cmd) for (i=0; i < cmd->num_fields; i++) { - if (cmd->fields[i].in_check_value || cmd->fields[i].in_value || cmd->fields[i].in_handler) + if (cmd->fields[i].in_value || cmd->fields[i].in_handler) type |= SCAN_IN; if (cmd->fields[i].out_value) type |= SCAN_OUT; diff --git a/src/jtag/jtag.h b/src/jtag/jtag.h index 1b03d615..0ea6f5b6 100644 --- a/src/jtag/jtag.h +++ b/src/jtag/jtag.h @@ -77,6 +77,8 @@ typedef struct scan_field_s u8 *out_value; /* value to be scanned into the device */ u8 *out_mask; /* only masked bits care */ u8 *in_value; /* pointer to a 32-bit memory location to take data scanned out */ + /* in_check_value/mask, in_handler_error_handler, in_handler_priv can be used by the in handler, otherwise they contain garbage */ + error_handler_t in_handler_error_handler; u8 *in_check_value; /* used to validate scan results */ u8 *in_check_mask; /* check specified bits against check_value */ int (*in_handler)(u8 *in_value, void *priv); /* process received buffer using this handler */ @@ -95,7 +97,6 @@ typedef struct scan_command_s int num_fields; /* number of fields in *fields array */ 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 */ - error_handler_t *error_handler; } scan_command_t; typedef struct statemove_command_s @@ -249,10 +250,10 @@ extern int jtag_init(struct command_context_s *cmd_ctx); extern int jtag_register_commands(struct command_context_s *cmd_ctx); /* JTAG interface */ -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, error_handler_t *error_handler); -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, error_handler_t *error_handler); +extern int jtag_add_ir_scan(int num_fields, scan_field_t *fields, enum tap_state endstate, void *dummy_anachronism); +extern int jtag_add_dr_scan(int num_fields, scan_field_t *fields, enum tap_state endstate, void *dummy_anachronism); +extern int jtag_add_plain_ir_scan(int num_fields, scan_field_t *fields, enum tap_state endstate, void *dummy_anachronism); +extern int jtag_add_plain_dr_scan(int num_fields, scan_field_t *fields, enum tap_state endstate, void *dummy_anachronism); 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_runtest(int num_cycles, enum tap_state endstate); @@ -263,6 +264,7 @@ extern int jtag_execute_queue(void); extern int jtag_cancel_queue(void); /* JTAG support functions */ +extern void jtag_set_check_value(scan_field_t *field, u8 *value, u8 *mask, error_handler_t *in_error_handler); extern enum scan_type jtag_scan_type(scan_command_t *cmd); extern int jtag_scan_size(scan_command_t *cmd); extern int jtag_read_buffer(u8 *buffer, scan_command_t *cmd); diff --git a/src/server/gdb_server.c b/src/server/gdb_server.c index ef45c772..42f04680 100644 --- a/src/server/gdb_server.c +++ b/src/server/gdb_server.c @@ -1223,7 +1223,7 @@ int gdb_breakpoint_watchpoint_packet(connection_t *connection, target_t *target, return ERROR_OK; } -/* print out XML and allocate more space as needed */ +/* print out a string and allocate more space as needed, mainly used for XML at this point */ void xml_printf(int *retval, char **xml, int *pos, int *size, const char *fmt, ...) { if (*retval != ERROR_OK) @@ -1240,10 +1240,13 @@ void xml_printf(int *retval, char **xml, int *pos, int *size, const char *fmt, . * Need minimum 2 bytes to fit 1 char and 0 terminator. */ *size = *size * 2 + 2; + char *t=*xml; *xml = realloc(*xml, *size); if (*xml == NULL) { - *retval = 1; + if (t) + free(t); + *retval=ERROR_SERVER_REMOTE_CLOSED; return; } } @@ -1290,7 +1293,6 @@ static int decode_xfer_read (char *buf, char **annex, int *ofs, unsigned int *le int gdb_query_packet(connection_t *connection, target_t *target, char *packet, int packet_size) { - char buffer[GDB_BUFFER_SIZE]; command_context_t *cmd_ctx = connection->cmd_ctx; if (strstr(packet, "qRcmd,")) @@ -1357,12 +1359,19 @@ int gdb_query_packet(connection_t *connection, target_t *target, char *packet, i { /* we currently support packet size and qXfer:memory-map:read (if enabled) * disable qXfer:features:read for the moment */ - - sprintf(buffer, "PacketSize=%x;qXfer:memory-map:read%c;qXfer:features:read-", - (GDB_BUFFER_SIZE - 1), gdb_use_memory_map == 1 ? '+' : '-'); - - gdb_put_packet(connection, buffer, strlen(buffer)); - return ERROR_OK; + int retval = ERROR_OK; + char *buffer = NULL; + int pos = 0; + int size = 0; + xml_printf(&retval, &buffer, &pos, &size, + "PacketSize=%x;qXfer:memory-map:read%c;qXfer:features:read-", + (GDB_BUFFER_SIZE - 1), gdb_use_memory_map == 1 ? '+' : '-'); + if (buffer!=NULL) + { + gdb_put_packet(connection, buffer, strlen(buffer)); + free(buffer); + } + return retval; } else if (strstr(packet, "qXfer:memory-map:read::")) { diff --git a/src/target/arm7_9_common.c b/src/target/arm7_9_common.c index b5434d68..ee814ba9 100644 --- a/src/target/arm7_9_common.c +++ b/src/target/arm7_9_common.c @@ -577,7 +577,8 @@ int arm7_9_execute_sys_speed(struct target_s *target) int arm7_9_execute_fast_sys_speed(struct target_s *target) { - u8 check_value[4], check_mask[4]; + static int set=0; + static u8 check_value[4], check_mask[4]; armv4_5_common_t *armv4_5 = target->arch_info; arm7_9_common_t *arm7_9 = armv4_5->arch_info; @@ -588,9 +589,18 @@ int arm7_9_execute_fast_sys_speed(struct target_s *target) jtag_add_end_state(TAP_RTI); arm_jtag_set_instr(jtag_info, 0x4, NULL); - /* check for DBGACK and SYSCOMP set (others don't care) */ - buf_set_u32(check_value, 0, 32, 0x9); - buf_set_u32(check_mask, 0, 32, 0x9); + if (!set) + { + /* check for DBGACK and SYSCOMP set (others don't care) */ + + /* NB! These are constants that must be available until after next jtag_execute() and + we evaluate the values upon first execution in lieu of setting up these constants + during early setup. + */ + buf_set_u32(check_value, 0, 32, 0x9); + buf_set_u32(check_mask, 0, 32, 0x9); + set=1; + } /* read debug status register */ embeddedice_read_reg_w_check(dbg_stat, check_value, check_value); diff --git a/src/target/arm_jtag.c b/src/target/arm_jtag.c index 305590c8..f87f37a5 100644 --- a/src/target/arm_jtag.c +++ b/src/target/arm_jtag.c @@ -59,17 +59,20 @@ int arm_jtag_set_instr(arm_jtag_t *jtag_info, u32 new_instr, error_handler_t *ca field.in_handler = NULL; field.in_handler_priv = NULL; + + if (caller_error_handler) { - jtag_add_ir_scan(1, &field, -1, caller_error_handler); + jtag_set_check_value(&field, NULL, NULL, 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); + jtag_set_check_value(&field, NULL, NULL, &error_handler); } + jtag_add_ir_scan(1, &field, -1, NULL); free(field.out_value); @@ -94,13 +97,12 @@ int arm_jtag_scann(arm_jtag_t *jtag_info, u32 new_scan_chain) field.out_mask = NULL; field.in_value = NULL; #ifdef _ARM_JTAG_SCAN_N_CHECK_ - field.in_check_value = &scan_n_check_value; + jtag_set_check_value(&field, &scan_n_check_value, NULL, NULL, NULL); #else - field.in_check_value = NULL; -#endif - field.in_check_mask = NULL; field.in_handler = NULL; field.in_handler_priv = NULL; +#endif + arm_jtag_set_instr(jtag_info, jtag_info->scann_instr, NULL); jtag_add_dr_scan(1, &field, -1, NULL); diff --git a/src/target/embeddedice.c b/src/target/embeddedice.c index 11f2e6c2..3713fe95 100644 --- a/src/target/embeddedice.c +++ b/src/target/embeddedice.c @@ -259,8 +259,7 @@ int embeddedice_read_reg_w_check(reg_t *reg, u8* check_value, u8* check_mask) jtag_add_dr_scan(3, fields, -1, NULL); 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); /* when reading the DCC data register, leaving the address field set to * EICE_COMMS_DATA would read the register twice diff --git a/src/target/etb.c b/src/target/etb.c index 53f9f30e..0c409fb0 100644 --- a/src/target/etb.c +++ b/src/target/etb.c @@ -293,9 +293,9 @@ int etb_read_reg_w_check(reg_t *reg, u8* check_value, u8* check_mask) */ buf_set_u32(fields[1].out_value, 0, 7, 0x0); 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); free(fields[1].out_value); diff --git a/src/target/etm.c b/src/target/etm.c index 0b8a8f5f..0d20b0d5 100644 --- a/src/target/etm.c +++ b/src/target/etm.c @@ -359,8 +359,7 @@ int etm_read_reg_w_check(reg_t *reg, u8* check_value, u8* check_mask) jtag_add_dr_scan(3, fields, -1, NULL); 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); diff --git a/src/target/xscale.c b/src/target/xscale.c index 13ecef1c..cb673df6 100644 --- a/src/target/xscale.c +++ b/src/target/xscale.c @@ -217,11 +217,8 @@ int xscale_jtag_set_instr(int chain_pos, u32 new_instr) buf_set_u32(field.out_value, 0, field.num_bits, new_instr); field.out_mask = NULL; field.in_value = NULL; - field.in_check_value = device->expected; - field.in_check_mask = device->expected_mask; - field.in_handler = NULL; - field.in_handler_priv = NULL; - + jtag_set_check_value(&field, device->expected, device->expected_mask, NULL); + jtag_add_ir_scan(1, &field, -1, NULL); free(field.out_value); @@ -275,10 +272,7 @@ int xscale_read_dcsr(target_t *target) fields[0].out_value = &field0; fields[0].out_mask = NULL; fields[0].in_value = NULL; - fields[0].in_check_value = &field0_check_value; - fields[0].in_check_mask = &field0_check_mask; - fields[0].in_handler = NULL; - fields[0].in_handler_priv = NULL; + jtag_set_check_value(fields+0, &field0_check_value, &field0_check_mask, NULL); fields[1].device = xscale->jtag_info.chain_pos; fields[1].num_bits = 32; @@ -289,16 +283,15 @@ int xscale_read_dcsr(target_t *target) fields[1].in_handler_priv = NULL; fields[1].in_check_value = NULL; fields[1].in_check_mask = NULL; + + fields[2].device = xscale->jtag_info.chain_pos; fields[2].num_bits = 1; fields[2].out_value = &field2; fields[2].out_mask = NULL; fields[2].in_value = NULL; - fields[2].in_check_value = &field2_check_value; - fields[2].in_check_mask = &field2_check_mask; - fields[2].in_handler = NULL; - fields[2].in_handler_priv = NULL; + jtag_set_check_value(fields+2, &field2_check_value, &field2_check_mask, NULL); jtag_add_dr_scan(3, fields, -1, NULL); @@ -354,10 +347,7 @@ int xscale_receive(target_t *target, u32 *buffer, int num_words) fields[0].out_value = NULL; fields[0].out_mask = NULL; /* fields[0].in_value = field0; */ - fields[0].in_check_value = &field0_check_value; - fields[0].in_check_mask = &field0_check_mask; - fields[0].in_handler = NULL; - fields[0].in_handler_priv = NULL; + jtag_set_check_value(fields+0, &field0_check_value, &field0_check_mask, NULL); fields[1].device = xscale->jtag_info.chain_pos; fields[1].num_bits = 32; @@ -368,16 +358,15 @@ int xscale_receive(target_t *target, u32 *buffer, int num_words) fields[1].in_handler_priv = NULL; fields[1].in_check_value = NULL; fields[1].in_check_mask = NULL; + + fields[2].device = xscale->jtag_info.chain_pos; fields[2].num_bits = 1; fields[2].out_value = NULL; fields[2].out_mask = NULL; fields[2].in_value = NULL; - fields[2].in_check_value = &field2_check_value; - fields[2].in_check_mask = &field2_check_mask; - fields[2].in_handler = NULL; - fields[2].in_handler_priv = NULL; + jtag_set_check_value(fields+2, &field2_check_value, &field2_check_mask, NULL); jtag_add_end_state(TAP_RTI); xscale_jtag_set_instr(xscale->jtag_info.chain_pos, xscale->jtag_info.dbgtx); @@ -460,10 +449,7 @@ int xscale_read_tx(target_t *target, int consume) fields[0].out_value = NULL; fields[0].out_mask = NULL; fields[0].in_value = &field0_in; - fields[0].in_check_value = &field0_check_value; - fields[0].in_check_mask = &field0_check_mask; - fields[0].in_handler = NULL; - fields[0].in_handler_priv = NULL; + jtag_set_check_value(fields+0, &field0_check_value, &field0_check_mask, NULL); fields[1].device = xscale->jtag_info.chain_pos; fields[1].num_bits = 32; @@ -474,16 +460,15 @@ int xscale_read_tx(target_t *target, int consume) fields[1].in_handler_priv = NULL; fields[1].in_check_value = NULL; fields[1].in_check_mask = NULL; + + fields[2].device = xscale->jtag_info.chain_pos; fields[2].num_bits = 1; fields[2].out_value = NULL; fields[2].out_mask = NULL; fields[2].in_value = NULL; - fields[2].in_check_value = &field2_check_value; - fields[2].in_check_mask = &field2_check_mask; - fields[2].in_handler = NULL; - fields[2].in_handler_priv = NULL; + jtag_set_check_value(fields+2, &field2_check_value, &field2_check_mask, NULL); gettimeofday(&timeout, NULL); timeval_add_time(&timeout, 5, 0); @@ -547,10 +532,7 @@ int xscale_write_rx(target_t *target) fields[0].out_value = &field0_out; fields[0].out_mask = NULL; fields[0].in_value = &field0_in; - fields[0].in_check_value = &field0_check_value; - fields[0].in_check_mask = &field0_check_mask; - fields[0].in_handler = NULL; - fields[0].in_handler_priv = NULL; + jtag_set_check_value(fields+0, &field0_check_value, &field0_check_mask, NULL); fields[1].device = xscale->jtag_info.chain_pos; fields[1].num_bits = 32; @@ -561,16 +543,15 @@ int xscale_write_rx(target_t *target) fields[1].in_handler_priv = NULL; fields[1].in_check_value = NULL; fields[1].in_check_mask = NULL; + + fields[2].device = xscale->jtag_info.chain_pos; fields[2].num_bits = 1; fields[2].out_value = &field2; fields[2].out_mask = NULL; fields[2].in_value = NULL; - fields[2].in_check_value = &field2_check_value; - fields[2].in_check_mask = &field2_check_mask; - fields[2].in_handler = NULL; - fields[2].in_handler_priv = NULL; + jtag_set_check_value(fields+2, &field2_check_value, &field2_check_mask, NULL); gettimeofday(&timeout, NULL); timeval_add_time(&timeout, 5, 0); @@ -637,10 +618,7 @@ int xscale_send(target_t *target, u8 *buffer, int count, int size) fields[0].out_value = &field0_out; fields[0].out_mask = NULL; fields[0].in_value = &field0_in; - fields[0].in_check_value = &field0_check_value; - fields[0].in_check_mask = &field0_check_mask; - fields[0].in_handler = NULL; - fields[0].in_handler_priv = NULL; + jtag_set_check_value(fields+0, &field0_check_value, &field0_check_mask, NULL); fields[1].device = xscale->jtag_info.chain_pos; fields[1].num_bits = 32; @@ -651,16 +629,15 @@ int xscale_send(target_t *target, u8 *buffer, int count, int size) fields[1].in_handler_priv = NULL; fields[1].in_check_value = NULL; fields[1].in_check_mask = NULL; + + fields[2].device = xscale->jtag_info.chain_pos; fields[2].num_bits = 1; fields[2].out_value = &field2; fields[2].out_mask = NULL; fields[2].in_value = NULL; - fields[2].in_check_value = &field2_check_value; - fields[2].in_check_mask = &field2_check_mask; - fields[2].in_handler = NULL; - fields[2].in_handler_priv = NULL; + jtag_set_check_value(fields+2, &field2_check_value, &field2_check_mask, NULL); while (done_count++ < count) { @@ -737,10 +714,7 @@ int xscale_write_dcsr(target_t *target, int hold_rst, int ext_dbg_brk) fields[0].out_value = &field0; fields[0].out_mask = NULL; fields[0].in_value = NULL; - fields[0].in_check_value = &field0_check_value; - fields[0].in_check_mask = &field0_check_mask; - fields[0].in_handler = NULL; - fields[0].in_handler_priv = NULL; + jtag_set_check_value(fields+0, &field0_check_value, &field0_check_mask, NULL); fields[1].device = xscale->jtag_info.chain_pos; fields[1].num_bits = 32; @@ -751,16 +725,15 @@ int xscale_write_dcsr(target_t *target, int hold_rst, int ext_dbg_brk) fields[1].in_handler_priv = NULL; fields[1].in_check_value = NULL; fields[1].in_check_mask = NULL; + + fields[2].device = xscale->jtag_info.chain_pos; fields[2].num_bits = 1; fields[2].out_value = &field2; fields[2].out_mask = NULL; fields[2].in_value = NULL; - fields[2].in_check_value = &field2_check_value; - fields[2].in_check_mask = &field2_check_mask; - fields[2].in_handler = NULL; - fields[2].in_handler_priv = NULL; + jtag_set_check_value(fields+2, &field2_check_value, &field2_check_mask, NULL); jtag_add_dr_scan(3, fields, -1, NULL); diff --git a/src/xsvf/xsvf.c b/src/xsvf/xsvf.c index fd9e364e..16012887 100644 --- a/src/xsvf/xsvf.c +++ b/src/xsvf/xsvf.c @@ -226,10 +226,7 @@ int handle_xsvf_command(struct command_context_s *cmd_ctx, char *cmd, char **arg field.out_value = dr_out_buf; field.out_mask = NULL; field.in_value = NULL; - field.in_check_value = dr_in_buf; - field.in_check_mask = dr_in_mask; - field.in_handler = NULL; - field.in_handler_priv = NULL; + jtag_set_check_value(&field, dr_in_buf, dr_in_mask, NULL); if (device == -1) jtag_add_plain_dr_scan(1, &field, TAP_PD, NULL); else @@ -303,10 +300,7 @@ int handle_xsvf_command(struct command_context_s *cmd_ctx, char *cmd, char **arg field.out_value = dr_out_buf; field.out_mask = NULL; field.in_value = NULL; - field.in_check_value = dr_in_buf; - field.in_check_mask = dr_in_mask; - field.in_handler = NULL; - field.in_handler_priv = NULL; + jtag_set_check_value(&field, dr_in_buf, dr_in_mask, NULL); if (device == -1) jtag_add_plain_dr_scan(1, &field, TAP_PD, NULL); else -- 2.39.5