tcl.c 39.9 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
43
44
45
46
47
static 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 }
};
48

49
50
/* jtag interfaces (parport, FTDI-USB, TI-USB, ...)
 */
51

52
#if BUILD_ECOSBOARD == 1
53
	extern jtag_interface_t zy1000_interface;
54
#elif defined(BUILD_MINIDRIVER_DUMMY)
55
	extern jtag_interface_t minidummy_interface;
56
#else // standard drivers
57
58
59
#if BUILD_PARPORT == 1
	extern jtag_interface_t parport_interface;
#endif
60

61
62
63
#if BUILD_DUMMY == 1
	extern jtag_interface_t dummy_interface;
#endif
64

65
66
67
68
69
70
71
72
73
74
75
76
#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

77
78
79
#if BUILD_EP93XX == 1
	extern jtag_interface_t ep93xx_interface;
#endif
80

81
82
83
#if BUILD_AT91RM9200 == 1
	extern jtag_interface_t at91rm9200_interface;
#endif
84

85
86
87
#if BUILD_GW16012 == 1
	extern jtag_interface_t gw16012_interface;
#endif
88

89
90
91
#if BUILD_PRESTO_LIBFTDI == 1 || BUILD_PRESTO_FTD2XX == 1
	extern jtag_interface_t presto_interface;
#endif
92

93
94
95
#if BUILD_USBPROG == 1
	extern jtag_interface_t usbprog_interface;
#endif
96

97
98
99
#if BUILD_JLINK == 1
	extern jtag_interface_t jlink_interface;
#endif
100

101
102
103
#if BUILD_VSLLINK == 1
	extern jtag_interface_t vsllink_interface;
#endif
104

105
106
107
#if BUILD_RLINK == 1
	extern jtag_interface_t rlink_interface;
#endif
108

109
110
111
112
#if BUILD_ARMJTAGEW == 1
	extern jtag_interface_t armjtagew_interface;
#endif
#endif // standard drivers
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
167
168
169
170
171
/**
 * 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,
};
172

173
extern jtag_interface_t *jtag_interface;
174

175
176
177
178
179
180
181
182
183
184
/* 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
185

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

188
189
190
191
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);
oharboe's avatar
oharboe committed
192
static int Jim_Command_pathmove(Jim_Interp *interp, int argc, Jim_Obj *const *argv);
193
static int Jim_Command_flush_count(Jim_Interp *interp, int argc, Jim_Obj *const *args);
194

195
196
197
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);
198

199
200
extern int jtag_examine_chain(void);
extern int jtag_validate_chain(void);
201

202
203
204
205
206
207
208
209
210
211
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
212
static int jtag_tap_configure_cmd( Jim_GetOptInfo *goi, jtag_tap_t * tap)
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
254
255
256
257
258
{
	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) {
259
						if (jteap->event == (enum jtag_tap_event)n->value) {
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
293
294
295
296
297
							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;
}
298

zwelch's avatar
zwelch committed
299
300
301
302
303
304
305
306
307
static int is_bad_irval(int ir_length, jim_wide w)
{
	jim_wide v = 1;

	v <<= ir_length;
	v -= 1;
	v = ~v;
	return (w & v) != 0;
}
308

309
static int jim_newtap_cmd( Jim_GetOptInfo *goi )
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
{
	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
326
		{ .name = "-enable"			,	.value = NTAP_OPT_ENABLED },
327
#define NTAP_OPT_DISABLED  4
328
		{ .name = "-disable"		,	.value = NTAP_OPT_DISABLED },
329
#define NTAP_OPT_EXPECTED_ID 5
330
331
		{ .name = "-expected-id"	,	.value = NTAP_OPT_EXPECTED_ID },
		{ .name = NULL				,	.value = -1 },
332
333
	};

zwelch's avatar
zwelch committed
334
335
336
	pTap = calloc(1, sizeof(jtag_tap_t));
	if (!pTap) {
		Jim_SetResult_sprintf(goi->interp, "no memory");
337
338
		return JIM_ERR;
	}
zwelch's avatar
zwelch committed
339

340
341
342
	/*
	 * we expect CHIP + TAP + OPTIONS
	 * */
343
344
345
346
347
348
349
350
351
	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
352

353
	/* name + dot + name + null */
354
355
356
357
358
	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
