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
a "*" character instead of the (ignored) version nibble.
---
Various folk have mentioned this idea, and I figured it would
make the "unified luminary chip" patch be much cleaner.  Plus
surely a few other target config files.  :)

 doc/openocd.texi |    6 ++++++
 src/jtag/core.c  |   13 +++++++++++--
 src/jtag/jtag.h  |    3 +++
 src/jtag/tcl.c   |   28 ++++++++++++++++++++++++----
 4 files changed, 44 insertions(+), 6 deletions(-)

--- a/doc/openocd.texi
+++ b/doc/openocd.texi
@@ -2763,6 +2763,12 @@ are provided in vendors' chip documentat
 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.
--- a/src/jtag/core.c
+++ b/src/jtag/core.c
@@ -958,16 +958,25 @@ static bool jtag_examine_chain_end(uint8
 
 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 */
--- 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
--- a/src/jtag/tcl.c
+++ b/src/jtag/tcl.c
@@ -454,6 +454,7 @@ static int jim_newtap_expected_id(Jim_Nv
 #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
                { .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
                                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_comman
 
        while (tap) {
                uint32_t expected, expected_mask, cur_instr, ii;
+
+               snprintf(expected_id, sizeof expected_id, "%#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, "%#08x",
+                                       (unsigned) tap->expected_ids[1]);
+                       if (tap->ignore_version)
+                               expected_id[2] = '*';
+
+                       command_print(CMD_CTX,
+       "   |                    |         |            | %s |      |      |    
  |         ",
+                                                 expected_id);
                }
 
                tap = tap->next_tap;
_______________________________________________
Openocd-development mailing list
Openocd-development@lists.berlios.de
https://lists.berlios.de/mailman/listinfo/openocd-development

Reply via email to