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, see <http://www.gnu.org/licenses/>. *
27  ***************************************************************************/
28 
29 #ifdef HAVE_CONFIG_H
30 #include "config.h"
31 #endif
32 
33 #include "jtag.h"
34 #include "interface.h"
35 
36 /**
37  * @see tap_set_state() and tap_get_state() accessors.
38  * Actual name is not important since accessors hide it.
39  */
40 static tap_state_t state_follower = TAP_RESET;
41 
tap_set_state_impl(tap_state_t new_state)42 void tap_set_state_impl(tap_state_t new_state)
43 {
44 	/* this is the state we think the TAPs are in now, was cur_state */
45 	state_follower = new_state;
46 }
47 
tap_get_state(void)48 tap_state_t tap_get_state(void)
49 {
50 	return state_follower;
51 }
52 
53 /**
54  * @see tap_set_end_state() and tap_get_end_state() accessors.
55  * Actual name is not important because accessors hide it.
56  */
57 static tap_state_t end_state_follower = TAP_RESET;
58 
tap_set_end_state(tap_state_t new_end_state)59 void tap_set_end_state(tap_state_t new_end_state)
60 {
61 	/* this is the state we think the TAPs will be in at completion of the
62 	 * current TAP operation, was end_state
63 	*/
64 	end_state_follower = new_end_state;
65 }
66 
tap_get_end_state(void)67 tap_state_t tap_get_end_state(void)
68 {
69 	return end_state_follower;
70 }
71 
tap_move_ndx(tap_state_t astate)72 int tap_move_ndx(tap_state_t 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 tap_move_ndx()",
101 					tap_state_name(astate));
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  */
113 struct tms_sequences {
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 
199 static tms_table *tms_seqs = &short_tms_seqs;
200 
tap_get_tms_path(tap_state_t from,tap_state_t to)201 int tap_get_tms_path(tap_state_t from, tap_state_t to)
202 {
203 	return (*tms_seqs)[tap_move_ndx(from)][tap_move_ndx(to)].bits;
204 }
205 
tap_get_tms_path_len(tap_state_t from,tap_state_t to)206 int tap_get_tms_path_len(tap_state_t from, tap_state_t to)
207 {
208 	return (*tms_seqs)[tap_move_ndx(from)][tap_move_ndx(to)].bit_count;
209 }
210 
tap_is_state_stable(tap_state_t astate)211 bool tap_is_state_stable(tap_state_t astate)
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 
tap_state_transition(tap_state_t cur_state,bool tms)234 tap_state_t tap_state_transition(tap_state_t cur_state, bool tms)
235 {
236 	tap_state_t 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 
tap_state_name(tap_state_t state)355 const char *tap_state_name(tap_state_t state)
356 {
357 	unsigned 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 
tap_state_by_name(const char * name)366 tap_state_t tap_state_by_name(const char *name)
367 {
368 	unsigned 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 
jtag_debug_state_machine_(const void * tms_buf,const void * tdi_buf,unsigned tap_bits,tap_state_t next_state)385 tap_state_t jtag_debug_state_machine_(const void *tms_buf, const void *tdi_buf,
386 	unsigned tap_bits, tap_state_t next_state)
387 {
388 	const uint8_t *tms_buffer;
389 	const uint8_t *tdi_buffer;
390 	unsigned tap_bytes;
391 	unsigned cur_byte;
392 	unsigned cur_bit;
393 
394 	unsigned tap_out_bits;
395 	char tms_str[33];
396 	char tdi_str[33];
397 
398 	tap_state_t 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 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 
tap_use_new_tms_table(bool use_new)458 void tap_use_new_tms_table(bool use_new)
459 {
460 	tms_seqs = use_new ? &short_tms_seqs : &old_tms_seqs;
461 }
tap_uses_new_tms_table(void)462 bool tap_uses_new_tms_table(void)
463 {
464 	return tms_seqs == &short_tms_seqs;
465 }
466