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

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)