359
	LOG_DEBUG("Creating New Tap, Chip: %s, Tap: %s, Dotted: %s, %d params",
360
361
			  pTap->chip, pTap->tapname, pTap->dotted_name, goi->argc);

362
	/* deal with options */
363
364
365
366
#define NTREQ_IRLEN      1
#define NTREQ_IRCAPTURE  2
#define NTREQ_IRMASK     4

367
	/* clear them as we find them */
368
	reqbits = (NTREQ_IRLEN | NTREQ_IRCAPTURE | NTREQ_IRMASK);
oharboe's avatar
oharboe committed
369

370
371
372
373
374
375
376
377
378
	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:
zwelch's avatar
zwelch committed
379
			pTap->disabled_after_reset = false;
380
381
			break;
		case NTAP_OPT_DISABLED:
zwelch's avatar
zwelch committed
382
			pTap->disabled_after_reset = true;
383
384
			break;
		case NTAP_OPT_EXPECTED_ID:
385
386
387
		{
			u32 *new_expected_ids;

388
			e = Jim_GetOpt_Wide( goi, &w );
389
390
391
392
393
394
395
396
397
398
399
400
401
402
			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;
403
404

			free(pTap->expected_ids);
405
406
			pTap->expected_ids = new_expected_ids;
			pTap->expected_ids_cnt++;
407
			break;
408
		}
409
410
411
412
413
414
415
416
417
418
		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;
			}
			switch(n->value){
			case NTAP_OPT_IRLEN:
zwelch's avatar
zwelch committed
419
				if (w > (jim_wide) (8 * sizeof(pTap->ir_capture_value)))
zwelch's avatar
zwelch committed
420
					LOG_WARNING("huge IR length %d", (int) w);
421
422
423
424
				pTap->ir_length = w;
				reqbits &= (~(NTREQ_IRLEN));
				break;
			case NTAP_OPT_IRMASK:
zwelch's avatar
zwelch committed
425
426
427
428
429
				if (is_bad_irval(pTap->ir_length, w)) {
					LOG_ERROR("IR mask %x too big",
							(int) w);
					return ERROR_FAIL;
				}
430
431
432
433
				pTap->ir_capture_mask = w;
				reqbits &= (~(NTREQ_IRMASK));
				break;
			case NTAP_OPT_IRCAPTURE:
zwelch's avatar
zwelch committed
434
435
436
437
438
				if (is_bad_irval(pTap->ir_length, w)) {
					LOG_ERROR("IR capture %x too big",
							(int) w);
					return ERROR_FAIL;
				}
439
440
441
442
				pTap->ir_capture_value = w;
				reqbits &= (~(NTREQ_IRCAPTURE));
				break;
			}
443
444
		} /* switch(n->value) */
	} /* while( goi->argc ) */
445

zwelch's avatar
zwelch committed
446
447
448
	/* default is enabled-after-reset */
	pTap->enabled = !pTap->disabled_after_reset;

449
450
451
452
453
	/* Did all the required option bits get cleared? */
	if (0 == reqbits)
	{
		jtag_tap_init(pTap);
		return ERROR_OK;
454
455
	}

456
457
458
	Jim_SetResult_sprintf(goi->interp,
			"newtap: %s missing required parameters",
			pTap->dotted_name);
459
	jtag_tap_free(pTap);
460
461
	return JIM_ERR;
}
462

463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
static void jtag_tap_handle_event( jtag_tap_t * tap, enum jtag_tap_event e)
{
	jtag_tap_event_action_t * jteap;
	int done;

	jteap = tap->event_action;

	done = 0;
	while (jteap) {
		if (jteap->event == e) {
			done = 1;
			LOG_DEBUG( "JTAG tap: %s event: %d (%s) action: %s\n",
					tap->dotted_name,
					e,
					Jim_Nvp_value2name_simple(nvp_jtag_tap_event, e)->name,
					Jim_GetString(jteap->body, NULL) );
			if (Jim_EvalObj(interp, jteap->body) != JIM_OK) {
				Jim_PrintErrorMessage(interp);
			}
		}

		jteap = jteap->next;
	}

	if (!done) {
		LOG_DEBUG( "event %d %s - no action",
				e,
				Jim_Nvp_value2name_simple( nvp_jtag_tap_event, e)->name);
	}
}


