jtag.c 82.7 KB
Newer Older
1
2
3
4
/***************************************************************************
 *   Copyright (C) 2005 by Dominic Rath                                    *
 *   Dominic.Rath@gmx.de                                                   *
 *                                                                         *
5
 *   Copyright (C) 2007,2008 yvind Harboe                                 *
6
 *   oyvind.harboe@zylin.com                                               *
ntfreak's avatar
ntfreak committed
7
8
 *                                                                         *
 *   Copyright (C) 2009 SoftPLC Corporation                                *
zwelch's avatar
zwelch committed
9
 *       http://softplc.com                                                *
ntfreak's avatar
ntfreak committed
10
 *   dick@softplc.com                                                      *
11
 *                                                                         *
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

31
#define INCLUDE_JTAG_MINIDRIVER_H
32
#define INCLUDE_JTAG_INTERFACE_H
33
34
#include "jtag.h"

35
36
37
#ifdef HAVE_STRINGS_H
#include <strings.h>
#endif
38

39

40
int jtag_flush_queue_count; /* count # of flushes for profiling / debugging purposes */
41

42
static void jtag_add_scan_check(void (*jtag_add_scan)(int in_num_fields, const scan_field_t *in_fields, tap_state_t state),
43
		int in_num_fields, scan_field_t *in_fields, tap_state_t state);
oharboe's avatar
oharboe committed
44

45
46
/* note that this is not marked as static as it must be available from outside jtag.c for those
   that implement the jtag_xxx() minidriver layer
oharboe's avatar
oharboe committed
47
*/
48
int jtag_error=ERROR_OK;
oharboe's avatar
oharboe committed
49

50
51
52
53
54
55
56
57
58
59
60
61
typedef struct cmd_queue_page_s
{
	void *address;
	size_t used;
	struct cmd_queue_page_s *next;
} cmd_queue_page_t;

#define CMD_QUEUE_PAGE_SIZE (1024 * 1024)
static cmd_queue_page_t *cmd_queue_pages = NULL;

char* jtag_event_strings[] =
{
62
	"JTAG controller reset (RESET or TRST)"
63
64
};

65
66
67
68
69
70
71
const Jim_Nvp nvp_jtag_tap_event[] = {
	{ .value = JTAG_TAP_EVENT_ENABLE,       .name = "tap-enable" },
	{ .value = JTAG_TAP_EVENT_DISABLE,      .name = "tap-disable" },

	{ .name = NULL, .value = -1 }
};

72
73
74
75
int jtag_trst = 0;
int jtag_srst = 0;

jtag_command_t *jtag_command_queue = NULL;
zwelch's avatar
zwelch committed
76
static jtag_command_t **next_command_pointer = &jtag_command_queue;
77
78
static jtag_tap_t *jtag_all_taps = NULL;

79
enum reset_types jtag_reset_config = RESET_NONE;
80
81
tap_state_t cmd_queue_end_state = TAP_RESET;
tap_state_t cmd_queue_cur_state = TAP_RESET;
82
83

int jtag_verify_capture_ir = 1;
oharboe's avatar
oharboe committed
84
int jtag_verify = 1;
85
86

/* how long the OpenOCD should wait before attempting JTAG communication after reset lines deasserted (in ms) */
87
88
static int jtag_nsrst_delay = 0; /* default to no nSRST delay */
static int jtag_ntrst_delay = 0; /* default to no nTRST delay */
89
90
91

/* maximum number of JTAG devices expected in the chain
 */
92
#define JTAG_MAX_CHAIN_SIZE 20
93
94
95
96

/* callbacks to inform high-level handlers about JTAG state changes */
jtag_event_callback_t *jtag_event_callbacks;

oharboe's avatar
   
oharboe committed
97
/* speed in kHz*/
oharboe's avatar
   
oharboe committed
98
static int speed_khz = 0;
oharboe's avatar
   
oharboe committed
99
100
101
/* flag if the kHz speed was defined */
static int hasKHz = 0;

102
103
/* jtag interfaces (parport, FTDI-USB, TI-USB, ...)
 */
104

105
#if BUILD_ECOSBOARD == 1
106
	extern jtag_interface_t zy1000_interface;
107
#endif
108

109
110
111
#if BUILD_PARPORT == 1
	extern jtag_interface_t parport_interface;
#endif
112

113
114
115
#if BUILD_DUMMY == 1
	extern jtag_interface_t dummy_interface;
#endif
116

117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
#if BUILD_FT2232_FTD2XX == 1
	extern jtag_interface_t ft2232_interface;
#endif

#if BUILD_FT2232_LIBFTDI == 1
	extern jtag_interface_t ft2232_interface;
#endif

#if BUILD_AMTJTAGACCEL == 1
	extern jtag_interface_t amt_jtagaccel_interface;
#endif

#if BUILD_EP93XX == 1
	extern jtag_interface_t ep93xx_interface;
#endif

#if BUILD_AT91RM9200 == 1
	extern jtag_interface_t at91rm9200_interface;
#endif

#if BUILD_GW16012 == 1
	extern jtag_interface_t gw16012_interface;
#endif

#if BUILD_PRESTO_LIBFTDI == 1 || BUILD_PRESTO_FTD2XX == 1
	extern jtag_interface_t presto_interface;
#endif

#if BUILD_USBPROG == 1
	extern jtag_interface_t usbprog_interface;
#endif

149
150
151
152
#if BUILD_JLINK == 1
	extern jtag_interface_t jlink_interface;
#endif

duane's avatar
duane committed
153
154
155
156
#if BUILD_VSLLINK == 1
	extern jtag_interface_t vsllink_interface;
#endif

157
158
159
160
#if BUILD_RLINK == 1
	extern jtag_interface_t rlink_interface;
#endif

161
162
163
164
#if BUILD_ARMJTAGEW == 1
	extern jtag_interface_t armjtagew_interface;
#endif

165
jtag_interface_t *jtag_interfaces[] = {
166
#if BUILD_ECOSBOARD == 1
167
	&zy1000_interface,
168
#endif
169
170
171
#if BUILD_PARPORT == 1
	&parport_interface,
#endif
172
173
174
#if BUILD_DUMMY == 1
	&dummy_interface,
#endif
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
#if BUILD_FT2232_FTD2XX == 1
	&ft2232_interface,
#endif
#if BUILD_FT2232_LIBFTDI == 1
	&ft2232_interface,
#endif
#if BUILD_AMTJTAGACCEL == 1
	&amt_jtagaccel_interface,
#endif
#if BUILD_EP93XX == 1
	&ep93xx_interface,
#endif
#if BUILD_AT91RM9200 == 1
	&at91rm9200_interface,
#endif
#if BUILD_GW16012 == 1
	&gw16012_interface,
#endif
#if BUILD_PRESTO_LIBFTDI == 1 || BUILD_PRESTO_FTD2XX == 1
	&presto_interface,
#endif
#if BUILD_USBPROG == 1
	&usbprog_interface,
198
199
200
#endif
#if BUILD_JLINK == 1
	&jlink_interface,
201
#endif
duane's avatar
duane committed
202
203
204
#if BUILD_VSLLINK == 1
	&vsllink_interface,
#endif
205
206
#if BUILD_RLINK == 1
	&rlink_interface,
207
208
209
#endif
#if BUILD_ARMJTAGEW == 1
	&armjtagew_interface,
210
211
212
213
#endif
	NULL,
};

214
struct jtag_interface_s *jtag = NULL;
215
216

/* configuration */
217
static jtag_interface_t *jtag_interface = NULL;
218
int jtag_speed = 0;
oharboe's avatar
   
oharboe committed
219

220
/* forward declarations */
221
222
223
224
225
226
//void jtag_add_pathmove(int num_states, tap_state_t *path);
//void jtag_add_runtest(int num_cycles, tap_state_t endstate);
//void jtag_add_end_state(tap_state_t endstate);
//void jtag_add_sleep(u32 us);
//int jtag_execute_queue(void);
static tap_state_t tap_state_by_name(const char *name);
227
228

/* jtag commands */
229
230
231
232
233
234
235
static int handle_interface_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
static int handle_jtag_speed_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
static int handle_jtag_khz_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
static int handle_jtag_device_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
static int handle_reset_config_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
static int handle_jtag_nsrst_delay_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
static int handle_jtag_ntrst_delay_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
236

237
static int handle_scan_chain_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
238

239
240
241
242
243
static int handle_endstate_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
static int handle_jtag_reset_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
static int handle_runtest_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
static int handle_irscan_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
static int Jim_Command_drscan(Jim_Interp *interp, int argc, Jim_Obj *const *argv);
244
static int Jim_Command_flush_count(Jim_Interp *interp, int argc, Jim_Obj *const *args);
245

246
static int handle_verify_ircapture_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
oharboe's avatar
oharboe committed
247
static int handle_verify_jtag_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
248
static int handle_tms_sequence_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
249

oharboe's avatar
oharboe committed
250
251
jtag_tap_t *jtag_AllTaps(void)
{
252
	return jtag_all_taps;
253
254
};

255
int jtag_NumTotalTaps(void)
256
257
258
259
260
261
262
263
264
265
266
267
268
{
	jtag_tap_t *t;
	int n;

	n = 0;
	t = jtag_AllTaps();
	while(t){
		n++;
		t = t->next_tap;
	}
	return n;
}

269
int jtag_NumEnabledTaps(void)
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
{
	jtag_tap_t *t;
	int n;

	n = 0;
	t = jtag_AllTaps();
	while(t){
		if( t->enabled ){
			n++;
		}
		t = t->next_tap;
	}
	return n;
}

jtag_tap_t *jtag_TapByString( const char *s )
{
	jtag_tap_t *t;
	char *cp;

	t = jtag_AllTaps();
ntfreak's avatar
ntfreak committed
291
	/* try name first */
292
293
294
295
296
297
298
	while(t){
		if( 0 == strcmp( t->dotted_name, s ) ){
			break;
		} else {
			t = t->next_tap;
		}
	}
ntfreak's avatar
ntfreak committed
299
	/* backup plan is by number */
300
301
302
303
304
305
306
307
308
309
310
311
	if( t == NULL ){
		/* ok - is "s" a number? */
		int n;
		n = strtol( s, &cp, 0 );
		if( (s != cp) && (*cp == 0) ){
			/* Then it is... */
			t = jtag_TapByAbsPosition(n);
		}
	}
	return t;
}

312
jtag_tap_t * jtag_TapByJimObj( Jim_Interp *interp, Jim_Obj *o )
313
314
315
316
317
318
319
320
321
322
{
	jtag_tap_t *t;
	const char *cp;

	cp = Jim_GetString( o, NULL );
	if(cp == NULL){
		cp = "(unknown)";
		t = NULL;
	}  else {
		t = jtag_TapByString( cp );
oharboe's avatar
oharboe committed
323
	}
324
325
326
327
328
329
330
	if( t == NULL ){
		Jim_SetResult_sprintf(interp,"Tap: %s is unknown", cp );
	}
	return t;
}

/* returns a pointer to the n-th device in the scan chain */
331
jtag_tap_t * jtag_TapByAbsPosition( int n )
332
333
334
335
336
337
{
	int orig_n;
	jtag_tap_t *t;

	orig_n = n;
	t = jtag_AllTaps();
oharboe's avatar
oharboe committed
338

339
340
341
	while( t && (n > 0)) {
		n--;
		t = t->next_tap;
342
	}
343
344
345
	return t;
}

346
347
348
int jtag_register_event_callback(int (*callback)(enum jtag_event event, void *priv), void *priv)
{
	jtag_event_callback_t **callbacks_p = &jtag_event_callbacks;
349

350
351
352
353
	if (callback == NULL)
	{
		return ERROR_INVALID_ARGUMENTS;
	}
354

355
356
357
358
359
360
	if (*callbacks_p)
	{
		while ((*callbacks_p)->next)
			callbacks_p = &((*callbacks_p)->next);
		callbacks_p = &((*callbacks_p)->next);
	}
361

362
363
364
365
	(*callbacks_p) = malloc(sizeof(jtag_event_callback_t));
	(*callbacks_p)->callback = callback;
	(*callbacks_p)->priv = priv;
	(*callbacks_p)->next = NULL;
366

367
368
369
370
371
372
	return ERROR_OK;
}

int jtag_unregister_event_callback(int (*callback)(enum jtag_event event, void *priv))
{
	jtag_event_callback_t **callbacks_p = &jtag_event_callbacks;
373

374
375
376
377
	if (callback == NULL)
	{
		return ERROR_INVALID_ARGUMENTS;
	}
378

379
380
381
382
383
384
385
386
387
388
	while (*callbacks_p)
	{
		jtag_event_callback_t **next = &((*callbacks_p)->next);
		if ((*callbacks_p)->callback == callback)
		{
			free(*callbacks_p);
			*callbacks_p = *next;
		}
		callbacks_p = next;
	}
389

390
391
392
393
394
395
	return ERROR_OK;
}

int jtag_call_event_callbacks(enum jtag_event event)
{
	jtag_event_callback_t *callback = jtag_event_callbacks;
396

397
	LOG_DEBUG("jtag event: %s", jtag_event_strings[event]);
398

399
400
401
402
403
	while (callback)
	{
		callback->callback(event, callback->priv);
		callback = callback->next;
	}
404

405
406
407
	return ERROR_OK;
}

408
409
void jtag_queue_command(jtag_command_t * cmd)
{
zwelch's avatar
zwelch committed
410
411
	// this command goes on the end, so ensure the queue terminates
	cmd->next = NULL;
412

zwelch's avatar
zwelch committed
413
414
415
	jtag_command_t **last_cmd = next_command_pointer;
	assert(NULL != last_cmd);
	assert(NULL == *last_cmd);
416
417
	*last_cmd = cmd;

zwelch's avatar
zwelch committed
418
419
	// store location where the next command pointer will be stored
	next_command_pointer = &cmd->next;
420
421
}

422
423
424
425
void* cmd_queue_alloc(size_t size)
{
	cmd_queue_page_t **p_page = &cmd_queue_pages;
	int offset;
oharboe's avatar
oharboe committed
426
	u8 *t;
427

428
429
430
431
432
433
434
435
436
437
438
439
440
441
	/*
	 * WARNING:
	 *    We align/round the *SIZE* per below
	 *    so that all pointers returned by
	 *    this function are reasonably well
	 *    aligned.
	 *
	 * If we did not, then an "odd-length" request would cause the
	 * *next* allocation to be at an *odd* address, and because
	 * this function has the same type of api as malloc() - we
	 * must also return pointers that have the same type of
	 * alignment.
	 *
	 * What I do not/have is a reasonable portable means
442
	 * to align by...
443
444
445
446
447
448
	 *
	 * The solution here, is based on these suggestions.
	 * http://gcc.gnu.org/ml/gcc-help/2008-12/msg00041.html
	 *
	 */
	union worse_case_align {
449
450
451
452
		int i;
		long l;
		float f;
		void *v;
453
454
455
	};
#define ALIGN_SIZE  (sizeof(union worse_case_align))

456
	/* The alignment process. */
457
	size = (size + ALIGN_SIZE -1) & (~(ALIGN_SIZE-1));
458
	/* Done... */
459

460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
	if (*p_page)
	{
		while ((*p_page)->next)
			p_page = &((*p_page)->next);
		if (CMD_QUEUE_PAGE_SIZE - (*p_page)->used < size)
			p_page = &((*p_page)->next);
	}

	if (!*p_page)
	{
		*p_page = malloc(sizeof(cmd_queue_page_t));
		(*p_page)->used = 0;
		(*p_page)->address = malloc(CMD_QUEUE_PAGE_SIZE);
		(*p_page)->next = NULL;
	}

	offset = (*p_page)->used;
	(*p_page)->used += size;
478

oharboe's avatar
oharboe committed
479
	t=(u8 *)((*p_page)->address);
480
481
482
	return t + offset;
}

oharboe's avatar
oharboe committed
483
void cmd_queue_free(void)
484
485
486
487
488
489
490
491
492
493
494
495
496
497
{
	cmd_queue_page_t *page = cmd_queue_pages;

	while (page)
	{
		cmd_queue_page_t *last = page;
		free(page->address);
		page = page->next;
		free(last);
	}

	cmd_queue_pages = NULL;
}

zwelch's avatar
zwelch committed
498
499
500
501
502
503
504
505
void jtag_command_queue_reset(void)
{
	cmd_queue_free();

	jtag_command_queue = NULL;
	next_command_pointer = &jtag_command_queue;
}

oharboe's avatar
oharboe committed
506
static void jtag_prelude1(void)
507
508
509
{
	if (jtag_trst == 1)
	{
510
		LOG_WARNING("JTAG command queued, while TRST is low (TAP in reset)");
oharboe's avatar
oharboe committed
511
		jtag_error=ERROR_JTAG_TRST_ASSERTED;
512
		return;
513
514
	}

515
	if (cmd_queue_end_state == TAP_RESET)
oharboe's avatar
oharboe committed
516
		jtag_call_event_callbacks(JTAG_TRST_ASSERTED);
517
518
}

519
static void jtag_prelude(tap_state_t state)
520
521
{
	jtag_prelude1();
522

mifi's avatar
mifi committed
523
	if (state != TAP_INVALID)
524
		jtag_add_end_state(state);
525

oharboe's avatar
oharboe committed
526
	cmd_queue_cur_state = cmd_queue_end_state;
527
528
}

529
void jtag_add_ir_scan_noverify(int in_num_fields, const scan_field_t *in_fields, tap_state_t state)
530
{
oharboe's avatar
oharboe committed
531
	int retval;
532
	jtag_prelude(state);
533

534
	retval=interface_jtag_add_ir_scan(in_num_fields, in_fields, cmd_queue_end_state);
oharboe's avatar
oharboe committed
535
536
	if (retval!=ERROR_OK)
		jtag_error=retval;
537
538
539
540

}


541
542
543
544
545
546
547
548
549
/**
 * Generate an IR SCAN with a list of scan fields with one entry for each enabled TAP.
 *
 * If the input field list contains an instruction value for a TAP then that is used
 * otherwise the TAP is set to bypass.
 *
 * TAPs for which no fields are passed are marked as bypassed for subsequent DR SCANs.
 *
 */
550
void jtag_add_ir_scan(int in_num_fields, scan_field_t *in_fields, tap_state_t state)
551
{
oharboe's avatar
oharboe committed
552
	if (jtag_verify&&jtag_verify_capture_ir)
553
	{
zwelch's avatar
zwelch committed
554
		/* 8 x 32 bit id's is enough for all invocations */
555
556

		for (int j = 0; j < in_num_fields; j++)
557
		{
oharboe's avatar
oharboe committed
558
559
560
			/* if we are to run a verification of the ir scan, we need to get the input back.
			 * We may have to allocate space if the caller didn't ask for the input back.
			 */
561
562
			in_fields[j].check_value=in_fields[j].tap->expected;
			in_fields[j].check_mask=in_fields[j].tap->expected_mask;
563
		}
564
		jtag_add_scan_check(jtag_add_ir_scan_noverify, in_num_fields, in_fields, state);
oharboe's avatar
oharboe committed
565
566
	} else
	{
567
		jtag_add_ir_scan_noverify(in_num_fields, in_fields, state);
568
	}
oharboe's avatar
oharboe committed
569
570
}

571
572
573
574
575
576
/**
 * Duplicate the scan fields passed into the function into an IR SCAN command
 *
 * This function assumes that the caller handles extra fields for bypassed TAPs
 *
 */
577
void jtag_add_plain_ir_scan(int in_num_fields, const scan_field_t *in_fields, tap_state_t state)
578
{
oharboe's avatar
oharboe committed
579
	int retval;
580

581
	jtag_prelude(state);
582

583
	retval=interface_jtag_add_plain_ir_scan(in_num_fields, in_fields, cmd_queue_end_state);
584
585
	if (retval!=ERROR_OK)
		jtag_error=retval;
586
587
}

588

589
590
591
592
593
594
595
596

int jtag_check_value_inner(u8 *captured, u8 *in_check_value, u8 *in_check_mask, int num_bits);

static int jtag_check_value_mask_callback(u8 *in, jtag_callback_data_t data1, jtag_callback_data_t data2, jtag_callback_data_t data3)
{
	return jtag_check_value_inner(in, (u8 *)data1, (u8 *)data2, (int)data3);
}

597
static void jtag_add_scan_check(void (*jtag_add_scan)(int in_num_fields, const scan_field_t *in_fields, tap_state_t state),
598
		int in_num_fields, scan_field_t *in_fields, tap_state_t state)
599
{
600
	for (int i = 0; i < in_num_fields; i++)
601
	{
602
603
604
605
606
607
608
		struct scan_field_s *field = &in_fields[i];
		field->allocated = 0;
		field->modified = 0;
		if (field->check_value || field->in_value)
			continue;
		interface_jtag_add_scan_check_alloc(field);
		field->modified = 1;
609
610
	}

611
	jtag_add_scan(in_num_fields, in_fields, state);
612

613
	for (int i = 0; i < in_num_fields; i++)
614
	{
615
		if ((in_fields[i].check_value != NULL) && (in_fields[i].in_value != NULL))
616
617
		{
			/* this is synchronous for a minidriver */
618
619
620
621
			jtag_add_callback4(jtag_check_value_mask_callback, in_fields[i].in_value,
				(jtag_callback_data_t)in_fields[i].check_value,
				(jtag_callback_data_t)in_fields[i].check_mask,
				(jtag_callback_data_t)in_fields[i].num_bits);
622
		}
623
		if (in_fields[i].allocated)
624
		{
625
			free(in_fields[i].in_value);
626
		}
627
		if (in_fields[i].modified)
628
		{
629
			in_fields[i].in_value = NULL;
630
631
		}
	}
632
}
633

634
void jtag_add_dr_scan_check(int in_num_fields, scan_field_t *in_fields, tap_state_t state)
635
{
oharboe's avatar
oharboe committed
636
637
	if (jtag_verify)
	{
638
		jtag_add_scan_check(jtag_add_dr_scan, in_num_fields, in_fields, state);
oharboe's avatar
oharboe committed
639
640
	} else
	{
641
		jtag_add_dr_scan(in_num_fields, in_fields, state);
oharboe's avatar
oharboe committed
642
	}
643
644
}

645
646
647
648
649
650
651
652
653
654

/**
 * Generate a DR SCAN using the fields passed to the function
 *
 * For not bypassed TAPs the function checks in_fields and uses fields specified there.
 * For bypassed TAPs the function generates a dummy 1bit field.
 *
 * The bypass status of TAPs is set by jtag_add_ir_scan().
 *
 */
655
void jtag_add_dr_scan(int in_num_fields, const scan_field_t *in_fields, tap_state_t state)
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
{
	int retval;

	jtag_prelude(state);

	retval=interface_jtag_add_dr_scan(in_num_fields, in_fields, cmd_queue_end_state);
	if (retval!=ERROR_OK)
		jtag_error=retval;
}



/**
 * Duplicate the scan fields passed into the function into a DR SCAN command
 *
 * This function assumes that the caller handles extra fields for bypassed TAPs
 *
 */
674
void jtag_add_plain_dr_scan(int in_num_fields, const scan_field_t *in_fields, tap_state_t state)
675
{
oharboe's avatar
oharboe committed
676
	int retval;
677

678
	jtag_prelude(state);
679

680
	retval=interface_jtag_add_plain_dr_scan(in_num_fields, in_fields, cmd_queue_end_state);
681
682
	if (retval!=ERROR_OK)
		jtag_error=retval;
683
684
}

685
686


687
void jtag_add_tlr(void)
688
{
689
	jtag_prelude(TAP_RESET);
690

691
	int retval;
692
	retval=interface_jtag_add_tlr();
693
694
	if (retval!=ERROR_OK)
		jtag_error=retval;
oharboe's avatar
oharboe committed
695
696
}

697
void jtag_add_pathmove(int num_states, const tap_state_t *path)
698
{
699
	tap_state_t cur_state = cmd_queue_cur_state;
oharboe's avatar
oharboe committed
700
701
702
	int i;
	int retval;

703
	/* the last state has to be a stable state */
704
	if (!tap_is_state_stable(path[num_states - 1]))
705
	{
706
		LOG_ERROR("BUG: TAP path doesn't finish in a stable state");
707
		exit(-1);
708
	}
709
710
711

	for (i=0; i<num_states; i++)
	{
712
		if (path[i] == TAP_RESET)
713
		{
714
			LOG_ERROR("BUG: TAP_RESET is not a valid state for pathmove sequences");
715
716
			exit(-1);
		}
717

718
719
		if ( tap_state_transition(cur_state, true)  != path[i]
		  && tap_state_transition(cur_state, false) != path[i])
720
		{
721
			LOG_ERROR("BUG: %s -> %s isn't a valid TAP transition", tap_state_name(cur_state), tap_state_name(path[i]));
722
723
724
725
			exit(-1);
		}
		cur_state = path[i];
	}
726

727
	jtag_prelude1();
728

729
	retval = interface_jtag_add_pathmove(num_states, path);
730
	cmd_queue_cur_state = path[num_states - 1];
731
732
	if (retval!=ERROR_OK)
		jtag_error=retval;
733
734
}

735
void jtag_add_runtest(int num_cycles, tap_state_t state)
oharboe's avatar
oharboe committed
736
{
oharboe's avatar
oharboe committed
737
	int retval;
738

739
	jtag_prelude(state);
740

oharboe's avatar
oharboe committed
741
	/* executed by sw or hw fifo */
oharboe's avatar
oharboe committed
742
	retval=interface_jtag_add_runtest(num_cycles, cmd_queue_end_state);
743
744
	if (retval!=ERROR_OK)
		jtag_error=retval;
745
746
}

747
748
749
750
751

void jtag_add_clocks( int num_cycles )
{
	int retval;

752
	if( !tap_is_state_stable(cmd_queue_cur_state) )
753
754
	{
		 LOG_ERROR( "jtag_add_clocks() was called with TAP in non-stable state \"%s\"",
755
				 tap_state_name(cmd_queue_cur_state) );
756
757
758
		 jtag_error = ERROR_JTAG_NOT_STABLE_STATE;
		 return;
	}
759

760
761
762
763
	if( num_cycles > 0 )
	{
		jtag_prelude1();

764
765
		retval = interface_jtag_add_clocks(num_cycles);
		if (retval != ERROR_OK)
766
767
			jtag_error=retval;
	}
768
769
}

770
void jtag_add_reset(int req_tlr_or_trst, int req_srst)
771
{
772
	int trst_with_tlr = 0;
oharboe's avatar
oharboe committed
773
	int retval;
774

775
776
	/* FIX!!! there are *many* different cases here. A better
	 * approach is needed for legal combinations of transitions...
oharboe's avatar
oharboe committed
777
	 */
778
	if ((jtag_reset_config & RESET_HAS_SRST)&&
779
			(jtag_reset_config & RESET_HAS_TRST)&&
780
			((jtag_reset_config & RESET_SRST_PULLS_TRST)==0))
781
782
783
784
785
786
	{
		if (((req_tlr_or_trst&&!jtag_trst)||
				(!req_tlr_or_trst&&jtag_trst))&&
				((req_srst&&!jtag_srst)||
						(!req_srst&&jtag_srst)))
		{
oharboe's avatar
oharboe committed
787
			/* FIX!!! srst_pulls_trst allows 1,1 => 0,0 transition.... */
788
			//LOG_ERROR("BUG: transition of req_tlr_or_trst and req_srst in the same jtag_add_reset() call is undefined");
789
790
		}
	}
791

792
793
	/* Make sure that jtag_reset_config allows the requested reset */
	/* if SRST pulls TRST, we can't fulfill srst == 1 with trst == 0 */
794
	if (((jtag_reset_config & RESET_SRST_PULLS_TRST) && (req_srst == 1)) && (!req_tlr_or_trst))
oharboe's avatar
oharboe committed
795
	{
796
797
798
		LOG_ERROR("BUG: requested reset would assert trst");
		jtag_error=ERROR_FAIL;
		return;
oharboe's avatar
oharboe committed
799
	}
800

801
	/* if TRST pulls SRST, we reset with TAP T-L-R */
802
	if (((jtag_reset_config & RESET_TRST_PULLS_SRST) && (req_tlr_or_trst)) && (req_srst == 0))
803
	{
804
		trst_with_tlr = 1;
805
	}
806

807
808
	if (req_srst && !(jtag_reset_config & RESET_HAS_SRST))
	{
809
		LOG_ERROR("BUG: requested SRST assertion, but the current configuration doesn't support this");
810
811
		jtag_error=ERROR_FAIL;
		return;
812
	}
813

814
	if (req_tlr_or_trst)
815
	{
816
		if (!trst_with_tlr && (jtag_reset_config & RESET_HAS_TRST))
817
818
819
820
		{
			jtag_trst = 1;
		} else
		{
821
			trst_with_tlr = 1;
822
823
824
825
		}
	} else
	{
		jtag_trst = 0;
826
	}
827

828
829
	jtag_srst = req_srst;

830
	retval = interface_jtag_add_reset(jtag_trst, jtag_srst);
831
832
833
	if (retval!=ERROR_OK)
	{
		jtag_error=retval;
834
		return;
835
	}
836
	jtag_execute_queue();
837

838
839
	if (jtag_srst)
	{
840
		LOG_DEBUG("SRST line asserted");
841
842
843
	}
	else
	{
844
		LOG_DEBUG("SRST line released");
845
846
847
		if (jtag_nsrst_delay)
			jtag_add_sleep(jtag_nsrst_delay * 1000);
	}
848

849
	if (trst_with_tlr)
850
	{
851
		LOG_DEBUG("JTAG reset with RESET instead of TRST");
852
		jtag_add_end_state(TAP_RESET);
853
		jtag_add_tlr();
854
		jtag_call_event_callbacks(JTAG_TRST_ASSERTED);
855
		return;
856
	}
857

858
	if (jtag_trst)
oharboe's avatar
oharboe committed
859
	{
860
861
862
		/* we just asserted nTRST, so we're now in Test-Logic-Reset,
		 * and inform possible listeners about this
		 */
863
		LOG_DEBUG("TRST line asserted");
864
		tap_set_state(TAP_RESET);
865
866
867
868
869
870
		jtag_call_event_callbacks(JTAG_TRST_ASSERTED);
	}
	else
	{
		if (jtag_ntrst_delay)
			jtag_add_sleep(jtag_ntrst_delay * 1000);
oharboe's avatar
oharboe committed
871
872
873
	}
}

