X-Git-Url: https://review.openocd.org/gitweb?a=blobdiff_plain;f=src%2Fjtag%2Fcore.c;h=07eec64f46528ed31b0d58662ac9bcc4f5702db8;hb=a2886fe3c66e7cdb05148234054e89730662103d;hp=78f67db33b8306464454bfc075fe5ac42c872cf3;hpb=c5949a03a7a6cff4d4c209e81736bcb7548a6e88;p=openocd.git diff --git a/src/jtag/core.c b/src/jtag/core.c index 78f67db33b..07eec64f46 100644 --- a/src/jtag/core.c +++ b/src/jtag/core.c @@ -61,8 +61,8 @@ static int jtag_error = ERROR_OK; static const char *jtag_event_strings[] = { [JTAG_TRST_ASSERTED] = "TAP reset", + [JTAG_TAP_EVENT_SETUP] = "TAP setup", [JTAG_TAP_EVENT_ENABLE] = "TAP enabled", - [JTAG_TAP_EVENT_POST_RESET] = "TAP post reset", [JTAG_TAP_EVENT_DISABLE] = "TAP disabled", }; @@ -489,7 +489,7 @@ void jtag_add_tlr(void) /* NOTE: order here matches TRST path in jtag_add_reset() */ jtag_call_event_callbacks(JTAG_TRST_ASSERTED); - jtag_notify_reset(); + jtag_notify_event(JTAG_TRST_ASSERTED); } void jtag_add_pathmove(int num_states, const tap_state_t *path) @@ -704,7 +704,7 @@ void jtag_add_reset(int req_tlr_or_trst, int req_srst) * sequence must match jtag_add_tlr(). */ jtag_call_event_callbacks(JTAG_TRST_ASSERTED); - jtag_notify_reset(); + jtag_notify_event(JTAG_TRST_ASSERTED); } } } @@ -959,10 +959,14 @@ static bool jtag_examine_chain_match_tap(const struct jtag_tap_s *tap) { if (tap->idcode == tap->expected_ids[ii]) return true; + + /* treat "-expected-id 0" as a "don't-warn" wildcard */ + if (0 == tap->expected_ids[ii]) + return true; } - /* If none of the expected ids matched, log an error */ - jtag_examine_chain_display(LOG_LVL_ERROR, "UNEXPECTED", + /* If none of the expected ids matched, warn */ + jtag_examine_chain_display(LOG_LVL_WARNING, "UNEXPECTED", tap->dotted_name, tap->idcode); for (ii = 0; ii < tap->expected_ids_cnt; ii++) { @@ -1025,7 +1029,7 @@ static int jtag_examine_chain(void) } tap->idcode = idcode; - // ensure the TAP ID does matches what was expected + /* ensure the TAP ID matches what was expected */ if (!jtag_examine_chain_match_tap(tap)) return ERROR_JTAG_INIT_FAILED; } @@ -1054,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) { @@ -1061,24 +1068,23 @@ static int jtag_validate_ircapture(void) int total_ir_length = 0; uint8_t *ir_test = NULL; scan_field_t field; + int val; 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; @@ -1086,18 +1092,16 @@ 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; - int val; + for (;;) { tap = jtag_tap_next_enabled(tap); if (tap == NULL) { @@ -1108,22 +1112,18 @@ static int jtag_validate_ircapture(void) * REVISIT we might be able to verify some MSBs too, using * ircapture/irmask attributes. */ - val = buf_get_u32(ir_test, chain_pos, 2); - if (val != 1) { - char *cbuf = buf_to_str(ir_test, total_ir_length, 16); - - 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; - } + val = buf_get_u32(ir_test, chain_pos, tap->ir_length); + if ((val & 0x3) != 1) { + LOG_ERROR("%s: IR capture error; saw 0x%0*x not 0x..1", + jtag_tap_name(tap), + (tap->ir_length + 7) / tap->ir_length, + val); + + retval = ERROR_JTAG_INIT_FAILED; + goto done; } + LOG_DEBUG("%s: IR capture 0x%0*x", jtag_tap_name(tap), + (tap->ir_length + 7) / tap->ir_length, val); chain_pos += tap->ir_length; } @@ -1136,13 +1136,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; } @@ -1231,6 +1234,7 @@ static int jtag_init_inner(struct command_context_s *cmd_ctx) { jtag_tap_t *tap; int retval; + bool issue_setup = true; LOG_DEBUG("Init JTAG chain"); @@ -1248,13 +1252,21 @@ static int jtag_init_inner(struct command_context_s *cmd_ctx) if (jtag_examine_chain() != ERROR_OK) { LOG_ERROR("Trying to use configured scan chain anyway..."); + issue_setup = false; } if (jtag_validate_ircapture() != ERROR_OK) { LOG_WARNING("Errors during IR capture, continuing anyway..."); + issue_setup = false; } + if (issue_setup) + jtag_notify_event(JTAG_TAP_EVENT_SETUP); + else + LOG_WARNING("Bypassing JTAG setup events due to errors"); + + return ERROR_OK; }