495
static int jim_jtag_command( Jim_Interp *interp, int argc, Jim_Obj *const *argv )
496
497
498
499
{
	Jim_GetOptInfo goi;
	int e;
	Jim_Nvp *n;
500
	Jim_Obj *o;
501
502
503
504
505
	struct command_context_s *context;

	enum {
		JTAG_CMD_INTERFACE,
		JTAG_CMD_INIT_RESET,
506
507
508
		JTAG_CMD_NEWTAP,
		JTAG_CMD_TAPENABLE,
		JTAG_CMD_TAPDISABLE,
509
510
511
		JTAG_CMD_TAPISENABLED,
		JTAG_CMD_CONFIGURE,
		JTAG_CMD_CGET
512
	};
513

514
515
516
	const Jim_Nvp jtag_cmds[] = {
		{ .name = "interface"     , .value = JTAG_CMD_INTERFACE },
		{ .name = "arp_init-reset", .value = JTAG_CMD_INIT_RESET },
517
518
519
520
		{ .name = "newtap"        , .value = JTAG_CMD_NEWTAP },
		{ .name = "tapisenabled"     , .value = JTAG_CMD_TAPISENABLED },
		{ .name = "tapenable"     , .value = JTAG_CMD_TAPENABLE },
		{ .name = "tapdisable"    , .value = JTAG_CMD_TAPDISABLE },
521
522
		{ .name = "configure"     , .value = JTAG_CMD_CONFIGURE },
		{ .name = "cget"          , .value = JTAG_CMD_CGET },
523

524
525
526
527
		{ .name = NULL, .value = -1 },
	};

	context = Jim_GetAssocData(interp, "context");
528
	/* go past the command */
529
530
531
532
533
534
535
536
537
538
	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:
539
540
541
		/* 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. */
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
		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;
559
560
561
562
563
564
565
566
567
568
	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
569
570

		{
571
			jtag_tap_t *t;
572
			t = jtag_tap_by_jim_obj( goi.interp, goi.argv[0] );
573
574
575
576
577
			if( t == NULL ){
				return JIM_ERR;
			}
			switch( n->value ){
			case JTAG_CMD_TAPISENABLED:
578
				e = t->enabled;
579
580
				break;
			case JTAG_CMD_TAPENABLE:
581
				jtag_tap_handle_event( t, JTAG_TAP_EVENT_ENABLE);
582
583
584
585
				e = 1;
				t->enabled = e;
				break;
			case JTAG_CMD_TAPDISABLE:
586
				jtag_tap_handle_event( t, JTAG_TAP_EVENT_DISABLE);
587
588
589
590
591
592
593
				e = 0;
				t->enabled = e;
				break;
			}
			Jim_SetResult( goi.interp, Jim_NewIntObj( goi.interp, e ) );
			return JIM_OK;
		}
594
595
596
597
598
599
600
601
602
603
604
605
		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);
606
			t = jtag_tap_by_jim_obj( goi.interp, o );
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
			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);
626
			t = jtag_tap_by_jim_obj( goi.interp, o );
627
628
629
630
631
632
633
			if( t == NULL ){
				return JIM_ERR;
			}

			goi.isconfigure = 1;
			return jtag_tap_configure_cmd( &goi, t);
		}
634
	}
635

636
637
638
	return JIM_ERR;
}

