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 <dbrownell@users.sourceforge.net>
This commit is contained in:
parent
814183a5c4
commit
79f71fad58
src/jtag
|
@ -73,20 +73,23 @@ tap_state_t tap_get_end_state()
|
||||||
|
|
||||||
int tap_move_ndx(tap_state_t astate)
|
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;
|
int ndx;
|
||||||
|
|
||||||
switch (astate)
|
switch (astate)
|
||||||
{
|
{
|
||||||
case TAP_RESET: ndx = 0; break;
|
case TAP_RESET: ndx = 0; break;
|
||||||
|
case TAP_IDLE: ndx = 1; break;
|
||||||
case TAP_DRSHIFT: ndx = 2; break;
|
case TAP_DRSHIFT: ndx = 2; break;
|
||||||
case TAP_DRPAUSE: ndx = 3; break;
|
case TAP_DRPAUSE: ndx = 3; break;
|
||||||
case TAP_IDLE: ndx = 1; break;
|
|
||||||
case TAP_IRSHIFT: ndx = 4; break;
|
case TAP_IRSHIFT: ndx = 4; break;
|
||||||
case TAP_IRPAUSE: ndx = 5; break;
|
case TAP_IRPAUSE: ndx = 5; break;
|
||||||
default:
|
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);
|
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
|
/* tap_move[i][j]: tap movement command to go from state i to state j
|
||||||
* 0: Test-Logic-Reset
|
* encodings of i and j are what tap_move_ndx() reports.
|
||||||
* 1: Run-Test/Idle
|
|
||||||
* 2: Shift-DR
|
|
||||||
* 3: Pause-DR
|
|
||||||
* 4: Shift-IR
|
|
||||||
* 5: Pause-IR
|
|
||||||
*
|
*
|
||||||
* DRSHIFT->DRSHIFT and IRSHIFT->IRSHIFT have to be caught in interface specific code
|
* 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 bits;
|
||||||
uint8_t bit_count;
|
uint8_t bit_count;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -333,47 +330,54 @@ tap_state_t tap_state_transition(tap_state_t cur_state, bool tms)
|
||||||
return new_state;
|
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)
|
for (i = 0; i < DIM(tap_name_mapping); i++) {
|
||||||
{
|
if (tap_name_mapping[i].symbol == state)
|
||||||
case TAP_RESET: ret = "RESET"; break;
|
return tap_name_mapping[i].name;
|
||||||
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 = "???";
|
|
||||||
}
|
}
|
||||||
|
return "???";
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
tap_state_t tap_state_by_name(const char *name)
|
tap_state_t tap_state_by_name(const char *name)
|
||||||
{
|
{
|
||||||
tap_state_t x;
|
unsigned i;
|
||||||
|
|
||||||
/* standard SVF name is "IDLE" */
|
for (i = 0; i < DIM(tap_name_mapping); i++) {
|
||||||
if (0 == strcasecmp(name, "IDLE"))
|
|
||||||
return TAP_IDLE;
|
|
||||||
|
|
||||||
for (x = 0 ; x < TAP_NUM_STATES ; x++) {
|
|
||||||
/* be nice to the human */
|
/* be nice to the human */
|
||||||
if (0 == strcasecmp(name, tap_state_name(x))) {
|
if (strcasecmp(name, tap_name_mapping[i].name) == 0)
|
||||||
return x;
|
return tap_name_mapping[i].symbol;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
/* not found */
|
/* not found */
|
||||||
return TAP_INVALID;
|
return TAP_INVALID;
|
||||||
|
|
|
@ -57,13 +57,17 @@
|
||||||
*
|
*
|
||||||
* These definitions were gleaned from the ARM7TDMI-S Technical
|
* These definitions were gleaned from the ARM7TDMI-S Technical
|
||||||
* Reference Manual and validated against several other ARM core
|
* Reference Manual and validated against several other ARM core
|
||||||
* technical manuals. tap_get_tms_path() is sensitive to this numbering
|
* technical manuals.
|
||||||
* and ordering of the TAP states; furthermore, some interfaces require
|
*
|
||||||
* specific numbers be used, as they are handed-off directly to their
|
* FIXME some interfaces require specific numbers be used, as they
|
||||||
* hardware implementations.
|
* 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
|
typedef enum tap_state
|
||||||
{
|
{
|
||||||
|
TAP_INVALID = -1,
|
||||||
|
|
||||||
#if BUILD_ZY1000
|
#if BUILD_ZY1000
|
||||||
/* These are the old numbers. Leave as-is for now... */
|
/* These are the old numbers. Leave as-is for now... */
|
||||||
TAP_RESET = 0, TAP_IDLE = 8,
|
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_IRSELECT = 9, TAP_IRCAPTURE = 10, TAP_IRSHIFT = 11, TAP_IREXIT1 = 12,
|
||||||
TAP_IRPAUSE = 13, TAP_IREXIT2 = 14, TAP_IRUPDATE = 15,
|
TAP_IRPAUSE = 13, TAP_IREXIT2 = 14, TAP_IRUPDATE = 15,
|
||||||
|
|
||||||
TAP_NUM_STATES = 16, TAP_INVALID = -1,
|
|
||||||
#else
|
#else
|
||||||
/* Proper ARM recommended numbers */
|
/* Proper ARM recommended numbers */
|
||||||
TAP_DREXIT2 = 0x0,
|
TAP_DREXIT2 = 0x0,
|
||||||
|
@ -92,9 +95,6 @@ typedef enum tap_state
|
||||||
TAP_IRCAPTURE = 0xe,
|
TAP_IRCAPTURE = 0xe,
|
||||||
TAP_RESET = 0x0f,
|
TAP_RESET = 0x0f,
|
||||||
|
|
||||||
TAP_NUM_STATES = 0x10,
|
|
||||||
|
|
||||||
TAP_INVALID = -1,
|
|
||||||
#endif
|
#endif
|
||||||
} tap_state_t;
|
} tap_state_t;
|
||||||
|
|
||||||
|
|
|
@ -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
|
* For "irscan" or "drscan" commands, the "end" (really, "next") state
|
||||||
* should be stable ... and *NOT* a shift state, otherwise free-running
|
* should be stable ... and *NOT* a shift state, otherwise free-running
|
||||||
* jtag clocks could change the values latched by the update state.
|
* 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)
|
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) {
|
if (argc >= 4) {
|
||||||
/* have at least one pair of numbers. */
|
/* have at least one pair of numbers. */
|
||||||
/* is last pair the magic text? */
|
/* is last pair the magic text? */
|
||||||
if (0 == strcmp("-endstate", args[ argc - 2 ])) {
|
if (strcmp("-endstate", args[argc - 2]) == 0) {
|
||||||
const char *cpA;
|
endstate = tap_state_by_name(args[argc - 1]);
|
||||||
const char *cpS;
|
if (endstate == TAP_INVALID)
|
||||||
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) {
|
|
||||||
return ERROR_COMMAND_SYNTAX_ERROR;
|
return ERROR_COMMAND_SYNTAX_ERROR;
|
||||||
} else {
|
if (!scan_is_safe(endstate))
|
||||||
if (!scan_is_safe(endstate))
|
LOG_WARNING("unstable irscan endstate \"%s\"",
|
||||||
LOG_WARNING("irscan with unsafe "
|
args[argc - 1]);
|
||||||
"endstate \"%s\"", cpA);
|
argc -= 2;
|
||||||
/* found - remove the last 2 args */
|
|
||||||
argc -= 2;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue