jtag.c 70.6 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
7
 *   oyvind.harboe@zylin.com                                               *
 *                                                                         *
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
 *   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

#include "replacements.h"

#include "jtag.h"

#include "command.h"
#include "log.h"

#include "stdlib.h"
#include "string.h"
#include <unistd.h>

38
39
/* 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
40
*/
41
int jtag_error=ERROR_OK;
oharboe's avatar
oharboe committed
42
43


44
45
char* tap_state_strings[16] =
{
46
	"tlr",
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
	"sds", "cd", "sd", "e1d", "pd", "e2d", "ud",
	"rti",
	"sis", "ci", "si", "e1i", "pi", "e2i", "ui"
};

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;

/* tap_move[i][j]: tap movement command to go from state i to state j
 * 0: Test-Logic-Reset
 * 1: Run-Test/Idle
 * 2: Shift-DR
 * 3: Pause-DR
 * 4: Shift-IR
 * 5: Pause-IR
69
 *
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
 * SD->SD and SI->SI have to be caught in interface specific code
 */
u8 tap_move[6][6] =
{
/*	  TLR   RTI   SD    PD    SI    PI             */
	{0x7f, 0x00, 0x17, 0x0a, 0x1b, 0x16},	/* TLR */
	{0x7f, 0x00, 0x25, 0x05, 0x2b, 0x0b},	/* RTI */
	{0x7f, 0x31, 0x00, 0x01, 0x0f, 0x2f},	/* SD  */
	{0x7f, 0x30, 0x20, 0x17, 0x1e, 0x2f},	/* PD  */
	{0x7f, 0x31, 0x07, 0x17, 0x00, 0x01},	/* SI  */
	{0x7f, 0x30, 0x1c, 0x17, 0x20, 0x2f}	/* PI  */
};

int tap_move_map[16] = {
	0, -1, -1,  2, -1,  3, -1, -1,
	1, -1, -1,  4, -1,  5, -1, -1
};

tap_transition_t tap_transitions[16] =
{
	{TAP_TLR, TAP_RTI},		/* TLR */
	{TAP_SIS, TAP_CD},		/* SDS */
	{TAP_E1D, TAP_SD},		/* CD  */
	{TAP_E1D, TAP_SD},		/* SD  */
	{TAP_UD,  TAP_PD}, 		/* E1D */
	{TAP_E2D, TAP_PD},		/* PD  */
	{TAP_UD,  TAP_SD},		/* E2D */
	{TAP_SDS, TAP_RTI},		/* UD  */
	{TAP_SDS, TAP_RTI},		/* RTI */
	{TAP_TLR, TAP_CI},		/* SIS */
	{TAP_E1I, TAP_SI},		/* CI  */
	{TAP_E1I, TAP_SI},		/* SI  */
	{TAP_UI,  TAP_PI}, 		/* E1I */
	{TAP_E2I, TAP_PI},		/* PI  */
	{TAP_UI,  TAP_SI},		/* E2I */
	{TAP_SDS, TAP_RTI}		/* UI  */
};

char* jtag_event_strings[] =
{
oharboe's avatar
oharboe committed
110
	"JTAG controller reset (TLR or TRST)"
111
112
};

113
114
115
116
117
/* kludge!!!! these are just global variables that the
 * interface use internally. They really belong
 * inside the drivers, but we don't want to break
 * linking the drivers!!!!
 */
118
119
120
121
122
123
124
enum tap_state end_state = TAP_TLR;
enum tap_state cur_state = TAP_TLR;
int jtag_trst = 0;
int jtag_srst = 0;

jtag_command_t *jtag_command_queue = NULL;
jtag_command_t **last_comand_pointer = &jtag_command_queue;
125
126
static jtag_tap_t *jtag_all_taps = NULL;

127
128
129
130
131
132
133
134
enum reset_types jtag_reset_config = RESET_NONE;
enum tap_state cmd_queue_end_state = TAP_TLR;
enum tap_state cmd_queue_cur_state = TAP_TLR;

int jtag_verify_capture_ir = 1;

/* how long the OpenOCD should wait before attempting JTAG communication after reset lines deasserted (in ms) */
int jtag_nsrst_delay = 0; /* default to no nSRST delay */
135
int jtag_ntrst_delay = 0; /* default to no nTRST delay */
136
137
138

