Stop ignoring most scan chain validation errors
Among other things this causes startup errors to kick in the fallback "reset harder" logic during server startup. Comments are also updated a bit, explaining what the various error paths signify (in at least my observation). There's one class of validation error that we can still plausibly ignore: when wrong IDCODE values are observed. This change seems to have helped make an OMAP5912 behave much more reliably. There's still some post-reset flakiness, but it's unrelated to scan verification. Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
This commit is contained in:
parent
22aff82cae
commit
40c9668b70
|
@ -892,7 +892,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,
|
/* 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)
|
if (zero_check == 0x00 || one_check == 0xff)
|
||||||
{
|
{
|
||||||
LOG_ERROR("JTAG scan chain interrogation failed: all %s",
|
LOG_ERROR("JTAG scan chain interrogation failed: all %s",
|
||||||
|
@ -988,11 +996,14 @@ static int jtag_examine_chain(void)
|
||||||
{
|
{
|
||||||
uint8_t idcode_buffer[JTAG_MAX_CHAIN_SIZE * 4];
|
uint8_t idcode_buffer[JTAG_MAX_CHAIN_SIZE * 4];
|
||||||
unsigned bit_count;
|
unsigned bit_count;
|
||||||
|
int retval;
|
||||||
|
|
||||||
/* DR scan to collect BYPASS or IDCODE register contents.
|
/* DR scan to collect BYPASS or IDCODE register contents.
|
||||||
* Then make sure the scan data has both ones and zeroes.
|
* Then make sure the scan data has both ones and zeroes.
|
||||||
*/
|
*/
|
||||||
jtag_examine_chain_execute(idcode_buffer, JTAG_MAX_CHAIN_SIZE);
|
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))
|
if (!jtag_examine_chain_check(idcode_buffer, JTAG_MAX_CHAIN_SIZE))
|
||||||
return ERROR_JTAG_INIT_FAILED;
|
return ERROR_JTAG_INIT_FAILED;
|
||||||
|
|
||||||
|
@ -1012,7 +1023,7 @@ static int jtag_examine_chain(void)
|
||||||
|
|
||||||
if ((idcode & 1) == 0)
|
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",
|
LOG_WARNING("TAP %s does not have IDCODE",
|
||||||
tap->dotted_name);
|
tap->dotted_name);
|
||||||
idcode = 0;
|
idcode = 0;
|
||||||
|
@ -1024,7 +1035,8 @@ static int jtag_examine_chain(void)
|
||||||
{
|
{
|
||||||
/* Friendly devices support IDCODE */
|
/* Friendly devices support IDCODE */
|
||||||
tap->hasidcode = true;
|
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);
|
tap->dotted_name, idcode);
|
||||||
|
|
||||||
bit_count += 32;
|
bit_count += 32;
|
||||||
|
@ -1033,7 +1045,7 @@ static int jtag_examine_chain(void)
|
||||||
|
|
||||||
/* ensure the TAP ID matches what was expected */
|
/* ensure the TAP ID matches what was expected */
|
||||||
if (!jtag_examine_chain_match_tap(tap))
|
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. */
|
/* Fail if too many TAPs were enabled for us to verify them all. */
|
||||||
|
@ -1049,11 +1061,14 @@ static int jtag_examine_chain(void)
|
||||||
if (jtag_examine_chain_end(idcode_buffer, bit_count,
|
if (jtag_examine_chain_end(idcode_buffer, bit_count,
|
||||||
8 * sizeof(idcode_buffer))) {
|
8 * sizeof(idcode_buffer))) {
|
||||||
LOG_ERROR("double-check your JTAG setup (interface, "
|
LOG_ERROR("double-check your JTAG setup (interface, "
|
||||||
"speed, TAPs, ...)");
|
"speed, missing TAPs, ...)");
|
||||||
return ERROR_JTAG_INIT_FAILED;
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1255,18 +1270,37 @@ int jtag_init_inner(struct command_context_s *cmd_ctx)
|
||||||
if ((retval = jtag_execute_queue()) != ERROR_OK)
|
if ((retval = jtag_execute_queue()) != ERROR_OK)
|
||||||
return retval;
|
return retval;
|
||||||
|
|
||||||
/* examine chain first, as this could discover the real chain layout */
|
/* Examine DR values first. This discovers problems which will
|
||||||
if (jtag_examine_chain() != ERROR_OK)
|
* 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...");
|
LOG_ERROR("Trying to use configured scan chain anyway...");
|
||||||
issue_setup = false;
|
issue_setup = false;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
/* some hard error; already issued diagnostics */
|
||||||
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (jtag_validate_ircapture() != ERROR_OK)
|
/* Now look at IR values. Problems here will prevent real
|
||||||
{
|
* communication. They mostly mean that the IR length is
|
||||||
LOG_WARNING("Errors during IR capture, continuing anyway...");
|
* wrong ... or that the IR capture value is wrong. (The
|
||||||
issue_setup = false;
|
* 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)
|
if (issue_setup)
|
||||||
jtag_notify_event(JTAG_TAP_EVENT_SETUP);
|
jtag_notify_event(JTAG_TAP_EVENT_SETUP);
|
||||||
|
|
|
@ -689,6 +689,7 @@ extern void jtag_sleep(uint32_t us);
|
||||||
#define ERROR_JTAG_DEVICE_ERROR (-107)
|
#define ERROR_JTAG_DEVICE_ERROR (-107)
|
||||||
#define ERROR_JTAG_STATE_INVALID (-108)
|
#define ERROR_JTAG_STATE_INVALID (-108)
|
||||||
#define ERROR_JTAG_TRANSITION_INVALID (-109)
|
#define ERROR_JTAG_TRANSITION_INVALID (-109)
|
||||||
|
#define ERROR_JTAG_INIT_SOFT_FAIL (-110)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* jtag_add_dr_out() is a version of jtag_add_dr_scan() which
|
* jtag_add_dr_out() is a version of jtag_add_dr_scan() which
|
||||||
|
|
Loading…
Reference in New Issue