jtag: add '-ignore-version' option

Add a "-ignore-version" to "jtag newtap" which makes the IDCODE
comparison logic optionally ignore version differences.

Update the "scan_chain" command to illustrate this by showing
the "*" character instead of the (ignored) version nibble.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
__archive__
David Brownell 2009-12-14 15:55:51 -08:00
parent 6f929dbd93
commit af79925eb1
4 changed files with 44 additions and 6 deletions

View File

@ -2763,6 +2763,12 @@ are provided in vendors' chip documentation, usually a technical
reference manual. Sometimes you may need to probe the JTAG reference manual. Sometimes you may need to probe the JTAG
hardware to find these values. hardware to find these values.
@xref{Autoprobing}. @xref{Autoprobing}.
@item @code{-ignore-version}
@*Specify this to ignore the JTAG version field in the @code{-expected-id}
option. When vendors put out multiple versions of a chip, or use the same
JTAG-level ID for several largely-compatible chips, it may be more practical
to ignore the version field than to update config files to handle all of
the various chip IDs.
@item @code{-ircapture} @var{NUMBER} @item @code{-ircapture} @var{NUMBER}
@*The bit pattern loaded by the TAP into the JTAG shift register @*The bit pattern loaded by the TAP into the JTAG shift register
on entry to the @sc{ircapture} state, such as 0x01. on entry to the @sc{ircapture} state, such as 0x01.

View File