/* maximum number of JTAG devices expected in the chain
 */
139
#define JTAG_MAX_CHAIN_SIZE 20
140
141
142
143

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

oharboe's avatar
   
oharboe committed
144
/* speed in kHz*/
oharboe's avatar
   
oharboe committed
145
static int speed_khz = 0;
oharboe's avatar
   
oharboe committed
146
147
148
/* flag if the kHz speed was defined */
static int hasKHz = 0;

149
150
/* jtag interfaces (parport, FTDI-USB, TI-USB, ...)
 */
151

152
#if BUILD_ECOSBOARD == 1
153
	extern jtag_interface_t zy1000_interface;
154
#endif
155

156
157
158
#if BUILD_PARPORT == 1
	extern jtag_interface_t parport_interface;
#endif
159

160
161
162
#if BUILD_DUMMY == 1
	extern jtag_interface_t dummy_interface;
#endif
163

164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
#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

196
197
198
199
#if BUILD_JLINK == 1
	extern jtag_interface_t jlink_interface;
#endif

200
jtag_interface_t *jtag_interfaces[] = {
201
#if BUILD_ECOSBOARD == 1
202
	&zy1000_interface,
203
#endif
204
205
206
#if BUILD_PARPORT == 1
	&parport_interface,
#endif
207
208
209
#if BUILD_DUMMY == 1
	&dummy_interface,
#endif
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
#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,
233
234
235
#endif
#if BUILD_JLINK == 1
	&jlink_interface,
236
237
238
239
240
241
242
243
244
#endif
	NULL,
};

jtag_interface_t *jtag = NULL;

/* configuration */
jtag_interface_t *jtag_interface = NULL;
int jtag_speed = 0;
oharboe's avatar
   
oharboe committed
245

246
247
248


/* forward declarations */
249
250
251
252
void jtag_add_pathmove(int num_states, enum tap_state *path);
void jtag_add_runtest(int num_cycles, enum tap_state endstate);
void jtag_add_end_state(enum tap_state endstate);
void jtag_add_sleep(u32 us);
253
int jtag_execute_queue(void);
254

255
256
257
258

/* jtag commands */
int handle_interface_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
int handle_jtag_speed_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
259
int handle_jtag_khz_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
260
261
262
263
264
265
266
267
268
269
270
int handle_jtag_device_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
int handle_reset_config_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
int handle_jtag_nsrst_delay_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
int handle_jtag_ntrst_delay_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);

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

int handle_endstate_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
int handle_jtag_reset_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
int handle_runtest_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
int handle_irscan_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
oharboe's avatar
oharboe committed
271
int Jim_Command_drscan(Jim_Interp *interp, int argc, Jim_Obj *const *argv);
272
273
274

int handle_verify_ircapture_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);

275

oharboe's avatar
oharboe committed
276
277
278
jtag_tap_t *jtag_AllTaps(void)
{
  return jtag_all_taps;
279
280
};

oharboe's avatar
oharboe committed
281
int
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
jtag_NumTotalTaps(void)
{
	jtag_tap_t *t;
	int n;

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

int
jtag_NumEnabledTaps(void)
{
	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();
	// try name first
	while(t){
		if( 0 == strcmp( t->dotted_name, s ) ){
			break;
		} else {
			t = t->next_tap;
		}
	}
	// backup plan is by number
	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;
}

jtag_tap_t *
jtag_TapByJimObj( Jim_Interp *interp, Jim_Obj *o )
{
	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
353
	}
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
	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 */
jtag_tap_t *
jtag_TapByAbsPosition( int n )
{
	int orig_n;
	jtag_tap_t *t;

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

370
371
372
373
374
375
376
377
	while( t && (n > 0)) {
		n--;
		t = t->next_tap;
    }
	return t;
}


378
379
380
int jtag_register_event_callback(int (*callback)(enum jtag_event event, void *priv), void *priv)
{
	jtag_event_callback_t **callbacks_p = &jtag_event_callbacks;
381

382
383
384
385
	if (callback == NULL)
	{
		return ERROR_INVALID_ARGUMENTS;
	}
386

387
388
389
390
391
392
	if (*callbacks_p)
	{
		while ((*callbacks_p)->next)
			callbacks_p = &((*callbacks_p)->next);
		callbacks_p = &((*callbacks_p)->next);
	}
393

394
395
396
397
	(*callbacks_p) = malloc(sizeof(jtag_event_callback_t));
	(*callbacks_p)->callback = callback;
	(*callbacks_p)->priv = priv;
	(*callbacks_p)->next = NULL;
398

399
400
401
402
403
404
	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;
405

406
407
408
409
	if (callback == NULL)
	{
		return ERROR_INVALID_ARGUMENTS;
	}
410

411
412
413
414
415
416
417
418
419
420
	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;
	}
421

422
423
424
425
426
427
	return ERROR_OK;
}

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

