6b420211c0d2ec815bd845cd4e26cd953b6f994c
[openocd.git] / src / jtag / tcl.c
1 /***************************************************************************
2 * Copyright (C) 2005 by Dominic Rath *
3 * Dominic.Rath@gmx.de *
4 * *
5 * Copyright (C) 2007,2008 Øyvind Harboe *
6 * oyvind.harboe@zylin.com *
7 * *
8 * Copyright (C) 2009 SoftPLC Corporation *
9 * http://softplc.com *
10 * dick@softplc.com *
11 * *
12 * Copyright (C) 2009 Zachary T Welch *
13 * zw@superlucidity.net *
14 * *
15 * This program is free software; you can redistribute it and/or modify *
16 * it under the terms of the GNU General Public License as published by *
17 * the Free Software Foundation; either version 2 of the License, or *
18 * (at your option) any later version. *
19 * *
20 * This program is distributed in the hope that it will be useful, *
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
23 * GNU General Public License for more details. *
24 * *
25 * You should have received a copy of the GNU General Public License *
26 * along with this program; if not, write to the *
27 * Free Software Foundation, Inc., *
28 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
29 ***************************************************************************/
30 #ifdef HAVE_CONFIG_H
31 #include "config.h"
32 #endif
33
34 #include "jtag.h"
35 #include "minidriver.h"
36 #include "interface.h"
37 #include "interfaces.h"
38
39 #ifdef HAVE_STRINGS_H
40 #include <strings.h>
41 #endif
42
43 static const Jim_Nvp nvp_jtag_tap_event[] = {
44 { .value = JTAG_TRST_ASSERTED, .name = "post-reset" },
45 { .value = JTAG_TAP_EVENT_SETUP, .name = "setup" },
46 { .value = JTAG_TAP_EVENT_ENABLE, .name = "tap-enable" },
47 { .value = JTAG_TAP_EVENT_DISABLE, .name = "tap-disable" },
48
49 { .name = NULL, .value = -1 }
50 };
51
52 extern struct jtag_interface *jtag_interface;
53
54 enum jtag_tap_cfg_param {
55 JCFG_EVENT
56 };
57
58 static Jim_Nvp nvp_config_opts[] = {
59 { .name = "-event", .value = JCFG_EVENT },
60
61 { .name = NULL, .value = -1 }
62 };
63
64 static int jtag_tap_configure_cmd(Jim_GetOptInfo *goi, struct jtag_tap * tap)
65 {
66 Jim_Nvp *n;
67 Jim_Obj *o;
68 int e;
69
70 /* parse config or cget options */
71 while (goi->argc > 0) {
72 Jim_SetEmptyResult (goi->interp);
73
74 e = Jim_GetOpt_Nvp(goi, nvp_config_opts, &n);
75 if (e != JIM_OK) {
76 Jim_GetOpt_NvpUnknown(goi, nvp_config_opts, 0);
77 return e;
78 }
79
80 switch (n->value) {
81 case JCFG_EVENT:
82 if (goi->argc == 0) {
83 Jim_WrongNumArgs(goi->interp, goi->argc, goi->argv, "-event ?event-name? ...");
84 return JIM_ERR;
85 }
86
87 e = Jim_GetOpt_Nvp(goi, nvp_jtag_tap_event, &n);
88 if (e != JIM_OK) {
89 Jim_GetOpt_NvpUnknown(goi, nvp_jtag_tap_event, 1);
90 return e;
91 }
92
93 if (goi->isconfigure) {
94 if (goi->argc != 1) {
95 Jim_WrongNumArgs(goi->interp, goi->argc, goi->argv, "-event ?event-name? ?EVENT-BODY?");
96 return JIM_ERR;
97 }
98 } else {
99 if (goi->argc != 0) {
100 Jim_WrongNumArgs(goi->interp, goi->argc, goi->argv, "-event ?event-name?");
101 return JIM_ERR;
102 }
103 }
104
105 {
106 struct jtag_tap_event_action *jteap;
107
108 jteap = tap->event_action;
109 /* replace existing? */
110 while (jteap) {
111 if (jteap->event == (enum jtag_event)n->value) {
112 break;
113 }
114 jteap = jteap->next;
115 }
116
117 if (goi->isconfigure) {
118 bool replace = true;
119 if (jteap == NULL) {
120 /* create new */
121 jteap = calloc(1, sizeof (*jteap));
122 replace = false;
123 }
124 jteap->event = n->value;
125 Jim_GetOpt_Obj(goi, &o);
126 if (jteap->body) {
127 Jim_DecrRefCount(interp, jteap->body);
128 }
129 jteap->body = Jim_DuplicateObj(goi->interp, o);
130 Jim_IncrRefCount(jteap->body);
131
132 if (!replace)
133 {
134 /* add to head of event list */
135 jteap->next = tap->event_action;
136 tap->event_action = jteap;
137 }
138 Jim_SetEmptyResult(goi->interp);
139 } else {
140 /* get */
141 if (jteap == NULL) {
142 Jim_SetEmptyResult(goi->interp);
143 } else {
144 Jim_SetResult(goi->interp, Jim_DuplicateObj(goi->interp, jteap->body));
145 }
146 }
147 }
148 /* loop for more */
149 break;
150 }
151 } /* while (goi->argc) */
152
153 return JIM_OK;
154 }
155
156 static int is_bad_irval(int ir_length, jim_wide w)
157 {
158 jim_wide v = 1;
159
160 v <<= ir_length;
161 v -= 1;
162 v = ~v;
163 return (w & v) != 0;
164 }
165
166 static int jim_newtap_cmd(Jim_GetOptInfo *goi)
167 {
168 struct jtag_tap *pTap;
169 jim_wide w;
170 int x;
171 int e;
172 Jim_Nvp *n;
173 char *cp;
174 const Jim_Nvp opts[] = {
175 #define NTAP_OPT_IRLEN 0
176 { .name = "-irlen" , .value = NTAP_OPT_IRLEN },
177 #define NTAP_OPT_IRMASK 1
178 { .name = "-irmask" , .value = NTAP_OPT_IRMASK },
179 #define NTAP_OPT_IRCAPTURE 2
180 { .name = "-ircapture" , .value = NTAP_OPT_IRCAPTURE },
181 #define NTAP_OPT_ENABLED 3
182 { .name = "-enable" , .value = NTAP_OPT_ENABLED },
183 #define NTAP_OPT_DISABLED 4
184 { .name = "-disable" , .value = NTAP_OPT_DISABLED },
185 #define NTAP_OPT_EXPECTED_ID 5
186 { .name = "-expected-id" , .value = NTAP_OPT_EXPECTED_ID },
187 { .name = NULL , .value = -1 },
188 };
189
190 pTap = calloc(1, sizeof(struct jtag_tap));
191 if (!pTap) {
192 Jim_SetResult_sprintf(goi->interp, "no memory");
193 return JIM_ERR;
194 }
195
196 /*
197 * we expect CHIP + TAP + OPTIONS
198 * */
199 if (goi->argc < 3) {
200 Jim_SetResult_sprintf(goi->interp, "Missing CHIP TAP OPTIONS ....");
201 free(pTap);
202 return JIM_ERR;
203 }
204 Jim_GetOpt_String(goi, &cp, NULL);
205 pTap->chip = strdup(cp);
206
207 Jim_GetOpt_String(goi, &cp, NULL);
208 pTap->tapname = strdup(cp);
209
210 /* name + dot + name + null */
211 x = strlen(pTap->chip) + 1 + strlen(pTap->tapname) + 1;
212 cp = malloc(x);
213 sprintf(cp, "%s.%s", pTap->chip, pTap->tapname);
214 pTap->dotted_name = cp;
215
216 LOG_DEBUG("Creating New Tap, Chip: %s, Tap: %s, Dotted: %s, %d params",
217 pTap->chip, pTap->tapname, pTap->dotted_name, goi->argc);
218
219 /* IEEE specifies that the two LSBs of an IR scan are 01, so make
220 * that the default. The "-irlen" and "-irmask" options are only
221 * needed to cope with nonstandard TAPs, or to specify more bits.
222 */
223 pTap->ir_capture_mask = 0x03;
224 pTap->ir_capture_value = 0x01;
225
226 while (goi->argc) {
227 e = Jim_GetOpt_Nvp(goi, opts, &n);
228 if (e != JIM_OK) {
229 Jim_GetOpt_NvpUnknown(goi, opts, 0);
230 free((void *)pTap->dotted_name);
231 free(pTap);
232 return e;
233 }
234 LOG_DEBUG("Processing option: %s", n->name);
235 switch (n->value) {
236 case NTAP_OPT_ENABLED:
237 pTap->disabled_after_reset = false;
238 break;
239 case NTAP_OPT_DISABLED:
240 pTap->disabled_after_reset = true;
241 break;
242 case NTAP_OPT_EXPECTED_ID:
243 {
244 uint32_t *new_expected_ids;
245
246 e = Jim_GetOpt_Wide(goi, &w);
247 if (e != JIM_OK) {
248 Jim_SetResult_sprintf(goi->interp, "option: %s bad parameter", n->name);
249 free((void *)pTap->dotted_name);
250 free(pTap);
251 return e;
252 }
253
254 new_expected_ids = malloc(sizeof(uint32_t) * (pTap->expected_ids_cnt + 1));
255 if (new_expected_ids == NULL) {
256 Jim_SetResult_sprintf(goi->interp, "no memory");
257 free((void *)pTap->dotted_name);
258 free(pTap);
259 return JIM_ERR;
260 }
261
262 memcpy(new_expected_ids, pTap->expected_ids, sizeof(uint32_t) * pTap->expected_ids_cnt);
263
264 new_expected_ids[pTap->expected_ids_cnt] = w;
265
266 free(pTap->expected_ids);
267 pTap->expected_ids = new_expected_ids;
268 pTap->expected_ids_cnt++;
269 break;
270 }
271 case NTAP_OPT_IRLEN:
272 case NTAP_OPT_IRMASK:
273 case NTAP_OPT_IRCAPTURE:
274 e = Jim_GetOpt_Wide(goi, &w);
275 if (e != JIM_OK) {
276 Jim_SetResult_sprintf(goi->interp, "option: %s bad parameter", n->name);
277 free((void *)pTap->dotted_name);
278 free(pTap);
279 return e;
280 }
281 switch (n->value) {
282 case NTAP_OPT_IRLEN:
283 if (w > (jim_wide) (8 * sizeof(pTap->ir_capture_value)))
284 LOG_WARNING("%s: huge IR length %d",
285 pTap->dotted_name,
286 (int) w);
287 pTap->ir_length = w;
288 break;
289 case NTAP_OPT_IRMASK:
290 if (is_bad_irval(pTap->ir_length, w)) {
291 LOG_ERROR("%s: IR mask %x too big",
292 pTap->dotted_name,
293 (int) w);
294 free((void *)pTap->dotted_name);
295 free(pTap);
296 return ERROR_FAIL;
297 }
298 if ((w & 3) != 3)
299 LOG_WARNING("%s: nonstandard IR mask",
300 pTap->dotted_name);
301 pTap->ir_capture_mask = w;
302 break;
303 case NTAP_OPT_IRCAPTURE:
304 if (is_bad_irval(pTap->ir_length, w)) {
305 LOG_ERROR("%s: IR capture %x too big",
306 pTap->dotted_name,
307 (int) w);
308 free((void *)pTap->dotted_name);
309 free(pTap);
310 return ERROR_FAIL;
311 }
312 if ((w & 3) != 1)
313 LOG_WARNING("%s: nonstandard IR value",
314 pTap->dotted_name);
315 pTap->ir_capture_value = w;
316 break;
317 }
318 } /* switch (n->value) */
319 } /* while (goi->argc) */
320
321 /* default is enabled-after-reset */
322 pTap->enabled = !pTap->disabled_after_reset;
323
324 /* Did all the required option bits get cleared? */
325 if (pTap->ir_length != 0)
326 {
327 jtag_tap_init(pTap);
328 return ERROR_OK;
329 }
330
331 Jim_SetResult_sprintf(goi->interp,
332 "newtap: %s missing IR length",
333 pTap->dotted_name);
334 jtag_tap_free(pTap);
335 return JIM_ERR;
336 }
337
338 static void jtag_tap_handle_event(struct jtag_tap *tap, enum jtag_event e)
339 {
340 struct jtag_tap_event_action * jteap;
341
342 for (jteap = tap->event_action; jteap != NULL; jteap = jteap->next) {
343 if (jteap->event == e) {
344 LOG_DEBUG("JTAG tap: %s event: %d (%s)\n\taction: %s",
345 tap->dotted_name,
346 e,
347 Jim_Nvp_value2name_simple(nvp_jtag_tap_event, e)->name,
348 Jim_GetString(jteap->body, NULL));
349 if (Jim_EvalObj(interp, jteap->body) != JIM_OK) {
350 Jim_PrintErrorMessage(interp);
351 } else switch (e) {
352 case JTAG_TAP_EVENT_ENABLE:
353 case JTAG_TAP_EVENT_DISABLE:
354 /* NOTE: we currently assume the handlers
355 * can't fail. Right here is where we should
356 * really be verifying the scan chains ...
357 */
358 tap->enabled = (e == JTAG_TAP_EVENT_ENABLE);
359 LOG_INFO("JTAG tap: %s %s", tap->dotted_name,
360 tap->enabled ? "enabled" : "disabled");
361 break;
362 default:
363 break;
364 }
365 }
366 }
367 }
368
369
370 static int jim_jtag_command(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
371 {
372 Jim_GetOptInfo goi;
373 int e;
374 Jim_Nvp *n;
375 Jim_Obj *o;
376 struct command_context *context;
377
378 enum {
379 JTAG_CMD_INTERFACE,
380 JTAG_CMD_INIT,
381 JTAG_CMD_INIT_RESET,
382 JTAG_CMD_NEWTAP,
383 JTAG_CMD_TAPENABLE,
384 JTAG_CMD_TAPDISABLE,
385 JTAG_CMD_TAPISENABLED,
386 JTAG_CMD_CONFIGURE,
387 JTAG_CMD_CGET,
388 JTAG_CMD_NAMES,
389 };
390
391 const Jim_Nvp jtag_cmds[] = {
392 { .name = "interface" , .value = JTAG_CMD_INTERFACE },
393 { .name = "arp_init" , .value = JTAG_CMD_INIT },
394 { .name = "arp_init-reset", .value = JTAG_CMD_INIT_RESET },
395 { .name = "newtap" , .value = JTAG_CMD_NEWTAP },
396 { .name = "tapisenabled" , .value = JTAG_CMD_TAPISENABLED },
397 { .name = "tapenable" , .value = JTAG_CMD_TAPENABLE },
398 { .name = "tapdisable" , .value = JTAG_CMD_TAPDISABLE },
399 { .name = "configure" , .value = JTAG_CMD_CONFIGURE },
400 { .name = "cget" , .value = JTAG_CMD_CGET },
401 { .name = "names" , .value = JTAG_CMD_NAMES },
402
403 { .name = NULL, .value = -1 },
404 };
405
406 context = Jim_GetAssocData(interp, "context");
407 /* go past the command */
408 Jim_GetOpt_Setup(&goi, interp, argc-1, argv + 1);
409
410 e = Jim_GetOpt_Nvp(&goi, jtag_cmds, &n);
411 if (e != JIM_OK) {
412 Jim_GetOpt_NvpUnknown(&goi, jtag_cmds, 0);
413 return e;
414 }
415 Jim_SetEmptyResult(goi.interp);
416 switch (n->value) {
417 case JTAG_CMD_INTERFACE:
418 /* return the name of the interface */
419 /* TCL code might need to know the exact type... */
420 /* FUTURE: we allow this as a means to "set" the interface. */
421 if (goi.argc != 0) {
422 Jim_WrongNumArgs(goi.interp, 1, goi.argv-1, "(no params)");
423 return JIM_ERR;
424 }
425 const char *name = jtag_interface ? jtag_interface->name : NULL;
426 Jim_SetResultString(goi.interp, name ? : "undefined", -1);
427 return JIM_OK;
428 case JTAG_CMD_INIT:
429 if (goi.argc != 0) {
430 Jim_WrongNumArgs(goi.interp, 1, goi.argv-1, "(no params)");
431 return JIM_ERR;
432 }
433 e = jtag_init_inner(context);
434 if (e != ERROR_OK) {
435 Jim_SetResult_sprintf(goi.interp, "error: %d", e);
436 return JIM_ERR;
437 }
438 return JIM_OK;
439 case JTAG_CMD_INIT_RESET:
440 if (goi.argc != 0) {
441 Jim_WrongNumArgs(goi.interp, 1, goi.argv-1, "(no params)");
442 return JIM_ERR;
443 }
444 e = jtag_init_reset(context);
445 if (e != ERROR_OK) {
446 Jim_SetResult_sprintf(goi.interp, "error: %d", e);
447 return JIM_ERR;
448 }
449 return JIM_OK;
450 case JTAG_CMD_NEWTAP:
451 return jim_newtap_cmd(&goi);
452 break;
453 case JTAG_CMD_TAPISENABLED:
454 case JTAG_CMD_TAPENABLE:
455 case JTAG_CMD_TAPDISABLE:
456 if (goi.argc != 1) {
457 Jim_SetResultString(goi.interp, "Too many parameters",-1);
458 return JIM_ERR;
459 }
460
461 {
462 struct jtag_tap *t;
463
464 t = jtag_tap_by_jim_obj(goi.interp, goi.argv[0]);
465 if (t == NULL)
466 return JIM_ERR;
467
468 switch (n->value) {
469 case JTAG_CMD_TAPISENABLED:
470 break;
471 case JTAG_CMD_TAPENABLE:
472 if (t->enabled)
473 break;
474 jtag_tap_handle_event(t, JTAG_TAP_EVENT_ENABLE);
475 if (!t->enabled)
476 break;
477
478 /* FIXME add JTAG sanity checks, w/o TLR
479 * - scan chain length grew by one (this)
480 * - IDs and IR lengths are as expected
481 */
482
483 jtag_call_event_callbacks(JTAG_TAP_EVENT_ENABLE);
484 break;
485 case JTAG_CMD_TAPDISABLE:
486 if (!t->enabled)
487 break;
488 jtag_tap_handle_event(t, JTAG_TAP_EVENT_DISABLE);
489 if (t->enabled)
490 break;
491
492 /* FIXME add JTAG sanity checks, w/o TLR
493 * - scan chain length shrank by one (this)
494 * - IDs and IR lengths are as expected
495 */
496
497 jtag_call_event_callbacks(JTAG_TAP_EVENT_DISABLE);
498 break;
499 }
500 e = t->enabled;
501 Jim_SetResult(goi.interp, Jim_NewIntObj(goi.interp, e));
502 return JIM_OK;
503 }
504 break;
505
506 case JTAG_CMD_CGET:
507 if (goi.argc < 2) {
508 Jim_WrongNumArgs(goi.interp, 0, NULL,
509 "cget tap_name queryparm");
510 return JIM_ERR;
511 }
512
513 {
514 struct jtag_tap *t;
515
516 Jim_GetOpt_Obj(&goi, &o);
517 t = jtag_tap_by_jim_obj(goi.interp, o);
518 if (t == NULL) {
519 return JIM_ERR;
520 }
521
522 goi.isconfigure = 0;
523 return jtag_tap_configure_cmd(&goi, t);
524 }
525 break;
526
527 case JTAG_CMD_CONFIGURE:
528 if (goi.argc < 3) {
529 Jim_WrongNumArgs(goi.interp, 0, NULL,
530 "configure tap_name attribute value ...");
531 return JIM_ERR;
532 }
533
534 {
535 struct jtag_tap *t;
536
537 Jim_GetOpt_Obj(&goi, &o);
538 t = jtag_tap_by_jim_obj(goi.interp, o);
539 if (t == NULL) {
540 return JIM_ERR;
541 }
542
543 goi.isconfigure = 1;
544 return jtag_tap_configure_cmd(&goi, t);
545 }
546 break;
547
548 case JTAG_CMD_NAMES:
549 if (goi.argc != 0) {
550 Jim_WrongNumArgs(goi.interp, 1, goi.argv, "Too many parameters");
551 return JIM_ERR;
552 }
553 Jim_SetResult(goi.interp, Jim_NewListObj(goi.interp, NULL, 0));
554 {
555 struct jtag_tap *tap;
556
557 for (tap = jtag_all_taps(); tap; tap = tap->next_tap) {
558 Jim_ListAppendElement(goi.interp,
559 Jim_GetResult(goi.interp),
560 Jim_NewStringObj(goi.interp,
561 tap->dotted_name, -1));
562 }
563 return JIM_OK;
564 }
565 break;
566
567 }
568
569 return JIM_ERR;
570 }
571
572
573 void jtag_notify_event(enum jtag_event event)
574 {
575 struct jtag_tap *tap;
576
577 for (tap = jtag_all_taps(); tap; tap = tap->next_tap)
578 jtag_tap_handle_event(tap, event);
579 }
580
581
582 static int default_khz(int khz, int *jtag_speed)
583 {
584 LOG_ERROR("Translation from khz to jtag_speed not implemented");
585 return ERROR_FAIL;
586 }
587
588 static int default_speed_div(int speed, int *khz)
589 {
590 LOG_ERROR("Translation from jtag_speed to khz not implemented");
591 return ERROR_FAIL;
592 }
593
594 static int default_power_dropout(int *dropout)
595 {
596 *dropout = 0; /* by default we can't detect power dropout */
597 return ERROR_OK;
598 }
599
600 static int default_srst_asserted(int *srst_asserted)
601 {
602 *srst_asserted = 0; /* by default we can't detect srst asserted */
603 return ERROR_OK;
604 }
605
606 COMMAND_HANDLER(handle_interface_list_command)
607 {
608 if (strcmp(CMD_NAME, "interface_list") == 0 && CMD_ARGC > 0)
609 return ERROR_COMMAND_SYNTAX_ERROR;
610
611 command_print(CMD_CTX, "The following JTAG interfaces are available:");
612 for (unsigned i = 0; NULL != jtag_interfaces[i]; i++)
613 {
614 const char *name = jtag_interfaces[i]->name;
615 command_print(CMD_CTX, "%u: %s", i + 1, name);
616 }
617
618 return ERROR_OK;
619 }
620
621 COMMAND_HANDLER(handle_interface_command)
622 {
623 /* check whether the interface is already configured */
624 if (jtag_interface)
625 {
626 LOG_WARNING("Interface already configured, ignoring");
627 return ERROR_OK;
628 }
629
630 /* interface name is a mandatory argument */
631 if (CMD_ARGC != 1 || CMD_ARGV[0][0] == '\0')
632 return ERROR_COMMAND_SYNTAX_ERROR;
633
634 for (unsigned i = 0; NULL != jtag_interfaces[i]; i++)
635 {
636 if (strcmp(CMD_ARGV[0], jtag_interfaces[i]->name) != 0)
637 continue;
638
639 if (NULL != jtag_interfaces[i]->commands)
640 {
641 int retval = register_commands(CMD_CTX, NULL,
642 jtag_interfaces[i]->commands);
643 if (ERROR_OK != retval)
644 return retval;
645 }
646
647 jtag_interface = jtag_interfaces[i];
648
649 if (jtag_interface->khz == NULL)
650 jtag_interface->khz = default_khz;
651 if (jtag_interface->speed_div == NULL)
652 jtag_interface->speed_div = default_speed_div;
653 if (jtag_interface->power_dropout == NULL)
654 jtag_interface->power_dropout = default_power_dropout;
655 if (jtag_interface->srst_asserted == NULL)
656 jtag_interface->srst_asserted = default_srst_asserted;
657
658 return ERROR_OK;
659 }
660
661 /* no valid interface was found (i.e. the configuration option,
662 * didn't match one of the compiled-in interfaces
663 */
664 LOG_ERROR("The specified JTAG interface was not found (%s)", CMD_ARGV[0]);
665 CALL_COMMAND_HANDLER(handle_interface_list_command);
666 return ERROR_JTAG_INVALID_INTERFACE;
667 }
668
669 COMMAND_HANDLER(handle_scan_chain_command)
670 {
671 struct jtag_tap *tap;
672
673 tap = jtag_all_taps();
674 command_print(CMD_CTX, " TapName | Enabled | IdCode Expected IrLen IrCap IrMask Instr ");
675 command_print(CMD_CTX, "---|--------------------|---------|------------|------------|------|------|------|---------");
676
677 while (tap) {
678 uint32_t expected, expected_mask, cur_instr, ii;
679 expected = buf_get_u32(tap->expected, 0, tap->ir_length);
680 expected_mask = buf_get_u32(tap->expected_mask, 0, tap->ir_length);
681 cur_instr = buf_get_u32(tap->cur_instr, 0, tap->ir_length);
682
683 command_print(CMD_CTX,
684 "%2d | %-18s | %c | 0x%08x | 0x%08x | 0x%02x | 0x%02x | 0x%02x | 0x%02x",
685 tap->abs_chain_position,
686 tap->dotted_name,
687 tap->enabled ? 'Y' : 'n',
688 (unsigned int)(tap->idcode),
689 (unsigned int)(tap->expected_ids_cnt > 0 ? tap->expected_ids[0] : 0),
690 (unsigned int)(tap->ir_length),
691 (unsigned int)(expected),
692 (unsigned int)(expected_mask),
693 (unsigned int)(cur_instr));
694
695 for (ii = 1; ii < tap->expected_ids_cnt; ii++) {
696 command_print(CMD_CTX, " | | | | 0x%08x | | | | ",
697 (unsigned int)(tap->expected_ids[ii]));
698 }
699
700 tap = tap->next_tap;
701 }
702
703 return ERROR_OK;
704 }
705
706 COMMAND_HANDLER(handle_reset_config_command)
707 {
708 int new_cfg = 0;
709 int mask = 0;
710
711 /* Original versions cared about the order of these tokens:
712 * reset_config signals [combination [trst_type [srst_type]]]
713 * They also clobbered the previous configuration even on error.
714 *
715 * Here we don't care about the order, and only change values
716 * which have been explicitly specified.
717 */
718 for (; CMD_ARGC; CMD_ARGC--, CMD_ARGV++) {
719 int tmp = 0;
720 int m;
721
722 /* gating */
723 m = RESET_SRST_NO_GATING;
724 if (strcmp(*CMD_ARGV, "srst_gates_jtag") == 0)
725 /* default: don't use JTAG while SRST asserted */;
726 else if (strcmp(*CMD_ARGV, "srst_nogate") == 0)
727 tmp = RESET_SRST_NO_GATING;
728 else
729 m = 0;
730 if (mask & m) {
731 LOG_ERROR("extra reset_config %s spec (%s)",
732 "gating", *CMD_ARGV);
733 return ERROR_INVALID_ARGUMENTS;
734 }
735 if (m)
736 goto next;
737
738 /* signals */
739 m = RESET_HAS_TRST | RESET_HAS_SRST;
740 if (strcmp(*CMD_ARGV, "none") == 0)
741 tmp = RESET_NONE;
742 else if (strcmp(*CMD_ARGV, "trst_only") == 0)
743 tmp = RESET_HAS_TRST;
744 else if (strcmp(*CMD_ARGV, "srst_only") == 0)
745 tmp = RESET_HAS_SRST;
746 else if (strcmp(*CMD_ARGV, "trst_and_srst") == 0)
747 tmp = RESET_HAS_TRST | RESET_HAS_SRST;
748 else
749 m = 0;
750 if (mask & m) {
751 LOG_ERROR("extra reset_config %s spec (%s)",
752 "signal", *CMD_ARGV);
753 return ERROR_INVALID_ARGUMENTS;
754 }
755 if (m)
756 goto next;
757
758 /* combination (options for broken wiring) */
759 m = RESET_SRST_PULLS_TRST | RESET_TRST_PULLS_SRST;
760 if (strcmp(*CMD_ARGV, "separate") == 0)
761 /* separate reset lines - default */;
762 else if (strcmp(*CMD_ARGV, "srst_pulls_trst") == 0)
763 tmp |= RESET_SRST_PULLS_TRST;
764 else if (strcmp(*CMD_ARGV, "trst_pulls_srst") == 0)
765 tmp |= RESET_TRST_PULLS_SRST;
766 else if (strcmp(*CMD_ARGV, "combined") == 0)
767 tmp |= RESET_SRST_PULLS_TRST | RESET_TRST_PULLS_SRST;
768 else
769 m = 0;
770 if (mask & m) {
771 LOG_ERROR("extra reset_config %s spec (%s)",
772 "combination", *CMD_ARGV);
773 return ERROR_INVALID_ARGUMENTS;
774 }
775 if (m)
776 goto next;
777
778 /* trst_type (NOP without HAS_TRST) */
779 m = RESET_TRST_OPEN_DRAIN;
780 if (strcmp(*CMD_ARGV, "trst_open_drain") == 0)
781 tmp |= RESET_TRST_OPEN_DRAIN;
782 else if (strcmp(*CMD_ARGV, "trst_push_pull") == 0)
783 /* push/pull from adapter - default */;
784 else
785 m = 0;
786 if (mask & m) {
787 LOG_ERROR("extra reset_config %s spec (%s)",
788 "trst_type", *CMD_ARGV);
789 return ERROR_INVALID_ARGUMENTS;
790 }
791 if (m)
792 goto next;
793
794 /* srst_type (NOP without HAS_SRST) */
795 m |= RESET_SRST_PUSH_PULL;
796 if (strcmp(*CMD_ARGV, "srst_push_pull") == 0)
797 tmp |= RESET_SRST_PUSH_PULL;
798 else if (strcmp(*CMD_ARGV, "srst_open_drain") == 0)
799 /* open drain from adapter - default */;
800 else
801 m = 0;
802 if (mask & m) {
803 LOG_ERROR("extra reset_config %s spec (%s)",
804 "srst_type", *CMD_ARGV);
805 return ERROR_INVALID_ARGUMENTS;
806 }
807 if (m)
808 goto next;
809
810 /* caller provided nonsense; fail */
811 LOG_ERROR("unknown reset_config flag (%s)", *CMD_ARGV);
812 return ERROR_INVALID_ARGUMENTS;
813
814 next:
815 /* Remember the bits which were specified (mask)
816 * and their new values (new_cfg).
817 */
818 mask |= m;
819 new_cfg |= tmp;
820 }
821
822 /* clear previous values of those bits, save new values */
823 if (mask) {
824 int old_cfg = jtag_get_reset_config();
825
826 old_cfg &= ~mask;
827 new_cfg |= old_cfg;
828 jtag_set_reset_config(new_cfg);
829 } else
830 new_cfg = jtag_get_reset_config();
831
832
833 /*
834 * Display the (now-)current reset mode
835 */
836 char *modes[5];
837
838 /* minimal JTAG has neither SRST nor TRST (so that's the default) */
839 switch (new_cfg & (RESET_HAS_TRST | RESET_HAS_SRST)) {
840 case RESET_HAS_SRST:
841 modes[0] = "srst_only";
842 break;
843 case RESET_HAS_TRST:
844 modes[0] = "trst_only";
845 break;
846 case RESET_TRST_AND_SRST:
847 modes[0] = "trst_and_srst";
848 break;
849 default:
850 modes[0] = "none";
851 break;
852 }
853
854 /* normally SRST and TRST are decoupled; but bugs happen ... */
855 switch (new_cfg & (RESET_SRST_PULLS_TRST | RESET_TRST_PULLS_SRST)) {
856 case RESET_SRST_PULLS_TRST:
857 modes[1] = "srst_pulls_trst";
858 break;
859 case RESET_TRST_PULLS_SRST:
860 modes[1] = "trst_pulls_srst";
861 break;
862 case RESET_SRST_PULLS_TRST | RESET_TRST_PULLS_SRST:
863 modes[1] = "combined";
864 break;
865 default:
866 modes[1] = "separate";
867 break;
868 }
869
870 /* TRST-less connectors include Altera, Xilinx, and minimal JTAG */
871 if (new_cfg & RESET_HAS_TRST) {
872 if (new_cfg & RESET_TRST_OPEN_DRAIN)
873 modes[3] = " trst_open_drain";
874 else
875 modes[3] = " trst_push_pull";
876 } else
877 modes[3] = "";
878
879 /* SRST-less connectors include TI-14, Xilinx, and minimal JTAG */
880 if (new_cfg & RESET_HAS_SRST) {
881 if (new_cfg & RESET_SRST_NO_GATING)
882 modes[2] = " srst_nogate";
883 else
884 modes[2] = " srst_gates_jtag";
885
886 if (new_cfg & RESET_SRST_PUSH_PULL)
887 modes[4] = " srst_push_pull";
888 else
889 modes[4] = " srst_open_drain";
890 } else {
891 modes[2] = "";
892 modes[4] = "";
893 }
894
895 command_print(CMD_CTX, "%s %s%s%s%s",
896 modes[0], modes[1],
897 modes[2], modes[3], modes[4]);
898
899 return ERROR_OK;
900 }
901
902 COMMAND_HANDLER(handle_jtag_nsrst_delay_command)
903 {
904 if (CMD_ARGC > 1)
905 return ERROR_COMMAND_SYNTAX_ERROR;
906 if (CMD_ARGC == 1)
907 {
908 unsigned delay;
909 COMMAND_PARSE_NUMBER(uint, CMD_ARGV[0], delay);
910
911 jtag_set_nsrst_delay(delay);
912 }
913 command_print(CMD_CTX, "jtag_nsrst_delay: %u", jtag_get_nsrst_delay());
914 return ERROR_OK;
915 }
916
917 COMMAND_HANDLER(handle_jtag_ntrst_delay_command)
918 {
919 if (CMD_ARGC > 1)
920 return ERROR_COMMAND_SYNTAX_ERROR;
921 if (CMD_ARGC == 1)
922 {
923 unsigned delay;
924 COMMAND_PARSE_NUMBER(uint, CMD_ARGV[0], delay);
925
926 jtag_set_ntrst_delay(delay);
927 }
928 command_print(CMD_CTX, "jtag_ntrst_delay: %u", jtag_get_ntrst_delay());
929 return ERROR_OK;
930 }
931
932 COMMAND_HANDLER(handle_jtag_nsrst_assert_width_command)
933 {
934 if (CMD_ARGC > 1)
935 return ERROR_COMMAND_SYNTAX_ERROR;
936 if (CMD_ARGC == 1)
937 {
938 unsigned delay;
939 COMMAND_PARSE_NUMBER(uint, CMD_ARGV[0], delay);
940
941 jtag_set_nsrst_assert_width(delay);
942 }
943 command_print(CMD_CTX, "jtag_nsrst_assert_width: %u", jtag_get_nsrst_assert_width());
944 return ERROR_OK;
945 }
946
947 COMMAND_HANDLER(handle_jtag_ntrst_assert_width_command)
948 {
949 if (CMD_ARGC > 1)
950 return ERROR_COMMAND_SYNTAX_ERROR;
951 if (CMD_ARGC == 1)
952 {
953 unsigned delay;
954 COMMAND_PARSE_NUMBER(uint, CMD_ARGV[0], delay);
955
956 jtag_set_ntrst_assert_width(delay);
957 }
958 command_print(CMD_CTX, "jtag_ntrst_assert_width: %u", jtag_get_ntrst_assert_width());
959 return ERROR_OK;
960 }
961
962 COMMAND_HANDLER(handle_jtag_khz_command)
963 {
964 if (CMD_ARGC > 1)
965 return ERROR_COMMAND_SYNTAX_ERROR;
966
967 int retval = ERROR_OK;
968 if (CMD_ARGC == 1)
969 {
970 unsigned khz = 0;
971 COMMAND_PARSE_NUMBER(uint, CMD_ARGV[0], khz);
972
973 retval = jtag_config_khz(khz);
974 if (ERROR_OK != retval)
975 return retval;
976 }
977
978 int cur_speed = jtag_get_speed_khz();
979 retval = jtag_get_speed_readable(&cur_speed);
980 if (ERROR_OK != retval)
981 return retval;
982
983 if (cur_speed)
984 command_print(CMD_CTX, "%d kHz", cur_speed);
985 else
986 command_print(CMD_CTX, "RCLK - adaptive");
987
988 return retval;
989 }
990
991 COMMAND_HANDLER(handle_jtag_rclk_command)
992 {
993 if (CMD_ARGC > 1)
994 return ERROR_COMMAND_SYNTAX_ERROR;
995
996 int retval = ERROR_OK;
997 if (CMD_ARGC == 1)
998 {
999 unsigned khz = 0;
1000 COMMAND_PARSE_NUMBER(uint, CMD_ARGV[0], khz);
1001
1002 retval = jtag_config_rclk(khz);
1003 if (ERROR_OK != retval)
1004 return retval;
1005 }
1006
1007 int cur_khz = jtag_get_speed_khz();
1008 retval = jtag_get_speed_readable(&cur_khz);
1009 if (ERROR_OK != retval)
1010 return retval;
1011
1012 if (cur_khz)
1013 command_print(CMD_CTX, "RCLK not supported - fallback to %d kHz", cur_khz);
1014 else
1015 command_print(CMD_CTX, "RCLK - adaptive");
1016
1017 return retval;
1018 }
1019
1020 COMMAND_HANDLER(handle_jtag_reset_command)
1021 {
1022 if (CMD_ARGC != 2)
1023 return ERROR_COMMAND_SYNTAX_ERROR;
1024
1025 int trst = -1;
1026 if (CMD_ARGV[0][0] == '1')
1027 trst = 1;
1028 else if (CMD_ARGV[0][0] == '0')
1029 trst = 0;
1030 else
1031 return ERROR_COMMAND_SYNTAX_ERROR;
1032
1033 int srst = -1;
1034 if (CMD_ARGV[1][0] == '1')
1035 srst = 1;
1036 else if (CMD_ARGV[1][0] == '0')
1037 srst = 0;
1038 else
1039 return ERROR_COMMAND_SYNTAX_ERROR;
1040
1041 if (jtag_interface_init(CMD_CTX) != ERROR_OK)
1042 return ERROR_JTAG_INIT_FAILED;
1043
1044 jtag_add_reset(trst, srst);
1045 return jtag_execute_queue();
1046 }
1047
1048 COMMAND_HANDLER(handle_runtest_command)
1049 {
1050 if (CMD_ARGC != 1)
1051 return ERROR_COMMAND_SYNTAX_ERROR;
1052
1053 unsigned num_clocks;
1054 COMMAND_PARSE_NUMBER(uint, CMD_ARGV[0], num_clocks);
1055
1056 jtag_add_runtest(num_clocks, TAP_IDLE);
1057 return jtag_execute_queue();
1058 }
1059
1060 /*
1061 * For "irscan" or "drscan" commands, the "end" (really, "next") state
1062 * should be stable ... and *NOT* a shift state, otherwise free-running
1063 * jtag clocks could change the values latched by the update state.
1064 * Not surprisingly, this is the same constraint as SVF; the "irscan"
1065 * and "drscan" commands are a write-only subset of what SVF provides.
1066 */
1067 static bool scan_is_safe(tap_state_t state)
1068 {
1069 switch (state)
1070 {
1071 case TAP_RESET:
1072 case TAP_IDLE:
1073 case TAP_DRPAUSE:
1074 case TAP_IRPAUSE:
1075 return true;
1076 default:
1077 return false;
1078 }
1079 }
1080
1081
1082 COMMAND_HANDLER(handle_irscan_command)
1083 {
1084 int i;
1085 struct scan_field *fields;
1086 struct jtag_tap *tap;
1087 tap_state_t endstate;
1088
1089 if ((CMD_ARGC < 2) || (CMD_ARGC % 2))
1090 {
1091 return ERROR_COMMAND_SYNTAX_ERROR;
1092 }
1093
1094 /* optional "-endstate" "statename" at the end of the arguments,
1095 * so that e.g. IRPAUSE can let us load the data register before
1096 * entering RUN/IDLE to execute the instruction we load here.
1097 */
1098 endstate = TAP_IDLE;
1099
1100 if (CMD_ARGC >= 4) {
1101 /* have at least one pair of numbers. */
1102 /* is last pair the magic text? */
1103 if (strcmp("-endstate", CMD_ARGV[CMD_ARGC - 2]) == 0) {
1104 endstate = tap_state_by_name(CMD_ARGV[CMD_ARGC - 1]);
1105 if (endstate == TAP_INVALID)
1106 return ERROR_COMMAND_SYNTAX_ERROR;
1107 if (!scan_is_safe(endstate))
1108 LOG_WARNING("unstable irscan endstate \"%s\"",
1109 CMD_ARGV[CMD_ARGC - 1]);
1110 CMD_ARGC -= 2;
1111 }
1112 }
1113
1114 int num_fields = CMD_ARGC / 2;
1115 size_t fields_len = sizeof(struct scan_field) * num_fields;
1116 fields = malloc(fields_len);
1117 memset(fields, 0, fields_len);
1118
1119 int retval;
1120 for (i = 0; i < num_fields; i++)
1121 {
1122 tap = jtag_tap_by_string(CMD_ARGV[i*2]);
1123 if (tap == NULL)
1124 {
1125 int j;
1126 for (j = 0; j < i; j++)
1127 free(fields[j].out_value);
1128 free(fields);
1129 command_print(CMD_CTX, "Tap: %s unknown", CMD_ARGV[i*2]);
1130
1131 return ERROR_FAIL;
1132 }
1133 int field_size = tap->ir_length;
1134 fields[i].tap = tap;
1135 fields[i].num_bits = field_size;
1136 fields[i].out_value = malloc(DIV_ROUND_UP(field_size, 8));
1137
1138 uint32_t value;
1139 retval = parse_u32(CMD_ARGV[i * 2 + 1], &value);
1140 if (ERROR_OK != retval)
1141 goto error_return;
1142 buf_set_u32(fields[i].out_value, 0, field_size, value);
1143 fields[i].in_value = NULL;
1144 }
1145
1146 /* did we have an endstate? */
1147 jtag_add_ir_scan(num_fields, fields, endstate);
1148
1149 retval = jtag_execute_queue();
1150
1151 error_return:
1152 for (i = 0; i < num_fields; i++)
1153 {
1154 if (NULL != fields[i].out_value)
1155 free(fields[i].out_value);
1156 }
1157
1158 free (fields);
1159
1160 return retval;
1161 }
1162
1163 static int Jim_Command_drscan(Jim_Interp *interp, int argc, Jim_Obj *const *args)
1164 {
1165 int retval;
1166 struct scan_field *fields;
1167 int num_fields;
1168 int field_count = 0;
1169 int i, e;
1170 struct jtag_tap *tap;
1171 tap_state_t endstate;
1172
1173 /* args[1] = device
1174 * args[2] = num_bits
1175 * args[3] = hex string
1176 * ... repeat num bits and hex string ...
1177 *
1178 * .. optionally:
1179 * args[N-2] = "-endstate"
1180 * args[N-1] = statename
1181 */
1182 if ((argc < 4) || ((argc % 2) != 0))
1183 {
1184 Jim_WrongNumArgs(interp, 1, args, "wrong arguments");
1185 return JIM_ERR;
1186 }
1187
1188 endstate = TAP_IDLE;
1189
1190 script_debug(interp, "drscan", argc, args);
1191
1192 /* validate arguments as numbers */
1193 e = JIM_OK;
1194 for (i = 2; i < argc; i += 2)
1195 {
1196 long bits;
1197 const char *cp;
1198
1199 e = Jim_GetLong(interp, args[i], &bits);
1200 /* If valid - try next arg */
1201 if (e == JIM_OK) {
1202 continue;
1203 }
1204
1205 /* Not valid.. are we at the end? */
1206 if (((i + 2) != argc)) {
1207 /* nope, then error */
1208 return e;
1209 }
1210
1211 /* it could be: "-endstate FOO"
1212 * e.g. DRPAUSE so we can issue more instructions
1213 * before entering RUN/IDLE and executing them.
1214 */
1215
1216 /* get arg as a string. */
1217 cp = Jim_GetString(args[i], NULL);
1218 /* is it the magic? */
1219 if (0 == strcmp("-endstate", cp)) {
1220 /* is the statename valid? */
1221 cp = Jim_GetString(args[i + 1], NULL);
1222
1223 /* see if it is a valid state name */
1224 endstate = tap_state_by_name(cp);
1225 if (endstate < 0) {
1226 /* update the error message */
1227 Jim_SetResult_sprintf(interp,"endstate: %s invalid", cp);
1228 } else {
1229 if (!scan_is_safe(endstate))
1230 LOG_WARNING("drscan with unsafe "
1231 "endstate \"%s\"", cp);
1232
1233 /* valid - so clear the error */
1234 e = JIM_OK;
1235 /* and remove the last 2 args */
1236 argc -= 2;
1237 }
1238 }
1239
1240 /* Still an error? */
1241 if (e != JIM_OK) {
1242 return e; /* too bad */
1243 }
1244 } /* validate args */
1245
1246 tap = jtag_tap_by_jim_obj(interp, args[1]);
1247 if (tap == NULL) {
1248 return JIM_ERR;
1249 }
1250
1251 num_fields = (argc-2)/2;
1252 fields = malloc(sizeof(struct scan_field) * num_fields);
1253 for (i = 2; i < argc; i += 2)
1254 {
1255 long bits;
1256 int len;
1257 const char *str;
1258
1259 Jim_GetLong(interp, args[i], &bits);
1260 str = Jim_GetString(args[i + 1], &len);
1261
1262 fields[field_count].tap = tap;
1263 fields[field_count].num_bits = bits;
1264 fields[field_count].out_value = malloc(DIV_ROUND_UP(bits, 8));
1265 str_to_buf(str, len, fields[field_count].out_value, bits, 0);
1266 fields[field_count].in_value = fields[field_count].out_value;
1267 field_count++;
1268 }
1269
1270 jtag_add_dr_scan(num_fields, fields, endstate);
1271
1272 retval = jtag_execute_queue();
1273 if (retval != ERROR_OK)
1274 {
1275 Jim_SetResultString(interp, "drscan: jtag execute failed",-1);
1276 return JIM_ERR;
1277 }
1278
1279 field_count = 0;
1280 Jim_Obj *list = Jim_NewListObj(interp, NULL, 0);
1281 for (i = 2; i < argc; i += 2)
1282 {
1283 long bits;
1284 char *str;
1285
1286 Jim_GetLong(interp, args[i], &bits);
1287 str = buf_to_str(fields[field_count].in_value, bits, 16);
1288 free(fields[field_count].out_value);
1289
1290 Jim_ListAppendElement(interp, list, Jim_NewStringObj(interp, str, strlen(str)));
1291 free(str);
1292 field_count++;
1293 }
1294
1295 Jim_SetResult(interp, list);
1296
1297 free(fields);
1298
1299 return JIM_OK;
1300 }
1301
1302
1303 static int Jim_Command_pathmove(Jim_Interp *interp, int argc, Jim_Obj *const *args)
1304 {
1305 tap_state_t states[8];
1306
1307 if ((argc < 2) || ((size_t)argc > (sizeof(states)/sizeof(*states) + 1)))
1308 {
1309 Jim_WrongNumArgs(interp, 1, args, "wrong arguments");
1310 return JIM_ERR;
1311 }
1312
1313 script_debug(interp, "pathmove", argc, args);
1314
1315 int i;
1316 for (i = 0; i < argc-1; i++)
1317 {
1318 const char *cp;
1319 cp = Jim_GetString(args[i + 1], NULL);
1320 states[i] = tap_state_by_name(cp);
1321 if (states[i] < 0)
1322 {
1323 /* update the error message */
1324 Jim_SetResult_sprintf(interp,"endstate: %s invalid", cp);
1325 return JIM_ERR;
1326 }
1327 }
1328
1329 if ((jtag_add_statemove(states[0]) != ERROR_OK) || (jtag_execute_queue()!= ERROR_OK))
1330 {
1331 Jim_SetResultString(interp, "pathmove: jtag execute failed",-1);
1332 return JIM_ERR;
1333 }
1334
1335 jtag_add_pathmove(argc-2, states + 1);
1336
1337 if (jtag_execute_queue()!= ERROR_OK)
1338 {
1339 Jim_SetResultString(interp, "pathmove: failed",-1);
1340 return JIM_ERR;
1341 }
1342
1343 return JIM_OK;
1344 }
1345
1346
1347 static int Jim_Command_flush_count(Jim_Interp *interp, int argc, Jim_Obj *const *args)
1348 {
1349 script_debug(interp, "flush_count", argc, args);
1350
1351 Jim_SetResult(interp, Jim_NewIntObj(interp, jtag_get_flush_queue_count()));
1352
1353 return JIM_OK;
1354 }
1355
1356
1357 COMMAND_HANDLER(handle_verify_ircapture_command)
1358 {
1359 if (CMD_ARGC > 1)
1360 return ERROR_COMMAND_SYNTAX_ERROR;
1361
1362 if (CMD_ARGC == 1)
1363 {
1364 bool enable;
1365 COMMAND_PARSE_ENABLE(CMD_ARGV[0], enable);
1366 jtag_set_verify_capture_ir(enable);
1367 }
1368
1369 const char *status = jtag_will_verify_capture_ir() ? "enabled": "disabled";
1370 command_print(CMD_CTX, "verify Capture-IR is %s", status);
1371
1372 return ERROR_OK;
1373 }
1374
1375 COMMAND_HANDLER(handle_verify_jtag_command)
1376 {
1377 if (CMD_ARGC > 1)
1378 return ERROR_COMMAND_SYNTAX_ERROR;
1379
1380 if (CMD_ARGC == 1)
1381 {
1382 bool enable;
1383 COMMAND_PARSE_ENABLE(CMD_ARGV[0], enable);
1384 jtag_set_verify(enable);
1385 }
1386
1387 const char *status = jtag_will_verify() ? "enabled": "disabled";
1388 command_print(CMD_CTX, "verify jtag capture is %s", status);
1389
1390 return ERROR_OK;
1391 }
1392
1393 COMMAND_HANDLER(handle_tms_sequence_command)
1394 {
1395 if (CMD_ARGC > 1)
1396 return ERROR_COMMAND_SYNTAX_ERROR;
1397
1398 if (CMD_ARGC == 1)
1399 {
1400 bool use_new_table;
1401 if (strcmp(CMD_ARGV[0], "short") == 0)
1402 use_new_table = true;
1403 else if (strcmp(CMD_ARGV[0], "long") == 0)
1404 use_new_table = false;
1405 else
1406 return ERROR_COMMAND_SYNTAX_ERROR;
1407
1408 tap_use_new_tms_table(use_new_table);
1409 }
1410
1411 command_print(CMD_CTX, "tms sequence is %s",
1412 tap_uses_new_tms_table() ? "short": "long");
1413
1414 return ERROR_OK;
1415 }
1416
1417 static const struct command_registration jtag_command_handlers[] = {
1418 {
1419 .name = "interface",
1420 .handler = &handle_interface_command,
1421 .mode = COMMAND_CONFIG,
1422 .help = "select a JTAG interface",
1423 .usage = "<driver_name>",
1424 },
1425 {
1426 .name = "interface_list",
1427 .handler = &handle_interface_list_command,
1428 .mode = COMMAND_ANY,
1429 .help = "list all built-in interfaces",
1430 },
1431 {
1432 .name = "jtag_khz",
1433 .handler = &handle_jtag_khz_command,
1434 .mode = COMMAND_ANY,
1435 .help = "set maximum jtag speed (if supported)",
1436 .usage = "<khz:0=rtck>",
1437 },
1438 {
1439 .name = "jtag_rclk",
1440 .handler = &handle_jtag_rclk_command,
1441 .mode = COMMAND_ANY,
1442 .help = "set JTAG speed to RCLK or use fallback speed",
1443 .usage = "<fallback_speed_khz>",
1444 },
1445 {
1446 .name = "reset_config",
1447 .handler = &handle_reset_config_command,
1448 .mode = COMMAND_ANY,
1449 .help = "configure JTAG reset behavior",
1450 .usage = "[none|trst_only|srst_only|trst_and_srst] "
1451 "[srst_pulls_trst|trst_pulls_srst|combined|separate] "
1452 "[srst_gates_jtag|srst_nogate] "
1453 "[trst_push_pull|trst_open_drain] "
1454 "[srst_push_pull|srst_open_drain]",
1455 },
1456 {
1457 .name = "jtag_nsrst_delay",
1458 .handler = &handle_jtag_nsrst_delay_command,
1459 .mode = COMMAND_ANY,
1460 .help = "delay after deasserting srst in ms",
1461 .usage = "<ms>",
1462 },
1463 {
1464 .name = "jtag_ntrst_delay",
1465 .handler = &handle_jtag_ntrst_delay_command,
1466 .mode = COMMAND_ANY,
1467 .help = "delay after deasserting trst in ms",
1468 .usage = "<ms>"
1469 },
1470 {
1471 .name = "jtag_nsrst_assert_width",
1472 .handler = &handle_jtag_nsrst_assert_width_command,
1473 .mode = COMMAND_ANY,
1474 .help = "delay after asserting srst in ms",
1475 .usage = "<ms>"
1476 },
1477 {
1478 .name = "jtag_ntrst_assert_width",
1479 .handler = &handle_jtag_ntrst_assert_width_command,
1480 .mode = COMMAND_ANY,
1481 .help = "delay after asserting trst in ms",
1482 .usage = "<ms>"
1483 },
1484 {
1485 .name = "scan_chain",
1486 .handler = &handle_scan_chain_command,
1487 .mode = COMMAND_EXEC,
1488 .help = "print current scan chain configuration",
1489 },
1490 {
1491 .name = "jtag_reset",
1492 .handler = &handle_jtag_reset_command,
1493 .mode = COMMAND_EXEC,
1494 .help = "toggle reset lines",
1495 .usage = "<trst> <srst>",
1496 },
1497 {
1498 .name = "runtest",
1499 .handler = &handle_runtest_command,
1500 .mode = COMMAND_EXEC,
1501 .help = "move to Run-Test/Idle, and execute <num_cycles>",
1502 .usage = "<num_cycles>"
1503 },
1504 {
1505 .name = "irscan",
1506 .handler = &handle_irscan_command,
1507 .mode = COMMAND_EXEC,
1508 .help = "execute IR scan",
1509 .usage = "<device> <instr> [dev2] [instr2] ...",
1510 },
1511 {
1512 .name = "verify_ircapture",
1513 .handler = &handle_verify_ircapture_command,
1514 .mode = COMMAND_ANY,
1515 .help = "verify value captured during Capture-IR",
1516 .usage = "<enable | disable>",
1517 },
1518 {
1519 .name = "verify_jtag",
1520 .handler = &handle_verify_jtag_command,
1521 .mode = COMMAND_ANY,
1522 .help = "verify value capture",
1523 .usage = "<enable | disable>",
1524 },
1525 {
1526 .name = "tms_sequence",
1527 .handler = &handle_tms_sequence_command,
1528 .mode = COMMAND_ANY,
1529 .help = "choose short(default) or long tms_sequence",
1530 .usage = "<short | long>",
1531 },
1532 COMMAND_REGISTRATION_DONE
1533 };
1534
1535 int jtag_register_commands(struct command_context *cmd_ctx)
1536 {
1537 register_jim(cmd_ctx, "jtag", jim_jtag_command,
1538 "perform jtag tap actions");
1539
1540 register_jim(cmd_ctx, "drscan", Jim_Command_drscan,
1541 "execute DR scan <device> "
1542 "<num_bits> <value> <num_bits1> <value2> ...");
1543
1544 register_jim(cmd_ctx, "flush_count", Jim_Command_flush_count,
1545 "returns number of times the JTAG queue has been flushed");
1546
1547 register_jim(cmd_ctx, "pathmove", Jim_Command_pathmove,
1548 "<state1>,<state2>,<state3>... "
1549 "- move JTAG to state1 then to state2, state3, etc.");
1550
1551 return register_commands(cmd_ctx, NULL, jtag_command_handlers);
1552 }
1553
1554

Linking to existing account procedure

If you already have an account and want to add another login method you MUST first sign in with your existing account and then change URL to read https://review.openocd.org/login/?link to get to this page again but this time it'll work for linking. Thank you.

SSH host keys fingerprints

1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=..              |
|+o..   .         |
|*.o   . .        |
|+B . . .         |
|Bo. = o S        |
|Oo.+ + =         |
|oB=.* = . o      |
| =+=.+   + E     |
|. .=o   . o      |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)