]> git.sur5r.net Git - openocd/blob - src/jtag/interface.c
jtag_add_statemove() always uses TLR to get to RESET
[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         for (x = 0 ; x < TAP_NUM_STATES ; x++) {
369                 /* be nice to the human */
370                 if (0 == strcasecmp(name, tap_state_name(x))) {
371                         return x;
372                 }
373         }
374         /* not found */
375         return TAP_INVALID;
376 }
377
378 #ifdef _DEBUG_JTAG_IO_
379
380 #define JTAG_DEBUG_STATE_APPEND(buf, len, bit) \
381                 do { buf[len] = bit ? '1' : '0'; } while (0)
382 #define JTAG_DEBUG_STATE_PRINT(a, b, astr, bstr) \
383                 DEBUG_JTAG_IO("TAP/SM: %9s -> %5s\tTMS: %s\tTDI: %s", \
384                         tap_state_name(a), tap_state_name(b), astr, bstr)
385
386 tap_state_t jtag_debug_state_machine(const void *tms_buf, const void *tdi_buf,
387                 unsigned tap_bits, tap_state_t next_state)
388 {
389         const uint8_t *tms_buffer;
390         const uint8_t *tdi_buffer;
391         unsigned tap_bytes;
392         unsigned cur_byte;
393         unsigned cur_bit;
394
395         unsigned tap_out_bits;
396         char tms_str[33];
397         char tdi_str[33];
398
399         tap_state_t last_state;
400
401         // set startstate (and possibly last, if tap_bits == 0)
402         last_state = next_state;
403         DEBUG_JTAG_IO("TAP/SM: START state: %s", tap_state_name(next_state));
404
405         tms_buffer = (const uint8_t *)tms_buf;
406         tdi_buffer = (const uint8_t *)tdi_buf;
407
408         tap_bytes = TAP_SCAN_BYTES(tap_bits);
409         DEBUG_JTAG_IO("TAP/SM: TMS bits: %u (bytes: %u)", tap_bits, tap_bytes);
410
411         tap_out_bits = 0;
412         for (cur_byte = 0; cur_byte < tap_bytes; cur_byte++)
413         {
414                 for (cur_bit = 0; cur_bit < 8; cur_bit++)
415                 {
416                         // make sure we do not run off the end of the buffers
417                         unsigned tap_bit = cur_byte * 8 + cur_bit;
418                         if (tap_bit == tap_bits)
419                                 break;
420
421                         // check and save TMS bit
422                         tap_bit = !!(tms_buffer[cur_byte] & (1 << cur_bit));
423                         JTAG_DEBUG_STATE_APPEND(tms_str, tap_out_bits, tap_bit);
424
425                         // use TMS bit to find the next TAP state
426                         next_state = tap_state_transition(last_state, tap_bit);
427
428                         // check and store TDI bit
429                         tap_bit = !!(tdi_buffer[cur_byte] & (1 << cur_bit));
430                         JTAG_DEBUG_STATE_APPEND(tdi_str, tap_out_bits, tap_bit);
431
432                         // increment TAP bits
433                         tap_out_bits++;
434
435                         // Only show TDO bits on state transitions, or
436                         // after some number of bits in the same state.
437                         if ((next_state == last_state) && (tap_out_bits < 32))
438                                 continue;
439
440                         // terminate strings and display state transition
441                         tms_str[tap_out_bits] = tdi_str[tap_out_bits] = 0;
442                         JTAG_DEBUG_STATE_PRINT(last_state, next_state, tms_str, tdi_str);
443
444                         // reset state
445                         last_state = next_state;
446                         tap_out_bits = 0;
447                 }
448         }
449
450         if (tap_out_bits)
451         {
452                 // terminate strings and display state transition
453                 tms_str[tap_out_bits] = tdi_str[tap_out_bits] = 0;
454                 JTAG_DEBUG_STATE_PRINT(last_state, next_state, tms_str, tdi_str);
455         }
456
457         DEBUG_JTAG_IO("TAP/SM: FINAL state: %s", tap_state_name(next_state));
458
459         return next_state;
460 }
461 #endif // _DEBUG_JTAG_IO_
462
463 void tap_use_new_tms_table(bool use_new)
464 {
465         tms_seqs = use_new ? &short_tms_seqs : &old_tms_seqs;
466 }
467 bool tap_uses_new_tms_table(void)
468 {
469         return tms_seqs == &short_tms_seqs;
470 }
471