* Copyright (C) 2005 by Dominic Rath *
* Dominic.Rath@gmx.de *
* *
- * Copyright (C) 2007,2008 Øyvind Harboe *
+ * Copyright (C) 2007,2008 Øyvind Harboe *
* oyvind.harboe@zylin.com *
* *
* Copyright (C) 2009 SoftPLC Corporation *
*/
static tap_state_t state_follower = TAP_RESET;
-void tap_set_state_impl( tap_state_t new_state )
+void tap_set_state_impl(tap_state_t new_state)
{
/* this is the state we think the TAPs are in now, was cur_state */
state_follower = new_state;
*/
static tap_state_t end_state_follower = TAP_RESET;
-void tap_set_end_state( tap_state_t new_end_state )
+void tap_set_end_state(tap_state_t new_end_state)
{
/* this is the state we think the TAPs will be in at completion of the
current TAP operation, was 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;
- switch( astate )
+ 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;
-
};
/*
#define HEX__(n) 0x##n##LU
#define B8__(x) \
- (((x) & 0x0000000FLU)?(1<<0):0) \
- +(((x) & 0x000000F0LU)?(1<<1):0) \
- +(((x) & 0x00000F00LU)?(1<<2):0) \
- +(((x) & 0x0000F000LU)?(1<<3):0) \
- +(((x) & 0x000F0000LU)?(1<<4):0) \
- +(((x) & 0x00F00000LU)?(1<<5):0) \
- +(((x) & 0x0F000000LU)?(1<<6):0) \
- +(((x) & 0xF0000000LU)?(1<<7):0)
+ (((x) & 0x0000000FLU)?(1 << 0):0) \
+ +(((x) & 0x000000F0LU)?(1 << 1):0) \
+ +(((x) & 0x00000F00LU)?(1 << 2):0) \
+ +(((x) & 0x0000F000LU)?(1 << 3):0) \
+ +(((x) & 0x000F0000LU)?(1 << 4):0) \
+ +(((x) & 0x00F00000LU)?(1 << 5):0) \
+ +(((x) & 0x0F000000LU)?(1 << 6):0) \
+ +(((x) & 0xF0000000LU)?(1 << 7):0)
#define B8(bits,count) { ((uint8_t)B8__(HEX__(bits))), (count) }
{
/* value clocked to TMS to move from one of six stable states to another.
* N.B. OOCD clocks TMS from LSB first, so read these right-to-left.
- * N.B. These values are tightly bound to the table in tap_get_tms_path_len().
* N.B. Reset only needs to be 0b11111, but in JLink an even byte of 1's is more stable.
* These extra ones cause no TAP state problem, because we go into reset and stay in reset.
*/
-
-
/* to state: */
/* RESET IDLE DRSHIFT DRPAUSE IRSHIFT IRPAUSE */ /* from state: */
{ B8(1111111,7), B8(0000000,7), B8(0010111,7), B8(0001010,7), B8(0011011,7), B8(0010110,7) }, /* RESET */
state specific comments:
------------------------
- *->RESET tried the 5 bit reset and it gave me problems, 7 bits seems to
+ *->RESET tried the 5 bit reset and it gave me problems, 7 bits seems to
work better on ARM9 with ft2232 driver. (Dick)
RESET->DRSHIFT add 1 extra clock cycles in the RESET state before advancing.
needed on ARM9 with ft2232 driver. (Dick)
+ (For a total of *THREE* extra clocks in RESET; NOP.)
RESET->IRSHIFT add 1 extra clock cycles in the RESET state before advancing.
needed on ARM9 with ft2232 driver. (Dick)
+ (For a total of *TWO* extra clocks in RESET; NOP.)
+
+ RESET->* always adds one or more clocks in the target state,
+ which should be NOPS; except shift states which (as
+ noted above) add those clocks in RESET.
+
+ The X-to-X transitions always add clocks; from *SHIFT, they go
+ via IDLE and thus *DO HAVE SIDE EFFECTS* (capture and update).
*/
/* to state: */
- /* RESET IDLE DRSHIFT DRPAUSE IRSHIFT IRPAUSE */ /* from state: */
- { B8(1111111,7), B8(0000000,7), B8(0010111,7), B8(0001010,7), B8(0011011,7), B8(0010110,7) }, /* RESET */
- { B8(1111111,7), B8(0000000,7), B8(001,3), B8(0101,4), B8(0011,4), B8(01011,5) }, /* IDLE */
- { B8(1111111,7), B8(011,3), B8(00111,5), B8(01,2), B8(001111,6), B8(0101111,7) }, /* DRSHIFT */
- { B8(1111111,7), B8(011,3), B8(01,2), B8(0,1), B8(001111,6), B8(0101111,7) }, /* DRPAUSE */
- { B8(1111111,7), B8(011,3), B8(00111,5), B8(010111,6), B8(001111,6), B8(01,2) }, /* IRSHIFT */
- { B8(1111111,7), B8(011,3), B8(00111,5), B8(010111,6), B8(01,2), B8(0,1) } /* IRPAUSE */
+ /* RESET IDLE DRSHIFT DRPAUSE IRSHIFT IRPAUSE */ /* from state: */
+ { B8(1111111,7), B8(0000000,7), B8(0010111,7), B8(0001010,7), B8(0011011,7), B8(0010110,7) }, /* RESET */
+ { B8(1111111,7), B8(0000000,7), B8(001,3), B8(0101,4), B8(0011,4), B8(01011,5) }, /* IDLE */
+ { B8(1111111,7), B8(011,3), B8(00111,5), B8(01,2), B8(001111,6), B8(0101111,7) }, /* DRSHIFT */
+ { B8(1111111,7), B8(011,3), B8(01,2), B8(0,1), B8(001111,6), B8(0101111,7) }, /* DRPAUSE */
+ { B8(1111111,7), B8(011,3), B8(00111,5), B8(010111,6), B8(001111,6), B8(01,2) }, /* IRSHIFT */
+ { B8(1111111,7), B8(011,3), B8(00111,5), B8(010111,6), B8(01,2), B8(0,1)} /* IRPAUSE */
};
static tms_table *tms_seqs=&short_tms_seqs;
-int tap_get_tms_path( tap_state_t from, tap_state_t to )
+int tap_get_tms_path(tap_state_t from, tap_state_t to)
{
return (*tms_seqs)[tap_move_ndx(from)][tap_move_ndx(to)].bits;
}
-int tap_get_tms_path_len( tap_state_t from, tap_state_t to )
+int tap_get_tms_path_len(tap_state_t from, tap_state_t to)
{
return (*tms_seqs)[tap_move_ndx(from)][tap_move_ndx(to)].bit_count;
}
{
bool is_stable;
- /* A switch() is used because it is symbol dependent
+ /* A switch () is used because it is symbol dependent
(not value dependent like an array), and can also check bounds.
*/
- switch( astate )
+ switch (astate)
{
case TAP_RESET:
case TAP_IDLE:
new_state = TAP_IREXIT2;
break;
default:
- LOG_ERROR( "fatal: invalid argument cur_state=%d", cur_state );
+ LOG_ERROR("fatal: invalid argument cur_state=%d", cur_state);
exit(1);
break;
}
new_state = TAP_IRPAUSE;
break;
default:
- LOG_ERROR( "fatal: invalid argument cur_state=%d", cur_state );
+ LOG_ERROR("fatal: invalid argument cur_state=%d", cur_state);
exit(1);
break;
}
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 < ARRAY_SIZE(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;
- for( x = 0 ; x < TAP_NUM_STATES ; x++ ){
+ for (i = 0; i < ARRAY_SIZE(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;
#ifdef _DEBUG_JTAG_IO_
#define JTAG_DEBUG_STATE_APPEND(buf, len, bit) \
- do { buf[len] = bit ? '1' : '0'; } while(0)
+ do { buf[len] = bit ? '1' : '0'; } while (0)
#define JTAG_DEBUG_STATE_PRINT(a, b, astr, bstr) \
DEBUG_JTAG_IO("TAP/SM: %9s -> %5s\tTMS: %s\tTDI: %s", \
tap_state_name(a), tap_state_name(b), astr, bstr)
tms_buffer = (const uint8_t *)tms_buf;
tdi_buffer = (const uint8_t *)tdi_buf;
- tap_bytes = TAP_SCAN_BYTES(tap_bits);
+ tap_bytes = DIV_ROUND_UP(tap_bits, 8);
DEBUG_JTAG_IO("TAP/SM: TMS bits: %u (bytes: %u)", tap_bits, tap_bytes);
tap_out_bits = 0;
- for(cur_byte = 0; cur_byte < tap_bytes; cur_byte++)
+ for (cur_byte = 0; cur_byte < tap_bytes; cur_byte++)
{
- for(cur_bit = 0; cur_bit < 8; cur_bit++)
+ for (cur_bit = 0; cur_bit < 8; cur_bit++)
{
// make sure we do not run off the end of the buffers
unsigned tap_bit = cur_byte * 8 + cur_bit;