jtag.c 91.1 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
9
10
 *                                                                         *
 *   Copyright (C) 2009 SoftPLC Corporation                                *
 * 	 http://softplc.com                                                    *
 *   dick@softplc.com                                                      *
11
 *                                                                         *
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
 *   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 "jtag.h"

33
34
35
#ifdef HAVE_STRINGS_H
#include <strings.h>
#endif
36

37

38
int jtag_flush_queue_count; /* count # of flushes for profiling / debugging purposes */
39

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

43
44
/* 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
45
*/
46
int jtag_error=ERROR_OK;
oharboe's avatar
oharboe committed
47

48
49
50
51
52
53
54
55
56
57
58
59
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[] =
{
60
	"JTAG controller reset (RESET or TRST)"
61
62
};

63
64
65
66
67
68
69
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 }
};

70
71
72
int jtag_trst = 0;
int jtag_srst = 0;

73
74
75
76
77
78
79
80
81
#ifndef HAVE_JTAG_MINIDRIVER_H
struct jtag_callback_entry
{
	struct jtag_callback_entry *next;

	jtag_callback_t callback;
	u8 *in;
	jtag_callback_data_t data1;
	jtag_callback_data_t data2;
82
	jtag_callback_data_t data3;
83
84
85
86
87
88
89
90
};


static struct jtag_callback_entry *jtag_callback_queue_head = NULL;
static struct jtag_callback_entry *jtag_callback_queue_tail = NULL;
#endif


91
jtag_command_t *jtag_command_queue = NULL;
92
jtag_command_t **last_command_pointer = &jtag_command_queue;
93
94
static jtag_tap_t *jtag_all_taps = NULL;

95
enum reset_types jtag_reset_config = RESET_NONE;
96
97
tap_state_t cmd_queue_end_state = TAP_RESET;
tap_state_t cmd_queue_cur_state = TAP_RESET;
98
99

int jtag_verify_capture_ir = 1;
oharboe's avatar
oharboe committed
100
int jtag_verify = 1;
101
102

/* how long the OpenOCD should wait before attempting JTAG communication after reset lines deasserted (in ms) */
103
104
static int jtag_nsrst_delay = 0; /* default to no nSRST delay */
static int jtag_ntrst_delay = 0; /* default to no nTRST delay */
105
106
107

/* maximum number of JTAG devices expected in the chain
 */
108
#define JTAG_MAX_CHAIN_SIZE 20
109
110
111
112

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

oharboe's avatar
   
oharboe committed
113
/* speed in kHz*/
oharboe's avatar
   
oharboe committed
114
static int speed_khz = 0;
oharboe's avatar
   
oharboe committed
115
116
117
/* flag if the kHz speed was defined */
static int hasKHz = 0;

118
119
/* jtag interfaces (parport, FTDI-USB, TI-USB, ...)
 */
120

121
#if BUILD_ECOSBOARD == 1
122
	extern jtag_interface_t zy1000_interface;
123
#endif
124

125
126
127
#if BUILD_PARPORT == 1
	extern jtag_interface_t parport_interface;
#endif
128

129
130
131
#if BUILD_DUMMY == 1
	extern jtag_interface_t dummy_interface;
#endif
132

133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
#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

165
166
167
168
#if BUILD_JLINK == 1
	extern jtag_interface_t jlink_interface;
#endif

duane's avatar
duane committed
169
170
171
172
#if BUILD_VSLLINK == 1
	extern jtag_interface_t vsllink_interface;
#endif

173
174
175
176
#if BUILD_RLINK == 1
	extern jtag_interface_t rlink_interface;
#endif

177
178
179
180
#if BUILD_ARMJTAGEW == 1
	extern jtag_interface_t armjtagew_interface;
#endif

181
jtag_interface_t *jtag_interfaces[] = {
182
#if BUILD_ECOSBOARD == 1
183
	&zy1000_interface,
184
#endif
185
186
187
#if BUILD_PARPORT == 1
	&parport_interface,
#endif
188
189
190
#if BUILD_DUMMY == 1
	&dummy_interface,
#endif
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
#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,
214
215
216
#endif
#if BUILD_JLINK == 1
	&jlink_interface,
217
#endif
duane's avatar
duane committed
218
219
220
#if BUILD_VSLLINK == 1
	&vsllink_interface,
#endif
221
222
#if BUILD_RLINK == 1
	&rlink_interface,
223
224
225
#endif
#if BUILD_ARMJTAGEW == 1
	&armjtagew_interface,
226
227
228
229
230
231
232
#endif
	NULL,
};

jtag_interface_t *jtag = NULL;

/* configuration */
233
static jtag_interface_t *jtag_interface = NULL;
234
int jtag_speed = 0;
oharboe's avatar
   
oharboe committed
235

236
/* forward declarations */
237
238
239
240
241
242
//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);
243
244

/* jtag commands */
245
246
247
248
249
250
251
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);
252

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

255
256
257
258
259
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);
260
static int Jim_Command_flush_count(Jim_Interp *interp, int argc, Jim_Obj *const *args);
261

262
static int handle_verify_ircapture_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
oharboe's avatar
oharboe committed
263
static int handle_verify_jtag_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
264
static int handle_tms_sequence_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
265

oharboe's avatar
oharboe committed
266
267
jtag_tap_t *jtag_AllTaps(void)
{
268
	return jtag_all_taps;
269
270
};

271
int jtag_NumTotalTaps(void)
272
273
274
275
276
277
278
279
280
281
282
283
284
{
	jtag_tap_t *t;
	int n;

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

285
int jtag_NumEnabledTaps(void)
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
{
	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
307
	/* try name first */
308
309
310
311
312
313
314
	while(t){
		if( 0 == strcmp( t->dotted_name, s ) ){
			break;
		} else {
			t = t->next_tap;
		}
	}
ntfreak's avatar
ntfreak committed
315
	/* backup plan is by number */
316
317
318
319
320
321
322
323
324
325
326
327
	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;
}

328
jtag_tap_t * jtag_TapByJimObj( Jim_Interp *interp, Jim_Obj *o )
329
330
331
332
333
334
335
336
337
338
{
	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
339
	}
340
341
342
343
344
345
346
	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 */
347
jtag_tap_t * jtag_TapByAbsPosition( int n )
348
349
350
351
352
353
{
	int orig_n;
	jtag_tap_t *t;

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

355
356
357
	while( t && (n > 0)) {
		n--;
		t = t->next_tap;
358
	}
359
360
361
	return t;
}

362
363
364
int jtag_register_event_callback(int (*callback)(enum jtag_event event, void *priv), void *priv)
{
	jtag_event_callback_t **callbacks_p = &jtag_event_callbacks;
365

366
367
368
369
	if (callback == NULL)
	{
		return ERROR_INVALID_ARGUMENTS;
	}
370

371
372
373
374
375
376
	if (*callbacks_p)
	{
		while ((*callbacks_p)->next)
			callbacks_p = &((*callbacks_p)->next);
		callbacks_p = &((*callbacks_p)->next);
	}
377

378
379
380
381
	(*callbacks_p) = malloc(sizeof(jtag_event_callback_t));
	(*callbacks_p)->callback = callback;
	(*callbacks_p)->priv = priv;
	(*callbacks_p)->next = NULL;
382

383
384
385
386
387
388
	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;
389

390
391
392
393
	if (callback == NULL)
	{
		return ERROR_INVALID_ARGUMENTS;
	}
394

395
396
397
398
399
400
401
402
403
404
	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;
	}
405

406
407
408
409
410
411
	return ERROR_OK;
}

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

413
	LOG_DEBUG("jtag event: %s", jtag_event_strings[event]);
414

415
416
417
418
419
	while (callback)
	{
		callback->callback(event, callback->priv);
		callback = callback->next;
	}
420

421
422
423
424
425
426
427
428
429
430
	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;
431

432
433
434
435
436
	if (cmd)
		while (cmd->next)
			cmd = cmd->next;
	else
		return &jtag_command_queue;
437

438
	return &cmd->next;*/
439

440
	return last_command_pointer;
441
442
}

443
444
445
446
447
448
449
450
451
452
453

void jtag_queue_command(jtag_command_t * cmd)
{
	jtag_command_t **last_cmd;

	last_cmd = jtag_get_last_command_p();

	*last_cmd = cmd;

	(*last_cmd)->next = NULL;

454
	last_command_pointer = &((*last_cmd)->next);
455
456
457
}


458
459
460
461
void* cmd_queue_alloc(size_t size)
{
	cmd_queue_page_t **p_page = &cmd_queue_pages;
	int offset;
oharboe's avatar
oharboe committed
462
	u8 *t;
463

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

492
	/* The alignment process. */
493
	size = (size + ALIGN_SIZE -1) & (~(ALIGN_SIZE-1));
494
	/* Done... */
495

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

oharboe's avatar
oharboe committed
515
	t=(u8 *)((*p_page)->address);
516
517
518
	return t + offset;
}

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

534
535
536
537
538
539
540
541
542
543
544
545
546
547
/**
 * Copy a scan_field_t for insertion into the queue.
 *
 * This allocates a new copy of out_value using cmd_queue_alloc.
 */
static void cmd_queue_scan_field_clone(scan_field_t * dst, const scan_field_t * src)
{
	dst->tap		= src->tap;
	dst->num_bits	= src->num_bits;
	dst->out_value	= buf_cpy(src->out_value, cmd_queue_alloc(CEIL(src->num_bits, 8)), src->num_bits);
	dst->in_value	= src->in_value;
}


oharboe's avatar
oharboe committed
548
static void jtag_prelude1(void)
549
550
551
{
	if (jtag_trst == 1)
	{
552
		LOG_WARNING("JTAG command queued, while TRST is low (TAP in reset)");
oharboe's avatar
oharboe committed
553
		jtag_error=ERROR_JTAG_TRST_ASSERTED;
554
		return;
555
556
	}

557
	if (cmd_queue_end_state == TAP_RESET)
oharboe's avatar
oharboe committed
558
		jtag_call_event_callbacks(JTAG_TRST_ASSERTED);
559
560
}

561
static void jtag_prelude(tap_state_t state)
562
563
{
	jtag_prelude1();
564

mifi's avatar
mifi committed
565
	if (state != TAP_INVALID)
566
		jtag_add_end_state(state);
567

oharboe's avatar
oharboe committed
568
	cmd_queue_cur_state = cmd_queue_end_state;
569
570
}

571
void jtag_add_ir_scan_noverify(int in_num_fields, const scan_field_t *in_fields, tap_state_t state)
572
{
oharboe's avatar
oharboe committed
573
	int retval;
574
	jtag_prelude(state);
575

576
	retval=interface_jtag_add_ir_scan(in_num_fields, in_fields, cmd_queue_end_state);
oharboe's avatar
oharboe committed
577
578
	if (retval!=ERROR_OK)
		jtag_error=retval;
579
580
581
582

}


583
584
585
586
587
588
589
590
591
/**
 * 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.
 *
 */
592
void jtag_add_ir_scan(int in_num_fields, scan_field_t *in_fields, tap_state_t state)
593
{
oharboe's avatar
oharboe committed
594
	if (jtag_verify&&jtag_verify_capture_ir)
595
	{
oharboe's avatar
oharboe committed
596
		/* 8 x 32 bit id's is enough for all invoations */
597
598

		for (int j = 0; j < in_num_fields; j++)
599
		{
600
601
			in_fields[j].check_value=NULL;
			in_fields[j].check_mask=NULL;
oharboe's avatar
oharboe committed
602
603
604
			/* 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.
			 */
605
606
			in_fields[j].check_value=in_fields[j].tap->expected;
			in_fields[j].check_mask=in_fields[j].tap->expected_mask;
607
		}
608
		jtag_add_scan_check(jtag_add_ir_scan_noverify, in_num_fields, in_fields, state);
oharboe's avatar
oharboe committed
609
610
	} else
	{
611
		jtag_add_ir_scan_noverify(in_num_fields, in_fields, state);
612
	}
oharboe's avatar
oharboe committed
613
614
}

615
/**
616
 * see jtag_add_ir_scan()
617
618
 *
 */
