summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authordbrownell <dbrownell@b42882b7-edfa-0310-969c-e2dbd0fdcd60>2009-09-29 19:28:08 +0000
committerdbrownell <dbrownell@b42882b7-edfa-0310-969c-e2dbd0fdcd60>2009-09-29 19:28:08 +0000
commite4de4251fe6e1fdefb4b10f4178bb7973248e0d2 (patch)
tree9b4b37045b9babd45d0f49cfa417a699e4052f0e /src
parent6d4cdddbe27d1b70528d9a70279a2a9b91c1f242 (diff)
downloadopenocd+libswd-e4de4251fe6e1fdefb4b10f4178bb7973248e0d2.tar.gz
openocd+libswd-e4de4251fe6e1fdefb4b10f4178bb7973248e0d2.tar.bz2
openocd+libswd-e4de4251fe6e1fdefb4b10f4178bb7973248e0d2.tar.xz
openocd+libswd-e4de4251fe6e1fdefb4b10f4178bb7973248e0d2.zip
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
Diffstat (limited to 'src')
-rw-r--r--src/jtag/core.c49
1 files changed, 23 insertions, 26 deletions
diff --git a/src/jtag/core.c b/src/jtag/core.c
index 056fa990..6177c1dc 100644
--- a/src/jtag/core.c
+++ b/src/jtag/core.c
@@ -1058,6 +1058,9 @@ static int jtag_examine_chain(void)
* Validate the date loaded by entry to the Capture-IR state, to help
* find errors related to scan chain configuration (wrong IR lengths)
* 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)
{
@@ -1066,23 +1069,21 @@ static int jtag_validate_ircapture(void)
uint8_t *ir_test = NULL;
scan_field_t field;
int chain_pos = 0;
+ int retval;
- tap = NULL;
- total_ir_length = 0;
- for (;;) {
- tap = jtag_tap_next_enabled(tap);
- if (tap == NULL) {
- break;
- }
- total_ir_length += tap->ir_length;
- }
+ for (tap = NULL, total_ir_length = 0;
+ (tap = jtag_tap_next_enabled(tap)) != NULL;
+ total_ir_length += tap->ir_length)
+ continue;
+ /* increase length to add 2 bit sentinel after scan */
total_ir_length += 2;
ir_test = malloc(CEIL(total_ir_length, 8));
if (ir_test == NULL)
return ERROR_FAIL;
+ /* after this scan, all TAPs will capture BYPASS instructions */
buf_set_ones(ir_test, total_ir_length);
field.tap = NULL;
@@ -1090,14 +1091,12 @@ static int jtag_validate_ircapture(void)
field.out_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);
- jtag_add_tlr();
-
- int retval;
+ LOG_DEBUG("IR capture validation scan");
retval = jtag_execute_queue();
if (retval != ERROR_OK)
- return retval;
+ goto done;
tap = NULL;
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",
jtag_tap_name(tap), cbuf);
- /* Fail only if we have IDCODE for this device.
- * REVISIT -- why not fail-always?
- */
- if (tap->hasidcode) {
- free(cbuf);
- free(ir_test);
- return ERROR_JTAG_INIT_FAILED;
- }
+ free(cbuf);
+ retval = ERROR_JTAG_INIT_FAILED;
+ goto done;
}
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",
chain_pos, cbuf);
free(cbuf);
- free(ir_test);
- return ERROR_JTAG_INIT_FAILED;
+ retval = ERROR_JTAG_INIT_FAILED;
}
+done:
free(ir_test);
-
- return ERROR_OK;
+ if (retval != ERROR_OK) {
+ jtag_add_tlr();
+ jtag_execute_queue();
+ }
+ return retval;
}