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

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)