X-Git-Url: https://review.openocd.org/gitweb?p=openocd.git;a=blobdiff_plain;f=src%2Fjtag%2Fcore.c;h=3684e06c8f7fc74eed22ff8f105c706c84aacecf;hp=e6bde518f61659cb9e8aef3f99174433b54ba9a2;hb=9f535f9af7c6b7e8843033049a6da0f6d76d513b;hpb=246ff4f6019ed59fe47295b3753728b3e4c0dc40 diff --git a/src/jtag/core.c b/src/jtag/core.c index e6bde518f6..3684e06c8f 100644 --- a/src/jtag/core.c +++ b/src/jtag/core.c @@ -43,8 +43,8 @@ /// The number of JTAG queue flushes (for profiling and debugging purposes). static int jtag_flush_queue_count; -static void jtag_add_scan_check(void (*jtag_add_scan)(int in_num_fields, const scan_field_t *in_fields, tap_state_t state), - int in_num_fields, scan_field_t *in_fields, tap_state_t state); +static void jtag_add_scan_check(void (*jtag_add_scan)(int in_num_fields, const struct scan_field *in_fields, tap_state_t state), + int in_num_fields, struct scan_field *in_fields, tap_state_t state); /** * The jtag_error variable is set when an error occurs while executing @@ -68,15 +68,17 @@ static const char *jtag_event_strings[] = /* * JTAG adapters must initialize with TRST and SRST de-asserted - * (they're negative logic, so that means *high*) + * (they're negative logic, so that means *high*). But some + * hardware doesn't necessarily work that way ... so set things + * up so that jtag_init() always forces that state. */ -static int jtag_trst = 0; -static int jtag_srst = 0; +static int jtag_trst = -1; +static int jtag_srst = -1; /** * List all TAPs that have been created. */ -static jtag_tap_t *__jtag_all_taps = NULL; +static struct jtag_tap *__jtag_all_taps = NULL; /** * The number of TAPs in the __jtag_all_taps list, used to track the * assigned chain position to new TAPs @@ -113,10 +115,10 @@ static int rclk_fallback_speed_khz = 0; static enum {CLOCK_MODE_SPEED, CLOCK_MODE_KHZ, CLOCK_MODE_RCLK} clock_mode; static int jtag_speed = 0; -static struct jtag_interface_s *jtag = NULL; +static struct jtag_interface *jtag = NULL; /* configuration */ -jtag_interface_t *jtag_interface = NULL; +struct jtag_interface *jtag_interface = NULL; void jtag_set_error(int error) { @@ -135,8 +137,34 @@ int jtag_error_clear(void) return temp; } +/************/ -jtag_tap_t *jtag_all_taps(void) +static bool jtag_poll = 1; + +bool is_jtag_poll_safe(void) +{ + /* Polling can be disabled explicitly with set_enabled(false). + * It is also implicitly disabled while TRST is active and + * while SRST is gating the JTAG clock. + */ + if (!jtag_poll || jtag_trst != 0) + return false; + return jtag_srst == 0 || (jtag_reset_config & RESET_SRST_NO_GATING); +} + +bool jtag_poll_get_enabled(void) +{ + return jtag_poll; +} + +void jtag_poll_set_enabled(bool value) +{ + jtag_poll = value; +} + +/************/ + +struct jtag_tap *jtag_all_taps(void) { return __jtag_all_taps; }; @@ -148,7 +176,7 @@ unsigned jtag_tap_count(void) unsigned jtag_tap_count_enabled(void) { - jtag_tap_t *t = jtag_all_taps(); + struct jtag_tap *t = jtag_all_taps(); unsigned n = 0; while (t) { @@ -160,20 +188,20 @@ unsigned jtag_tap_count_enabled(void) } /// Append a new TAP to the chain of all taps. -void jtag_tap_add(struct jtag_tap_s *t) +void jtag_tap_add(struct jtag_tap *t) { t->abs_chain_position = jtag_num_taps++; - jtag_tap_t **tap = &__jtag_all_taps; + struct jtag_tap **tap = &__jtag_all_taps; while (*tap != NULL) tap = &(*tap)->next_tap; *tap = t; } /* returns a pointer to the n-th device in the scan chain */ -static inline jtag_tap_t *jtag_tap_by_position(unsigned n) +static inline struct jtag_tap *jtag_tap_by_position(unsigned n) { - jtag_tap_t *t = jtag_all_taps(); + struct jtag_tap *t = jtag_all_taps(); while (t && n-- > 0) t = t->next_tap; @@ -181,10 +209,10 @@ static inline jtag_tap_t *jtag_tap_by_position(unsigned n) return t; } -jtag_tap_t *jtag_tap_by_string(const char *s) +struct jtag_tap *jtag_tap_by_string(const char *s) { /* try by name first */ - jtag_tap_t *t = jtag_all_taps(); + struct jtag_tap *t = jtag_all_taps(); while (t) { @@ -210,10 +238,10 @@ jtag_tap_t *jtag_tap_by_string(const char *s) return t; } -jtag_tap_t *jtag_tap_by_jim_obj(Jim_Interp *interp, Jim_Obj *o) +struct jtag_tap *jtag_tap_by_jim_obj(Jim_Interp *interp, Jim_Obj *o) { const char *cp = Jim_GetString(o, NULL); - jtag_tap_t *t = cp ? jtag_tap_by_string(cp) : NULL; + struct jtag_tap *t = cp ? jtag_tap_by_string(cp) : NULL; if (NULL == cp) cp = "(unknown)"; if (NULL == t) @@ -221,7 +249,7 @@ jtag_tap_t *jtag_tap_by_jim_obj(Jim_Interp *interp, Jim_Obj *o) return t; } -jtag_tap_t* jtag_tap_next_enabled(jtag_tap_t* p) +struct jtag_tap* jtag_tap_next_enabled(struct jtag_tap* p) { p = p ? p->next_tap : jtag_all_taps(); while (p) @@ -233,7 +261,7 @@ jtag_tap_t* jtag_tap_next_enabled(jtag_tap_t* p) return NULL; } -const char *jtag_tap_name(const jtag_tap_t *tap) +const char *jtag_tap_name(const struct jtag_tap *tap) { return (tap == NULL) ? "(unknown)" : tap->dotted_name; } @@ -325,12 +353,12 @@ static void jtag_prelude(tap_state_t state) cmd_queue_cur_state = state; } -void jtag_alloc_in_value32(scan_field_t *field) +void jtag_alloc_in_value32(struct scan_field *field) { interface_jtag_alloc_in_value32(field); } -void jtag_add_ir_scan_noverify(int in_count, const scan_field_t *in_fields, +void jtag_add_ir_scan_noverify(int in_count, const struct scan_field *in_fields, tap_state_t state) { jtag_prelude(state); @@ -340,7 +368,7 @@ void jtag_add_ir_scan_noverify(int in_count, const scan_field_t *in_fields, } -void jtag_add_ir_scan(int in_num_fields, scan_field_t *in_fields, tap_state_t state) +void jtag_add_ir_scan(int in_num_fields, struct scan_field *in_fields, tap_state_t state) { assert(state != TAP_RESET); @@ -363,7 +391,7 @@ void jtag_add_ir_scan(int in_num_fields, scan_field_t *in_fields, tap_state_t st } } -void jtag_add_plain_ir_scan(int in_num_fields, const scan_field_t *in_fields, +void jtag_add_plain_ir_scan(int in_num_fields, const struct scan_field *in_fields, tap_state_t state) { assert(state != TAP_RESET); @@ -395,12 +423,12 @@ static int jtag_check_value_mask_callback(jtag_callback_data_t data0, jtag_callb return jtag_check_value_inner((uint8_t *)data0, (uint8_t *)data1, (uint8_t *)data2, (int)data3); } -static void jtag_add_scan_check(void (*jtag_add_scan)(int in_num_fields, const scan_field_t *in_fields, tap_state_t state), - int in_num_fields, scan_field_t *in_fields, tap_state_t state) +static void jtag_add_scan_check(void (*jtag_add_scan)(int in_num_fields, const struct scan_field *in_fields, tap_state_t state), + int in_num_fields, struct scan_field *in_fields, tap_state_t state) { for (int i = 0; i < in_num_fields; i++) { - struct scan_field_s *field = &in_fields[i]; + struct scan_field *field = &in_fields[i]; field->allocated = 0; field->modified = 0; if (field->check_value || field->in_value) @@ -432,7 +460,7 @@ static void jtag_add_scan_check(void (*jtag_add_scan)(int in_num_fields, const s } } -void jtag_add_dr_scan_check(int in_num_fields, scan_field_t *in_fields, tap_state_t state) +void jtag_add_dr_scan_check(int in_num_fields, struct scan_field *in_fields, tap_state_t state) { if (jtag_verify) { @@ -444,7 +472,7 @@ void jtag_add_dr_scan_check(int in_num_fields, scan_field_t *in_fields, tap_stat } -void jtag_add_dr_scan(int in_num_fields, const scan_field_t *in_fields, +void jtag_add_dr_scan(int in_num_fields, const struct scan_field *in_fields, tap_state_t state) { assert(state != TAP_RESET); @@ -456,7 +484,7 @@ void jtag_add_dr_scan(int in_num_fields, const scan_field_t *in_fields, jtag_set_error(retval); } -void jtag_add_plain_dr_scan(int in_num_fields, const scan_field_t *in_fields, +void jtag_add_plain_dr_scan(int in_num_fields, const struct scan_field *in_fields, tap_state_t state) { assert(state != TAP_RESET); @@ -468,7 +496,7 @@ void jtag_add_plain_dr_scan(int in_num_fields, const scan_field_t *in_fields, jtag_set_error(retval); } -void jtag_add_dr_out(jtag_tap_t* tap, +void jtag_add_dr_out(struct jtag_tap* tap, int num_fields, const int* num_bits, const uint32_t* value, tap_state_t end_state) { @@ -539,12 +567,14 @@ int jtag_add_statemove(tap_state_t goal_state) tap_state_name(goal_state)); - if (goal_state == cur_state) - ; /* nothing to do */ - else if (goal_state == TAP_RESET) - { + /* If goal is RESET, be paranoid and force that that transition + * (e.g. five TCK cycles, TMS high). Else trust "cur_state". + */ + if (goal_state == TAP_RESET) jtag_add_tlr(); - } + else if (goal_state == cur_state) + /* nothing to do */ ; + else if (tap_is_state_stable(cur_state) && tap_is_state_stable(goal_state)) { unsigned tms_bits = tap_get_tms_path(cur_state, goal_state); @@ -776,7 +806,7 @@ static int jtag_check_value_inner(uint8_t *captured, uint8_t *in_check_value, return retval; } -void jtag_check_value_mask(scan_field_t *field, uint8_t *value, uint8_t *mask) +void jtag_check_value_mask(struct scan_field *field, uint8_t *value, uint8_t *mask) { assert(field->in_value != NULL); @@ -826,7 +856,7 @@ int jtag_execute_queue(void) static int jtag_reset_callback(enum jtag_event event, void *priv) { - jtag_tap_t *tap = priv; + struct jtag_tap *tap = priv; if (event == JTAG_TRST_ASSERTED) { @@ -860,9 +890,12 @@ void jtag_sleep(uint32_t us) */ #define END_OF_CHAIN_FLAG 0x000000ff +/* a larger IR length than we ever expect to autoprobe */ +#define JTAG_IRLEN_MAX 60 + static int jtag_examine_chain_execute(uint8_t *idcode_buffer, unsigned num_idcode) { - scan_field_t field = { + struct scan_field field = { .tap = NULL, .num_bits = num_idcode * 32, .out_value = idcode_buffer, @@ -890,7 +923,15 @@ static bool jtag_examine_chain_check(uint8_t *idcodes, unsigned count) } /* if there wasn't a single non-zero bit or if all bits were one, - * the scan is not valid */ + * the scan is not valid. We wrote a mix of both values; either + * + * - There's a hardware issue (almost certainly): + * + all-zeroes can mean a target stuck in JTAG reset + * + all-ones tends to mean no target + * - The scan chain is WAY longer than we can handle, *AND* either + * + there are several hundreds of TAPs in bypass, or + * + at least a few dozen TAPs all have an all-ones IDCODE + */ if (zero_check == 0x00 || one_check == 0xff) { LOG_ERROR("JTAG scan chain interrogation failed: all %s", @@ -937,8 +978,9 @@ static bool jtag_examine_chain_end(uint8_t *idcodes, unsigned count, unsigned ma for (; count < max - 31; count += 32) { uint32_t idcode = buf_get_u32(idcodes, count, 32); - // do not trigger the warning if the data looks good - if (!triggered && jtag_idcode_is_final(idcode)) + + /* do not trigger the warning if the data looks good */ + if (jtag_idcode_is_final(idcode)) continue; LOG_WARNING("Unexpected idcode after end of chain: %d 0x%08x", count, (unsigned int)idcode); @@ -947,15 +989,16 @@ static bool jtag_examine_chain_end(uint8_t *idcodes, unsigned count, unsigned ma return triggered; } -static bool jtag_examine_chain_match_tap(const struct jtag_tap_s *tap) +static bool jtag_examine_chain_match_tap(const struct jtag_tap *tap) { /* ignore expected BYPASS codes; warn otherwise */ if (0 == tap->expected_ids_cnt && !tap->idcode) return true; /* Loop over the expected identification codes and test for a match */ - uint8_t ii; - for (ii = 0; ii < tap->expected_ids_cnt; ii++) + unsigned ii, limit = tap->expected_ids_cnt; + + for (ii = 0; ii < limit; ii++) { if (tap->idcode == tap->expected_ids[ii]) return true; @@ -968,11 +1011,11 @@ static bool jtag_examine_chain_match_tap(const struct jtag_tap_s *tap) /* 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++) + for (ii = 0; ii < limit; ii++) { char msg[32]; - snprintf(msg, sizeof(msg), "expected %hhu of %hhu", - ii + 1, tap->expected_ids_cnt); + + snprintf(msg, sizeof(msg), "expected %u of %u", ii + 1, limit); jtag_examine_chain_display(LOG_LVL_ERROR, msg, tap->dotted_name, tap->expected_ids[ii]); } @@ -986,21 +1029,25 @@ static int jtag_examine_chain(void) { uint8_t idcode_buffer[JTAG_MAX_CHAIN_SIZE * 4]; unsigned bit_count; + int retval; + int tapcount = 0; + bool autoprobe = false; /* DR scan to collect BYPASS or IDCODE register contents. * Then make sure the scan data has both ones and zeroes. */ - jtag_examine_chain_execute(idcode_buffer, JTAG_MAX_CHAIN_SIZE); + LOG_DEBUG("DR scan interrogation for IDCODE/BYPASS"); + retval = jtag_examine_chain_execute(idcode_buffer, JTAG_MAX_CHAIN_SIZE); + if (retval != ERROR_OK) + return retval; if (!jtag_examine_chain_check(idcode_buffer, JTAG_MAX_CHAIN_SIZE)) return ERROR_JTAG_INIT_FAILED; /* point at the 1st tap */ - jtag_tap_t *tap = jtag_tap_next_enabled(NULL); - if (tap == NULL) - { - LOG_ERROR("JTAG: No taps enabled?"); - return ERROR_JTAG_INIT_FAILED; - } + struct jtag_tap *tap = jtag_tap_next_enabled(NULL); + + if (!tap) + autoprobe = true; for (bit_count = 0; tap && bit_count < (JTAG_MAX_CHAIN_SIZE * 32) - 31; @@ -1010,7 +1057,7 @@ static int jtag_examine_chain(void) if ((idcode & 1) == 0) { - /* LSB must not be 0, this indicates a device in bypass */ + /* Zero for LSB indicates a device in bypass */ LOG_WARNING("TAP %s does not have IDCODE", tap->dotted_name); idcode = 0; @@ -1022,7 +1069,8 @@ static int jtag_examine_chain(void) { /* Friendly devices support IDCODE */ tap->hasidcode = true; - jtag_examine_chain_display(LOG_LVL_INFO, "tap/device found", + jtag_examine_chain_display(LOG_LVL_INFO, + "tap/device found", tap->dotted_name, idcode); bit_count += 32; @@ -1031,7 +1079,7 @@ static int jtag_examine_chain(void) /* ensure the TAP ID matches what was expected */ if (!jtag_examine_chain_match_tap(tap)) - return ERROR_JTAG_INIT_FAILED; + retval = ERROR_JTAG_INIT_SOFT_FAIL; } /* Fail if too many TAPs were enabled for us to verify them all. */ @@ -1041,17 +1089,73 @@ static int jtag_examine_chain(void) return ERROR_JTAG_INIT_FAILED; } + /* if autoprobing, the tap list is still empty ... populate it! */ + while (autoprobe && bit_count < (JTAG_MAX_CHAIN_SIZE * 32) - 31) { + uint32_t idcode; + char buf[12]; + + /* Is there another TAP? */ + idcode = buf_get_u32(idcode_buffer, bit_count, 32); + if (jtag_idcode_is_final(idcode)) + break; + + /* Default everything in this TAP except IR length. + * + * REVISIT create a jtag_alloc(chip, tap) routine, and + * share it with jim_newtap_cmd(). + */ + tap = calloc(1, sizeof *tap); + if (!tap) + return ERROR_FAIL; + + sprintf(buf, "auto%d", tapcount++); + tap->chip = strdup(buf); + tap->tapname = strdup("tap"); + + sprintf(buf, "%s.%s", tap->chip, tap->tapname); + tap->dotted_name = strdup(buf); + + /* tap->ir_length == 0 ... signifying irlen autoprobe */ + tap->ir_capture_mask = 0x03; + tap->ir_capture_value = 0x01; + + tap->enabled = true; + + if ((idcode & 1) == 0) { + bit_count += 1; + tap->hasidcode = false; + } else { + bit_count += 32; + tap->hasidcode = true; + tap->idcode = idcode; + + tap->expected_ids_cnt = 1; + tap->expected_ids = malloc(sizeof(uint32_t)); + tap->expected_ids[0] = idcode; + } + + LOG_WARNING("AUTO %s - use \"jtag newtap " + "%s %s -expected-id 0x%8.8" PRIx32 " ...\"", + tap->dotted_name, tap->chip, tap->tapname, + tap->idcode); + + jtag_tap_init(tap); + } + /* After those IDCODE or BYPASS register values should be * only the data we fed into the scan chain. */ if (jtag_examine_chain_end(idcode_buffer, bit_count, 8 * sizeof(idcode_buffer))) { LOG_ERROR("double-check your JTAG setup (interface, " - "speed, TAPs, ...)"); + "speed, missing TAPs, ...)"); return ERROR_JTAG_INIT_FAILED; } - return ERROR_OK; + /* Return success or, for backwards compatibility if only + * some IDCODE values mismatched, a soft/continuable fault. + */ + return retval; } /* @@ -1064,18 +1168,21 @@ static int jtag_examine_chain(void) */ static int jtag_validate_ircapture(void) { - jtag_tap_t *tap; + struct jtag_tap *tap; int total_ir_length = 0; uint8_t *ir_test = NULL; - scan_field_t field; + struct scan_field field; int val; int chain_pos = 0; int retval; + /* when autoprobing, accomodate huge IR lengths */ for (tap = NULL, total_ir_length = 0; (tap = jtag_tap_next_enabled(tap)) != NULL; - total_ir_length += tap->ir_length) - continue; + total_ir_length += tap->ir_length) { + if (tap->ir_length == 0) + total_ir_length += JTAG_IRLEN_MAX; + } /* increase length to add 2 bit sentinel after scan */ total_ir_length += 2; @@ -1108,6 +1215,25 @@ static int jtag_validate_ircapture(void) break; } + /* If we're autoprobing, guess IR lengths. They must be at + * least two bits. Guessing will fail if (a) any TAP does + * not conform to the JTAG spec; or (b) when the upper bits + * captured from some conforming TAP are nonzero. + * + * REVISIT alternative approach: escape to some tcl code + * which could provide more knowledge, based on IDCODE; and + * only guess when that has no success. + */ + if (tap->ir_length == 0) { + tap->ir_length = 2; + while ((val = buf_get_u32(ir_test, chain_pos, + tap->ir_length + 1)) == 1) { + tap->ir_length++; + } + LOG_WARNING("AUTO %s - use \"... -irlen %d\"", + jtag_tap_name(tap), tap->ir_length); + } + /* Validate the two LSBs, which must be 01 per JTAG spec. * * Or ... more bits could be provided by TAP declaration. @@ -1122,7 +1248,7 @@ static int jtag_validate_ircapture(void) (tap->ir_length + 7) / tap->ir_length, val, (tap->ir_length + 7) / tap->ir_length, - tap->ir_capture_value); + (unsigned) tap->ir_capture_value); retval = ERROR_JTAG_INIT_FAILED; goto done; @@ -1154,22 +1280,30 @@ done: } -void jtag_tap_init(jtag_tap_t *tap) +void jtag_tap_init(struct jtag_tap *tap) { - assert(0 != tap->ir_length); + unsigned ir_len_bits; + unsigned ir_len_bytes; - /// @todo fix, this allocates one byte per bit for all three fields! - tap->expected = malloc(tap->ir_length); - tap->expected_mask = malloc(tap->ir_length); - tap->cur_instr = malloc(tap->ir_length); + /* if we're autoprobing, cope with potentially huge ir_length */ + ir_len_bits = tap->ir_length ? : JTAG_IRLEN_MAX; + ir_len_bytes = CEIL(ir_len_bits, 8); - /// @todo cope sanely with ir_length bigger than 32 bits - buf_set_u32(tap->expected, 0, tap->ir_length, tap->ir_capture_value); - buf_set_u32(tap->expected_mask, 0, tap->ir_length, tap->ir_capture_mask); - buf_set_ones(tap->cur_instr, tap->ir_length); + tap->expected = calloc(1, ir_len_bytes); + tap->expected_mask = calloc(1, ir_len_bytes); + tap->cur_instr = malloc(ir_len_bytes); + + /// @todo cope better with ir_length bigger than 32 bits + if (ir_len_bits > 32) + ir_len_bits = 32; + + buf_set_u32(tap->expected, 0, ir_len_bits, tap->ir_capture_value); + buf_set_u32(tap->expected_mask, 0, ir_len_bits, tap->ir_capture_mask); - // place TAP in bypass mode + // TAP will be in bypass mode after jtag_validate_ircapture() tap->bypass = 1; + buf_set_ones(tap->cur_instr, tap->ir_length); + // register the reset callback for the TAP jtag_register_event_callback(&jtag_reset_callback, tap); @@ -1181,7 +1315,7 @@ void jtag_tap_init(jtag_tap_t *tap) jtag_tap_add(tap); } -void jtag_tap_free(jtag_tap_t *tap) +void jtag_tap_free(struct jtag_tap *tap) { jtag_unregister_event_callback(&jtag_reset_callback, tap); @@ -1237,7 +1371,7 @@ int jtag_interface_init(struct command_context_s *cmd_ctx) int jtag_init_inner(struct command_context_s *cmd_ctx) { - jtag_tap_t *tap; + struct jtag_tap *tap; int retval; bool issue_setup = true; @@ -1245,26 +1379,58 @@ int jtag_init_inner(struct command_context_s *cmd_ctx) tap = jtag_tap_next_enabled(NULL); if (tap == NULL) { - LOG_ERROR("There are no enabled taps?"); - return ERROR_JTAG_INIT_FAILED; + /* Once JTAG itself is properly set up, and the scan chain + * isn't absurdly large, IDCODE autoprobe should work fine. + * + * But ... IRLEN autoprobe can fail even on systems which + * are fully conformant to JTAG. Also, JTAG setup can be + * quite finicky on some systems. + * + * REVISIT: if TAP autoprobe works OK, then in many cases + * we could escape to tcl code and set up targets based on + * the TAP's IDCODE values. + */ + LOG_WARNING("There are no enabled taps. " + "AUTO PROBING MIGHT NOT WORK!!"); + + /* REVISIT default clock will often be too fast ... */ } jtag_add_tlr(); if ((retval = jtag_execute_queue()) != ERROR_OK) return retval; - /* examine chain first, as this could discover the real chain layout */ - if (jtag_examine_chain() != ERROR_OK) - { + /* Examine DR values first. This discovers problems which will + * prevent communication ... hardware issues like TDO stuck, or + * configuring the wrong number of (enabled) TAPs. + */ + retval = jtag_examine_chain(); + switch (retval) { + case ERROR_OK: + /* complete success */ + break; + case ERROR_JTAG_INIT_SOFT_FAIL: + /* For backward compatibility reasons, try coping with + * configuration errors involving only ID mismatches. + * We might be able to talk to the devices. + */ LOG_ERROR("Trying to use configured scan chain anyway..."); issue_setup = false; + break; + default: + /* some hard error; already issued diagnostics */ + return retval; } - if (jtag_validate_ircapture() != ERROR_OK) - { - LOG_WARNING("Errors during IR capture, continuing anyway..."); - issue_setup = false; - } + /* Now look at IR values. Problems here will prevent real + * communication. They mostly mean that the IR length is + * wrong ... or that the IR capture value is wrong. (The + * latter is uncommon, but easily worked around: provide + * ircapture/irmask values during TAP setup.) + */ + retval = jtag_validate_ircapture(); + if (retval != ERROR_OK) + return retval; if (issue_setup) jtag_notify_event(JTAG_TAP_EVENT_SETUP); @@ -1296,22 +1462,31 @@ int jtag_init_reset(struct command_context_s *cmd_ctx) if ((retval = jtag_interface_init(cmd_ctx)) != ERROR_OK) return retval; - LOG_DEBUG("Trying to bring the JTAG controller to life by asserting TRST / TLR"); + LOG_DEBUG("Initializing with hard TRST+SRST reset"); - /* Reset can happen after a power cycle. - * - * Ideally we would only assert TRST or run TLR before the target reset. + /* + * This procedure is used by default when OpenOCD triggers a reset. + * It's now done through an overridable Tcl "init_reset" wrapper. * - * However w/srst_pulls_trst, trst is asserted together with the target - * reset whether we want it or not. + * This started out as a more powerful "get JTAG working" reset than + * jtag_init_inner(), applying TRST because some chips won't activate + * JTAG without a TRST cycle (presumed to be async, though some of + * those chips synchronize JTAG activation using TCK). * - * NB! Some targets have JTAG circuitry disabled until a - * trst & srst has been asserted. + * But some chips only activate JTAG as part of an SRST cycle; SRST + * got mixed in. So it became a hard reset routine, which got used + * in more places, and which coped with JTAG reset being forced as + * part of SRST (srst_pulls_trst). * - * NB! here we assume nsrst/ntrst delay are sufficient! + * And even more corner cases started to surface: TRST and/or SRST + * assertion timings matter; some chips need other JTAG operations; + * TRST/SRST sequences can need to be different from these, etc. * - * NB! order matters!!!! srst *can* disconnect JTAG circuitry + * Systems should override that wrapper to support system-specific + * requirements that this not-fully-generic code doesn't handle. * + * REVISIT once Tcl code can read the reset_config modes, this won't + * need to be a C routine at all... */ jtag_add_reset(1, 0); /* TAP_RESET, using TMS+TCK or TRST */ if (jtag_reset_config & RESET_HAS_SRST) @@ -1337,9 +1512,15 @@ int jtag_init_reset(struct command_context_s *cmd_ctx) int jtag_init(struct command_context_s *cmd_ctx) { int retval; + if ((retval = jtag_interface_init(cmd_ctx)) != ERROR_OK) return retval; + /* guard against oddball hardware: force resets to be inactive */ + jtag_add_reset(0, 0); + if ((retval = jtag_execute_queue()) != ERROR_OK) + return retval; + if (Jim_Eval_Named(interp, "jtag_init", __FILE__, __LINE__) != JIM_OK) return ERROR_FAIL; @@ -1388,13 +1569,6 @@ static int jtag_set_speed(int speed) return jtag ? jtag->speed(speed) : ERROR_OK; } -int jtag_config_speed(int speed) -{ - LOG_DEBUG("handle jtag speed"); - clock_mode = CLOCK_MODE_SPEED; - return jtag_set_speed(speed); -} - int jtag_config_khz(unsigned khz) { LOG_DEBUG("handle jtag khz");