SVF: clean up, mostly for TAP state name handling
[fw/openocd] / src / jtag / interface.c
1 /***************************************************************************
2  *   Copyright (C) 2005 by Dominic Rath                                    *
3  *   Dominic.Rath@gmx.de                                                   *
4  *                                                                         *
5  *   Copyright (C) 2007,2008 Ã˜yvind Harboe                                 *
6  *   oyvind.harboe@zylin.com                                               *
7  *                                                                         *
8  *   Copyright (C) 2009 SoftPLC Corporation                                *
9  *       http://softplc.com                                                *
10  *   dick@softplc.com                                                      *
11  *                                                                         *
12  *   Copyright (C) 2009 Zachary T Welch                                    *
13  *   zw@superlucidity.net                                                  *
14  *                                                                         *
15  *   This program is free software; you can redistribute it and/or modify  *
16  *   it under the terms of the GNU General Public License as published by  *
17  *   the Free Software Foundation; either version 2 of the License, or     *
18  *   (at your option) any later version.                                   *
19  *                                                                         *
20  *   This program is distributed in the hope that it will be useful,       *
21  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
22  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
23  *   GNU General Public License for more details.                          *
24  *                                                                         *
25  *   You should have received a copy of the GNU General Public License     *
26  *   along with this program; if not, write to the                         *
27  *   Free Software Foundation, Inc.,                                       *
28  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
29  ***************************************************************************/
30 #ifdef HAVE_CONFIG_H
31 #include "config.h"
32 #endif
33
34 #include "jtag.h"
35 #include "interface.h"
36
37 /**
38  * @see tap_set_state() and tap_get_state() accessors.
39  * Actual name is not important since accessors hide it.
40  */
41 static tap_state_t state_follower = TAP_RESET;
42
43 void tap_set_state_impl(tap_state_t new_state)
44 {
45         /* this is the state we think the TAPs are in now, was cur_state */
46         state_follower = new_state;
47 }
48
49 tap_state_t tap_get_state()
50 {
51         return state_follower;
52 }
53
54 /**
55  * @see tap_set_end_state() and tap_get_end_state() accessors.
56  * Actual name is not important because accessors hide it.
57  */
58 static tap_state_t end_state_follower = TAP_RESET;
59
60 void tap_set_end_state(tap_state_t new_end_state)
61 {
62         /* this is the state we think the TAPs will be in at completion of the
63            current TAP operation, was end_state
64         */
65         end_state_follower = new_end_state;
66 }
67
68 tap_state_t tap_get_end_state()
69 {
70         return end_state_follower;
71 }
72
73
74 int tap_move_ndx(tap_state_t astate)
75 {
76         /* given a stable state, return the index into the tms_seqs[] array within tap_get_tms_path() */
77
78         int ndx;
79
80         switch (astate)
81         {
82         case TAP_RESET:         ndx = 0;                        break;
83         case TAP_DRSHIFT:       ndx = 2;                        break;
84         case TAP_DRPAUSE:       ndx = 3;                        break;
85         case TAP_IDLE:          ndx = 1;                        break;
86         case TAP_IRSHIFT:       ndx = 4;                        break;
87         case TAP_IRPAUSE:       ndx = 5;                        break;
88         default:
89                 LOG_ERROR("fatal: unstable state \"%s\" used in tap_move_ndx()", tap_state_name(astate));
90                 exit(1);
91         }
92
93         return ndx;
94 }
95
96
97 /* tap_move[i][j]: tap movement command to go from state i to state j
98  * 0: Test-Logic-Reset
99  * 1: Run-Test/Idle
100  * 2: Shift-DR
101  * 3: Pause-DR
102  * 4: Shift-IR
103  * 5: Pause-IR
104  *
105  * DRSHIFT->DRSHIFT and IRSHIFT->IRSHIFT have to be caught in interface specific code
106  */
107 struct tms_sequences
108 {
109         uint8_t bits;
110         uint8_t bit_count;
111
112 };
113
114 /*
115  * These macros allow us to specify TMS state transitions by bits rather than hex bytes.
116  * Read the bits from LSBit first to MSBit last (right-to-left).
117  */
118 #define HEX__(n) 0x##n##LU
119
120 #define B8__(x) \
121          (((x) & 0x0000000FLU)?(1 << 0):0) \
122         +(((x) & 0x000000F0LU)?(1 << 1):0) \
123         +(((x) & 0x00000F00LU)?(1 << 2):0) \
124         +(((x) & 0x0000F000LU)?(1 << 3):0) \
125         +(((x) & 0x000F0000LU)?(1 << 4):0) \
126         +(((x) & 0x00F00000LU)?(1 << 5):0) \
127         +(((x) & 0x0F000000LU)?(1 << 6):0) \
128         +(((x) & 0xF0000000LU)?(1 << 7):0)
129
130 #define B8(bits,count)          { ((uint8_t)B8__(HEX__(bits))), (count) }
131
132 static const struct tms_sequences old_tms_seqs[6][6] =          /*  [from_state_ndx][to_state_ndx] */
133 {
134         /* value clocked to TMS to move from one of six stable states to another.
135          * N.B. OOCD clocks TMS from LSB first, so read these right-to-left.
136          * N.B. Reset only needs to be 0b11111, but in JLink an even byte of 1's is more stable.
137          * These extra ones cause no TAP state problem, because we go into reset and stay in reset.
138          */
139
140         /* to state: */
141         /*      RESET                   IDLE                    DRSHIFT                 DRPAUSE                 IRSHIFT                 IRPAUSE         */              /* from state: */
142         {       B8(1111111,7),  B8(0000000,7),  B8(0010111,7),  B8(0001010,7),  B8(0011011,7),  B8(0010110,7) },        /* RESET */
143         {       B8(1111111,7),  B8(0000000,7),  B8(0100101,7),  B8(0000101,7),  B8(0101011,7),  B8(0001011,7) },        /* IDLE */
144         {       B8(1111111,7),  B8(0110001,7),  B8(0000000,7),  B8(0000001,7),  B8(0001111,7),  B8(0101111,7) },        /* DRSHIFT */
145         {       B8(1111111,7),  B8(0110000,7),  B8(0100000,7),  B8(0010111,7),  B8(0011110,7),  B8(0101111,7) },        /* DRPAUSE */
146         {       B8(1111111,7),  B8(0110001,7),  B8(0000111,7),  B8(0010111,7),  B8(0000000,7),  B8(0000001,7) },        /* IRSHIFT */
147         {       B8(1111111,7),  B8(0110000,7),  B8(0011100,7),  B8(0010111,7),  B8(0011110,7),  B8(0101111,7) },        /* IRPAUSE */
148 };
149
150
151
152 static const struct tms_sequences short_tms_seqs[6][6] =                /*  [from_state_ndx][to_state_ndx] */
153 {
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
198 typedef const struct tms_sequences tms_table[6][6];
199
200 static tms_table *tms_seqs=&short_tms_seqs;
201
202 int tap_get_tms_path(tap_state_t from, tap_state_t to)
203 {
204         return (*tms_seqs)[tap_move_ndx(from)][tap_move_ndx(to)].bits;
205 }
206
207
208 int tap_get_tms_path_len(tap_state_t from, tap_state_t to)
209 {
210         return (*tms_seqs)[tap_move_ndx(from)][tap_move_ndx(to)].bit_count;
211 }
212
213
214 bool tap_is_state_stable(tap_state_t astate)
215 {
216         bool is_stable;
217
218         /*      A switch () is used because it is symbol dependent
219                 (not value dependent like an array), and can also check bounds.
220         */
221         switch (astate)
222         {
223         case TAP_RESET:
224         case TAP_IDLE:
225         case TAP_DRSHIFT:
226         case TAP_DRPAUSE:
227         case TAP_IRSHIFT:
228         case TAP_IRPAUSE:
229                 is_stable = true;
230                 break;
231         default:
232                 is_stable = false;
233         }
234
235         return is_stable;
236 }
237
238 tap_state_t tap_state_transition(tap_state_t cur_state, bool tms)
239 {
240         tap_state_t new_state;
241
242         /*      A switch is used because it is symbol dependent and not value dependent
243                 like an array.  Also it can check for out of range conditions.
244         */
245
246         if (tms)
247         {
248                 switch (cur_state)
249                 {
250                 case TAP_RESET:
251                         new_state = cur_state;
252                         break;
253                 case TAP_IDLE:
254                 case TAP_DRUPDATE:
255                 case TAP_IRUPDATE:
256                         new_state = TAP_DRSELECT;
257                         break;
258                 case TAP_DRSELECT:
259                         new_state = TAP_IRSELECT;
260                         break;
261                 case TAP_DRCAPTURE:
262                 case TAP_DRSHIFT:
263                         new_state = TAP_DREXIT1;
264                         break;
265                 case TAP_DREXIT1:
266                 case TAP_DREXIT2:
267                         new_state = TAP_DRUPDATE;
268                         break;
269                 case TAP_DRPAUSE:
270                         new_state = TAP_DREXIT2;
271                         break;
272                 case TAP_IRSELECT:
273                         new_state = TAP_RESET;
274                         break;
275                 case TAP_IRCAPTURE:
276                 case TAP_IRSHIFT:
277                         new_state = TAP_IREXIT1;
278                         break;
279                 case TAP_IREXIT1:
280                 case TAP_IREXIT2:
281                         new_state = TAP_IRUPDATE;
282                         break;
283                 case TAP_IRPAUSE:
284                         new_state = TAP_IREXIT2;
285                         break;
286                 default:
287                         LOG_ERROR("fatal: invalid argument cur_state=%d", cur_state);
288                         exit(1);
289                         break;
290                 }
291         }
292         else
293         {
294                 switch (cur_state)
295                 {
296                 case TAP_RESET:
297                 case TAP_IDLE:
298                 case TAP_DRUPDATE:
299                 case TAP_IRUPDATE:
300                         new_state = TAP_IDLE;
301                         break;
302                 case TAP_DRSELECT:
303                         new_state = TAP_DRCAPTURE;
304                         break;
305                 case TAP_DRCAPTURE:
306                 case TAP_DRSHIFT:
307                 case TAP_DREXIT2:
308                         new_state = TAP_DRSHIFT;
309                         break;
310                 case TAP_DREXIT1:
311                 case TAP_DRPAUSE:
312                         new_state = TAP_DRPAUSE;
313                         break;
314                 case TAP_IRSELECT:
315                         new_state = TAP_IRCAPTURE;
316                         break;
317                 case TAP_IRCAPTURE:
318                 case TAP_IRSHIFT:
319                 case TAP_IREXIT2:
320                         new_state = TAP_IRSHIFT;
321                         break;
322                 case TAP_IREXIT1:
323                 case TAP_IRPAUSE:
324                         new_state = TAP_IRPAUSE;
325                         break;
326                 default:
327                         LOG_ERROR("fatal: invalid argument cur_state=%d", cur_state);
328                         exit(1);
329                         break;
330                 }
331         }
332
333         return new_state;
334 }
335
336 const char* tap_state_name(tap_state_t state)
337 {
338         const char* ret;
339
340         switch (state)
341         {
342         case TAP_RESET:         ret = "RESET";                  break;
343         case TAP_IDLE:          ret = "RUN/IDLE";               break;
344         case TAP_DRSELECT:      ret = "DRSELECT";               break;
345         case TAP_DRCAPTURE: ret = "DRCAPTURE";          break;
346         case TAP_DRSHIFT:       ret = "DRSHIFT";                        break;
347         case TAP_DREXIT1:       ret = "DREXIT1";                        break;
348         case TAP_DRPAUSE:       ret = "DRPAUSE";                        break;
349         case TAP_DREXIT2:       ret = "DREXIT2";                        break;
350         case TAP_DRUPDATE:      ret = "DRUPDATE";               break;
351         case TAP_IRSELECT:      ret = "IRSELECT";               break;
352         case TAP_IRCAPTURE: ret = "IRCAPTURE";          break;
353         case TAP_IRSHIFT:       ret = "IRSHIFT";                        break;
354         case TAP_IREXIT1:       ret = "IREXIT1";                        break;
355         case TAP_IRPAUSE:       ret = "IRPAUSE";                        break;
356         case TAP_IREXIT2:       ret = "IREXIT2";                        break;
357         case TAP_IRUPDATE:      ret = "IRUPDATE";               break;
358         default:                                ret = "???";
359         }
360
361         return ret;
362 }
363
364 tap_state_t tap_state_by_name(const char *name)
365 {
366         tap_state_t x;
367
368         /* standard SVF name is "IDLE" */
369         if (0 == strcasecmp(name, "IDLE"))
370                 return TAP_IDLE;
371
372         for (x = 0 ; x < TAP_NUM_STATES ; x++) {
373                 /* be nice to the human */
374                 if (0 == strcasecmp(name, tap_state_name(x))) {
375                         return x;
376                 }
377         }
378         /* not found */
379         return TAP_INVALID;
380 }
381
382 #ifdef _DEBUG_JTAG_IO_
383
384 #define JTAG_DEBUG_STATE_APPEND(buf, len, bit) \
385                 do { buf[len] = bit ? '1' : '0'; } while (0)
386 #define JTAG_DEBUG_STATE_PRINT(a, b, astr, bstr) \
387                 DEBUG_JTAG_IO("TAP/SM: %9s -> %5s\tTMS: %s\tTDI: %s", \
388                         tap_state_name(a), tap_state_name(b), astr, bstr)
389
390 tap_state_t jtag_debug_state_machine(const void *tms_buf, const void *tdi_buf,
391                 unsigned tap_bits, tap_state_t next_state)
392 {
393         const uint8_t *tms_buffer;
394         const uint8_t *tdi_buffer;
395         unsigned tap_bytes;
396         unsigned cur_byte;
397         unsigned cur_bit;
398
399         unsigned tap_out_bits;
400         char tms_str[33];
401         char tdi_str[33];
402
403         tap_state_t last_state;
404
405         // set startstate (and possibly last, if tap_bits == 0)
406         last_state = next_state;
407         DEBUG_JTAG_IO("TAP/SM: START state: %s", tap_state_name(next_state));
408
409         tms_buffer = (const uint8_t *)tms_buf;
410         tdi_buffer = (const uint8_t *)tdi_buf;
411
412         tap_bytes = TAP_SCAN_BYTES(tap_bits);
413         DEBUG_JTAG_IO("TAP/SM: TMS bits: %u (bytes: %u)", tap_bits, tap_bytes);
414
415         tap_out_bits = 0;
416         for (cur_byte = 0; cur_byte < tap_bytes; cur_byte++)
417         {
418                 for (cur_bit = 0; cur_bit < 8; cur_bit++)
419                 {
420                         // make sure we do not run off the end of the buffers
421                         unsigned tap_bit = cur_byte * 8 + cur_bit;
422                         if (tap_bit == tap_bits)
423                                 break;
424
425                         // check and save TMS bit
426                         tap_bit = !!(tms_buffer[cur_byte] & (1 << cur_bit));
427                         JTAG_DEBUG_STATE_APPEND(tms_str, tap_out_bits, tap_bit);
428
429                         // use TMS bit to find the next TAP state
430                         next_state = tap_state_transition(last_state, tap_bit);
431
432                         // check and store TDI bit
433                         tap_bit = !!(tdi_buffer[cur_byte] & (1 << cur_bit));
434                         JTAG_DEBUG_STATE_APPEND(tdi_str, tap_out_bits, tap_bit);
435
436                         // increment TAP bits
437                         tap_out_bits++;
438
439                         // Only show TDO bits on state transitions, or
440                         // after some number of bits in the same state.
441                         if ((next_state == last_state) && (tap_out_bits < 32))
442                                 continue;
443
444                         // terminate strings and display state transition
445                         tms_str[tap_out_bits] = tdi_str[tap_out_bits] = 0;
446                         JTAG_DEBUG_STATE_PRINT(last_state, next_state, tms_str, tdi_str);
447
448                         // reset state
449                         last_state = next_state;
450                         tap_out_bits = 0;
451                 }
452         }
453
454         if (tap_out_bits)
455         {
456                 // terminate strings and display state transition
457                 tms_str[tap_out_bits] = tdi_str[tap_out_bits] = 0;
458                 JTAG_DEBUG_STATE_PRINT(last_state, next_state, tms_str, tdi_str);
459         }
460
461         DEBUG_JTAG_IO("TAP/SM: FINAL state: %s", tap_state_name(next_state));
462
463         return next_state;
464 }
465 #endif // _DEBUG_JTAG_IO_
466
467 void tap_use_new_tms_table(bool use_new)
468 {
469         tms_seqs = use_new ? &short_tms_seqs : &old_tms_seqs;
470 }
471 bool tap_uses_new_tms_table(void)
472 {
473         return tms_seqs == &short_tms_seqs;
474 }
475