429
	LOG_DEBUG("jtag event: %s", jtag_event_strings[event]);
430

431
432
433
434
435
	while (callback)
	{
		callback->callback(event, callback->priv);
		callback = callback->next;
	}
436

437
438
439
440
441
442
443
444
445
446
	return ERROR_OK;
}

/* returns a pointer to the pointer of the last command in queue
 * this may be a pointer to the root pointer (jtag_command_queue)
 * or to the next member of the last but one command
 */
jtag_command_t** jtag_get_last_command_p(void)
{
/*	jtag_command_t *cmd = jtag_command_queue;
447

448
449
450
451
452
	if (cmd)
		while (cmd->next)
			cmd = cmd->next;
	else
		return &jtag_command_queue;
453

454
	return &cmd->next;*/
455

456
457
458
459
460
461
462
463
	return last_comand_pointer;
}


void* cmd_queue_alloc(size_t size)
{
	cmd_queue_page_t **p_page = &cmd_queue_pages;
	int offset;
oharboe's avatar
oharboe committed
464
	u8 *t;
465

466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
	/*
	 * 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
	 * to align by... 
	 *
	 * The solution here, is based on these suggestions.
	 * http://gcc.gnu.org/ml/gcc-help/2008-12/msg00041.html
	 *
	 */
	union worse_case_align {
	  int i;
	  long l;
	  float f;
	  void *v;
	};
#define ALIGN_SIZE  (sizeof(union worse_case_align))

	// The alignment process.
	size = (size + ALIGN_SIZE -1) & (~(ALIGN_SIZE-1));
	// Done... 
	

499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
	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;
517

oharboe's avatar
oharboe committed
518
	t=(u8 *)((*p_page)->address);
519
520
521
	return t + offset;
}

oharboe's avatar
oharboe committed
522
void cmd_queue_free(void)
523
524
525
526
527
528
529
530
531
532
533
534
535
536
{
	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;
}

oharboe's avatar
oharboe committed
537
static void jtag_prelude1(void)
538
539
540
{
	if (jtag_trst == 1)
	{
541
		LOG_WARNING("JTAG command queued, while TRST is low (TAP in reset)");
oharboe's avatar
oharboe committed
542
		jtag_error=ERROR_JTAG_TRST_ASSERTED;
543
		return;
544
545
	}

oharboe's avatar
oharboe committed
546
547
	if (cmd_queue_end_state == TAP_TLR)
		jtag_call_event_callbacks(JTAG_TRST_ASSERTED);
548
549
550
551
552
}

static void jtag_prelude(enum tap_state state)
{
	jtag_prelude1();
553

554
	if (state != -1)
555
		jtag_add_end_state(state);
556

oharboe's avatar
oharboe committed
557
	cmd_queue_cur_state = cmd_queue_end_state;
558
559
560
561
}

void jtag_add_ir_scan(int num_fields, scan_field_t *fields, enum tap_state state)
{
oharboe's avatar
oharboe committed
562
	int retval;
563

564
	jtag_prelude(state);
565

oharboe's avatar
oharboe committed
566
	retval=interface_jtag_add_ir_scan(num_fields, fields, cmd_queue_end_state);
oharboe's avatar
oharboe committed
567
568
569
570
	if (retval!=ERROR_OK)
		jtag_error=retval;
}

oharboe's avatar
oharboe committed
571
int MINIDRIVER(interface_jtag_add_ir_scan)(int num_fields, scan_field_t *fields, enum tap_state state)
572
{
oharboe's avatar
oharboe committed
573
	jtag_command_t **last_cmd;
574
575
576
577
	jtag_tap_t *tap;
	int j;
	int x;
	int nth_tap;
oharboe's avatar
oharboe committed
578
579
580
	int scan_size = 0;


581
	last_cmd = jtag_get_last_command_p();
582

583
584
585
586
587
588
589
590
591
	/* allocate memory for a new list member */
	*last_cmd = cmd_queue_alloc(sizeof(jtag_command_t));
	(*last_cmd)->next = NULL;
	last_comand_pointer = &((*last_cmd)->next);
	(*last_cmd)->type = JTAG_SCAN;

	/* allocate memory for ir scan command */
	(*last_cmd)->cmd.scan = cmd_queue_alloc(sizeof(scan_command_t));
	(*last_cmd)->cmd.scan->ir_scan = 1;
592
593
594
	x = jtag_NumEnabledTaps();
	(*last_cmd)->cmd.scan->num_fields = x;	/* one field per device */
	(*last_cmd)->cmd.scan->fields = cmd_queue_alloc(x  * sizeof(scan_field_t));
595
596
	(*last_cmd)->cmd.scan->end_state = state;

597
598
599
	nth_tap = -1;
	tap = NULL;
	for(;;){
600
		int found = 0;
601
602
603
604
605

		// do this here so it is not forgotten
		tap = jtag_NextEnabledTap(tap);
		if( tap == NULL ){
			break;
606
		}
607
608
609
610
611
612
		nth_tap++;
		scan_size = tap->ir_length;
		(*last_cmd)->cmd.scan->fields[nth_tap].tap = tap;
		(*last_cmd)->cmd.scan->fields[nth_tap].num_bits = scan_size;
		(*last_cmd)->cmd.scan->fields[nth_tap].in_value = NULL;
		(*last_cmd)->cmd.scan->fields[nth_tap].in_handler = NULL;	/* disable verification by default */
613
614
615
616

		/* search the list */
		for (j = 0; j < num_fields; j++)
		{
617
			if (tap == fields[j].tap)
618
619
			{
				found = 1;
620
621
				(*last_cmd)->cmd.scan->fields[nth_tap].out_value = buf_cpy(fields[j].out_value, cmd_queue_alloc(CEIL(scan_size, 8)), scan_size);
				(*last_cmd)->cmd.scan->fields[nth_tap].out_mask = buf_cpy(fields[j].out_mask, cmd_queue_alloc(CEIL(scan_size, 8)), scan_size);
622

623
624
625
626
				if (jtag_verify_capture_ir)
				{
					if (fields[j].in_handler==NULL)
					{
627
						jtag_set_check_value((*last_cmd)->cmd.scan->fields+nth_tap, tap->expected, tap->expected_mask, NULL);
628
629
					} else
					{
630
631
632
633
						(*last_cmd)->cmd.scan->fields[nth_tap].in_handler = fields[j].in_handler;
						(*last_cmd)->cmd.scan->fields[nth_tap].in_handler_priv = fields[j].in_handler_priv;
						(*last_cmd)->cmd.scan->fields[nth_tap].in_check_value = tap->expected;
						(*last_cmd)->cmd.scan->fields[nth_tap].in_check_mask = tap->expected_mask;
634
635
					}
				}
636

637
				tap->bypass = 0;
638
639
640
				break;
			}
		}
641

642
643
		if (!found)
		{
644
645
646
647
			/* if a tap isn't listed, set it to BYPASS */
			(*last_cmd)->cmd.scan->fields[nth_tap].out_value = buf_set_ones(cmd_queue_alloc(CEIL(scan_size, 8)), scan_size);
			(*last_cmd)->cmd.scan->fields[nth_tap].out_mask = NULL;
			tap->bypass = 1;
648

649
		}
650

651
		/* update device information */
652
		buf_cpy((*last_cmd)->cmd.scan->fields[nth_tap].out_value, tap->cur_instr, scan_size);
653
	}
654

655
656
657
	return ERROR_OK;
}

658
void jtag_add_plain_ir_scan(int num_fields, scan_field_t *fields, enum tap_state state)
659
{
oharboe's avatar
oharboe committed
660
	int retval;
661

662
	jtag_prelude(state);
663

oharboe's avatar
oharboe committed
664
	retval=interface_jtag_add_plain_ir_scan(num_fields, fields, cmd_queue_end_state);
665
666
	if (retval!=ERROR_OK)
		jtag_error=retval;
667
668
}

oharboe's avatar
oharboe committed
669
int MINIDRIVER(interface_jtag_add_plain_ir_scan)(int num_fields, scan_field_t *fields, enum tap_state state)
670
671
672
{
	int i;
	jtag_command_t **last_cmd;
673

674
	last_cmd = jtag_get_last_command_p();
675

676
677
678
679
680
681
682
683
684
685
686
687
688
	/* allocate memory for a new list member */
	*last_cmd = cmd_queue_alloc(sizeof(jtag_command_t));
	(*last_cmd)->next = NULL;
	last_comand_pointer = &((*last_cmd)->next);
	(*last_cmd)->type = JTAG_SCAN;

	/* allocate memory for ir scan command */
	(*last_cmd)->cmd.scan = cmd_queue_alloc(sizeof(scan_command_t));
	(*last_cmd)->cmd.scan->ir_scan = 1;
	(*last_cmd)->cmd.scan->num_fields = num_fields;
	(*last_cmd)->cmd.scan->fields = cmd_queue_alloc(num_fields * sizeof(scan_field_t));
	(*last_cmd)->cmd.scan->end_state = state;

689
	for( i = 0 ; i < num_fields ; i++ ){
690
691
		int num_bits = fields[i].num_bits;
		int num_bytes = CEIL(fields[i].num_bits, 8);
692
		(*last_cmd)->cmd.scan->fields[i].tap = fields[i].tap;
693
694
695
696
697
698
699
700
701
702
703
704
		(*last_cmd)->cmd.scan->fields[i].num_bits = num_bits;
		(*last_cmd)->cmd.scan->fields[i].out_value = buf_cpy(fields[i].out_value, cmd_queue_alloc(num_bytes), num_bits);
		(*last_cmd)->cmd.scan->fields[i].out_mask = buf_cpy(fields[i].out_mask, cmd_queue_alloc(num_bytes), num_bits);
		(*last_cmd)->cmd.scan->fields[i].in_value = fields[i].in_value;
		(*last_cmd)->cmd.scan->fields[i].in_check_value = fields[i].in_check_value;
		(*last_cmd)->cmd.scan->fields[i].in_check_mask = fields[i].in_check_mask;
		(*last_cmd)->cmd.scan->fields[i].in_handler = NULL;
		(*last_cmd)->cmd.scan->fields[i].in_handler_priv = NULL;
	}
	return ERROR_OK;
}

705
void jtag_add_dr_scan(int num_fields, scan_field_t *fields, enum tap_state state)
706
{
oharboe's avatar
oharboe committed
707
	int retval;
708

709
	jtag_prelude(state);
710

oharboe's avatar
oharboe committed
711
	retval=interface_jtag_add_dr_scan(num_fields, fields, cmd_queue_end_state);
712
713
	if (retval!=ERROR_OK)
		jtag_error=retval;
714
715
}

oharboe's avatar
oharboe committed
716
int MINIDRIVER(interface_jtag_add_dr_scan)(int num_fields, scan_field_t *fields, enum tap_state state)
717
{
718
719
	int j;
	int nth_tap;
720
721
722
723
	int bypass_devices = 0;
	int field_count = 0;
	int scan_size;

724
	jtag_command_t **last_cmd = jtag_get_last_command_p();
725
	jtag_tap_t *tap;
726
727

	/* count devices in bypass */
728
729
730
731
732
733
734
735
	tap = NULL;
	bypass_devices = 0;
	for(;;){
		tap = jtag_NextEnabledTap(tap);
		if( tap == NULL ){
			break;
		}
		if( tap->bypass ){
736
			bypass_devices++;
737
		}
738
	}
739

740
741
742
743
744
745
746
747
748
749
750
751
	/* allocate memory for a new list member */
	*last_cmd = cmd_queue_alloc(sizeof(jtag_command_t));
	last_comand_pointer = &((*last_cmd)->next);
	(*last_cmd)->next = NULL;
	(*last_cmd)->type = JTAG_SCAN;

	/* allocate memory for dr scan command */
	(*last_cmd)->cmd.scan = cmd_queue_alloc(sizeof(scan_command_t));
	(*last_cmd)->cmd.scan->ir_scan = 0;
	(*last_cmd)->cmd.scan->num_fields = num_fields + bypass_devices;
	(*last_cmd)->cmd.scan->fields = cmd_queue_alloc((num_fields + bypass_devices) * sizeof(scan_field_t));
	(*last_cmd)->cmd.scan->end_state = state;
752

753
754
755
756
757
758
759
760
	tap = NULL;
	nth_tap = -1;
	for(;;){
		nth_tap++;
		tap = jtag_NextEnabledTap(tap);
		if( tap == NULL ){
			break;
		}
761
		int found = 0;
762
		(*last_cmd)->cmd.scan->fields[field_count].tap = tap;
763

764
765
		for (j = 0; j < num_fields; j++)
		{
766
			if (tap == fields[j].tap)
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
			{
				found = 1;
				scan_size = fields[j].num_bits;
				(*last_cmd)->cmd.scan->fields[field_count].num_bits = scan_size;
				(*last_cmd)->cmd.scan->fields[field_count].out_value = buf_cpy(fields[j].out_value, cmd_queue_alloc(CEIL(scan_size, 8)), scan_size);
				(*last_cmd)->cmd.scan->fields[field_count].out_mask = buf_cpy(fields[j].out_mask, cmd_queue_alloc(CEIL(scan_size, 8)), scan_size);
				(*last_cmd)->cmd.scan->fields[field_count].in_value = fields[j].in_value;
				(*last_cmd)->cmd.scan->fields[field_count].in_check_value = fields[j].in_check_value;
				(*last_cmd)->cmd.scan->fields[field_count].in_check_mask = fields[j].in_check_mask;
				(*last_cmd)->cmd.scan->fields[field_count].in_handler = fields[j].in_handler;
				(*last_cmd)->cmd.scan->fields[field_count++].in_handler_priv = fields[j].in_handler_priv;
			}
		}
		if (!found)
		{
782
#ifdef _DEBUG_JTAG_IO_
783
			/* if a device isn't listed, the BYPASS register should be selected */
784
			if (! tap->bypass)
785
			{
786
				LOG_ERROR("BUG: no scan data for a device not in BYPASS");
787
788
				exit(-1);
			}
789
#endif
790
791
792
793
794
795
796
797
798
799
800
801
			/* program the scan field to 1 bit length, and ignore it's value */
			(*last_cmd)->cmd.scan->fields[field_count].num_bits = 1;
			(*last_cmd)->cmd.scan->fields[field_count].out_value = NULL;
			(*last_cmd)->cmd.scan->fields[field_count].out_mask = NULL;
			(*last_cmd)->cmd.scan->fields[field_count].in_value = NULL;
			(*last_cmd)->cmd.scan->fields[field_count].in_check_value = NULL;
			(*last_cmd)->cmd.scan->fields[field_count].in_check_mask = NULL;
			(*last_cmd)->cmd.scan->fields[field_count].in_handler = NULL;
			(*last_cmd)->cmd.scan->fields[field_count++].in_handler_priv = NULL;
		}
		else
		{
802
#ifdef _DEBUG_JTAG_IO_
803
			/* if a device is listed, the BYPASS register must not be selected */
804
			if (tap->bypass)
805
			{
806
				LOG_ERROR("BUG: scan data for a device in BYPASS");
807
				exit(-1);
808
			}
809
#endif
810
811
812
813
814
		}
	}
	return ERROR_OK;
}

815
void MINIDRIVER(interface_jtag_add_dr_out)(jtag_tap_t *target_tap,
816
		int num_fields,
817
818
		const int *num_bits,
		const u32 *value,
819
820
		enum tap_state end_state)
{
821
	int nth_tap;
822
823
824
825
826
	int field_count = 0;
	int scan_size;
	int bypass_devices = 0;

	jtag_command_t **last_cmd = jtag_get_last_command_p();
827
828
	jtag_tap_t *tap;

829
	/* count devices in bypass */
830
831
832
833
834
835
836
837
	tap = NULL;
	bypass_devices = 0;
	for(;;){
		tap = jtag_NextEnabledTap(tap);
		if( tap == NULL ){
			break;
		}
		if( tap->bypass ){
838
			bypass_devices++;
839
		}
840
	}
841

842
843
844
845
846
847
848
849
850
851
852
853
	/* allocate memory for a new list member */
	*last_cmd = cmd_queue_alloc(sizeof(jtag_command_t));
	last_comand_pointer = &((*last_cmd)->next);
	(*last_cmd)->next = NULL;
	(*last_cmd)->type = JTAG_SCAN;

	/* allocate memory for dr scan command */
	(*last_cmd)->cmd.scan = cmd_queue_alloc(sizeof(scan_command_t));
	(*last_cmd)->cmd.scan->ir_scan = 0;
	(*last_cmd)->cmd.scan->num_fields = num_fields + bypass_devices;
	(*last_cmd)->cmd.scan->fields = cmd_queue_alloc((num_fields + bypass_devices) * sizeof(scan_field_t));
	(*last_cmd)->cmd.scan->end_state = end_state;
854

855
856
857
858
859
860
861
862
863
	tap = NULL;
	nth_tap = -1;
	for(;;){
		tap = jtag_NextEnabledTap(tap);
		if( tap == NULL ){
			break;
		}
		nth_tap++;
		(*last_cmd)->cmd.scan->fields[field_count].tap = tap;
864

865
		if (tap == target_tap)
866
867
868
869
		{
			int j;
#ifdef _DEBUG_JTAG_IO_
			/* if a device is listed, the BYPASS register must not be selected */
870
			if (tap->bypass)
871
			{
872
				LOG_ERROR("BUG: scan data for a device in BYPASS");
873
874
875
876
877
				exit(-1);
			}
#endif
			for (j = 0; j < num_fields; j++)
			{
oharboe's avatar
oharboe committed
878
				u8 out_value[4];
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
				scan_size = num_bits[j];
				buf_set_u32(out_value, 0, scan_size, value[j]);
				(*last_cmd)->cmd.scan->fields[field_count].num_bits = scan_size;
				(*last_cmd)->cmd.scan->fields[field_count].out_value = buf_cpy(out_value, cmd_queue_alloc(CEIL(scan_size, 8)), scan_size);
				(*last_cmd)->cmd.scan->fields[field_count].out_mask = NULL;
				(*last_cmd)->cmd.scan->fields[field_count].in_value = NULL;
				(*last_cmd)->cmd.scan->fields[field_count].in_check_value = NULL;
				(*last_cmd)->cmd.scan->fields[field_count].in_check_mask = NULL;
				(*last_cmd)->cmd.scan->fields[field_count].in_handler = NULL;
				(*last_cmd)->cmd.scan->fields[field_count++].in_handler_priv = NULL;
			}
		} else
		{
#ifdef _DEBUG_JTAG_IO_
			/* if a device isn't listed, the BYPASS register should be selected */
894
			if (! tap->bypass)
895
			{
896
				LOG_ERROR("BUG: no scan data for a device not in BYPASS");
897
898
				exit(-1);
			}
899
#endif
900
901
902
903
904
905
906
907
908
909
910
911
912
			/* program the scan field to 1 bit length, and ignore it's value */
			(*last_cmd)->cmd.scan->fields[field_count].num_bits = 1;
			(*last_cmd)->cmd.scan->fields[field_count].out_value = NULL;
			(*last_cmd)->cmd.scan->fields[field_count].out_mask = NULL;
			(*last_cmd)->cmd.scan->fields[field_count].in_value = NULL;
			(*last_cmd)->cmd.scan->fields[field_count].in_check_value = NULL;
			(*last_cmd)->cmd.scan->fields[field_count].in_check_mask = NULL;
			(*last_cmd)->cmd.scan->fields[field_count].in_handler = NULL;
			(*last_cmd)->cmd.scan->fields[field_count++].in_handler_priv = NULL;
		}
	}
}

913
void jtag_add_plain_dr_scan(int num_fields, scan_field_t *fields, enum tap_state state)
914
{
oharboe's avatar
oharboe committed
915
	int retval;
916

917
	jtag_prelude(state);
918

oharboe's avatar
oharboe committed
919
	retval=interface_jtag_add_plain_dr_scan(num_fields, fields, cmd_queue_end_state);
920
921
	if (retval!=ERROR_OK)
		jtag_error=retval;
922
923
}