639
640
int jtag_register_commands(struct command_context_s *cmd_ctx)
{
641
642
	register_jim( cmd_ctx, "jtag", jim_jtag_command, "perform jtag tap actions");

643
	register_command(cmd_ctx, NULL, "interface", handle_interface_command,
oharboe's avatar
oharboe committed
644
		COMMAND_CONFIG, "try to configure interface");
645
646
647
	register_command(cmd_ctx, NULL,
		"interface_list", &handle_interface_list_command,
		COMMAND_ANY, "list all built-in interfaces");
648
	register_command(cmd_ctx, NULL, "jtag_speed", handle_jtag_speed_command,
zwelch's avatar
zwelch committed
649
		COMMAND_ANY, "(DEPRECATED) set jtag speed (if supported)");
650
	register_command(cmd_ctx, NULL, "jtag_khz", handle_jtag_khz_command,
zwelch's avatar
zwelch committed
651
652
		COMMAND_ANY, "set maximum jtag speed (if supported); "
		"parameter is maximum khz, or 0 for adaptive clocking (RTCK).");
653
	register_command(cmd_ctx, NULL, "jtag_device", handle_jtag_device_command,
zwelch's avatar
zwelch committed
654
		COMMAND_CONFIG, "(DEPRECATED) jtag_device <ir_length> <ir_expected> <ir_mask>");
655
	register_command(cmd_ctx, NULL, "reset_config", handle_reset_config_command,
656
657
		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]");
658
	register_command(cmd_ctx, NULL, "jtag_nsrst_delay", handle_jtag_nsrst_delay_command,
659
		COMMAND_ANY, "jtag_nsrst_delay <ms> - delay after deasserting srst in ms");
660
	register_command(cmd_ctx, NULL, "jtag_ntrst_delay", handle_jtag_ntrst_delay_command,
661
		COMMAND_ANY, "jtag_ntrst_delay <ms> - delay after deasserting trst in ms");
662

663
664
665
666
667
668
669
670
671
	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] ...");
672
	register_jim(cmd_ctx, "drscan", Jim_Command_drscan, "execute DR scan <device> <num_bits> <value> <num_bits1> <value2> ...");
673
	register_jim(cmd_ctx, "flush_count", Jim_Command_flush_count, "returns number of times the JTAG queue has been flushed");
oharboe's avatar
oharboe committed
674
	register_jim(cmd_ctx, "pathmove", Jim_Command_pathmove, "move JTAG to state1 then to state2, state3, etc. <state1>,<state2>,<stat3>...");
675
676
677

	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
678
679
	register_command(cmd_ctx, NULL, "verify_jtag", handle_verify_jtag_command,
		COMMAND_ANY, "verify value capture <enable|disable>");
680
681
	register_command(cmd_ctx, NULL, "tms_sequence", handle_tms_sequence_command,
		COMMAND_ANY, "choose short(default) or long tms_sequence <short|long>");
682
683
684
	return ERROR_OK;
}

685
686
static int default_khz(int khz, int *jtag_speed)
{
687
	LOG_ERROR("Translation from khz to jtag_speed not implemented");
688
689
690
	return ERROR_FAIL;
}

oharboe's avatar
oharboe committed
691
static int default_speed_div(int speed, int *khz)
692
{
693
	LOG_ERROR("Translation from jtag_speed to khz not implemented");
694
695
696
697
698
699
700
701
702
703
704
705
706
	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;
707
708
}

709
710
static int handle_interface_command(struct command_context_s *cmd_ctx,
		char *cmd, char **args, int argc)
711
712
713
714
{
	/* check whether the interface is already configured */
	if (jtag_interface)
	{
715
		LOG_WARNING("Interface already configured, ignoring");
716
717
718
719
		return ERROR_OK;
	}

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

723
	for (unsigned i = 0; NULL != jtag_interfaces[i]; i++)
724
	{
725
726
727
728
729
		if (strcmp(args[0], jtag_interfaces[i]->name) != 0)
			continue;

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

732
		jtag_interface = jtag_interfaces[i];
733

734
735
736
737
738
739
740
741
		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;
742

743
		return ERROR_OK;
744
745
746
747
748
	}

	/* no valid interface was found (i.e. the configuration option,
	 * didn't match one of the compiled-in interfaces
	 */
749
	LOG_ERROR("The specified JTAG interface was not found (%s)", args[0]);
750
751
752
753
754
755
756
757
758
759
760
	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:");
761
	for (unsigned i = 0; NULL != jtag_interfaces[i]; i++)
762
763
764
765
	{
		const char *name = jtag_interfaces[i]->name;
		command_print(cmd_ctx, "%u: %s", i + 1, name);
	}
766

767
	return ERROR_OK;
768
769
}