874
void jtag_add_end_state(tap_state_t state)
875
{
876
	cmd_queue_end_state = state;
877
	if ((cmd_queue_end_state == TAP_DRSHIFT)||(cmd_queue_end_state == TAP_IRSHIFT))
878
	{
879
		LOG_ERROR("BUG: TAP_DRSHIFT/IRSHIFT can't be end state. Calling code should use a larger scan field");
880
	}
881
882
}

883
void jtag_add_sleep(u32 us)
884
{
oharboe's avatar
oharboe committed
885
	keep_alive(); /* we might be running on a very slow JTAG clk */
886
887
888
889
	int retval=interface_jtag_add_sleep(us);
	if (retval!=ERROR_OK)
		jtag_error=retval;
	return;
890
891
}

892
int jtag_scan_size(const scan_command_t *cmd)
893
894
895
896
897
898
899
900
901
902
903
904
905
{
	int bit_count = 0;
	int i;

	/* count bits in scan command */
	for (i = 0; i < cmd->num_fields; i++)
	{
		bit_count += cmd->fields[i].num_bits;
	}

	return bit_count;
}

906
int jtag_build_buffer(const scan_command_t *cmd, u8 **buffer)
907
908
909
{
	int bit_count = 0;
	int i;
910

911
	bit_count = jtag_scan_size(cmd);
912
	*buffer = calloc(1,CEIL(bit_count, 8));
913

914
915
	bit_count = 0;

916
#ifdef _DEBUG_JTAG_IO_
917
	LOG_DEBUG("%s num_fields: %i", cmd->ir_scan ? "IRSCAN" : "DRSCAN", cmd->num_fields);
918
#endif
919

920
921
922
923
924
	for (i = 0; i < cmd->num_fields; i++)
	{
		if (cmd->fields[i].out_value)
		{
#ifdef _DEBUG_JTAG_IO_
925
			char* char_buf = buf_to_str(cmd->fields[i].out_value, (cmd->fields[i].num_bits > DEBUG_JTAG_IOZ) ? DEBUG_JTAG_IOZ : cmd->fields[i].num_bits, 16);
926
927
928
#endif
			buf_set_buf(cmd->fields[i].out_value, 0, *buffer, bit_count, cmd->fields[i].num_bits);
#ifdef _DEBUG_JTAG_IO_
929
			LOG_DEBUG("fields[%i].out_value[%i]: 0x%s", i, cmd->fields[i].num_bits, char_buf);
930
931
932
			free(char_buf);
#endif
		}
933
934
935
936
937
938
		else
		{
#ifdef _DEBUG_JTAG_IO_
			LOG_DEBUG("fields[%i].out_value[%i]: NULL", i, cmd->fields[i].num_bits);
#endif
		}
939

940
941
942
		bit_count += cmd->fields[i].num_bits;
	}

943
944
945
946
#ifdef _DEBUG_JTAG_IO_
	//LOG_DEBUG("bit_count totalling: %i",  bit_count );
#endif

947
948
949
	return bit_count;
}

950
int jtag_read_buffer(u8 *buffer, const scan_command_t *cmd)
951
952
953
954
{
	int i;
	int bit_count = 0;
	int retval;
955

956
957
	/* we return ERROR_OK, unless a check fails, or a handler reports a problem */
	retval = ERROR_OK;
958

959
960
961
962
963
	for (i = 0; i < cmd->num_fields; i++)
	{
		/* if neither in_value nor in_handler
		 * are specified we don't have to examine this field
		 */
964
		if (cmd->fields[i].in_value)
965
966
967
		{
			int num_bits = cmd->fields[i].num_bits;
			u8 *captured = buf_set_buf(buffer, bit_count, malloc(CEIL(num_bits, 8)), 0, num_bits);
968

969
#ifdef _DEBUG_JTAG_IO_
970
			char *char_buf = buf_to_str(captured, (num_bits > DEBUG_JTAG_IOZ) ? DEBUG_JTAG_IOZ : num_bits, 16);
971
			LOG_DEBUG("fields[%i].in_value[%i]: 0x%s", i, num_bits, char_buf);
972
973
			free(char_buf);
#endif
974

975
976
977
978
979
980
981
982
983
984
985
986
987
			if (cmd->fields[i].in_value)
			{
				buf_cpy(captured, cmd->fields[i].in_value, num_bits);
			}

			free(captured);
		}
		bit_count += cmd->fields[i].num_bits;
	}

	return retval;
}

988
static const char *jtag_tap_name(const jtag_tap_t *tap)
oharboe's avatar
oharboe committed
989
990
991
992
{
	return (tap == NULL) ? "(unknown)" : tap->dotted_name;
}