jtag.c 94.5 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
 *   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
int jtag_trst = 0;
int jtag_srst = 0;

75
76
77
78
79
80
81
82
83
#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;
84
	jtag_callback_data_t data3;
85
86
87
88
89
90
91
92
};


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


93
jtag_command_t *jtag_command_queue = NULL;
94
jtag_command_t **last_command_pointer = &jtag_command_queue;
95
96
static jtag_tap_t *jtag_all_taps = NULL;

97
enum reset_types jtag_reset_config = RESET_NONE;
98
99
tap_state_t cmd_queue_end_state = TAP_RESET;
tap_state_t cmd_queue_cur_state = TAP_RESET;
100
101

int jtag_verify_capture_ir = 1;
oharboe's avatar
oharboe committed
102
int jtag_verify = 1;
103
104

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

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

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

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

120
121
/* jtag interfaces (parport, FTDI-USB, TI-USB, ...)
 */
122

123
#if BUILD_ECOSBOARD == 1
124
	extern jtag_interface_t zy1000_interface;
125
#endif
126

127
128
129
#if BUILD_PARPORT == 1
	extern jtag_interface_t parport_interface;
#endif
130

131
132
133
#if BUILD_DUMMY == 1
	extern jtag_interface_t dummy_interface;
#endif
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
165
166
#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

167
168
169
170
#if BUILD_JLINK == 1
	extern jtag_interface_t jlink_interface;
#endif

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

175
176
177
178
#if BUILD_RLINK == 1
	extern jtag_interface_t rlink_interface;
#endif

179
180
181
182
#if BUILD_ARMJTAGEW == 1
	extern jtag_interface_t armjtagew_interface;
#endif

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

232
static jtag_interface_t *jtag = NULL;
233
234

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

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

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

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

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

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

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

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

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

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

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

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

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

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

368
369
370
371
	if (callback == NULL)
	{
		return ERROR_INVALID_ARGUMENTS;
	}
372

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

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

385
386
387
388
389
390
	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;
391

392
393
394
395
	if (callback == NULL)
	{
		return ERROR_INVALID_ARGUMENTS;
	}
396

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

408
409
410
411
412
413
	return ERROR_OK;
}

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

415
	LOG_DEBUG("jtag event: %s", jtag_event_strings[event]);
416

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

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

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

440
	return &cmd->next;*/
441

442
	return last_command_pointer;
443
444
}

445
446
447
448
449
450
451
452
453
454
455

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;

456
	last_command_pointer = &((*last_cmd)->next);
457
458
459
}


460
461
462
463
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
	/*
	 * 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
480
	 * to align by...
481
482
483
484
485
486
	 *
	 * The solution here, is based on these suggestions.
	 * http://gcc.gnu.org/ml/gcc-help/2008-12/msg00041.html
	 *
	 */
	union worse_case_align {
487
488
489
490
		int i;
		long l;
		float f;
		void *v;
491
492
493
	};
#define ALIGN_SIZE  (sizeof(union worse_case_align))

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

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

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

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

536
537
538
539
540
541
542
543
544
545
546
547
548
549
/**
 * 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
550
static void jtag_prelude1(void)
551
552
553
{
	if (jtag_trst == 1)
	{
554
		LOG_WARNING("JTAG command queued, while TRST is low (TAP in reset)");
oharboe's avatar
oharboe committed
555
		jtag_error=ERROR_JTAG_TRST_ASSERTED;
556
		return;
557
558
	}

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

563
static void jtag_prelude(tap_state_t state)
564
565
{
	jtag_prelude1();
566

mifi's avatar
mifi committed
567
	if (state != TAP_INVALID)
568
		jtag_add_end_state(state);
569

oharboe's avatar
oharboe committed
570
	cmd_queue_cur_state = cmd_queue_end_state;
571
572
}

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

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

}


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

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

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

625
626
627
	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));
628

629
	jtag_queue_command(cmd);
630

631
632
633
634
635
	cmd->type				= JTAG_SCAN;
	cmd->cmd.scan			= scan;

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

639
640
641
642

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

	/* loop over all enabled TAPs */
643
644
645

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

		bool found = false;
649

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

655
656
657
			/* if TAP is listed in input fields, copy the value */

			found = true;
658

659
			tap->bypass = 0;
660

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

663
664
665
			cmd_queue_scan_field_clone(field, in_fields + j);

			break;
666
		}
667

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

672
			tap->bypass = 1;
673

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

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

		field++;
684
	}
685

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

688
689
690
	return ERROR_OK;
}

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

701
	jtag_prelude(state);
702

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

708
709
710
711
712

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

716
717
718
	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));
719
720
	
	jtag_queue_command(cmd);
721

722
723
	cmd->type				= JTAG_SCAN;
	cmd->cmd.scan			= scan;
724

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

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

733
734
735
	return ERROR_OK;
}

736

737
738
739
740
741
742
743
744

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

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

772
	jtag_add_scan(in_num_fields, in_fields, state);
773

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

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

806
807
808
809
810
811
812
813
814
815

/**
 * 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().
 *
 */
816
void jtag_add_dr_scan(int in_num_fields, const scan_field_t *in_fields, tap_state_t state)
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
{
	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()
 *
 */
832
int MINIDRIVER(interface_jtag_add_dr_scan)(int in_num_fields, const scan_field_t *in_fields, tap_state_t state)
833
834
{
	/* count devices in bypass */
835
836
837
838
839
840

	size_t bypass_devices = 0;

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

844
845
846
	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));
847
848
849
	
	jtag_queue_command(cmd);
	
850
851
	cmd->type				= JTAG_SCAN;
	cmd->cmd.scan			= scan;
852

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

858
859
860
861
862

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

	/* loop over all enabled TAPs */

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

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

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

				cmd_queue_scan_field_clone(field, in_fields + j);

				field++;
879
			}
880
881

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

			field++;
893
894
		}
	}
895

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

898
899
900
	return ERROR_OK;
}

901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916


/**
 * 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().
 *
 */
917
void MINIDRIVER(interface_jtag_add_dr_out)(jtag_tap_t *target_tap,
918
		int in_num_fields,
919
920
		const int *num_bits,
		const u32 *value,
921
		tap_state_t end_state)
922
923
{
	/* count devices in bypass */
924
925
926
927
928
929

	size_t bypass_devices = 0;

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

933

934
935
936
	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));
937
938
939

	jtag_queue_command(cmd);

940
941
	cmd->type				= JTAG_SCAN;
	cmd->cmd.scan			= scan;
942

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

948
949
950
951
952
953
954

	bool target_tap_match	= false;

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

	/* loop over all enabled TAPs */

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

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

			target_tap_match = true;

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

				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++;
977
			}
978
979
980
981
		}

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

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

			field++;
990
991
		}
	}
992
993

	assert(target_tap_match);	/* target_tap should be enabled and not bypassed */
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