summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/openocd.texi6
-rw-r--r--src/jtag/core.c13
-rw-r--r--src/jtag/jtag.h3
-rw-r--r--src/jtag/tcl.c28
4 files changed, 44 insertions, 6 deletions
diff --git a/doc/openocd.texi b/doc/openocd.texi
index a83c966b..01dfa76b 100644
--- a/doc/openocd.texi
+++ b/doc/openocd.texi
@@ -2763,6 +2763,12 @@ are provided in vendors' chip documentation, usually a technical
reference manual. Sometimes you may need to probe the JTAG
hardware to find these values.
@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}
@*The bit pattern loaded by the TAP into the JTAG shift register
on entry to the @sc{ircapture} state, such as 0x01.
diff --git a/src/jtag/core.c b/src/jtag/core.c
index 77cf48ac..e311bfbc 100644
--- a/src/jtag/core.c
+++ b/src/jtag/core.c
@@ -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)
{
+ uint32_t idcode = tap->idcode;
+
/* ignore expected BYPASS codes; warn otherwise */
- if (0 == tap->expected_ids_cnt && !tap->idcode)
+ if (0 == tap->expected_ids_cnt && !idcode)
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 */
unsigned ii, limit = tap->expected_ids_cnt;
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;
/* treat "-expected-id 0" as a "don't-warn" wildcard */
diff --git a/src/jtag/jtag.h b/src/jtag/jtag.h
index fa2fcdca..f79ef93f 100644
--- a/src/jtag/jtag.h
+++ b/src/jtag/jtag.h
@@ -156,6 +156,9 @@ struct jtag_tap {
/// Number of expected identification codes
uint8_t expected_ids_cnt;
+ /// Flag saying whether to ignore version field in expected_ids[]
+ bool ignore_version;
+
/// current instruction
uint8_t* cur_instr;
/// Bypass register selected
diff --git a/src/jtag/tcl.c b/src/jtag/tcl.c
index 9704c302..f4815c8e 100644
--- a/src/jtag/tcl.c
+++ b/src/jtag/tcl.c
@@ -454,6 +454,7 @@ static int jim_newtap_expected_id(Jim_Nvp *n, Jim_GetOptInfo *goi,
#define NTAP_OPT_ENABLED 3
#define NTAP_OPT_DISABLED 4
#define NTAP_OPT_EXPECTED_ID 5
+#define NTAP_OPT_VERSION 6
static int jim_newtap_ir_param(Jim_Nvp *n, Jim_GetOptInfo *goi,
struct jtag_tap *pTap)
@@ -520,6 +521,7 @@ static int jim_newtap_cmd(Jim_GetOptInfo *goi)
{ .name = "-enable" , .value = NTAP_OPT_ENABLED },
{ .name = "-disable" , .value = NTAP_OPT_DISABLED },
{ .name = "-expected-id" , .value = NTAP_OPT_EXPECTED_ID },
+ { .name = "-ignore-version" , .value = NTAP_OPT_VERSION },
{ .name = NULL , .value = -1 },
};
@@ -595,6 +597,9 @@ static int jim_newtap_cmd(Jim_GetOptInfo *goi)
return e;
}
break;
+ case NTAP_OPT_VERSION:
+ pTap->ignore_version = true;
+ break;
} /* switch (n->value) */
} /* while (goi->argc) */
@@ -1013,6 +1018,7 @@ COMMAND_HANDLER(handle_interface_command)
COMMAND_HANDLER(handle_scan_chain_command)
{
struct jtag_tap *tap;
+ char expected_id[12];
tap = jtag_all_taps();
command_print(CMD_CTX, " TapName | Enabled | IdCode Expected IrLen IrCap IrMask Instr ");
@@ -1020,25 +1026,39 @@ COMMAND_HANDLER(handle_scan_chain_command)
while (tap) {
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_mask = buf_get_u32(tap->expected_mask, 0, tap->ir_length);
cur_instr = buf_get_u32(tap->cur_instr, 0, tap->ir_length);
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->dotted_name,
tap->enabled ? 'Y' : 'n',
(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)(expected),
(unsigned int)(expected_mask),
(unsigned int)(cur_instr));
for (ii = 1; ii < tap->expected_ids_cnt; ii++) {
- command_print(CMD_CTX, " | | | | 0x%08x | | | | ",
- (unsigned int)(tap->expected_ids[ii]));
+ snprintf(expected_id, sizeof expected_id, "0x%08x",
+ (unsigned) tap->expected_ids[1]);
+ if (tap->ignore_version)
+ expected_id[2] = '*';
+
+ command_print(CMD_CTX,
+ " | | | | %s | | | | ",
+ expected_id);
}
tap = tap->next_tap;