tcl.c 37.4 KB
Newer Older
1
2
3
4
/***************************************************************************
 *   Copyright (C) 2005 by Dominic Rath                                    *
 *   Dominic.Rath@gmx.de                                                   *
 *                                                                         *
5
 *   Copyright (C) 2007,2008 yvind Harboe                                 *
6
 *   oyvind.harboe@zylin.com                                               *
ntfreak's avatar
ntfreak committed
7
8
 *                                                                         *
 *   Copyright (C) 2009 SoftPLC Corporation                                *
zwelch's avatar
zwelch committed
9
 *       http://softplc.com                                                *
ntfreak's avatar
ntfreak committed
10
 *   dick@softplc.com                                                      *
11
 *                                                                         *
12
13
14
 *   Copyright (C) 2009 Zachary T Welch                                    *
 *   zw@superlucidity.net                                                  *
 *                                                                         *
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
 *   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"
zwelch's avatar
zwelch committed
35
#include "minidriver.h"
36
#include "interface.h"
37

38
39
40
#ifdef HAVE_STRINGS_H
#include <strings.h>
#endif
41

42
extern bool hasKHz;
oharboe's avatar
   
oharboe committed
43

44
45
/* jtag interfaces (parport, FTDI-USB, TI-USB, ...)
 */
46

47
#if BUILD_ECOSBOARD == 1
48
	extern jtag_interface_t zy1000_interface;
49
#elif defined(BUILD_MINIDRIVER_DUMMY)
50
	extern jtag_interface_t minidummy_interface;
51
#else // standard drivers
52
53
54
#if BUILD_PARPORT == 1
	extern jtag_interface_t parport_interface;
#endif
55

56
57
58
#if BUILD_DUMMY == 1
	extern jtag_interface_t dummy_interface;
#endif
59

60
61
62
63
64
65
66
67
68
69
70
71
#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

72
73
74
#if BUILD_EP93XX == 1
	extern jtag_interface_t ep93xx_interface;
#endif
75

76
77
78
#if BUILD_AT91RM9200 == 1
	extern jtag_interface_t at91rm9200_interface;
#endif
79

80
81
82
#if BUILD_GW16012 == 1
	extern jtag_interface_t gw16012_interface;
#endif
83

84
85
86
#if BUILD_PRESTO_LIBFTDI == 1 || BUILD_PRESTO_FTD2XX == 1
	extern jtag_interface_t presto_interface;
#endif
87

88
89
90
#if BUILD_USBPROG == 1
	extern jtag_interface_t usbprog_interface;
#endif
91

92
93
94
#if BUILD_JLINK == 1
	extern jtag_interface_t jlink_interface;
#endif
95

96
97
98
#if BUILD_VSLLINK == 1
	extern jtag_interface_t vsllink_interface;
#endif
99

100
101
102
#if BUILD_RLINK == 1
	extern jtag_interface_t rlink_interface;
#endif
103

104
105
106
107
#if BUILD_ARMJTAGEW == 1
	extern jtag_interface_t armjtagew_interface;
#endif
#endif // standard drivers
108

109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
/**
 * The list of built-in JTAG interfaces, containing entries for those
 * drivers that were enabled by the @c configure script.
 *
 * The list should be defined to contain either one minidriver interface
 * or some number of standard driver interfaces, never both.
 */
jtag_interface_t *jtag_interfaces[] = {
#if BUILD_ECOSBOARD == 1
	&zy1000_interface,
#elif defined(BUILD_MINIDRIVER_DUMMY)
	&minidummy_interface,
#else // standard drivers
#if BUILD_PARPORT == 1
	&parport_interface,
#endif
#if BUILD_DUMMY == 1
	&dummy_interface,
#endif
#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,
#endif
#if BUILD_JLINK == 1
	&jlink_interface,
#endif
#if BUILD_VSLLINK == 1
	&vsllink_interface,
#endif
#if BUILD_RLINK == 1
	&rlink_interface,
#endif
#if BUILD_ARMJTAGEW == 1
	&armjtagew_interface,
#endif
#endif // standard drivers
	NULL,
};
167

168
169
extern struct jtag_interface_s *jtag;
extern jtag_interface_t *jtag_interface;
170

171
172
173
174
175
176
177
178
179
180
/* jtag commands */
static int handle_interface_list_command(struct command_context_s *cmd_ctx,
		char *cmd, char **args, int argc);
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);
oharboe's avatar
oharboe committed
181

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

184
185
186
187
188
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);
static int Jim_Command_flush_count(Jim_Interp *interp, int argc, Jim_Obj *const *args);
189

190
191
192
static int handle_verify_ircapture_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
static int handle_verify_jtag_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
static int handle_tms_sequence_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
193

194
195
extern int jtag_examine_chain(void);
extern int jtag_validate_chain(void);
196

197
198
199
200
201
202
203
204
205
206
enum jtag_tap_cfg_param {
	JCFG_EVENT
};

