void jtag_add_reset(int req_tlr_or_trst, int req_srst)
{
int trst_with_tlr = 0;
- int new_srst;
+ int new_srst = 0;
int new_trst = 0;
+ /* Without SRST, we must use target-specific JTAG operations
+ * on each target; callers should not be requesting SRST when
+ * that signal doesn't exist.
+ *
+ * RESET_SRST_PULLS_TRST is a board or chip level quirk, which
+ * can kick in even if the JTAG adapter can't drive TRST.
+ */
+ if (req_srst) {
+ if (!(jtag_reset_config & RESET_HAS_SRST)) {
+ LOG_ERROR("BUG: can't assert SRST");
+ jtag_set_error(ERROR_FAIL);
+ return;
+ }
+ if ((jtag_reset_config & RESET_SRST_PULLS_TRST) != 0
+ && !req_tlr_or_trst) {
+ LOG_ERROR("BUG: can't assert only SRST");
+ jtag_set_error(ERROR_FAIL);
+ return;
+ }
+ new_srst = 1;
+ }
+
/* JTAG reset (entry to TAP_RESET state) can always be achieved
* using TCK and TMS; that may go through a TAP_{IR,DR}UPDATE
* state first. TRST accelerates it, and bypasses those states.
new_trst = 1;
}
- /* FIX!!! there are *many* different cases here. A better
- * approach is needed for legal combinations of transitions...
- */
- if ((jtag_reset_config & RESET_HAS_SRST)&&
- (jtag_reset_config & RESET_HAS_TRST)&&
- ((jtag_reset_config & RESET_SRST_PULLS_TRST) == 0))
- {
- if (((req_tlr_or_trst&&!jtag_trst)||
- (!req_tlr_or_trst && jtag_trst))&&
- ((req_srst&&!jtag_srst)||
- (!req_srst && jtag_srst)))
- {
- /* FIX!!! srst_pulls_trst allows 1,1 => 0,0 transition.... */
- //LOG_ERROR("BUG: transition of req_tlr_or_trst and req_srst in the same jtag_add_reset() call is undefined");
- }
- }
-
- /* Make sure that jtag_reset_config allows the requested reset */
- /* if SRST pulls TRST, we can't fulfill srst == 1 with trst == 0 */
- if (((jtag_reset_config & RESET_SRST_PULLS_TRST) && (req_srst == 1)) && (!req_tlr_or_trst))
- {
- LOG_ERROR("BUG: requested reset would assert trst");
- jtag_set_error(ERROR_FAIL);
- return;
- }
-
- if (req_srst && !(jtag_reset_config & RESET_HAS_SRST))
- {
- LOG_ERROR("BUG: requested SRST assertion, but the current configuration doesn't support this");
- jtag_set_error(ERROR_FAIL);
- return;
- }
-
- new_srst = req_srst;
-
/* Maybe change TRST and/or SRST signal state */
if (jtag_srst != new_srst || jtag_trst != new_trst) {
int retval;
/* If none of the expected ids matched, log an error */
if (ii != tap->expected_ids_cnt)
{
- LOG_INFO("JTAG Tap/device matched");
+ LOG_DEBUG("JTAG Tap/device matched");
return true;
}
jtag_examine_chain_display(LOG_LVL_ERROR, "got",
return ERROR_JTAG_INIT_FAILED;
}
- for (unsigned bit_count = 0; bit_count < (JTAG_MAX_CHAIN_SIZE * 32) - 31;)
+ for (unsigned bit_count = 0;
+ tap && bit_count < (JTAG_MAX_CHAIN_SIZE * 32) - 31;
+ tap = jtag_tap_next_enabled(tap))
{
uint32_t idcode = buf_get_u32(idcode_buffer, bit_count, 32);
+
if ((idcode & 1) == 0)
{
/* LSB must not be 0, this indicates a device in bypass */
LOG_WARNING("Tap/Device does not have IDCODE");
idcode = 0;
+ tap->hasidcode = false;
bit_count += 1;
}
else
{
- /*
+ tap->hasidcode = true;
+
+ /*
* End of chain (invalid manufacturer ID) some devices, such
* as AVR will output all 1's instead of TDI input value at
* end of chain.
tap->idcode = idcode;
// ensure the TAP ID does matches what was expected
- if (!jtag_examine_chain_match_tap(tap))
+ if (!jtag_examine_chain_match_tap(tap))
return ERROR_JTAG_INIT_FAILED;
-
- tap = jtag_tap_next_enabled(tap);
}
/* see if number of discovered devices matches configuration */
jtag_add_plain_ir_scan(1, &field, TAP_RESET);
- jtag_execute_queue();
+ int retval;
+ retval = jtag_execute_queue();
+ if (retval != ERROR_OK)
+ return retval;
tap = NULL;
chain_pos = 0;
}
val = buf_get_u32(ir_test, chain_pos, 2);
- if (val != 0x1)
+ /* Only fail this check if we have IDCODE for this device */
+ if ((val != 0x1)&&(tap->hasidcode))
{
char *cbuf = buf_to_str(ir_test, total_ir_length, 16);
LOG_ERROR("Could not validate JTAG scan chain, IR mismatch, scan returned 0x%s. tap=%s pos=%d expected 0x1 got %0x", cbuf, jtag_tap_name(tap), chain_pos, val);