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

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)