From 79f71fad58f3cd1a59142b65c3b79b145943b6e6 Mon Sep 17 00:00:00 2001 From: David Brownell Date: Fri, 23 Oct 2009 01:02:22 -0700 Subject: [PATCH] jtag: clean up TAP state name handling Some cosmetic cleanup, and switch to a single table mapping between state names and symbols (vs two routines which only share that state with difficulty). Get rid of TAP_NUM_STATES, and some related knowledge about how TAP numbers are assigned. Later on, this will help us get rid of more such hardwired knowlege. Signed-off-by: David Brownell --- src/jtag/interface.c | 88 +++++++++++++++++++++++--------------------- src/jtag/jtag.h | 16 ++++---- src/jtag/tcl.c | 27 +++++--------- 3 files changed, 63 insertions(+), 68 deletions(-) diff --git a/src/jtag/interface.c b/src/jtag/interface.c index fcdb8ee7f..e475b482d 100644 --- a/src/jtag/interface.c +++ b/src/jtag/interface.c @@ -73,20 +73,23 @@ tap_state_t tap_get_end_state() 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); } @@ -95,12 +98,7 @@ int tap_move_ndx(tap_state_t astate) /* 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 */ @@ -108,7 +106,6 @@ struct tms_sequences { uint8_t bits; uint8_t bit_count; - }; /* @@ -333,47 +330,54 @@ tap_state_t tap_state_transition(tap_state_t cur_state, bool tms) 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; + unsigned i; - /* standard SVF name is "IDLE" */ - if (0 == strcasecmp(name, "IDLE")) - return TAP_IDLE; - - 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; diff --git a/src/jtag/jtag.h b/src/jtag/jtag.h index 1dae00fa3..ca09f923e 100644 --- a/src/jtag/jtag.h +++ b/src/jtag/jtag.h @@ -57,13 +57,17 @@ * * 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, @@ -72,7 +76,6 @@ typedef enum tap_state 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, @@ -92,9 +95,6 @@ typedef enum tap_state TAP_IRCAPTURE = 0xe, TAP_RESET = 0x0f, - TAP_NUM_STATES = 0x10, - - TAP_INVALID = -1, #endif } tap_state_t; diff --git a/src/jtag/tcl.c b/src/jtag/tcl.c index e080279a0..6a6e3ae01 100644 --- a/src/jtag/tcl.c +++ b/src/jtag/tcl.c @@ -1248,6 +1248,8 @@ static int handle_runtest_command(struct command_context_s *cmd_ctx, * 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) { @@ -1285,25 +1287,14 @@ static int handle_irscan_command(struct command_context_s *cmd_ctx, char *cmd, c 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; } }