Streamline Capture-IR validation code

- Don't issue needless JTAG resets ... only do them after
   errors. Normal exit now leaves every TAP in BYPASS.
   
 - Fix an unlikely memory leak on one fault path.

 - Remove the oddball limitation that invalid capture LSBs 
   trigger errors only for TAPs that support IDCODE.

Re the JTAG reset:  there are too many of them, and they can
(and do!) change system state.  So the needless ones should
get removed.  This one was especially pointless.


git-svn-id: svn://svn.berlios.de/openocd/trunk@2777 b42882b7-edfa-0310-969c-e2dbd0fdcd60
This commit is contained in:
dbrownell 2009-09-29 19:28:08 +00:00
parent 6d4cdddbe2
commit e4de4251fe
1 changed files with 23 additions and 26 deletions

View File

@ -1058,6 +1058,9 @@ static int jtag_examine_chain(void)
* Validate the date loaded by entry to the Capture-IR state, to help * Validate the date loaded by entry to the Capture-IR state, to help
* find errors related to scan chain configuration (wrong IR lengths) * find errors related to scan chain configuration (wrong IR lengths)
* or communication. * or communication.
*
* Entry state can be anything. On non-error exit, all TAPs are in
* bypass mode. On error exits, the scan chain is reset.
*/ */
static int jtag_validate_ircapture(void) static int jtag_validate_ircapture(void)
{ {
@ -1066,23 +1069,21 @@ static int jtag_validate_ircapture(void)
uint8_t *ir_test = NULL; uint8_t *ir_test = NULL;
scan_field_t field; scan_field_t field;
int chain_pos = 0; int chain_pos = 0;
int retval;
tap = NULL; for (tap = NULL, total_ir_length = 0;
total_ir_length = 0; (tap = jtag_tap_next_enabled(tap)) != NULL;
for (;;) { total_ir_length += tap->ir_length)
tap = jtag_tap_next_enabled(tap); continue;
if (tap == NULL) {
break;
}
total_ir_length += tap->ir_length;
}
/* increase length to add 2 bit sentinel after scan */
total_ir_length += 2; total_ir_length += 2;
ir_test = malloc(CEIL(total_ir_length, 8)); ir_test = malloc(CEIL(total_ir_length, 8));
if (ir_test == NULL) if (ir_test == NULL)
return ERROR_FAIL; return ERROR_FAIL;
/* after this scan, all TAPs will capture BYPASS instructions */
buf_set_ones(ir_test, total_ir_length); buf_set_ones(ir_test, total_ir_length);
field.tap = NULL; field.tap = NULL;
@ -1090,14 +1091,12 @@ static int jtag_validate_ircapture(void)
field.out_value = ir_test; field.out_value = ir_test;
field.in_value = ir_test; field.in_value = ir_test;
jtag_add_plain_ir_scan(1, &field, TAP_IDLE);
jtag_add_plain_ir_scan(1, &field, TAP_IRPAUSE); LOG_DEBUG("IR capture validation scan");
jtag_add_tlr();
int retval;
retval = jtag_execute_queue(); retval = jtag_execute_queue();
if (retval != ERROR_OK) if (retval != ERROR_OK)
return retval; goto done;
tap = NULL; tap = NULL;
chain_pos = 0; chain_pos = 0;
@ -1119,14 +1118,9 @@ static int jtag_validate_ircapture(void)
LOG_ERROR("%s: IR capture error; saw 0x%s not 0x..1", LOG_ERROR("%s: IR capture error; saw 0x%s not 0x..1",
jtag_tap_name(tap), cbuf); jtag_tap_name(tap), cbuf);
/* Fail only if we have IDCODE for this device. free(cbuf);
* REVISIT -- why not fail-always? retval = ERROR_JTAG_INIT_FAILED;
*/ goto done;
if (tap->hasidcode) {
free(cbuf);
free(ir_test);
return ERROR_JTAG_INIT_FAILED;
}
} }
chain_pos += tap->ir_length; chain_pos += tap->ir_length;
} }
@ -1140,13 +1134,16 @@ static int jtag_validate_ircapture(void)
LOG_ERROR("IR capture error at bit %d, saw 0x%s not 0x...3", LOG_ERROR("IR capture error at bit %d, saw 0x%s not 0x...3",
chain_pos, cbuf); chain_pos, cbuf);
free(cbuf); free(cbuf);
free(ir_test); retval = ERROR_JTAG_INIT_FAILED;
return ERROR_JTAG_INIT_FAILED;
} }
done:
free(ir_test); free(ir_test);
if (retval != ERROR_OK) {
return ERROR_OK; jtag_add_tlr();
jtag_execute_queue();
}
return retval;
} }