X-Git-Url: https://review.openocd.org/gitweb?p=openocd.git;a=blobdiff_plain;f=src%2Fjtag%2Fjtag.c;h=e02b91f088d5d6a818232c7e2cc3a9de8ec2a1be;hp=981f47e128bb794c365172df3f82587ee74d145c;hb=84dfdd4de680d2f16275dee2445c5bfcaa363538;hpb=c4ee880715121ccfb2ad960673d0f5e603c60d3d diff --git a/src/jtag/jtag.c b/src/jtag/jtag.c index 981f47e128..e02b91f088 100644 --- a/src/jtag/jtag.c +++ b/src/jtag/jtag.c @@ -41,6 +41,7 @@ #ifdef HAVE_STRINGS_H #include #endif +#include @@ -521,15 +522,65 @@ static void jtag_prelude(tap_state_t state) cmd_queue_cur_state = cmd_queue_end_state; } -void jtag_add_ir_scan(int num_fields, scan_field_t *fields, tap_state_t state) +void jtag_add_ir_scan_noverify(int num_fields, scan_field_t *fields, tap_state_t state) { int retval; - jtag_prelude(state); retval=interface_jtag_add_ir_scan(num_fields, fields, cmd_queue_end_state); if (retval!=ERROR_OK) jtag_error=retval; + +} + + +void jtag_add_ir_scan(int num_fields, scan_field_t *fields, tap_state_t state) +{ + /* 8 x 32 bit id's is enough for all invoations */ + u32 id[8]; + int modified[8]; + + /* if we are to run a verification of the ir scan, we need to get the input back. + * We may have to allocate space if the caller didn't ask for the input back. + * + */ + if (jtag_verify_capture_ir) + { + int j; + for (j = 0; j < num_fields; j++) + { + modified[j]=0; + if ((fields[j].in_value==NULL)&&(fields[j].num_bits<=32)) + { + if (j<8) + { + modified[j]=1; + fields[j].in_value=(u8 *)(id+j); + } else + { + LOG_DEBUG("caller must provide in_value space for verify_capture_ir to work"); + } + } + } + } + + jtag_add_ir_scan_noverify(num_fields, fields, state); + + if (jtag_verify_capture_ir) + { + int j; + for (j = 0; j < num_fields; j++) + { + jtag_tap_t *tap=fields[j].tap; + jtag_check_value_mask(fields+j, tap->expected, tap->expected_mask); + + if (modified[j]) + { + fields[j].in_value=NULL; + } + } + } + } int MINIDRIVER(interface_jtag_add_ir_scan)(int num_fields, scan_field_t *fields, tap_state_t state) @@ -582,20 +633,6 @@ int MINIDRIVER(interface_jtag_add_ir_scan)(int num_fields, scan_field_t *fields, found = 1; (*last_cmd)->cmd.scan->fields[nth_tap].out_value = buf_cpy(fields[j].out_value, cmd_queue_alloc(CEIL(scan_size, 8)), scan_size); - if (jtag_verify_capture_ir) - { - if (fields[j].in_handler==NULL) - { - jtag_set_check_value((*last_cmd)->cmd.scan->fields+nth_tap, tap->expected, tap->expected_mask, NULL); - } else - { - (*last_cmd)->cmd.scan->fields[nth_tap].in_handler = fields[j].in_handler; - (*last_cmd)->cmd.scan->fields[nth_tap].in_handler_priv = fields[j].in_handler_priv; - (*last_cmd)->cmd.scan->fields[nth_tap].in_check_value = tap->expected; - (*last_cmd)->cmd.scan->fields[nth_tap].in_check_mask = tap->expected_mask; - } - } - tap->bypass = 0; break; } @@ -1347,7 +1384,7 @@ static const char *jtag_tap_name(jtag_tap_t *tap) return (tap == NULL) ? "(unknown)" : tap->dotted_name; } -int jtag_check_value(u8 *captured, void *priv, scan_field_t *field) +int jtag_check_value_inner(u8 *captured, scan_field_t *field, u8 *in_check_value, u8 *in_check_mask) { int retval = ERROR_OK; int num_bits = field->num_bits; @@ -1355,9 +1392,9 @@ int jtag_check_value(u8 *captured, void *priv, scan_field_t *field) 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); + compare_failed = buf_cmp_mask(captured, in_check_value, in_check_mask, num_bits); else - compare_failed = buf_cmp(captured, field->in_check_value, num_bits); + compare_failed = buf_cmp(captured, in_check_value, num_bits); if (compare_failed){ /* An error handler could have caught the failing check @@ -1369,12 +1406,12 @@ int jtag_check_value(u8 *captured, void *priv, scan_field_t *field) if (compare_failed) { char *captured_char = buf_to_str(captured, (num_bits > DEBUG_JTAG_IOZ) ? DEBUG_JTAG_IOZ : num_bits, 16); - char *in_check_value_char = buf_to_str(field->in_check_value, (num_bits > DEBUG_JTAG_IOZ) ? DEBUG_JTAG_IOZ : num_bits, 16); + char *in_check_value_char = buf_to_str(in_check_value, (num_bits > DEBUG_JTAG_IOZ) ? DEBUG_JTAG_IOZ : num_bits, 16); - if (field->in_check_mask) + if (in_check_mask) { char *in_check_mask_char; - in_check_mask_char = buf_to_str(field->in_check_mask, (num_bits > DEBUG_JTAG_IOZ) ? DEBUG_JTAG_IOZ : num_bits, 16); + in_check_mask_char = buf_to_str(in_check_mask, (num_bits > DEBUG_JTAG_IOZ) ? DEBUG_JTAG_IOZ : num_bits, 16); LOG_WARNING("value captured during scan didn't pass the requested check:"); LOG_WARNING("captured: 0x%s check_value: 0x%s check_mask: 0x%s", captured_char, in_check_value_char, in_check_mask_char); @@ -1395,11 +1432,16 @@ int jtag_check_value(u8 *captured, void *priv, scan_field_t *field) return retval; } +int jtag_check_value(u8 *captured, void *priv, scan_field_t *field) +{ + return jtag_check_value_inner(captured, field, field->in_check_value, field->in_check_mask); +} + /* 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) +void jtag_set_check_value(scan_field_t *field, u8 *value, u8 *mask, struct invalidstruct *obsolete) { if (value) field->in_handler = jtag_check_value; @@ -1410,6 +1452,25 @@ void jtag_set_check_value(scan_field_t *field, u8 *value, u8 *mask, error_handle field->in_check_mask = mask; } +void jtag_check_value_mask(scan_field_t *field, u8 *value, u8 *mask) +{ + assert(field->in_value != NULL); + + if (value==NULL) + { + /* no checking to do */ + return; + } + + jtag_execute_queue_noclear(); + + int retval=jtag_check_value_inner(field->in_value, field, value, mask); + jtag_set_error(retval); + +} + + + enum scan_type jtag_scan_type(scan_command_t *cmd) { int i;