int tap_move_ndx(tap_state_t astate)
{
- /* given a stable state, return the index into the tms_seqs[] array within tap_get_tms_path() */
+ /* given a stable state, return the index into the tms_seqs[]
+ * array within tap_get_tms_path()
+ */
int ndx;
switch (astate)
{
case TAP_RESET: ndx = 0; break;
+ case TAP_IDLE: ndx = 1; break;
case TAP_DRSHIFT: ndx = 2; break;
case TAP_DRPAUSE: ndx = 3; break;
- case TAP_IDLE: ndx = 1; break;
case TAP_IRSHIFT: ndx = 4; break;
case TAP_IRPAUSE: ndx = 5; break;
default:
- LOG_ERROR("fatal: unstable state \"%s\" used in tap_move_ndx()", tap_state_name(astate));
+ LOG_ERROR("FATAL: unstable state \"%s\" in tap_move_ndx()",
+ tap_state_name(astate));
exit(1);
}
/* tap_move[i][j]: tap movement command to go from state i to state j
- * 0: Test-Logic-Reset
- * 1: Run-Test/Idle
- * 2: Shift-DR
- * 3: Pause-DR
- * 4: Shift-IR
- * 5: Pause-IR
+ * encodings of i and j are what tap_move_ndx() reports.
*
* DRSHIFT->DRSHIFT and IRSHIFT->IRSHIFT have to be caught in interface specific code
*/
{
uint8_t bits;
uint8_t bit_count;
-
};
/*
return new_state;
}
-const char* tap_state_name(tap_state_t state)
+
+/* NOTE: do not change these state names. They're documented,
+ * and we rely on them to match SVF input (except for "RUN/IDLE").
+ */
+static const struct name_mapping {
+ enum tap_state symbol;
+ const char *name;
+} tap_name_mapping[] = {
+ { TAP_RESET, "RESET", },
+ { TAP_IDLE, "RUN/IDLE", },
+ { TAP_DRSELECT, "DRSELECT", },
+ { TAP_DRCAPTURE,"DRCAPTURE", },
+ { TAP_DRSHIFT, "DRSHIFT", },
+ { TAP_DREXIT1, "DREXIT1", },
+ { TAP_DRPAUSE, "DRPAUSE", },
+ { TAP_DREXIT2, "DREXIT2", },
+ { TAP_DRUPDATE, "DRUPDATE", },
+ { TAP_IRSELECT, "IRSELECT", },
+ { TAP_IRCAPTURE,"IRCAPTURE", },
+ { TAP_IRSHIFT, "IRSHIFT", },
+ { TAP_IREXIT1, "IREXIT1", },
+ { TAP_IRPAUSE, "IRPAUSE", },
+ { TAP_IREXIT2, "IREXIT2", },
+ { TAP_IRUPDATE, "IRUPDATE", },
+
+ /* only for input: accept standard SVF name */
+ { TAP_IDLE, "IDLE", },
+};
+
+const char *tap_state_name(tap_state_t state)
{
- const char* ret;
+ unsigned i;
- switch (state)
- {
- case TAP_RESET: ret = "RESET"; break;
- case TAP_IDLE: ret = "RUN/IDLE"; break;
- case TAP_DRSELECT: ret = "DRSELECT"; break;
- case TAP_DRCAPTURE: ret = "DRCAPTURE"; break;
- case TAP_DRSHIFT: ret = "DRSHIFT"; break;
- case TAP_DREXIT1: ret = "DREXIT1"; break;
- case TAP_DRPAUSE: ret = "DRPAUSE"; break;
- case TAP_DREXIT2: ret = "DREXIT2"; break;
- case TAP_DRUPDATE: ret = "DRUPDATE"; break;
- case TAP_IRSELECT: ret = "IRSELECT"; break;
- case TAP_IRCAPTURE: ret = "IRCAPTURE"; break;
- case TAP_IRSHIFT: ret = "IRSHIFT"; break;
- case TAP_IREXIT1: ret = "IREXIT1"; break;
- case TAP_IRPAUSE: ret = "IRPAUSE"; break;
- case TAP_IREXIT2: ret = "IREXIT2"; break;
- case TAP_IRUPDATE: ret = "IRUPDATE"; break;
- default: ret = "???";
+ for (i = 0; i < DIM(tap_name_mapping); i++) {
+ if (tap_name_mapping[i].symbol == state)
+ return tap_name_mapping[i].name;
}
-
- return ret;
+ return "???";
}
tap_state_t tap_state_by_name(const char *name)
{
- tap_state_t x;
-
- /* standard SVF name is "IDLE" */
- if (0 == strcasecmp(name, "IDLE"))
- return TAP_IDLE;
+ unsigned i;
- for (x = 0 ; x < TAP_NUM_STATES ; x++) {
+ for (i = 0; i < DIM(tap_name_mapping); i++) {
/* be nice to the human */
- if (0 == strcasecmp(name, tap_state_name(x))) {
- return x;
- }
+ if (strcasecmp(name, tap_name_mapping[i].name) == 0)
+ return tap_name_mapping[i].symbol;
}
/* not found */
return TAP_INVALID;
*
* These definitions were gleaned from the ARM7TDMI-S Technical
* Reference Manual and validated against several other ARM core
- * technical manuals. tap_get_tms_path() is sensitive to this numbering
- * and ordering of the TAP states; furthermore, some interfaces require
- * specific numbers be used, as they are handed-off directly to their
- * hardware implementations.
+ * technical manuals.
+ *
+ * FIXME some interfaces require specific numbers be used, as they
+ * are handed-off directly to their hardware implementations.
+ * Fix those drivers to map as appropriate ... then pick some
+ * sane set of numbers here (where 0/uninitialized == INVALID).
*/
typedef enum tap_state
{
+ TAP_INVALID = -1,
+
#if BUILD_ZY1000
/* These are the old numbers. Leave as-is for now... */
TAP_RESET = 0, TAP_IDLE = 8,
TAP_IRSELECT = 9, TAP_IRCAPTURE = 10, TAP_IRSHIFT = 11, TAP_IREXIT1 = 12,
TAP_IRPAUSE = 13, TAP_IREXIT2 = 14, TAP_IRUPDATE = 15,
- TAP_NUM_STATES = 16, TAP_INVALID = -1,
#else
/* Proper ARM recommended numbers */
TAP_DREXIT2 = 0x0,
TAP_IRCAPTURE = 0xe,
TAP_RESET = 0x0f,
- TAP_NUM_STATES = 0x10,
-
- TAP_INVALID = -1,
#endif
} tap_state_t;
* For "irscan" or "drscan" commands, the "end" (really, "next") state
* should be stable ... and *NOT* a shift state, otherwise free-running
* jtag clocks could change the values latched by the update state.
+ * Not surprisingly, this is the same constraint as SVF; the "irscan"
+ * and "drscan" commands are a write-only subset of what SVF provides.
*/
static bool scan_is_safe(tap_state_t state)
{
if (argc >= 4) {
/* have at least one pair of numbers. */
/* is last pair the magic text? */
- if (0 == strcmp("-endstate", args[ argc - 2 ])) {
- const char *cpA;
- const char *cpS;
- cpA = args[ argc-1 ];
- for (endstate = 0 ; endstate < TAP_NUM_STATES ; endstate++) {
- cpS = tap_state_name(endstate);
- if (0 == strcmp(cpA, cpS)) {
- break;
- }
- }
- if (endstate >= TAP_NUM_STATES) {
+ if (strcmp("-endstate", args[argc - 2]) == 0) {
+ endstate = tap_state_by_name(args[argc - 1]);
+ if (endstate == TAP_INVALID)
return ERROR_COMMAND_SYNTAX_ERROR;
- } else {
- if (!scan_is_safe(endstate))
- LOG_WARNING("irscan with unsafe "
- "endstate \"%s\"", cpA);
- /* found - remove the last 2 args */
- argc -= 2;
- }
+ if (!scan_is_safe(endstate))
+ LOG_WARNING("unstable irscan endstate \"%s\"",
+ args[argc - 1]);
+ argc -= 2;
}
}