From e4de4251fe6e1fdefb4b10f4178bb7973248e0d2 Mon Sep 17 00:00:00 2001 From: dbrownell Date: Tue, 29 Sep 2009 19:28:08 +0000 Subject: [PATCH] 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 --- src/jtag/core.c | 49 +++++++++++++++++++++++-------------------------- 1 file changed, 23 insertions(+), 26 deletions(-) diff --git a/src/jtag/core.c b/src/jtag/core.c index 056fa9905..6177c1dc8 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; }