619
int MINIDRIVER(interface_jtag_add_ir_scan)(int in_num_fields, const scan_field_t *in_fields, tap_state_t state)
620
{
621
	size_t num_taps = jtag_NumEnabledTaps();
622

623
624
625
	jtag_command_t * cmd		= cmd_queue_alloc(sizeof(jtag_command_t));
	scan_command_t * scan		= cmd_queue_alloc(sizeof(scan_command_t));
	scan_field_t * out_fields	= cmd_queue_alloc(num_taps  * sizeof(scan_field_t));
626

627
	jtag_queue_command(cmd);
628

629
630
631
632
633
	cmd->type				= JTAG_SCAN;
	cmd->cmd.scan			= scan;

	scan->ir_scan			= true;
	scan->num_fields		= num_taps;	/* one field per device */
634
	scan->fields			= out_fields;
635
	scan->end_state			= state;
636

637
638
639
640

	scan_field_t * field = out_fields;	/* keep track where we insert data */

	/* loop over all enabled TAPs */
641
642
643

	for (jtag_tap_t * tap = jtag_NextEnabledTap(NULL); tap != NULL; tap = jtag_NextEnabledTap(tap))
	{
644
645
646
		/* search the input field list for fields for the current TAP */

		bool found = false;
647

648
		for (int j = 0; j < in_num_fields; j++)
649
		{
650
651
652
			if (tap != in_fields[j].tap)
				continue;

653
654
655
			/* if TAP is listed in input fields, copy the value */

			found = true;
656

657
			tap->bypass = 0;
658

659
			assert(in_fields[j].num_bits == tap->ir_length); /* input fields must have the same length as the TAP's IR */
660

661
662
663
			cmd_queue_scan_field_clone(field, in_fields + j);

			break;
664
		}
665

666
667
		if (!found)
		{
668
			/* if a TAP isn't listed in input fields, set it to BYPASS */
669

670
			tap->bypass = 1;
671

672
			field->tap			= tap;
673
674
			field->num_bits		= tap->ir_length;
			field->out_value	= buf_set_ones(cmd_queue_alloc(CEIL(tap->ir_length, 8)), tap->ir_length);
675
			field->in_value		= NULL; /* do not collect input for tap's in bypass */
676
		}
677

678
		/* update device information */
679
		buf_cpy(field->out_value, tap->cur_instr, tap->ir_length);
680
681

		field++;
682
	}
683

684
	assert(field == out_fields + num_taps); /* paranoia: jtag_NumEnabledTaps() and jtag_NextEnabledTap() not in sync */
685

686
687
688
	return ERROR_OK;
}

689
690
691
692
693
694
/**
 * 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
 *
 */
695
void jtag_add_plain_ir_scan(int in_num_fields, const scan_field_t *in_fields, tap_state_t state)
696
{
oharboe's avatar
oharboe committed
697
	int retval;
698

699
	jtag_prelude(state);
700

701
	retval=interface_jtag_add_plain_ir_scan(in_num_fields, in_fields, cmd_queue_end_state);
702
703
	if (retval!=ERROR_OK)
		jtag_error=retval;
704
705
}

706
707
708
709
710

/**
 * see jtag_add_plain_ir_scan()
 *
 */
711
int MINIDRIVER(interface_jtag_add_plain_ir_scan)(int in_num_fields, const scan_field_t *in_fields, tap_state_t state)
712
{
713

714
715
716
	jtag_command_t * cmd		= cmd_queue_alloc(sizeof(jtag_command_t));
	scan_command_t * scan		= cmd_queue_alloc(sizeof(scan_command_t));
	scan_field_t * out_fields	= cmd_queue_alloc(in_num_fields * sizeof(scan_field_t));
717
718
	
	jtag_queue_command(cmd);
719

720
721
	cmd->type				= JTAG_SCAN;
	cmd->cmd.scan			= scan;
722

723
724
	scan->ir_scan			= true;
	scan->num_fields		= in_num_fields;
725
	scan->fields			= out_fields;
726
	scan->end_state			= state;
727

728
	for (int i = 0; i < in_num_fields; i++)
729
		cmd_queue_scan_field_clone(out_fields + i, in_fields + i);
730

731
732
733
	return ERROR_OK;
}

734

735
736
737
738
739
740
741
742

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);
}

743
static void jtag_add_scan_check(void (*jtag_add_scan)(int in_num_fields, const scan_field_t *in_fields, tap_state_t state),
744
		int in_num_fields, scan_field_t *in_fields, tap_state_t state)
745
{
746
	for (int i = 0; i < in_num_fields; i++)
747
	{
748
749
750
		in_fields[i].allocated = 0;
		in_fields[i].modified = 0;
		if ((in_fields[i].check_value != NULL) && (in_fields[i].in_value == NULL))
751
		{
752
			in_fields[i].modified = 1;
753
754
			/* we need storage space... */
#ifdef HAVE_JTAG_MINIDRIVER_H
755
			if (in_fields[i].num_bits <= 32)
756
757
			{
				/* This is enough space and we're executing this synchronously */
758
				in_fields[i].in_value = in_fields[i].intmp;
759
760
			} else
			{
761
762
				in_fields[i].in_value = (u8 *)malloc(CEIL(in_fields[i].num_bits, 8));
				in_fields[i].allocated = 1;
763
764
			}
#else
765
			in_fields[i].in_value = (u8 *)cmd_queue_alloc(CEIL(in_fields[i].num_bits, 8));
766
767
768
769
#endif
		}
	}

770
	jtag_add_scan(in_num_fields, in_fields, state);
771

772
	for (int i = 0; i < in_num_fields; i++)
773
	{
774
		if ((in_fields[i].check_value != NULL) && (in_fields[i].in_value != NULL))
775
776
		{
			/* this is synchronous for a minidriver */
777
778
779
780
			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);
781
		}
782
		if (in_fields[i].allocated)
783
		{
784
			free(in_fields[i].in_value);
785
		}
786
		if (in_fields[i].modified)
787
		{
788
			in_fields[i].in_value = NULL;
789
790
		}
	}
791
}
792

793
void jtag_add_dr_scan_check(int in_num_fields, scan_field_t *in_fields, tap_state_t state)
794
{
oharboe's avatar
oharboe committed
795
796
	if (jtag_verify)
	{
797
		jtag_add_scan_check(jtag_add_dr_scan, in_num_fields, in_fields, state);
oharboe's avatar
oharboe committed
798
799
	} else
	{
800
		jtag_add_dr_scan(in_num_fields, in_fields, state);
oharboe's avatar
oharboe committed
801
	}
802
803
}

804
805
806
807
808
809
810
811
812
813

/**
 * 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().
 *
 */
814
void jtag_add_dr_scan(int in_num_fields, const scan_field_t *in_fields, tap_state_t state)
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
{
	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;
}


/**
 * see jtag_add_dr_scan()
 *
 */
830
int MINIDRIVER(interface_jtag_add_dr_scan)(int in_num_fields, const scan_field_t *in_fields, tap_state_t state)
831
832
{
	/* count devices in bypass */
833
834
835
836
837
838

	size_t bypass_devices = 0;

	for (jtag_tap_t * tap = jtag_NextEnabledTap(NULL); tap != NULL; tap = jtag_NextEnabledTap(tap))
	{
		if (tap->bypass)
839
			bypass_devices++;
840
	}
841

842
843
844
	jtag_command_t * cmd		= cmd_queue_alloc(sizeof(jtag_command_t));
	scan_command_t * scan		= cmd_queue_alloc(sizeof(scan_command_t));
	scan_field_t * out_fields	= cmd_queue_alloc((in_num_fields + bypass_devices) * sizeof(scan_field_t));
845
846
847
	
	jtag_queue_command(cmd);
	
848
849
	cmd->type				= JTAG_SCAN;
	cmd->cmd.scan			= scan;
850

851
852
	scan->ir_scan			= false;
	scan->num_fields		= in_num_fields + bypass_devices;
853
	scan->fields			= out_fields;
854
	scan->end_state			= state;
855

856
857
858
859
860

	scan_field_t * field = out_fields;	/* keep track where we insert data */

	/* loop over all enabled TAPs */

861
862
	for (jtag_tap_t * tap = jtag_NextEnabledTap(NULL); tap != NULL; tap = jtag_NextEnabledTap(tap))
	{
863
		/* if TAP is not bypassed insert matching input fields */
864

865
		if (!tap->bypass)
866
		{
867
			scan_field_t * start_field = field;	/* keep initial position for assert() */
868

869
			for (int j = 0; j < in_num_fields; j++)
870
			{
871
872
873
874
875
876
				if (tap != in_fields[j].tap)
					continue;

				cmd_queue_scan_field_clone(field, in_fields + j);

				field++;
877
			}
878
879

			assert(field > start_field);	/* must have at least one input field per not bypassed TAP */
880
		}
881
882
		
		/* if a TAP is bypassed, generated a dummy bit*/
883
884
		else
		{
885
886
887
888
889
890
			field->tap			= tap;
			field->num_bits		= 1;
			field->out_value	= NULL;
			field->in_value		= NULL;

			field++;
891
892
		}
	}
893

894
895
	assert(field == out_fields + scan->num_fields); /* no superfluous input fields permitted */

896
897
898
	return ERROR_OK;
}