770
static int handle_jtag_device_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
771
{
772
773
774
	int e;
	char buf[1024];
	Jim_Obj *newargs[ 10 ];
775
776
777
778
779
780
781
782
	/*
	 * 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
783

784
785
	if( argc < 4 ){
		command_print( cmd_ctx, "OLD DEPRECATED SYNTAX: Please use the NEW syntax");
786
		return ERROR_OK;
787
788
789
790
791
792
	}
	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] );
793
794
795
	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\"");
796
	command_print( cmd_ctx, "And then refer to the taps by the dotted name.");
oharboe's avatar
oharboe committed
797

798
799
	newargs[0] = Jim_NewStringObj( interp, "jtag", -1   );
	newargs[1] = Jim_NewStringObj( interp, "newtap", -1 );
800
	sprintf( buf, "chip%d", jtag_tap_count() );
801
	newargs[2] = Jim_NewStringObj( interp, buf, -1 );
802
	sprintf( buf, "tap%d", jtag_tap_count() );
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
	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;
829
830
}

831
static int handle_scan_chain_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
832
{
833
	jtag_tap_t *tap;
834

835
	tap = jtag_all_taps();
836
837
838
839
	command_print(cmd_ctx, "     TapName            | Enabled |   IdCode      Expected    IrLen IrCap  IrMask Instr     ");
	command_print(cmd_ctx, "---|--------------------|---------|------------|------------|------|------|------|---------");

	while( tap ){
840
		u32 expected, expected_mask, cur_instr, ii;
841
842
843
		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);
844

845
846
847
848
849
		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
850
					  tap->idcode,
851
					  (tap->expected_ids_cnt > 0 ? tap->expected_ids[0] : 0),
oharboe's avatar
oharboe committed
852
853
854
					  tap->ir_length,
					  expected,
					  expected_mask,
855
					  cur_instr);
856
857
858
859
860
861

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

862
		tap = tap->next_tap;
863
864
865
866
867
	}

	return ERROR_OK;
}

868
static int handle_reset_config_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
869
{
zwelch's avatar
zwelch committed
870
871
872
	int new_cfg = 0;
	int mask = 0;

873
874
	if (argc < 1)
		return ERROR_COMMAND_SYNTAX_ERROR;
875

zwelch's avatar
zwelch committed
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
	/* 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;
897
		else
zwelch's avatar
zwelch committed
898
899
900
901
			m = 0;
		if (mask & m) {
			LOG_ERROR("extra reset_config %s spec (%s)",
					"signal", *args);
902
903
			return ERROR_INVALID_ARGUMENTS;
		}
zwelch's avatar
zwelch committed
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
		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;
923
		}
zwelch's avatar
zwelch committed
924
925
926
927
928
929
930
931
932
		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 */;
933
		else
zwelch's avatar
zwelch committed
934
935
936
937
			m = 0;
		if (mask & m) {
			LOG_ERROR("extra reset_config %s spec (%s)",
					"trst_type", *args);
938
939
			return ERROR_INVALID_ARGUMENTS;
		}
zwelch's avatar
zwelch committed
940
941
942
943
944
945
946
947
948
		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 */;
949
		else
zwelch's avatar
zwelch committed
950
951
952
953
			m = 0;
		if (mask & m) {
			LOG_ERROR("extra reset_config %s spec (%s)",
					"srst_type", *args);
954
955
			return ERROR_INVALID_ARGUMENTS;
		}
zwelch's avatar
zwelch committed
956
957
958
959
960
961
962
963
964
965
966
967
968
		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;
969
	}
970

zwelch's avatar
zwelch committed
971
	/* clear previous values of those bits, save new values */
972
973
974
975
	enum reset_types old_cfg = jtag_get_reset_config();
	old_cfg &= ~mask;
	new_cfg |= old_cfg;
	jtag_set_reset_config(new_cfg);
zwelch's avatar
zwelch committed
976

977
978
979
	return ERROR_OK;
}

980
981
static int handle_jtag_nsrst_delay_command(struct command_context_s *cmd_ctx,
		char *cmd, char **args, int argc)
982
{
983
	if (argc > 1)
984
		return ERROR_COMMAND_SYNTAX_ERROR;
985
	if (argc == 1)
986
987
988
989
990
991
992
	{
		unsigned delay;
		int retval = parse_uint(args[0], &delay);
		if (ERROR_OK != retval)
			return retval;
		jtag_set_nsrst_delay(delay);
	}
993
	command_print(cmd_ctx, "jtag_nsrst_delay: %u", jtag_get_nsrst_delay());
994
995
996
	return ERROR_OK;
}

997
998
static int handle_jtag_ntrst_delay_command(struct command_context_s *cmd_ctx,
		char *cmd, char **args, int argc)
999
{
1000
	if (argc > 1)
For faster browsing, not all history is shown. View entire blame