@ -958,16 +958,25 @@ static bool jtag_examine_chain_end(uint8_t *idcodes, unsigned count, unsigned ma
static bool jtag_examine_chain_match_tap(const struct jtag_tap *tap) static bool jtag_examine_chain_match_tap(const struct jtag_tap *tap)
{ {
uint32_t idcode = tap->idcode;
/* ignore expected BYPASS codes; warn otherwise */ /* ignore expected BYPASS codes; warn otherwise */
if (0 == tap->expected_ids_cnt && !tap->idcode) if (0 == tap->expected_ids_cnt && !idcode)
return true; return true;
/* optionally ignore the JTAG version field */
uint32_t mask = tap->ignore_version ? ~(0xff << 24) : ~0;
idcode &= mask;
/* Loop over the expected identification codes and test for a match */ /* Loop over the expected identification codes and test for a match */
unsigned ii, limit = tap->expected_ids_cnt; unsigned ii, limit = tap->expected_ids_cnt;
for (ii = 0; ii < limit; ii++) for (ii = 0; ii < limit; ii++)
{ {
if (tap->idcode == tap->expected_ids[ii]) uint32_t expected = tap->expected_ids[ii] & mask;
if (idcode == expected)
return true; return true;
/* treat "-expected-id 0" as a "don't-warn" wildcard */ /* treat "-expected-id 0" as a "don't-warn" wildcard */

View File

@ -156,6 +156,9 @@ struct jtag_tap {
/// Number of expected identification codes /// Number of expected identification codes
uint8_t expected_ids_cnt; uint8_t expected_ids_cnt;
/// Flag saying whether to ignore version field in expected_ids[]
bool ignore_version;
/// current instruction /// current instruction
uint8_t* cur_instr; uint8_t* cur_instr;
/// Bypass register selected /// Bypass register selected

View File

@ -454,6 +454,7 @@ static int jim_newtap_expected_id(Jim_Nvp *n, Jim_GetOptInfo *goi,
#define NTAP_OPT_ENABLED 3 #define NTAP_OPT_ENABLED 3
#define NTAP_OPT_DISABLED 4 #define NTAP_OPT_DISABLED 4
#define NTAP_OPT_EXPECTED_ID 5 #define NTAP_OPT_EXPECTED_ID 5
#define NTAP_OPT_VERSION 6
static int jim_newtap_ir_param(Jim_Nvp *n, Jim_GetOptInfo *goi, static int jim_newtap_ir_param(Jim_Nvp *n, Jim_GetOptInfo *goi,
struct jtag_tap *pTap) struct jtag_tap *pTap)
@ -520,6 +521,7 @@ static int jim_newtap_cmd(Jim_GetOptInfo *goi)
{ .name = "-enable" , .value = NTAP_OPT_ENABLED }, { .name = "-enable" , .value = NTAP_OPT_ENABLED },
{ .name = "-disable" , .value = NTAP_OPT_DISABLED }, { .name = "-disable" , .value = NTAP_OPT_DISABLED },
{ .name = "-expected-id" , .value = NTAP_OPT_EXPECTED_ID }, { .name = "-expected-id" , .value = NTAP_OPT_EXPECTED_ID },
{ .name = "-ignore-version" , .value = NTAP_OPT_VERSION },
{ .name = NULL , .value = -1 }, { .name = NULL , .value = -1 },
}; };
@ -595,6 +597,9 @@ static int jim_newtap_cmd(Jim_GetOptInfo *goi)
return e; return e;
} }
break; break;
case NTAP_OPT_VERSION:
pTap->ignore_version = true;
break;
} /* switch (n->value) */ } /* switch (n->value) */
} /* while (goi->argc) */ } /* while (goi->argc) */
@ -1013,6 +1018,7 @@ COMMAND_HANDLER(handle_interface_command)
COMMAND_HANDLER(handle_scan_chain_command) COMMAND_HANDLER(handle_scan_chain_command)
{ {
struct jtag_tap *tap; struct jtag_tap *tap;
char expected_id[12];
tap = jtag_all_taps(); tap = jtag_all_taps();
command_print(CMD_CTX, " TapName | Enabled | IdCode Expected IrLen IrCap IrMask Instr "); command_print(CMD_CTX, " TapName | Enabled | IdCode Expected IrLen IrCap IrMask Instr ");
@ -1020,25 +1026,39 @@ COMMAND_HANDLER(handle_scan_chain_command)
while (tap) { while (tap) {
uint32_t expected, expected_mask, cur_instr, ii; uint32_t expected, expected_mask, cur_instr, ii;
snprintf(expected_id, sizeof expected_id, "0x%08x",
(unsigned)((tap->expected_ids_cnt > 0)
? tap->expected_ids[0]
: 0));
if (tap->ignore_version)
expected_id[2] = '*';
expected = buf_get_u32(tap->expected, 0, tap->ir_length); expected = buf_get_u32(tap->expected, 0, tap->ir_length);
expected_mask = buf_get_u32(tap->expected_mask, 0, tap->ir_length); expected_mask = buf_get_u32(tap->expected_mask, 0, tap->ir_length);
cur_instr = buf_get_u32(tap->cur_instr, 0, tap->ir_length); cur_instr = buf_get_u32(tap->cur_instr, 0, tap->ir_length);
command_print(CMD_CTX, command_print(CMD_CTX,
"%2d | %-18s | %c | 0x%08x | 0x%08x | 0x%02x | 0x%02x | 0x%02x | 0x%02x", "%2d | %-18s | %c | 0x%08x | %s | 0x%02x | 0x%02x | 0x%02x | 0x%02x",
tap->abs_chain_position, tap->abs_chain_position,
tap->dotted_name, tap->dotted_name,
tap->enabled ? 'Y' : 'n', tap->enabled ? 'Y' : 'n',
(unsigned int)(tap->idcode), (unsigned int)(tap->idcode),
(unsigned int)(tap->expected_ids_cnt > 0 ? tap->expected_ids[0] : 0), expected_id,
(unsigned int)(tap->ir_length), (unsigned int)(tap->ir_length),
(unsigned int)(expected), (unsigned int)(expected),
(unsigned int)(expected_mask), (unsigned int)(expected_mask),
(unsigned int)(cur_instr)); (unsigned int)(cur_instr));
for (ii = 1; ii < tap->expected_ids_cnt; ii++) { for (ii = 1; ii < tap->expected_ids_cnt; ii++) {
command_print(CMD_CTX, " | | | | 0x%08x | | | | ", snprintf(expected_id, sizeof expected_id, "0x%08x",
(unsigned int)(tap->expected_ids[ii])); (unsigned) tap->expected_ids[1]);
if (tap->ignore_version)
expected_id[2] = '*';
command_print(CMD_CTX,
" | | | | %s | | | | ",
expected_id);
} }
tap = tap->next_tap; tap = tap->next_tap;