899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914


/**
 * Generate a DR SCAN using the array of output values passed to the function
 *
 * This function assumes that the parameter target_tap specifies the one TAP
 * that is not bypassed. All other TAPs must be bypassed and the function will
 * generate a dummy 1bit field for them.
 *
 * For the target_tap a sequence of output-only fields will be generated where
 * each field has the size num_bits and the field's values are taken from
 * the array value.
 *
 * The bypass status of TAPs is set by jtag_add_ir_scan().
 *
 */
915
void MINIDRIVER(interface_jtag_add_dr_out)(jtag_tap_t *target_tap,
916
		int in_num_fields,
917
918
		const int *num_bits,
		const u32 *value,
919
		tap_state_t end_state)
920
921
{
	/* count devices in bypass */
922
923
924
925
926
927

	size_t bypass_devices = 0;

	for (jtag_tap_t * tap = jtag_NextEnabledTap(NULL); tap != NULL; tap = jtag_NextEnabledTap(tap))
	{
		if (tap->bypass)
928
929
			bypass_devices++;
	}
930

931

932
933
934
	jtag_command_t * cmd		= cmd_queue_alloc(sizeof(jtag_command_t));
	scan_command_t * scan		= cmd_queue_alloc(sizeof(scan_command_t));
	scan_field_t * out_fields	= cmd_queue_alloc((in_num_fields + bypass_devices) * sizeof(scan_field_t));
935
936
937

	jtag_queue_command(cmd);

938
939
	cmd->type				= JTAG_SCAN;
	cmd->cmd.scan			= scan;
940

941
942
	scan->ir_scan			= false;
	scan->num_fields		= in_num_fields + bypass_devices;
943
	scan->fields			= out_fields;
944
	scan->end_state			= end_state;
945

946
947
948
949
950
951
952

	bool target_tap_match	= false;

	scan_field_t * field = out_fields;	/* keep track where we insert data */

	/* loop over all enabled TAPs */

953
954
	for (jtag_tap_t * tap = jtag_NextEnabledTap(NULL); tap != NULL; tap = jtag_NextEnabledTap(tap))
	{
955
		/* if TAP is not bypassed insert matching input fields */
956

957
		if (!tap->bypass)
958
		{
959
960
961
962
			assert(tap == target_tap); /* target_tap must match the one not bypassed TAP */

			target_tap_match = true;

963
			for (int j = 0; j < in_num_fields; j++)
964
			{
oharboe's avatar
oharboe committed
965
				u8 out_value[4];
966
				size_t scan_size = num_bits[j];
967
				buf_set_u32(out_value, 0, scan_size, value[j]);
968
969
970
971
972
973
974

				field->tap			= tap;
				field->num_bits		= scan_size;
				field->out_value	= buf_cpy(out_value, cmd_queue_alloc(CEIL(scan_size, 8)), scan_size);
				field->in_value		= NULL;

				field++;
975
			}
976
977
978
979
		}

		/* if a TAP is bypassed, generated a dummy bit*/
		else
980
		{
981
982
983
984
985
986
987

			field->tap				= tap;
			field->num_bits			= 1;
			field->out_value		= NULL;
			field->in_value			= NULL;

			field++;
988
989
		}
	}
990
991

	assert(target_tap_match);	/* target_tap should be enabled and not bypassed */
992
993
}

994
995
996
997
998
999
1000

/**
 * 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
 *
 */
For faster browsing, not all history is shown. View entire blame