OpenOCD
interface.c
Go to the documentation of this file.
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 
3 /***************************************************************************
4  * Copyright (C) 2005 by Dominic Rath *
5  * Dominic.Rath@gmx.de *
6  * *
7  * Copyright (C) 2007,2008 Øyvind Harboe *
8  * oyvind.harboe@zylin.com *
9  * *
10  * Copyright (C) 2009 SoftPLC Corporation *
11  * http://softplc.com *
12  * dick@softplc.com *
13  * *
14  * Copyright (C) 2009 Zachary T Welch *
15  * zw@superlucidity.net *
16  ***************************************************************************/
17 
18 #ifdef HAVE_CONFIG_H
19 #include "config.h"
20 #endif
21 
22 #include "jtag.h"
23 #include "interface.h"
24 
29 static enum tap_state state_follower = TAP_RESET;
30 
31 void tap_set_state_impl(enum tap_state new_state)
32 {
33  /* this is the state we think the TAPs are in now, was cur_state */
34  state_follower = new_state;
35 }
36 
37 enum tap_state tap_get_state(void)
38 {
39  return state_follower;
40 }
41 
47 
48 void tap_set_end_state(enum tap_state new_end_state)
49 {
50  /* this is the state we think the TAPs will be in at completion of the
51  * current TAP operation, was end_state
52  */
53  end_state_follower = new_end_state;
54 }
55 
56 int tap_set_end_state_stable(enum tap_state new_end_state)
57 {
58  if (!tap_is_state_stable(new_end_state)) {
59  LOG_ERROR("BUG: %i is not a valid end state", new_end_state);
61  }
62 
63  tap_set_end_state(new_end_state);
64  return ERROR_OK;
65 }
66 
68 {
69  return end_state_follower;
70 }
71 
72 int tap_move_ndx(enum tap_state astate)
73 {
74  /* given a stable state, return the index into the tms_seqs[]
75  * array within tap_get_tms_path()
76  */
77 
78  int ndx;
79 
80  switch (astate) {
81  case TAP_RESET:
82  ndx = 0;
83  break;
84  case TAP_IDLE:
85  ndx = 1;
86  break;
87  case TAP_DRSHIFT:
88  ndx = 2;
89  break;
90  case TAP_DRPAUSE:
91  ndx = 3;
92  break;
93  case TAP_IRSHIFT:
94  ndx = 4;
95  break;
96  case TAP_IRPAUSE:
97  ndx = 5;
98  break;
99  default:
100  LOG_ERROR("FATAL: unstable state \"%s\" in %s()",
101  tap_state_name(astate), __func__);
102  exit(1);
103  }
104 
105  return ndx;
106 }
107 
108 /* tap_move[i][j]: tap movement command to go from state i to state j
109  * encodings of i and j are what tap_move_ndx() reports.
110  *
111  * DRSHIFT->DRSHIFT and IRSHIFT->IRSHIFT have to be caught in interface specific code
112  */
114  uint8_t bits;
115  uint8_t bit_count;
116 };
117 
118 /*
119  * These macros allow us to specify TMS state transitions by bits rather than hex bytes.
120  * Read the bits from LSBit first to MSBit last (right-to-left).
121  */
122 #define HEX__(n) 0x##n##LU
123 
124 #define B8__(x) \
125  ((((x) & 0x0000000FLU) ? (1 << 0) : 0) \
126  +(((x) & 0x000000F0LU) ? (1 << 1) : 0) \
127  +(((x) & 0x00000F00LU) ? (1 << 2) : 0) \
128  +(((x) & 0x0000F000LU) ? (1 << 3) : 0) \
129  +(((x) & 0x000F0000LU) ? (1 << 4) : 0) \
130  +(((x) & 0x00F00000LU) ? (1 << 5) : 0) \
131  +(((x) & 0x0F000000LU) ? (1 << 6) : 0) \
132  +(((x) & 0xF0000000LU) ? (1 << 7) : 0))
133 
134 #define B8(bits, count) {((uint8_t)B8__(HEX__(bits))), (count)}
135 
136 static const struct tms_sequences old_tms_seqs[6][6] = { /* [from_state_ndx][to_state_ndx] */
137  /* value clocked to TMS to move from one of six stable states to another.
138  * N.B. OOCD clocks TMS from LSB first, so read these right-to-left.
139  * N.B. Reset only needs to be 0b11111, but in JLink an even byte of 1's is more stable.
140  * These extra ones cause no TAP state problem, because we go into reset and stay in reset.
141  */
142 
143 /* to state: */
144 /* RESET IDLE DRSHIFT DRPAUSE IRSHIFT IRPAUSE */ /* from state: */
145 {B8(1111111, 7), B8(0000000, 7), B8(0010111, 7), B8(0001010, 7), B8(0011011, 7), B8(0010110, 7)},/* RESET */
146 {B8(1111111, 7), B8(0000000, 7), B8(0100101, 7), B8(0000101, 7), B8(0101011, 7), B8(0001011, 7)},/* IDLE */
147 {B8(1111111, 7), B8(0110001, 7), B8(0000000, 7), B8(0000001, 7), B8(0001111, 7), B8(0101111, 7)},/* DRSHIFT */
148 {B8(1111111, 7), B8(0110000, 7), B8(0100000, 7), B8(0010111, 7), B8(0011110, 7), B8(0101111, 7)},/* DRPAUSE */
149 {B8(1111111, 7), B8(0110001, 7), B8(0000111, 7), B8(0010111, 7), B8(0000000, 7), B8(0000001, 7)},/* IRSHIFT */
150 {B8(1111111, 7), B8(0110000, 7), B8(0011100, 7), B8(0010111, 7), B8(0011110, 7), B8(0101111, 7)},/* IRPAUSE */
151 };
152 
153 static const struct tms_sequences short_tms_seqs[6][6] = { /* [from_state_ndx][to_state_ndx] */
154  /* this is the table submitted by Jeff Williams on 3/30/2009 with this comment:
155 
156  OK, I added Peter's version of the state table, and it works OK for
157  me on MC1322x. I've recreated the jlink portion of patch with this
158  new state table. His changes to my state table are pretty minor in
159  terms of total transitions, but Peter feels that his version fixes
160  some long-standing problems.
161  Jeff
162 
163  I added the bit count into the table, reduced RESET column to 7 bits from 8.
164  Dick
165 
166  state specific comments:
167  ------------------------
168  *->RESET tried the 5 bit reset and it gave me problems, 7 bits seems to
169  work better on ARM9 with ft2232 driver. (Dick)
170 
171  RESET->DRSHIFT add 1 extra clock cycles in the RESET state before advancing.
172  needed on ARM9 with ft2232 driver. (Dick)
173  (For a total of *THREE* extra clocks in RESET; NOP.)
174 
175  RESET->IRSHIFT add 1 extra clock cycles in the RESET state before advancing.
176  needed on ARM9 with ft2232 driver. (Dick)
177  (For a total of *TWO* extra clocks in RESET; NOP.)
178 
179  RESET->* always adds one or more clocks in the target state,
180  which should be NOPS; except shift states which (as
181  noted above) add those clocks in RESET.
182 
183  The X-to-X transitions always add clocks; from *SHIFT, they go
184  via IDLE and thus *DO HAVE SIDE EFFECTS* (capture and update).
185 */
186 
187 /* to state: */
188 /* RESET IDLE DRSHIFT DRPAUSE IRSHIFT IRPAUSE */ /* from state: */
189 {B8(1111111, 7), B8(0000000, 7), B8(0010111, 7), B8(0001010, 7), B8(0011011, 7), B8(0010110, 7)}, /* RESET */
190 {B8(1111111, 7), B8(0000000, 7), B8(001, 3), B8(0101, 4), B8(0011, 4), B8(01011, 5)}, /* IDLE */
191 {B8(1111111, 7), B8(011, 3), B8(00111, 5), B8(01, 2), B8(001111, 6), B8(0101111, 7)}, /* DRSHIFT */
192 {B8(1111111, 7), B8(011, 3), B8(01, 2), B8(0, 1), B8(001111, 6), B8(0101111, 7)}, /* DRPAUSE */
193 {B8(1111111, 7), B8(011, 3), B8(00111, 5), B8(010111, 6), B8(001111, 6), B8(01, 2)}, /* IRSHIFT */
194 {B8(1111111, 7), B8(011, 3), B8(00111, 5), B8(010111, 6), B8(01, 2), B8(0, 1)} /* IRPAUSE */
195 };
196 
197 typedef const struct tms_sequences tms_table[6][6];
198 
200 
201 int tap_get_tms_path(enum tap_state from, enum tap_state to)
202 {
203  return (*tms_seqs)[tap_move_ndx(from)][tap_move_ndx(to)].bits;
204 }
205 
206 int tap_get_tms_path_len(enum tap_state from, enum tap_state to)
207 {
208  return (*tms_seqs)[tap_move_ndx(from)][tap_move_ndx(to)].bit_count;
209 }
210 
212 {
213  bool is_stable;
214 
215  /* A switch () is used because it is symbol dependent
216  * (not value dependent like an array), and can also check bounds.
217  */
218  switch (astate) {
219  case TAP_RESET:
220  case TAP_IDLE:
221  case TAP_DRSHIFT:
222  case TAP_DRPAUSE:
223  case TAP_IRSHIFT:
224  case TAP_IRPAUSE:
225  is_stable = true;
226  break;
227  default:
228  is_stable = false;
229  }
230 
231  return is_stable;
232 }
233 
234 enum tap_state tap_state_transition(enum tap_state cur_state, bool tms)
235 {
236  enum tap_state new_state;
237 
238  /* A switch is used because it is symbol dependent and not value dependent
239  * like an array. Also it can check for out of range conditions.
240  */
241 
242  if (tms) {
243  switch (cur_state) {
244  case TAP_RESET:
245  new_state = cur_state;
246  break;
247  case TAP_IDLE:
248  case TAP_DRUPDATE:
249  case TAP_IRUPDATE:
250  new_state = TAP_DRSELECT;
251  break;
252  case TAP_DRSELECT:
253  new_state = TAP_IRSELECT;
254  break;
255  case TAP_DRCAPTURE:
256  case TAP_DRSHIFT:
257  new_state = TAP_DREXIT1;
258  break;
259  case TAP_DREXIT1:
260  case TAP_DREXIT2:
261  new_state = TAP_DRUPDATE;
262  break;
263  case TAP_DRPAUSE:
264  new_state = TAP_DREXIT2;
265  break;
266  case TAP_IRSELECT:
267  new_state = TAP_RESET;
268  break;
269  case TAP_IRCAPTURE:
270  case TAP_IRSHIFT:
271  new_state = TAP_IREXIT1;
272  break;
273  case TAP_IREXIT1:
274  case TAP_IREXIT2:
275  new_state = TAP_IRUPDATE;
276  break;
277  case TAP_IRPAUSE:
278  new_state = TAP_IREXIT2;
279  break;
280  default:
281  LOG_ERROR("fatal: invalid argument cur_state=%d", cur_state);
282  exit(1);
283  break;
284  }
285  } else {
286  switch (cur_state) {
287  case TAP_RESET:
288  case TAP_IDLE:
289  case TAP_DRUPDATE:
290  case TAP_IRUPDATE:
291  new_state = TAP_IDLE;
292  break;
293  case TAP_DRSELECT:
294  new_state = TAP_DRCAPTURE;
295  break;
296  case TAP_DRCAPTURE:
297  case TAP_DRSHIFT:
298  case TAP_DREXIT2:
299  new_state = TAP_DRSHIFT;
300  break;
301  case TAP_DREXIT1:
302  case TAP_DRPAUSE:
303  new_state = TAP_DRPAUSE;
304  break;
305  case TAP_IRSELECT:
306  new_state = TAP_IRCAPTURE;
307  break;
308  case TAP_IRCAPTURE:
309  case TAP_IRSHIFT:
310  case TAP_IREXIT2:
311  new_state = TAP_IRSHIFT;
312  break;
313  case TAP_IREXIT1:
314  case TAP_IRPAUSE:
315  new_state = TAP_IRPAUSE;
316  break;
317  default:
318  LOG_ERROR("fatal: invalid argument cur_state=%d", cur_state);
319  exit(1);
320  break;
321  }
322  }
323 
324  return new_state;
325 }
326 
327 /* NOTE: do not change these state names. They're documented,
328  * and we rely on them to match SVF input (except for "RUN/IDLE").
329  */
330 static const struct name_mapping {
331  enum tap_state symbol;
332  const char *name;
333 } tap_name_mapping[] = {
334  { TAP_RESET, "RESET", },
335  { TAP_IDLE, "RUN/IDLE", },
336  { TAP_DRSELECT, "DRSELECT", },
337  { TAP_DRCAPTURE, "DRCAPTURE", },
338  { TAP_DRSHIFT, "DRSHIFT", },
339  { TAP_DREXIT1, "DREXIT1", },
340  { TAP_DRPAUSE, "DRPAUSE", },
341  { TAP_DREXIT2, "DREXIT2", },
342  { TAP_DRUPDATE, "DRUPDATE", },
343  { TAP_IRSELECT, "IRSELECT", },
344  { TAP_IRCAPTURE, "IRCAPTURE", },
345  { TAP_IRSHIFT, "IRSHIFT", },
346  { TAP_IREXIT1, "IREXIT1", },
347  { TAP_IRPAUSE, "IRPAUSE", },
348  { TAP_IREXIT2, "IREXIT2", },
349  { TAP_IRUPDATE, "IRUPDATE", },
350 
351  /* only for input: accept standard SVF name */
352  { TAP_IDLE, "IDLE", },
353 };
354 
355 const char *tap_state_name(enum tap_state state)
356 {
357  unsigned int i;
358 
359  for (i = 0; i < ARRAY_SIZE(tap_name_mapping); i++) {
360  if (tap_name_mapping[i].symbol == state)
361  return tap_name_mapping[i].name;
362  }
363  return "???";
364 }
365 
366 enum tap_state tap_state_by_name(const char *name)
367 {
368  unsigned int i;
369 
370  for (i = 0; i < ARRAY_SIZE(tap_name_mapping); i++) {
371  /* be nice to the human */
372  if (strcasecmp(name, tap_name_mapping[i].name) == 0)
373  return tap_name_mapping[i].symbol;
374  }
375  /* not found */
376  return TAP_INVALID;
377 }
378 
379 #define JTAG_DEBUG_STATE_APPEND(buf, len, bit) \
380  do { buf[len] = bit ? '1' : '0'; } while (0)
381 #define JTAG_DEBUG_STATE_PRINT(a, b, astr, bstr) \
382  LOG_DEBUG_IO("TAP/SM: %9s -> %5s\tTMS: %s\tTDI: %s", \
383  tap_state_name(a), tap_state_name(b), astr, bstr)
384 
385 enum tap_state jtag_debug_state_machine_(const void *tms_buf, const void *tdi_buf,
386  unsigned int tap_bits, enum tap_state next_state)
387 {
388  const uint8_t *tms_buffer;
389  const uint8_t *tdi_buffer;
390  unsigned int tap_bytes;
391  unsigned int cur_byte;
392  unsigned int cur_bit;
393 
394  unsigned int tap_out_bits;
395  char tms_str[33];
396  char tdi_str[33];
397 
398  enum tap_state last_state;
399 
400  /* set startstate (and possibly last, if tap_bits == 0) */
401  last_state = next_state;
402  LOG_DEBUG_IO("TAP/SM: START state: %s", tap_state_name(next_state));
403 
404  tms_buffer = (const uint8_t *)tms_buf;
405  tdi_buffer = (const uint8_t *)tdi_buf;
406 
407  tap_bytes = DIV_ROUND_UP(tap_bits, 8);
408  LOG_DEBUG_IO("TAP/SM: TMS bits: %u (bytes: %u)", tap_bits, tap_bytes);
409 
410  tap_out_bits = 0;
411  for (cur_byte = 0; cur_byte < tap_bytes; cur_byte++) {
412  for (cur_bit = 0; cur_bit < 8; cur_bit++) {
413  /* make sure we do not run off the end of the buffers */
414  unsigned int tap_bit = cur_byte * 8 + cur_bit;
415  if (tap_bit == tap_bits)
416  break;
417 
418  /* check and save TMS bit */
419  tap_bit = !!(tms_buffer[cur_byte] & (1 << cur_bit));
420  JTAG_DEBUG_STATE_APPEND(tms_str, tap_out_bits, tap_bit);
421 
422  /* use TMS bit to find the next TAP state */
423  next_state = tap_state_transition(last_state, tap_bit);
424 
425  /* check and store TDI bit */
426  tap_bit = !!(tdi_buffer[cur_byte] & (1 << cur_bit));
427  JTAG_DEBUG_STATE_APPEND(tdi_str, tap_out_bits, tap_bit);
428 
429  /* increment TAP bits */
430  tap_out_bits++;
431 
432  /* Only show TDO bits on state transitions, or */
433  /* after some number of bits in the same state. */
434  if ((next_state == last_state) && (tap_out_bits < 32))
435  continue;
436 
437  /* terminate strings and display state transition */
438  tms_str[tap_out_bits] = tdi_str[tap_out_bits] = 0;
439  JTAG_DEBUG_STATE_PRINT(last_state, next_state, tms_str, tdi_str);
440 
441  /* reset state */
442  last_state = next_state;
443  tap_out_bits = 0;
444  }
445  }
446 
447  if (tap_out_bits) {
448  /* terminate strings and display state transition */
449  tms_str[tap_out_bits] = tdi_str[tap_out_bits] = 0;
450  JTAG_DEBUG_STATE_PRINT(last_state, next_state, tms_str, tdi_str);
451  }
452 
453  LOG_DEBUG_IO("TAP/SM: FINAL state: %s", tap_state_name(next_state));
454 
455  return next_state;
456 }
457 
458 void tap_use_new_tms_table(bool use_new)
459 {
460  tms_seqs = use_new ? &short_tms_seqs : &old_tms_seqs;
461 }
463 {
464  return tms_seqs == &short_tms_seqs;
465 }
const char * name
Definition: am13e230x.c:167
static uint8_t tms_buffer[ARMJTAGEW_TAP_BUFFER_SIZE]
Definition: arm-jtag-ew.c:506
static uint8_t tdi_buffer[ARMJTAGEW_TAP_BUFFER_SIZE]
Definition: arm-jtag-ew.c:507
static const struct name_mapping tap_name_mapping[]
static const struct tms_sequences old_tms_seqs[6][6]
Definition: interface.c:136
enum tap_state tap_get_end_state(void)
For more information,.
Definition: interface.c:67
enum tap_state tap_state_transition(enum tap_state cur_state, bool tms)
Function tap_state_transition takes a current TAP state and returns the next state according to the t...
Definition: interface.c:234
const char * tap_state_name(enum tap_state state)
Function tap_state_name Returns a string suitable for display representing the JTAG tap_state.
Definition: interface.c:355
enum tap_state jtag_debug_state_machine_(const void *tms_buf, const void *tdi_buf, unsigned int tap_bits, enum tap_state next_state)
Definition: interface.c:385
#define JTAG_DEBUG_STATE_PRINT(a, b, astr, bstr)
Definition: interface.c:381
void tap_use_new_tms_table(bool use_new)
Allow switching between old and new TMS tables.
Definition: interface.c:458
bool tap_uses_new_tms_table(void)
Definition: interface.c:462
int tap_get_tms_path_len(enum tap_state from, enum tap_state to)
Function int tap_get_tms_path_len returns the total number of bits that represents a TMS path transit...
Definition: interface.c:206
#define JTAG_DEBUG_STATE_APPEND(buf, len, bit)
Definition: interface.c:379
const struct tms_sequences tms_table[6][6]
Definition: interface.c:197
static const struct tms_sequences short_tms_seqs[6][6]
Definition: interface.c:153
void tap_set_end_state(enum tap_state new_end_state)
This function sets the state of an "end state follower" which tracks the state that any cable driver ...
Definition: interface.c:48
static enum tap_state end_state_follower
Definition: interface.c:46
void tap_set_state_impl(enum tap_state new_state)
implementation of wrapper function tap_set_state()
Definition: interface.c:31
enum tap_state tap_state_by_name(const char *name)
Provides user-friendly name lookup of TAP states.
Definition: interface.c:366
int tap_set_end_state_stable(enum tap_state new_end_state)
Similar as tap_set_end_state(), checks new_end_state is stable.
Definition: interface.c:56
static enum tap_state state_follower
Definition: interface.c:29
int tap_move_ndx(enum tap_state astate)
Function tap_move_ndx when given a stable state, returns an index from 0-5.
Definition: interface.c:72
#define B8(bits, count)
Definition: interface.c:134
enum tap_state tap_get_state(void)
This function gets the state of the "state follower" which tracks the state of the TAPs connected to ...
Definition: interface.c:37
bool tap_is_state_stable(enum tap_state astate)
Function tap_is_state_stable returns true if the astate is stable.
Definition: interface.c:211
int tap_get_tms_path(enum tap_state from, enum tap_state to)
This function provides a "bit sequence" indicating what has to be done with TMS during a sequence of ...
Definition: interface.c:201
static tms_table * tms_seqs
Definition: interface.c:199
The JTAG interface can be implemented with a software or hardware fifo.
tap_state
Defines JTAG Test Access Port states.
Definition: jtag.h:37
@ TAP_IRCAPTURE
Definition: jtag.h:55
@ TAP_RESET
Definition: jtag.h:56
@ TAP_DRCAPTURE
Definition: jtag.h:47
@ TAP_DRSELECT
Definition: jtag.h:48
@ TAP_DREXIT1
Definition: jtag.h:42
@ TAP_IREXIT1
Definition: jtag.h:50
@ TAP_DRPAUSE
Definition: jtag.h:44
@ TAP_IRSELECT
Definition: jtag.h:45
@ TAP_IRUPDATE
Definition: jtag.h:54
@ TAP_IREXIT2
Definition: jtag.h:49
@ TAP_IRSHIFT
Definition: jtag.h:51
@ TAP_DREXIT2
Definition: jtag.h:41
@ TAP_IDLE
Definition: jtag.h:53
@ TAP_DRSHIFT
Definition: jtag.h:43
@ TAP_IRPAUSE
Definition: jtag.h:52
@ TAP_DRUPDATE
Definition: jtag.h:46
@ TAP_INVALID
Definition: jtag.h:38
#define ERROR_JTAG_NOT_STABLE_STATE
Definition: jtag.h:557
#define LOG_DEBUG_IO(expr ...)
Definition: log.h:116
#define LOG_ERROR(expr ...)
Definition: log.h:147
#define ERROR_OK
Definition: log.h:182
const char * name
Definition: interface.c:332
enum tap_state symbol
Definition: interface.c:331
uint8_t bits
Definition: interface.c:114
uint8_t bit_count
Definition: interface.c:115
#define ARRAY_SIZE(x)
Compute the number of elements of a variable length array.
Definition: types.h:57
#define DIV_ROUND_UP(m, n)
Rounds m up to the nearest multiple of n using division.
Definition: types.h:79
uint8_t state[4]
Definition: vdebug.c:21