static Jim_Nvp nvp_config_opts[] = {
	{ .name = "-event",      .value = JCFG_EVENT },

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

ntfreak's avatar
ntfreak committed
207
static int jtag_tap_configure_cmd( Jim_GetOptInfo *goi, jtag_tap_t * tap)
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
{
	Jim_Nvp *n;
	Jim_Obj *o;
	int e;

	/* parse config or cget options */
	while (goi->argc > 0) {
		Jim_SetEmptyResult (goi->interp);

		e = Jim_GetOpt_Nvp(goi, nvp_config_opts, &n);
		if (e != JIM_OK) {
			Jim_GetOpt_NvpUnknown(goi, nvp_config_opts, 0);
			return e;
		}

		switch (n->value) {
			case JCFG_EVENT:
				if (goi->argc == 0) {
					Jim_WrongNumArgs( goi->interp, goi->argc, goi->argv, "-event ?event-name? ..." );
					return JIM_ERR;
				}

				e = Jim_GetOpt_Nvp( goi, nvp_jtag_tap_event, &n );
				if (e != JIM_OK) {
					Jim_GetOpt_NvpUnknown(goi, nvp_jtag_tap_event, 1);
					return e;
				}

				if (goi->isconfigure) {
					if (goi->argc != 1) {
						Jim_WrongNumArgs(goi->interp, goi->argc, goi->argv, "-event ?event-name? ?EVENT-BODY?");
						return JIM_ERR;
					}
				} else {
					if (goi->argc != 0) {
						Jim_WrongNumArgs(goi->interp, goi->argc, goi->argv, "-event ?event-name?");
						return JIM_ERR;
					}
				}

				{
					jtag_tap_event_action_t *jteap;

					jteap = tap->event_action;
					/* replace existing? */
					while (jteap) {
254
						if (jteap->event == (enum jtag_tap_event)n->value) {
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
							break;
						}
						jteap = jteap->next;
					}

					if (goi->isconfigure) {
						if (jteap == NULL) {
							/* create new */
							jteap = calloc(1, sizeof (*jteap));
						}
						jteap->event = n->value;
						Jim_GetOpt_Obj( goi, &o);
						if (jteap->body) {
							Jim_DecrRefCount(interp, jteap->body);
						}
						jteap->body = Jim_DuplicateObj(goi->interp, o);
						Jim_IncrRefCount(jteap->body);

						/* add to head of event list */
						jteap->next = tap->event_action;
						tap->event_action = jteap;
						Jim_SetEmptyResult(goi->interp);
					} else {
						/* get */
						if (jteap == NULL) {
							Jim_SetEmptyResult(goi->interp);
						} else {
							Jim_SetResult(goi->interp, Jim_DuplicateObj(goi->interp, jteap->body));
						}
					}
				}
				/* loop for more */
				break;
		}
	} /* while (goi->argc) */

	return JIM_OK;
}
293

294

295
296
extern void jtag_tap_init(jtag_tap_t *tap);
extern void jtag_tap_free(jtag_tap_t *tap);
297

298
static int jim_newtap_cmd( Jim_GetOptInfo *goi )
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
{
	jtag_tap_t *pTap;
	jim_wide w;
	int x;
	int e;
	int reqbits;
	Jim_Nvp *n;
	char *cp;
	const Jim_Nvp opts[] = {
#define NTAP_OPT_IRLEN     0
		{ .name = "-irlen"			,	.value = NTAP_OPT_IRLEN },
#define NTAP_OPT_IRMASK    1
		{ .name = "-irmask"			,	.value = NTAP_OPT_IRMASK },
#define NTAP_OPT_IRCAPTURE 2
		{ .name = "-ircapture"		,	.value = NTAP_OPT_IRCAPTURE },
#define NTAP_OPT_ENABLED   3
315
		{ .name = "-enable"			,	.value = NTAP_OPT_ENABLED },
316
#define NTAP_OPT_DISABLED  4
317
		{ .name = "-disable"		,	.value = NTAP_OPT_DISABLED },
318
#define NTAP_OPT_EXPECTED_ID 5
319
320
		{ .name = "-expected-id"	,	.value = NTAP_OPT_EXPECTED_ID },
		{ .name = NULL				,	.value = -1 },
321
322
323
324
325
326
327
328
	};

	pTap = malloc( sizeof(jtag_tap_t) );
	memset( pTap, 0, sizeof(*pTap) );
	if( !pTap ){
		Jim_SetResult_sprintf( goi->interp, "no memory");
		return JIM_ERR;
	}
329
330
331
	/*
	 * we expect CHIP + TAP + OPTIONS
	 * */
332
333
334
335
336
337
338
339
340
	if( goi->argc < 3 ){
		Jim_SetResult_sprintf(goi->interp, "Missing CHIP TAP OPTIONS ....");
		return JIM_ERR;
	}
	Jim_GetOpt_String( goi, &cp, NULL );
	pTap->chip = strdup(cp);

	Jim_GetOpt_String( goi, &cp, NULL );
	pTap->tapname = strdup(cp);
oharboe's avatar
oharboe committed
341

342
	/* name + dot + name + null */
343
344
345
346
347
	x = strlen(pTap->chip) + 1 + strlen(pTap->tapname) + 1;
	cp = malloc( x );
	sprintf( cp, "%s.%s", pTap->chip, pTap->tapname );
	pTap->dotted_name = cp;

oharboe's avatar
oharboe committed
348
	LOG_DEBUG("Creating New Tap, Chip: %s, Tap: %s, Dotted: %s, %d params",
349
350
			  pTap->chip, pTap->tapname, pTap->dotted_name, goi->argc);

351
	/* default is enabled */
352
353
	pTap->enabled = 1;

354
	/* deal with options */
355
356
357
358
#define NTREQ_IRLEN      1
#define NTREQ_IRCAPTURE  2
#define NTREQ_IRMASK     4

359
	/* clear them as we find them */
360
	reqbits = (NTREQ_IRLEN | NTREQ_IRCAPTURE | NTREQ_IRMASK);
oharboe's avatar
oharboe committed
361

362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
	while( goi->argc ){
		e = Jim_GetOpt_Nvp( goi, opts, &n );
		if( e != JIM_OK ){
			Jim_GetOpt_NvpUnknown( goi, opts, 0 );
			return e;
		}
		LOG_DEBUG("Processing option: %s", n->name );
		switch( n->value ){
		case NTAP_OPT_ENABLED:
			pTap->enabled = 1;
			break;
		case NTAP_OPT_DISABLED:
			pTap->enabled = 0;
			break;
		case NTAP_OPT_EXPECTED_ID:
377
378
379
		{
			u32 *new_expected_ids;

380
			e = Jim_GetOpt_Wide( goi, &w );
381
382
383
384
385
386
387
388
389
390
391
392
393
394
			if( e != JIM_OK) {
				Jim_SetResult_sprintf(goi->interp, "option: %s bad parameter", n->name);
				return e;
			}

			new_expected_ids = malloc(sizeof(u32) * (pTap->expected_ids_cnt + 1));
			if (new_expected_ids == NULL) {
				Jim_SetResult_sprintf( goi->interp, "no memory");
				return JIM_ERR;
			}

			memcpy(new_expected_ids, pTap->expected_ids, sizeof(u32) * pTap->expected_ids_cnt);

			new_expected_ids[pTap->expected_ids_cnt] = w;
395
396

			free(pTap->expected_ids);
397
398
			pTap->expected_ids = new_expected_ids;
			pTap->expected_ids_cnt++;
399
			break;
400
		}
401
402
403
404
405
406
407
408
409
		case NTAP_OPT_IRLEN:
		case NTAP_OPT_IRMASK:
		case NTAP_OPT_IRCAPTURE:
			e = Jim_GetOpt_Wide( goi, &w );
			if( e != JIM_OK ){
				Jim_SetResult_sprintf( goi->interp, "option: %s bad parameter", n->name );
				return e;
			}
			if( (w < 0) || (w > 0xffff) ){
410
				/* wacky value */
oharboe's avatar
oharboe committed
411
				Jim_SetResult_sprintf( goi->interp, "option: %s - wacky value: %d (0x%x)",
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
									   n->name, (int)(w), (int)(w));
				return JIM_ERR;
			}
			switch(n->value){
			case NTAP_OPT_IRLEN:
				pTap->ir_length = w;
				reqbits &= (~(NTREQ_IRLEN));
				break;
			case NTAP_OPT_IRMASK:
				pTap->ir_capture_mask = w;
				reqbits &= (~(NTREQ_IRMASK));
				break;
			case NTAP_OPT_IRCAPTURE:
				pTap->ir_capture_value = w;
				reqbits &= (~(NTREQ_IRCAPTURE));
				break;
			}
429
430
		} /* switch(n->value) */
	} /* while( goi->argc ) */
431

432
433
434
435
436
	/* Did all the required option bits get cleared? */
	if (0 == reqbits)
	{
		jtag_tap_init(pTap);
		return ERROR_OK;
437
438
	}

439
440
441
	Jim_SetResult_sprintf(goi->interp,
			"newtap: %s missing required parameters",
			pTap->dotted_name);
442
	jtag_tap_free(pTap);
443
444
	return JIM_ERR;
}
445

446
static int jim_jtag_command( Jim_Interp *interp, int argc, Jim_Obj *const *argv )
447
448
449
450
{
	Jim_GetOptInfo goi;
	int e;
	Jim_Nvp *n;
451
	Jim_Obj *o;
452
453
454
455
456
	struct command_context_s *context;

	enum {
		JTAG_CMD_INTERFACE,
		JTAG_CMD_INIT_RESET,
457
458
459
		JTAG_CMD_NEWTAP,
		JTAG_CMD_TAPENABLE,
		JTAG_CMD_TAPDISABLE,
460
461
462
		JTAG_CMD_TAPISENABLED,
		JTAG_CMD_CONFIGURE,
		JTAG_CMD_CGET
463
	};
464

465
466
467
	const Jim_Nvp jtag_cmds[] = {
		{ .name = "interface"     , .value = JTAG_CMD_INTERFACE },
		{ .name = "arp_init-reset", .value = JTAG_CMD_INIT_RESET },
468
469
470
471
		{ .name = "newtap"        , .value = JTAG_CMD_NEWTAP },
		{ .name = "tapisenabled"     , .value = JTAG_CMD_TAPISENABLED },
		{ .name = "tapenable"     , .value = JTAG_CMD_TAPENABLE },
		{ .name = "tapdisable"    , .value = JTAG_CMD_TAPDISABLE },
472
473
		{ .name = "configure"     , .value = JTAG_CMD_CONFIGURE },
		{ .name = "cget"          , .value = JTAG_CMD_CGET },
474

475
476
477
478
		{ .name = NULL, .value = -1 },
	};

	context = Jim_GetAssocData(interp, "context");
479
	/* go past the command */
480
481
482
483
484
485
486
487
488
489
	Jim_GetOpt_Setup( &goi, interp, argc-1, argv+1 );

	e = Jim_GetOpt_Nvp( &goi, jtag_cmds, &n );
	if( e != JIM_OK ){
		Jim_GetOpt_NvpUnknown( &goi, jtag_cmds, 0 );
		return e;
	}
		Jim_SetEmptyResult( goi.interp );
	switch( n->value ){
	case JTAG_CMD_INTERFACE:
490
491
492
		/* return the name of the interface */
		/* TCL code might need to know the exact type... */
		/* FUTURE: we allow this as a means to "set" the interface. */
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
		if( goi.argc != 0 ){
			Jim_WrongNumArgs( goi.interp, 1, goi.argv-1, "(no params)");
			return JIM_ERR;
		}
		Jim_SetResultString( goi.interp, jtag_interface->name, -1 );
		return JIM_OK;
	case JTAG_CMD_INIT_RESET:
		if( goi.argc != 0 ){
			Jim_WrongNumArgs( goi.interp, 1, goi.argv-1, "(no params)");
			return JIM_ERR;
		}
		e = jtag_init_reset(context);
		if( e != ERROR_OK ){
			Jim_SetResult_sprintf( goi.interp, "error: %d", e);
			return JIM_ERR;
		}
		return JIM_OK;
510
511
512
513
514
515
516
517
518
519
	case JTAG_CMD_NEWTAP:
		return jim_newtap_cmd( &goi );
		break;
	case JTAG_CMD_TAPISENABLED:
	case JTAG_CMD_TAPENABLE:
	case JTAG_CMD_TAPDISABLE:
		if( goi.argc != 1 ){
			Jim_SetResultString( goi.interp, "Too many parameters",-1 );
			return JIM_ERR;
		}
oharboe's avatar
oharboe committed
520
521

		{
522
			jtag_tap_t *t;
523
			t = jtag_tap_by_jim_obj( goi.interp, goi.argv[0] );
524
525
526
527
528
			if( t == NULL ){
				return JIM_ERR;
			}
			switch( n->value ){
			case JTAG_CMD_TAPISENABLED:
529
				e = t->enabled;
530
531
				break;
			case JTAG_CMD_TAPENABLE:
532
				jtag_tap_handle_event( t, JTAG_TAP_EVENT_ENABLE);
533
534
535
536
				e = 1;
				t->enabled = e;
				break;
			case JTAG_CMD_TAPDISABLE:
537
				jtag_tap_handle_event( t, JTAG_TAP_EVENT_DISABLE);
538
539
540
541
542
543
544
				e = 0;
				t->enabled = e;
				break;
			}
			Jim_SetResult( goi.interp, Jim_NewIntObj( goi.interp, e ) );
			return JIM_OK;
		}
545
546
547
548
549
550
551
552
553
554
555
556
		break;

	case JTAG_CMD_CGET:
		if( goi.argc < 2 ){
			Jim_WrongNumArgs( goi.interp, 0, NULL, "?tap-name? -option ...");
			return JIM_ERR;
		}

		{
			jtag_tap_t *t;

			Jim_GetOpt_Obj(&goi, &o);
557
			t = jtag_tap_by_jim_obj( goi.interp, o );
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
			if( t == NULL ){
				return JIM_ERR;
			}

			goi.isconfigure = 0;
			return jtag_tap_configure_cmd( &goi, t);
		}
		break;

	case JTAG_CMD_CONFIGURE:
		if( goi.argc < 3 ){
			Jim_WrongNumArgs( goi.interp, 0, NULL, "?tap-name? -option ?VALUE? ...");
			return JIM_ERR;
		}

		{
			jtag_tap_t *t;

			Jim_GetOpt_Obj(&goi, &o);
577
			t = jtag_tap_by_jim_obj( goi.interp, o );
578
579
580
581
582
583
584
			if( t == NULL ){
				return JIM_ERR;
			}

			goi.isconfigure = 1;
			return jtag_tap_configure_cmd( &goi, t);
		}
585
	}
586

587
588
589
	return JIM_ERR;
}

590
591
int jtag_register_commands(struct command_context_s *cmd_ctx)
{
592
593
	register_jim( cmd_ctx, "jtag", jim_jtag_command, "perform jtag tap actions");

594
	register_command(cmd_ctx, NULL, "interface", handle_interface_command,
oharboe's avatar
oharboe committed
595
		COMMAND_CONFIG, "try to configure interface");
596
597
598
	register_command(cmd_ctx, NULL,
		"interface_list", &handle_interface_list_command,
		COMMAND_ANY, "list all built-in interfaces");
599
	register_command(cmd_ctx, NULL, "jtag_speed", handle_jtag_speed_command,
zwelch's avatar
zwelch committed
600
		COMMAND_ANY, "(DEPRECATED) set jtag speed (if supported)");
601
	register_command(cmd_ctx, NULL, "jtag_khz", handle_jtag_khz_command,
zwelch's avatar
zwelch committed
602
603
		COMMAND_ANY, "set maximum jtag speed (if supported); "
		"parameter is maximum khz, or 0 for adaptive clocking (RTCK).");
604
	register_command(cmd_ctx, NULL, "jtag_device", handle_jtag_device_command,
zwelch's avatar
zwelch committed
605
		COMMAND_CONFIG, "(DEPRECATED) jtag_device <ir_length> <ir_expected> <ir_mask>");
606
	register_command(cmd_ctx, NULL, "reset_config", handle_reset_config_command,
607
608
		COMMAND_ANY,
		"[none/trst_only/srst_only/trst_and_srst] [srst_pulls_trst/trst_pulls_srst] [combined/separate] [trst_push_pull/trst_open_drain] [srst_push_pull/srst_open_drain]");
609
	register_command(cmd_ctx, NULL, "jtag_nsrst_delay", handle_jtag_nsrst_delay_command,
610
		COMMAND_ANY, "jtag_nsrst_delay <ms> - delay after deasserting srst in ms");
611
	register_command(cmd_ctx, NULL, "jtag_ntrst_delay", handle_jtag_ntrst_delay_command,
612
		COMMAND_ANY, "jtag_ntrst_delay <ms> - delay after deasserting trst in ms");
613

614
615
616
617
618
619
620
621
622
	register_command(cmd_ctx, NULL, "scan_chain", handle_scan_chain_command,
		COMMAND_EXEC, "print current scan chain configuration");

	register_command(cmd_ctx, NULL, "jtag_reset", handle_jtag_reset_command,
		COMMAND_EXEC, "toggle reset lines <trst> <srst>");
	register_command(cmd_ctx, NULL, "runtest", handle_runtest_command,
		COMMAND_EXEC, "move to Run-Test/Idle, and execute <num_cycles>");
	register_command(cmd_ctx, NULL, "irscan", handle_irscan_command,
		COMMAND_EXEC, "execute IR scan <device> <instr> [dev2] [instr2] ...");
623
	register_jim(cmd_ctx, "drscan", Jim_Command_drscan, "execute DR scan <device> <num_bits> <value> <num_bits1> <value2> ...");
624
	register_jim(cmd_ctx, "flush_count", Jim_Command_flush_count, "returns number of times the JTAG queue has been flushed");
625
626
627

	register_command(cmd_ctx, NULL, "verify_ircapture", handle_verify_ircapture_command,
		COMMAND_ANY, "verify value captured during Capture-IR <enable|disable>");
oharboe's avatar
oharboe committed
628
629
	register_command(cmd_ctx, NULL, "verify_jtag", handle_verify_jtag_command,
		COMMAND_ANY, "verify value capture <enable|disable>");
630
631
	register_command(cmd_ctx, NULL, "tms_sequence", handle_tms_sequence_command,
		COMMAND_ANY, "choose short(default) or long tms_sequence <short|long>");
632
633
634
	return ERROR_OK;
}

635
636
static int default_khz(int khz, int *jtag_speed)
{
637
	LOG_ERROR("Translation from khz to jtag_speed not implemented");
638
639
640
	return ERROR_FAIL;
}

oharboe's avatar
oharboe committed
641
static int default_speed_div(int speed, int *khz)
642
{
643
	LOG_ERROR("Translation from jtag_speed to khz not implemented");
644
645
646
647
648
649
650
651
652
653
654
655
656
	return ERROR_FAIL;
}

static int default_power_dropout(int *dropout)
{
	*dropout=0; /* by default we can't detect power dropout */
	return ERROR_OK;
}

static int default_srst_asserted(int *srst_asserted)
{
	*srst_asserted=0; /* by default we can't detect srst asserted */
	return ERROR_OK;
657
658
}

659
660
static int handle_interface_command(struct command_context_s *cmd_ctx,
		char *cmd, char **args, int argc)
661
662
663
664
{
	/* check whether the interface is already configured */
	if (jtag_interface)
	{
665
		LOG_WARNING("Interface already configured, ignoring");
666
667
668
669
		return ERROR_OK;
	}

	/* interface name is a mandatory argument */
670
	if (argc != 1 || args[0][0] == '\0')
671
672
		return ERROR_COMMAND_SYNTAX_ERROR;

673
	for (unsigned i = 0; NULL != jtag_interfaces[i]; i++)
674
	{
675
676
677
678
679
		if (strcmp(args[0], jtag_interfaces[i]->name) != 0)
			continue;

		int retval = jtag_interfaces[i]->register_commands(cmd_ctx);
		if (ERROR_OK != retval)
680
				return retval;
681

682
		jtag_interface = jtag_interfaces[i];
683

684
685
686
687
688
689
690
691
		if (jtag_interface->khz == NULL)
			jtag_interface->khz = default_khz;
		if (jtag_interface->speed_div == NULL)
			jtag_interface->speed_div = default_speed_div;
		if (jtag_interface->power_dropout == NULL)
			jtag_interface->power_dropout = default_power_dropout;
		if (jtag_interface->srst_asserted == NULL)
			jtag_interface->srst_asserted = default_srst_asserted;
692

693
		return ERROR_OK;
694
695
696
697
698
	}

	/* no valid interface was found (i.e. the configuration option,
	 * didn't match one of the compiled-in interfaces
	 */
699
	LOG_ERROR("The specified JTAG interface was not found (%s)", args[0]);
700
701
702
703
704
705
706
707
708
709
710
	handle_interface_list_command(cmd_ctx, cmd, args, argc);
	return ERROR_JTAG_INVALID_INTERFACE;
}

static int handle_interface_list_command(struct command_context_s *cmd_ctx,
		char *cmd, char **args, int argc)
{
	if (strcmp(cmd, "interface_list") == 0 && argc > 0)
		return ERROR_COMMAND_SYNTAX_ERROR;

	command_print(cmd_ctx, "The following JTAG interfaces are available:");
711
	for (unsigned i = 0; NULL != jtag_interfaces[i]; i++)
712
713
714
715
	{
		const char *name = jtag_interfaces[i]->name;
		command_print(cmd_ctx, "%u: %s", i + 1, name);
	}
716

717
	return ERROR_OK;
718
719
}

720
static int handle_jtag_device_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
721
{
722
723
724
	int e;
	char buf[1024];
	Jim_Obj *newargs[ 10 ];
725
726
727
728
729
730
731
732
	/*
	 * CONVERT SYNTAX
	 * argv[-1] = command
	 * argv[ 0] = ir length
	 * argv[ 1] = ir capture
	 * argv[ 2] = ir mask
	 * argv[ 3] = not actually used by anything but in the docs
	 */
oharboe's avatar
oharboe committed
733

734
735
	if( argc < 4 ){
		command_print( cmd_ctx, "OLD DEPRECATED SYNTAX: Please use the NEW syntax");
736
		return ERROR_OK;
737
738
739
740
741
742
	}
	command_print( cmd_ctx, "OLD SYNTAX: DEPRECATED - translating to new syntax");
	command_print( cmd_ctx, "jtag newtap CHIP TAP -irlen %s -ircapture %s -irvalue %s",
				   args[0],
				   args[1],
				   args[2] );
743
744
745
	command_print( cmd_ctx, "Example: STM32 has 2 taps, the cortexM3(len4) + boundaryscan(len5)");
	command_print( cmd_ctx, "jtag newtap stm32 cortexm3 ....., thus creating the tap: \"stm32.cortexm3\"");
	command_print( cmd_ctx, "jtag newtap stm32 boundary ....., and the tap: \"stm32.boundary\"");
746
	command_print( cmd_ctx, "And then refer to the taps by the dotted name.");
oharboe's avatar
oharboe committed
747

748
749
	newargs[0] = Jim_NewStringObj( interp, "jtag", -1   );
	newargs[1] = Jim_NewStringObj( interp, "newtap", -1 );
750
	sprintf( buf, "chip%d", jtag_tap_count() );
751
	newargs[2] = Jim_NewStringObj( interp, buf, -1 );
752
	sprintf( buf, "tap%d", jtag_tap_count() );
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
	newargs[3] = Jim_NewStringObj( interp, buf, -1  );
	newargs[4] = Jim_NewStringObj( interp, "-irlen", -1  );
	newargs[5] = Jim_NewStringObj( interp, args[0], -1  );
	newargs[6] = Jim_NewStringObj( interp, "-ircapture", -1  );
	newargs[7] = Jim_NewStringObj( interp, args[1], -1  );
	newargs[8] = Jim_NewStringObj( interp, "-irmask", -1  );
	newargs[9] = Jim_NewStringObj( interp, args[2], -1  );

	command_print( cmd_ctx, "NEW COMMAND:");
	sprintf( buf, "%s %s %s %s %s %s %s %s %s %s",
			 Jim_GetString( newargs[0], NULL ),
			 Jim_GetString( newargs[1], NULL ),
			 Jim_GetString( newargs[2], NULL ),
			 Jim_GetString( newargs[3], NULL ),
			 Jim_GetString( newargs[4], NULL ),
			 Jim_GetString( newargs[5], NULL ),
			 Jim_GetString( newargs[6], NULL ),
			 Jim_GetString( newargs[7], NULL ),
			 Jim_GetString( newargs[8], NULL ),
			 Jim_GetString( newargs[9], NULL ) );

	e = jim_jtag_command( interp, 10, newargs );
	if( e != JIM_OK ){
		command_print( cmd_ctx, "%s", Jim_GetString( Jim_GetResult(interp), NULL ) );
	}
	return e;
779
780
}

781
static int handle_scan_chain_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
782
{
783
	jtag_tap_t *tap;
784

785
	tap = jtag_all_taps();
786
787
788
789
	command_print(cmd_ctx, "     TapName            | Enabled |   IdCode      Expected    IrLen IrCap  IrMask Instr     ");
	command_print(cmd_ctx, "---|--------------------|---------|------------|------------|------|------|------|---------");

	while( tap ){
790
		u32 expected, expected_mask, cur_instr, ii;
791
792
793
		expected = buf_get_u32(tap->expected, 0, tap->ir_length);
		expected_mask = buf_get_u32(tap->expected_mask, 0, tap->ir_length);
		cur_instr = buf_get_u32(tap->cur_instr, 0, tap->ir_length);
794

795
796
797
798
799
		command_print(cmd_ctx,
					  "%2d | %-18s |    %c    | 0x%08x | 0x%08x | 0x%02x | 0x%02x | 0x%02x | 0x%02x",
					  tap->abs_chain_position,
					  tap->dotted_name,
					  tap->enabled ? 'Y' : 'n',
oharboe's avatar
oharboe committed
800
					  tap->idcode,
801
					  (tap->expected_ids_cnt > 0 ? tap->expected_ids[0] : 0),
oharboe's avatar
oharboe committed
802
803
804
					  tap->ir_length,
					  expected,
					  expected_mask,
805
					  cur_instr);
806
807
808
809
810
811

		for (ii = 1; ii < tap->expected_ids_cnt; ii++) {
			command_print(cmd_ctx, "   |                    |         |            | 0x%08x |      |      |      |         ",
						  tap->expected_ids[ii]);
		}

812
		tap = tap->next_tap;
813
814
815
816
817
	}

	return ERROR_OK;
}

818
static int handle_reset_config_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
819
{
zwelch's avatar
zwelch committed
820
821
822
	int new_cfg = 0;
	int mask = 0;

823
824
	if (argc < 1)
		return ERROR_COMMAND_SYNTAX_ERROR;
825

zwelch's avatar
zwelch committed
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
	/* Original versions cared about the order of these tokens:
	 *   reset_config signals [combination [trst_type [srst_type]]]
	 * They also clobbered the previous configuration even on error.
	 *
	 * Here we don't care about the order, and only change values
	 * which have been explicitly specified.
	 */
	for (; argc; argc--, args++) {
		int tmp = 0;
		int m;

		/* signals */
		m = RESET_HAS_TRST | RESET_HAS_SRST;
		if (strcmp(*args, "none") == 0)
			tmp = RESET_NONE;
		else if (strcmp(*args, "trst_only") == 0)
			tmp = RESET_HAS_TRST;
		else if (strcmp(*args, "srst_only") == 0)
			tmp = RESET_HAS_SRST;
		else if (strcmp(*args, "trst_and_srst") == 0)
			tmp = RESET_HAS_TRST | RESET_HAS_SRST;
847
		else
zwelch's avatar
zwelch committed
848
849
850
851
			m = 0;
		if (mask & m) {
			LOG_ERROR("extra reset_config %s spec (%s)",
					"signal", *args);
852
853
			return ERROR_INVALID_ARGUMENTS;
		}
zwelch's avatar
zwelch committed
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
		if (m)
			goto next;

		/* combination (options for broken wiring) */
		m = RESET_SRST_PULLS_TRST | RESET_TRST_PULLS_SRST;
		if (strcmp(*args, "separate") == 0)
			/* separate reset lines - default */;
		else if (strcmp(*args, "srst_pulls_trst") == 0)
			tmp |= RESET_SRST_PULLS_TRST;
		else if (strcmp(*args, "trst_pulls_srst") == 0)
			tmp |= RESET_TRST_PULLS_SRST;
		else if (strcmp(*args, "combined") == 0)
			tmp |= RESET_SRST_PULLS_TRST | RESET_TRST_PULLS_SRST;
		else
			m = 0;
		if (mask & m) {
			LOG_ERROR("extra reset_config %s spec (%s)",
					"combination", *args);
			return ERROR_INVALID_ARGUMENTS;
873
		}
zwelch's avatar
zwelch committed
874
875
876
877
878
879
880
881
882
		if (m)
			goto next;

		/* trst_type (NOP without HAS_TRST) */
		m = RESET_TRST_OPEN_DRAIN;
		if (strcmp(*args, "trst_open_drain") == 0)
			tmp |= RESET_TRST_OPEN_DRAIN;
		else if (strcmp(*args, "trst_push_pull") == 0)
			/* push/pull from adapter - default */;
883
		else
zwelch's avatar
zwelch committed
884
885
886
887
			m = 0;
		if (mask & m) {
			LOG_ERROR("extra reset_config %s spec (%s)",
					"trst_type", *args);
888
889
			return ERROR_INVALID_ARGUMENTS;
		}
zwelch's avatar
zwelch committed
890
891
892
893
894
895
896
897
898
		if (m)
			goto next;

		/* srst_type (NOP without HAS_SRST) */
		m |= RESET_SRST_PUSH_PULL;
		if (strcmp(*args, "srst_push_pull") == 0)
			tmp |= RESET_SRST_PUSH_PULL;
		else if (strcmp(*args, "srst_open_drain") == 0)
			/* open drain from adapter - default */;
899
		else
zwelch's avatar
zwelch committed
900
901
902
903
			m = 0;
		if (mask & m) {
			LOG_ERROR("extra reset_config %s spec (%s)",
					"srst_type", *args);
904
905
			return ERROR_INVALID_ARGUMENTS;
		}
zwelch's avatar
zwelch committed
906
907
908
909
910
911
912
913
914
915
916
917
918
		if (m)
			goto next;

		/* caller provided nonsense; fail */
		LOG_ERROR("unknown reset_config flag (%s)", *args);
		return ERROR_INVALID_ARGUMENTS;

next:
		/* Remember the bits which were specified (mask)
		 * and their new values (new_cfg).
		 */
		mask |= m;
		new_cfg |= tmp;
919
	}
920

zwelch's avatar
zwelch committed
921
922
923
924
	/* clear previous values of those bits, save new values */
	jtag_reset_config &= ~mask;
	jtag_reset_config |= new_cfg;

925
926
927
	return ERROR_OK;
}

928
929
static int handle_jtag_nsrst_delay_command(struct command_context_s *cmd_ctx,
		char *cmd, char **args, int argc)
930
{
931
	if (argc > 1)
932
		return ERROR_COMMAND_SYNTAX_ERROR;
933
934
935
	if (argc == 1)
		jtag_set_nsrst_delay(strtoul(args[0], NULL, 0));
	command_print(cmd_ctx, "jtag_nsrst_delay: %u", jtag_get_nsrst_delay());
936
937
938
	return ERROR_OK;
}

939
940
static int handle_jtag_ntrst_delay_command(struct command_context_s *cmd_ctx,
		char *cmd, char **args, int argc)
941
{
942
	if (argc > 1)
943
		return ERROR_COMMAND_SYNTAX_ERROR;
944
945
946
	if (argc == 1)
		jtag_set_ntrst_delay(strtoul(args[0], NULL, 0));
	command_print(cmd_ctx, "jtag_ntrst_delay: %u", jtag_get_ntrst_delay());
947
948
949
	return ERROR_OK;
}

950
static int handle_jtag_speed_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
951
{
952
	int retval = ERROR_OK;
953

954
955
	if (argc > 1)
		return ERROR_COMMAND_SYNTAX_ERROR;
oharboe's avatar
   
oharboe committed
956
	if (argc == 1)
oharboe's avatar
oharboe committed
957
958
	{
		LOG_DEBUG("handle jtag speed");
oharboe's avatar
   
oharboe committed
959
960
961

		int cur_speed = 0;
		cur_speed = jtag_speed = strtoul(args[0], NULL, 0);
962
963

		/* this command can be called during CONFIG,
oharboe's avatar
oharboe committed
964
965
		 * in which case jtag isn't initialized */
		if (jtag)
966
			retval = jtag->speed(cur_speed);
oharboe's avatar
   
oharboe committed
967
968
	}
	command_print(cmd_ctx, "jtag_speed: %d", jtag_speed);
969

oharboe's avatar
   
oharboe committed
970
	return retval;
971
972
}

973
static int handle_jtag_khz_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
974
{
975
976
	if (argc > 1)
		return ERROR_COMMAND_SYNTAX_ERROR;
977

978
	int retval = ERROR_OK;
979
	int cur_speed = 0;
980
	if (argc == 1)
oharboe's avatar
   
oharboe committed
981
	{
982
983
		LOG_DEBUG("handle jtag khz");

984
		jtag_set_speed_khz(strtoul(args[0], NULL, 0));
985
986
987
		if (jtag != NULL)
		{
			LOG_DEBUG("have interface set up");
oharboe's avatar
   
oharboe committed
988
			int speed_div1;
989
990
			retval = jtag->khz(jtag_get_speed_khz(), &speed_div1);
			if (ERROR_OK != retval)
oharboe's avatar
oharboe committed
991
			{
992
				jtag_set_speed_khz(0);
oharboe's avatar
   
oharboe committed
993
				return retval;
oharboe's avatar
oharboe committed
994
			}
oharboe's avatar
   
oharboe committed
995
			cur_speed = jtag_speed = speed_div1;
996

997
			retval = jtag->speed(cur_speed);
998
		}
999
1000
		else
			hasKHz = true;
For faster browsing, not all history is shown. View entire blame