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

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)