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