oharboe's avatar
oharboe committed
924
int MINIDRIVER(interface_jtag_add_plain_dr_scan)(int num_fields, scan_field_t *fields, enum tap_state state)
925
926
927
{
	int i;
	jtag_command_t **last_cmd = jtag_get_last_command_p();
928

929
930
931
932
933
934
935
936
937
938
939
940
	/* allocate memory for a new list member */
	*last_cmd = cmd_queue_alloc(sizeof(jtag_command_t));
	last_comand_pointer = &((*last_cmd)->next);
	(*last_cmd)->next = NULL;
	(*last_cmd)->type = JTAG_SCAN;

	/* allocate memory for scan command */
	(*last_cmd)->cmd.scan = cmd_queue_alloc(sizeof(scan_command_t));
	(*last_cmd)->cmd.scan->ir_scan = 0;
	(*last_cmd)->cmd.scan->num_fields = num_fields;
	(*last_cmd)->cmd.scan->fields = cmd_queue_alloc(num_fields * sizeof(scan_field_t));
	(*last_cmd)->cmd.scan->end_state = state;
941

942
943
944
945
	for (i = 0; i < num_fields; i++)
	{
		int num_bits = fields[i].num_bits;
		int num_bytes = CEIL(fields[i].num_bits, 8);
946
		(*last_cmd)->cmd.scan->fields[i].tap = fields[i].tap;
947
948
949
950
951
952
953
954
955
956
957
958
		(*last_cmd)->cmd.scan->fields[i].num_bits = num_bits;
		(*last_cmd)->cmd.scan->fields[i].out_value = buf_cpy(fields[i].out_value, cmd_queue_alloc(num_bytes), num_bits);
		(*last_cmd)->cmd.scan->fields[i].out_mask = buf_cpy(fields[i].out_mask, cmd_queue_alloc(num_bytes), num_bits);
		(*last_cmd)->cmd.scan->fields[i].in_value = fields[i].in_value;
		(*last_cmd)->cmd.scan->fields[i].in_check_value = fields[i].in_check_value;
		(*last_cmd)->cmd.scan->fields[i].in_check_mask = fields[i].in_check_mask;
		(*last_cmd)->cmd.scan->fields[i].in_handler = fields[i].in_handler;
		(*last_cmd)->cmd.scan->fields[i].in_handler_priv = fields[i].in_handler_priv;
	}

	return ERROR_OK;
}
oharboe's avatar
oharboe committed
959

960
void jtag_add_tlr(void)
961
962
{
	jtag_prelude(TAP_TLR);
963

964
	int retval;
965
	retval=interface_jtag_add_tlr();
966
967
	if (retval!=ERROR_OK)
		jtag_error=retval;
oharboe's avatar
oharboe committed
968
969
}

970
int MINIDRIVER(interface_jtag_add_tlr)()
oharboe's avatar
oharboe committed
971
{
972
	enum tap_state state = TAP_TLR;
oharboe's avatar
oharboe committed
973
	jtag_command_t **last_cmd = jtag_get_last_command_p();
974

oharboe's avatar
oharboe committed
975
976
977
978
979
980
981
982
	/* allocate memory for a new list member */
	*last_cmd = cmd_queue_alloc(sizeof(jtag_command_t));
	last_comand_pointer = &((*last_cmd)->next);
	(*last_cmd)->next = NULL;
	(*last_cmd)->type = JTAG_STATEMOVE;

	(*last_cmd)->cmd.statemove = cmd_queue_alloc(sizeof(statemove_command_t));
	(*last_cmd)->cmd.statemove->end_state = state;
983
984


985
986
987
	return ERROR_OK;
}

988
void jtag_add_pathmove(int num_states, enum tap_state *path)
989
{
oharboe's avatar
oharboe committed
990
991
992
993
	enum tap_state cur_state=cmd_queue_cur_state;
	int i;
	int retval;

994
995
996
	/* the last state has to be a stable state */
	if (tap_move_map[path[num_states - 1]] == -1)
	{
997
		LOG_ERROR("BUG: TAP path doesn't finish in a stable state");
998
		exit(-1);
999
	}
1000

For faster browsing, not all history is shown. View entire blame