diff options
author | dbrownell <dbrownell@b42882b7-edfa-0310-969c-e2dbd0fdcd60> | 2009-09-29 19:28:08 +0000 |
---|---|---|
committer | dbrownell <dbrownell@b42882b7-edfa-0310-969c-e2dbd0fdcd60> | 2009-09-29 19:28:08 +0000 |
commit | e4de4251fe6e1fdefb4b10f4178bb7973248e0d2 (patch) | |
tree | 9b4b37045b9babd45d0f49cfa417a699e4052f0e /src | |
parent | 6d4cdddbe27d1b70528d9a70279a2a9b91c1f242 (diff) | |
download | openocd+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.c | 49 |
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; } |