jtag: rewrite command 'drscan' as COMMAND_HANDLER
[openocd.git] / src / jtag / tcl.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
2
3 /***************************************************************************
4 * Copyright (C) 2005 by Dominic Rath *
5 * Dominic.Rath@gmx.de *
6 * *
7 * Copyright (C) 2007-2010 Øyvind Harboe *
8 * oyvind.harboe@zylin.com *
9 * *
10 * Copyright (C) 2009 SoftPLC Corporation *
11 * http://softplc.com *
12 * dick@softplc.com *
13 * *
14 * Copyright (C) 2009 Zachary T Welch *
15 * zw@superlucidity.net *
16 ***************************************************************************/
17
18 #ifdef HAVE_CONFIG_H
19 #include "config.h"
20 #endif
21
22 #include "adapter.h"
23 #include "jtag.h"
24 #include "swd.h"
25 #include "minidriver.h"
26 #include "interface.h"
27 #include "interfaces.h"
28 #include "tcl.h"
29
30 #ifdef HAVE_STRINGS_H
31 #include <strings.h>
32 #endif
33
34 #include <helper/time_support.h>
35 #include "transport/transport.h"
36
37 /**
38 * @file
39 * Holds support for accessing JTAG-specific mechanisms from TCl scripts.
40 */
41
42 static const struct jim_nvp nvp_jtag_tap_event[] = {
43 { .value = JTAG_TRST_ASSERTED, .name = "post-reset" },
44 { .value = JTAG_TAP_EVENT_SETUP, .name = "setup" },
45 { .value = JTAG_TAP_EVENT_ENABLE, .name = "tap-enable" },
46 { .value = JTAG_TAP_EVENT_DISABLE, .name = "tap-disable" },
47
48 { .name = NULL, .value = -1 }
49 };
50
51 struct jtag_tap *jtag_tap_by_jim_obj(Jim_Interp *interp, Jim_Obj *o)
52 {
53 const char *cp = Jim_GetString(o, NULL);
54 struct jtag_tap *t = cp ? jtag_tap_by_string(cp) : NULL;
55 if (!cp)
56 cp = "(unknown)";
57 if (!t)
58 Jim_SetResultFormatted(interp, "Tap '%s' could not be found", cp);
59 return t;
60 }
61
62 static bool scan_is_safe(tap_state_t state)
63 {
64 switch (state) {
65 case TAP_RESET:
66 case TAP_IDLE:
67 case TAP_DRPAUSE:
68 case TAP_IRPAUSE:
69 return true;
70 default:
71 return false;
72 }
73 }
74
75 static COMMAND_HELPER(handle_jtag_command_drscan_fields, struct scan_field *fields)
76 {
77 unsigned int field_count = 0;
78 for (unsigned int i = 1; i < CMD_ARGC; i += 2) {
79 unsigned int bits;
80 COMMAND_PARSE_NUMBER(uint, CMD_ARGV[i], bits);
81 fields[field_count].num_bits = bits;
82
83 void *t = malloc(DIV_ROUND_UP(bits, 8));
84 if (!t) {
85 LOG_ERROR("Out of memory");
86 return ERROR_FAIL;
87 }
88 fields[field_count].out_value = t;
89 str_to_buf(CMD_ARGV[i + 1], strlen(CMD_ARGV[i + 1]), t, bits, 0);
90 fields[field_count].in_value = t;
91 field_count++;
92 }
93
94 return ERROR_OK;
95 }
96
97 COMMAND_HANDLER(handle_jtag_command_drscan)
98 {
99 /*
100 * CMD_ARGV[0] = device
101 * CMD_ARGV[1] = num_bits
102 * CMD_ARGV[2] = hex string
103 * ... repeat num bits and hex string ...
104 *
105 * ... optionally:
106 * CMD_ARGV[CMD_ARGC-2] = "-endstate"
107 * CMD_ARGV[CMD_ARGC-1] = statename
108 */
109
110 if (CMD_ARGC < 3 || (CMD_ARGC % 2) != 1)
111 return ERROR_COMMAND_SYNTAX_ERROR;
112
113 struct jtag_tap *tap = jtag_tap_by_string(CMD_ARGV[0]);
114 if (!tap) {
115 command_print(CMD, "Tap '%s' could not be found", CMD_ARGV[0]);
116 return ERROR_COMMAND_ARGUMENT_INVALID;
117 }
118
119 tap_state_t endstate = TAP_IDLE;
120 if (CMD_ARGC > 3 && !strcmp("-endstate", CMD_ARGV[CMD_ARGC - 2])) {
121 const char *state_name = CMD_ARGV[CMD_ARGC - 1];
122 endstate = tap_state_by_name(state_name);
123 if (endstate < 0) {
124 command_print(CMD, "endstate: %s invalid", state_name);
125 return ERROR_COMMAND_ARGUMENT_INVALID;
126 }
127
128 if (!scan_is_safe(endstate))
129 LOG_WARNING("drscan with unsafe endstate \"%s\"", state_name);
130
131 CMD_ARGC -= 2;
132 }
133
134 unsigned int num_fields = (CMD_ARGC - 1) / 2;
135 struct scan_field *fields = calloc(num_fields, sizeof(struct scan_field));
136 if (!fields) {
137 LOG_ERROR("Out of memory");
138 return ERROR_FAIL;
139 }
140
141 int retval = CALL_COMMAND_HANDLER(handle_jtag_command_drscan_fields, fields);
142 if (retval != ERROR_OK)
143 goto fail;
144
145 jtag_add_dr_scan(tap, num_fields, fields, endstate);
146
147 retval = jtag_execute_queue();
148 if (retval != ERROR_OK) {
149 command_print(CMD, "drscan: jtag execute failed");
150 goto fail;
151 }
152
153 for (unsigned int i = 0; i < num_fields; i++) {
154 char *str = buf_to_hex_str(fields[i].in_value, fields[i].num_bits);
155 command_print(CMD, "%s", str);
156 free(str);
157 }
158
159 fail:
160 for (unsigned int i = 0; i < num_fields; i++)
161 free(fields[i].in_value);
162 free(fields);
163
164 return retval;
165 }
166
167 static int jim_command_pathmove(Jim_Interp *interp, int argc, Jim_Obj * const *args)
168 {
169 tap_state_t states[8];
170
171 if ((argc < 2) || ((size_t)argc > (ARRAY_SIZE(states) + 1))) {
172 Jim_WrongNumArgs(interp, 1, args, "wrong arguments");
173 return JIM_ERR;
174 }
175
176 int i;
177 for (i = 0; i < argc-1; i++) {
178 const char *cp;
179 cp = Jim_GetString(args[i + 1], NULL);
180 states[i] = tap_state_by_name(cp);
181 if (states[i] < 0) {
182 /* update the error message */
183 Jim_SetResultFormatted(interp, "endstate: %s invalid", cp);
184 return JIM_ERR;
185 }
186 }
187
188 if ((jtag_add_statemove(states[0]) != ERROR_OK) || (jtag_execute_queue() != ERROR_OK)) {
189 Jim_SetResultString(interp, "pathmove: jtag execute failed", -1);
190 return JIM_ERR;
191 }
192
193 jtag_add_pathmove(argc - 2, states + 1);
194
195 if (jtag_execute_queue() != ERROR_OK) {
196 Jim_SetResultString(interp, "pathmove: failed", -1);
197 return JIM_ERR;
198 }
199
200 return JIM_OK;
201 }
202
203 COMMAND_HANDLER(handle_jtag_flush_count)
204 {
205 if (CMD_ARGC != 0)
206 return ERROR_COMMAND_SYNTAX_ERROR;
207
208 int count = jtag_get_flush_queue_count();
209 command_print_sameline(CMD, "%d", count);
210
211 return ERROR_OK;
212 }
213
214 /* REVISIT Just what about these should "move" ... ?
215 * These registrations, into the main JTAG table?
216 *
217 * There's a minor compatibility issue, these all show up twice;
218 * that's not desirable:
219 * - jtag drscan ... NOT DOCUMENTED!
220 * - drscan ...
221 *
222 * The "irscan" command (for example) doesn't show twice.
223 */
224 static const struct command_registration jtag_command_handlers_to_move[] = {
225 {
226 .name = "drscan",
227 .mode = COMMAND_EXEC,
228 .handler = handle_jtag_command_drscan,
229 .help = "Execute Data Register (DR) scan for one TAP. "
230 "Other TAPs must be in BYPASS mode.",
231 .usage = "tap_name [num_bits value]* ['-endstate' state_name]",
232 },
233 {
234 .name = "flush_count",
235 .mode = COMMAND_EXEC,
236 .handler = handle_jtag_flush_count,
237 .help = "Returns the number of times the JTAG queue "
238 "has been flushed.",
239 .usage = "",
240 },
241 {
242 .name = "pathmove",
243 .mode = COMMAND_EXEC,
244 .jim_handler = jim_command_pathmove,
245 .usage = "start_state state1 [state2 [state3 ...]]",
246 .help = "Move JTAG state machine from current state "
247 "(start_state) to state1, then state2, state3, etc.",
248 },
249 COMMAND_REGISTRATION_DONE
250 };
251
252
253 enum jtag_tap_cfg_param {
254 JCFG_EVENT,
255 JCFG_IDCODE,
256 };
257
258 static struct jim_nvp nvp_config_opts[] = {
259 { .name = "-event", .value = JCFG_EVENT },
260 { .name = "-idcode", .value = JCFG_IDCODE },
261
262 { .name = NULL, .value = -1 }
263 };
264
265 static int jtag_tap_configure_event(struct jim_getopt_info *goi, struct jtag_tap *tap)
266 {
267 if (goi->argc == 0) {
268 Jim_WrongNumArgs(goi->interp, goi->argc, goi->argv, "-event <event-name> ...");
269 return JIM_ERR;
270 }
271
272 struct jim_nvp *n;
273 int e = jim_getopt_nvp(goi, nvp_jtag_tap_event, &n);
274 if (e != JIM_OK) {
275 jim_getopt_nvp_unknown(goi, nvp_jtag_tap_event, 1);
276 return e;
277 }
278
279 if (goi->isconfigure) {
280 if (goi->argc != 1) {
281 Jim_WrongNumArgs(goi->interp,
282 goi->argc,
283 goi->argv,
284 "-event <event-name> <event-body>");
285 return JIM_ERR;
286 }
287 } else {
288 if (goi->argc != 0) {
289 Jim_WrongNumArgs(goi->interp, goi->argc, goi->argv, "-event <event-name>");
290 return JIM_ERR;
291 }
292 }
293
294 struct jtag_tap_event_action *jteap = tap->event_action;
295 /* replace existing event body */
296 bool found = false;
297 while (jteap) {
298 if (jteap->event == (enum jtag_event)n->value) {
299 found = true;
300 break;
301 }
302 jteap = jteap->next;
303 }
304
305 Jim_SetEmptyResult(goi->interp);
306
307 if (goi->isconfigure) {
308 if (!found)
309 jteap = calloc(1, sizeof(*jteap));
310 else if (jteap->body)
311 Jim_DecrRefCount(goi->interp, jteap->body);
312
313 jteap->interp = goi->interp;
314 jteap->event = n->value;
315
316 Jim_Obj *o;
317 jim_getopt_obj(goi, &o);
318 jteap->body = Jim_DuplicateObj(goi->interp, o);
319 Jim_IncrRefCount(jteap->body);
320
321 if (!found) {
322 /* add to head of event list */
323 jteap->next = tap->event_action;
324 tap->event_action = jteap;
325 }
326 } else if (found) {
327 jteap->interp = goi->interp;
328 Jim_SetResult(goi->interp,
329 Jim_DuplicateObj(goi->interp, jteap->body));
330 }
331 return JIM_OK;
332 }
333
334 static int jtag_tap_configure_cmd(struct jim_getopt_info *goi, struct jtag_tap *tap)
335 {
336 /* parse config or cget options */
337 while (goi->argc > 0) {
338 Jim_SetEmptyResult(goi->interp);
339
340 struct jim_nvp *n;
341 int e = jim_getopt_nvp(goi, nvp_config_opts, &n);
342 if (e != JIM_OK) {
343 jim_getopt_nvp_unknown(goi, nvp_config_opts, 0);
344 return e;
345 }
346
347 switch (n->value) {
348 case JCFG_EVENT:
349 e = jtag_tap_configure_event(goi, tap);
350 if (e != JIM_OK)
351 return e;
352 break;
353 case JCFG_IDCODE:
354 if (goi->isconfigure) {
355 Jim_SetResultFormatted(goi->interp,
356 "not settable: %s", n->name);
357 return JIM_ERR;
358 } else {
359 if (goi->argc != 0) {
360 Jim_WrongNumArgs(goi->interp,
361 goi->argc, goi->argv,
362 "NO PARAMS");
363 return JIM_ERR;
364 }
365 }
366 Jim_SetResult(goi->interp, Jim_NewIntObj(goi->interp, tap->idcode));
367 break;
368 default:
369 Jim_SetResultFormatted(goi->interp, "unknown value: %s", n->name);
370 return JIM_ERR;
371 }
372 }
373
374 return JIM_OK;
375 }
376
377 static int is_bad_irval(int ir_length, jim_wide w)
378 {
379 jim_wide v = 1;
380
381 v <<= ir_length;
382 v -= 1;
383 v = ~v;
384 return (w & v) != 0;
385 }
386
387 static int jim_newtap_expected_id(struct jim_nvp *n, struct jim_getopt_info *goi,
388 struct jtag_tap *tap)
389 {
390 jim_wide w;
391 int e = jim_getopt_wide(goi, &w);
392 if (e != JIM_OK) {
393 Jim_SetResultFormatted(goi->interp, "option: %s bad parameter", n->name);
394 return e;
395 }
396
397 uint32_t *p = realloc(tap->expected_ids,
398 (tap->expected_ids_cnt + 1) * sizeof(uint32_t));
399 if (!p) {
400 Jim_SetResultFormatted(goi->interp, "no memory");
401 return JIM_ERR;
402 }
403
404 tap->expected_ids = p;
405 tap->expected_ids[tap->expected_ids_cnt++] = w;
406
407 return JIM_OK;
408 }
409
410 #define NTAP_OPT_IRLEN 0
411 #define NTAP_OPT_IRMASK 1
412 #define NTAP_OPT_IRCAPTURE 2
413 #define NTAP_OPT_ENABLED 3
414 #define NTAP_OPT_DISABLED 4
415 #define NTAP_OPT_EXPECTED_ID 5
416 #define NTAP_OPT_VERSION 6
417 #define NTAP_OPT_BYPASS 7
418
419 static int jim_newtap_ir_param(struct jim_nvp *n, struct jim_getopt_info *goi,
420 struct jtag_tap *tap)
421 {
422 jim_wide w;
423 int e = jim_getopt_wide(goi, &w);
424 if (e != JIM_OK) {
425 Jim_SetResultFormatted(goi->interp,
426 "option: %s bad parameter", n->name);
427 return e;
428 }
429 switch (n->value) {
430 case NTAP_OPT_IRLEN:
431 if (w > (jim_wide) (8 * sizeof(tap->ir_capture_value))) {
432 LOG_WARNING("%s: huge IR length %d",
433 tap->dotted_name, (int) w);
434 }
435 tap->ir_length = w;
436 break;
437 case NTAP_OPT_IRMASK:
438 if (is_bad_irval(tap->ir_length, w)) {
439 LOG_ERROR("%s: IR mask %x too big",
440 tap->dotted_name,
441 (int) w);
442 return JIM_ERR;
443 }
444 if ((w & 3) != 3)
445 LOG_WARNING("%s: nonstandard IR mask", tap->dotted_name);
446 tap->ir_capture_mask = w;
447 break;
448 case NTAP_OPT_IRCAPTURE:
449 if (is_bad_irval(tap->ir_length, w)) {
450 LOG_ERROR("%s: IR capture %x too big",
451 tap->dotted_name, (int) w);
452 return JIM_ERR;
453 }
454 if ((w & 3) != 1)
455 LOG_WARNING("%s: nonstandard IR value",
456 tap->dotted_name);
457 tap->ir_capture_value = w;
458 break;
459 default:
460 return JIM_ERR;
461 }
462 return JIM_OK;
463 }
464
465 static int jim_newtap_cmd(struct jim_getopt_info *goi)
466 {
467 struct jtag_tap *tap;
468 int x;
469 int e;
470 struct jim_nvp *n;
471 char *cp;
472 const struct jim_nvp opts[] = {
473 { .name = "-irlen", .value = NTAP_OPT_IRLEN },
474 { .name = "-irmask", .value = NTAP_OPT_IRMASK },
475 { .name = "-ircapture", .value = NTAP_OPT_IRCAPTURE },
476 { .name = "-enable", .value = NTAP_OPT_ENABLED },
477 { .name = "-disable", .value = NTAP_OPT_DISABLED },
478 { .name = "-expected-id", .value = NTAP_OPT_EXPECTED_ID },
479 { .name = "-ignore-version", .value = NTAP_OPT_VERSION },
480 { .name = "-ignore-bypass", .value = NTAP_OPT_BYPASS },
481 { .name = NULL, .value = -1 },
482 };
483
484 tap = calloc(1, sizeof(struct jtag_tap));
485 if (!tap) {
486 Jim_SetResultFormatted(goi->interp, "no memory");
487 return JIM_ERR;
488 }
489
490 /*
491 * we expect CHIP + TAP + OPTIONS
492 * */
493 if (goi->argc < 3) {
494 Jim_SetResultFormatted(goi->interp, "Missing CHIP TAP OPTIONS ....");
495 free(tap);
496 return JIM_ERR;
497 }
498
499 const char *tmp;
500 jim_getopt_string(goi, &tmp, NULL);
501 tap->chip = strdup(tmp);
502
503 jim_getopt_string(goi, &tmp, NULL);
504 tap->tapname = strdup(tmp);
505
506 /* name + dot + name + null */
507 x = strlen(tap->chip) + 1 + strlen(tap->tapname) + 1;
508 cp = malloc(x);
509 sprintf(cp, "%s.%s", tap->chip, tap->tapname);
510 tap->dotted_name = cp;
511
512 LOG_DEBUG("Creating New Tap, Chip: %s, Tap: %s, Dotted: %s, %d params",
513 tap->chip, tap->tapname, tap->dotted_name, goi->argc);
514
515 /* IEEE specifies that the two LSBs of an IR scan are 01, so make
516 * that the default. The "-ircapture" and "-irmask" options are only
517 * needed to cope with nonstandard TAPs, or to specify more bits.
518 */
519 tap->ir_capture_mask = 0x03;
520 tap->ir_capture_value = 0x01;
521
522 while (goi->argc) {
523 e = jim_getopt_nvp(goi, opts, &n);
524 if (e != JIM_OK) {
525 jim_getopt_nvp_unknown(goi, opts, 0);
526 free(cp);
527 free(tap);
528 return e;
529 }
530 LOG_DEBUG("Processing option: %s", n->name);
531 switch (n->value) {
532 case NTAP_OPT_ENABLED:
533 tap->disabled_after_reset = false;
534 break;
535 case NTAP_OPT_DISABLED:
536 tap->disabled_after_reset = true;
537 break;
538 case NTAP_OPT_EXPECTED_ID:
539 e = jim_newtap_expected_id(n, goi, tap);
540 if (e != JIM_OK) {
541 free(cp);
542 free(tap);
543 return e;
544 }
545 break;
546 case NTAP_OPT_IRLEN:
547 case NTAP_OPT_IRMASK:
548 case NTAP_OPT_IRCAPTURE:
549 e = jim_newtap_ir_param(n, goi, tap);
550 if (e != JIM_OK) {
551 free(cp);
552 free(tap);
553 return e;
554 }
555 break;
556 case NTAP_OPT_VERSION:
557 tap->ignore_version = true;
558 break;
559 case NTAP_OPT_BYPASS:
560 tap->ignore_bypass = true;
561 break;
562 } /* switch (n->value) */
563 } /* while (goi->argc) */
564
565 /* default is enabled-after-reset */
566 tap->enabled = !tap->disabled_after_reset;
567
568 /* Did all the required option bits get cleared? */
569 if (!transport_is_jtag() || tap->ir_length != 0) {
570 jtag_tap_init(tap);
571 return JIM_OK;
572 }
573
574 Jim_SetResultFormatted(goi->interp,
575 "newtap: %s missing IR length",
576 tap->dotted_name);
577 jtag_tap_free(tap);
578 return JIM_ERR;
579 }
580
581 static void jtag_tap_handle_event(struct jtag_tap *tap, enum jtag_event e)
582 {
583 struct jtag_tap_event_action *jteap;
584 int retval;
585
586 for (jteap = tap->event_action; jteap; jteap = jteap->next) {
587 if (jteap->event != e)
588 continue;
589
590 struct jim_nvp *nvp = jim_nvp_value2name_simple(nvp_jtag_tap_event, e);
591 LOG_DEBUG("JTAG tap: %s event: %d (%s)\n\taction: %s",
592 tap->dotted_name, e, nvp->name,
593 Jim_GetString(jteap->body, NULL));
594
595 retval = Jim_EvalObj(jteap->interp, jteap->body);
596 if (retval == JIM_RETURN)
597 retval = jteap->interp->returnCode;
598
599 if (retval != JIM_OK) {
600 Jim_MakeErrorMessage(jteap->interp);
601 LOG_USER("%s", Jim_GetString(Jim_GetResult(jteap->interp), NULL));
602 continue;
603 }
604
605 switch (e) {
606 case JTAG_TAP_EVENT_ENABLE:
607 case JTAG_TAP_EVENT_DISABLE:
608 /* NOTE: we currently assume the handlers
609 * can't fail. Right here is where we should
610 * really be verifying the scan chains ...
611 */
612 tap->enabled = (e == JTAG_TAP_EVENT_ENABLE);
613 LOG_INFO("JTAG tap: %s %s", tap->dotted_name,
614 tap->enabled ? "enabled" : "disabled");
615 break;
616 default:
617 break;
618 }
619 }
620 }
621
622 COMMAND_HANDLER(handle_jtag_arp_init)
623 {
624 if (CMD_ARGC != 0)
625 return ERROR_COMMAND_SYNTAX_ERROR;
626
627 return jtag_init_inner(CMD_CTX);
628 }
629
630 COMMAND_HANDLER(handle_jtag_arp_init_reset)
631 {
632 if (CMD_ARGC != 0)
633 return ERROR_COMMAND_SYNTAX_ERROR;
634
635 if (transport_is_jtag())
636 return jtag_init_reset(CMD_CTX);
637
638 if (transport_is_swd())
639 return swd_init_reset(CMD_CTX);
640
641 return ERROR_OK;
642 }
643
644 int jim_jtag_newtap(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
645 {
646 struct jim_getopt_info goi;
647 jim_getopt_setup(&goi, interp, argc-1, argv + 1);
648 return jim_newtap_cmd(&goi);
649 }
650
651 static bool jtag_tap_enable(struct jtag_tap *t)
652 {
653 if (t->enabled)
654 return false;
655 jtag_tap_handle_event(t, JTAG_TAP_EVENT_ENABLE);
656 if (!t->enabled)
657 return false;
658
659 /* FIXME add JTAG sanity checks, w/o TLR
660 * - scan chain length grew by one (this)
661 * - IDs and IR lengths are as expected
662 */
663 jtag_call_event_callbacks(JTAG_TAP_EVENT_ENABLE);
664 return true;
665 }
666 static bool jtag_tap_disable(struct jtag_tap *t)
667 {
668 if (!t->enabled)
669 return false;
670 jtag_tap_handle_event(t, JTAG_TAP_EVENT_DISABLE);
671 if (t->enabled)
672 return false;
673
674 /* FIXME add JTAG sanity checks, w/o TLR
675 * - scan chain length shrank by one (this)
676 * - IDs and IR lengths are as expected
677 */
678 jtag_call_event_callbacks(JTAG_TAP_EVENT_DISABLE);
679 return true;
680 }
681
682 int jim_jtag_tap_enabler(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
683 {
684 struct command *c = jim_to_command(interp);
685 const char *cmd_name = c->name;
686 struct jim_getopt_info goi;
687 jim_getopt_setup(&goi, interp, argc-1, argv + 1);
688 if (goi.argc != 1) {
689 Jim_SetResultFormatted(goi.interp, "usage: %s <name>", cmd_name);
690 return JIM_ERR;
691 }
692
693 struct jtag_tap *t;
694
695 t = jtag_tap_by_jim_obj(goi.interp, goi.argv[0]);
696 if (!t)
697 return JIM_ERR;
698
699 if (strcasecmp(cmd_name, "tapisenabled") == 0) {
700 /* do nothing, just return the value */
701 } else if (strcasecmp(cmd_name, "tapenable") == 0) {
702 if (!jtag_tap_enable(t)) {
703 LOG_WARNING("failed to enable tap %s", t->dotted_name);
704 return JIM_ERR;
705 }
706 } else if (strcasecmp(cmd_name, "tapdisable") == 0) {
707 if (!jtag_tap_disable(t)) {
708 LOG_WARNING("failed to disable tap %s", t->dotted_name);
709 return JIM_ERR;
710 }
711 } else {
712 LOG_ERROR("command '%s' unknown", cmd_name);
713 return JIM_ERR;
714 }
715 bool e = t->enabled;
716 Jim_SetResult(goi.interp, Jim_NewIntObj(goi.interp, e));
717 return JIM_OK;
718 }
719
720 int jim_jtag_configure(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
721 {
722 struct command *c = jim_to_command(interp);
723 const char *cmd_name = c->name;
724 struct jim_getopt_info goi;
725 jim_getopt_setup(&goi, interp, argc-1, argv + 1);
726 goi.isconfigure = !strcmp(cmd_name, "configure");
727 if (goi.argc < 2 + goi.isconfigure) {
728 Jim_WrongNumArgs(goi.interp, 0, NULL,
729 "<tap_name> <attribute> ...");
730 return JIM_ERR;
731 }
732
733 struct jtag_tap *t;
734
735 Jim_Obj *o;
736 jim_getopt_obj(&goi, &o);
737 t = jtag_tap_by_jim_obj(goi.interp, o);
738 if (!t)
739 return JIM_ERR;
740
741 return jtag_tap_configure_cmd(&goi, t);
742 }
743
744 COMMAND_HANDLER(handle_jtag_names)
745 {
746 if (CMD_ARGC != 0)
747 return ERROR_COMMAND_SYNTAX_ERROR;
748
749 for (struct jtag_tap *tap = jtag_all_taps(); tap; tap = tap->next_tap)
750 command_print(CMD, "%s", tap->dotted_name);
751
752 return ERROR_OK;
753 }
754
755 COMMAND_HANDLER(handle_jtag_init_command)
756 {
757 if (CMD_ARGC != 0)
758 return ERROR_COMMAND_SYNTAX_ERROR;
759
760 static bool jtag_initialized;
761 if (jtag_initialized) {
762 LOG_INFO("'jtag init' has already been called");
763 return ERROR_OK;
764 }
765 jtag_initialized = true;
766
767 LOG_DEBUG("Initializing jtag devices...");
768 return jtag_init(CMD_CTX);
769 }
770
771 static const struct command_registration jtag_subcommand_handlers[] = {
772 {
773 .name = "init",
774 .mode = COMMAND_ANY,
775 .handler = handle_jtag_init_command,
776 .help = "initialize jtag scan chain",
777 .usage = ""
778 },
779 {
780 .name = "arp_init",
781 .mode = COMMAND_ANY,
782 .handler = handle_jtag_arp_init,
783 .help = "Validates JTAG scan chain against the list of "
784 "declared TAPs using just the four standard JTAG "
785 "signals.",
786 .usage = "",
787 },
788 {
789 .name = "arp_init-reset",
790 .mode = COMMAND_ANY,
791 .handler = handle_jtag_arp_init_reset,
792 .help = "Uses TRST and SRST to try resetting everything on "
793 "the JTAG scan chain, then performs 'jtag arp_init'.",
794 .usage = "",
795 },
796 {
797 .name = "newtap",
798 .mode = COMMAND_CONFIG,
799 .jim_handler = jim_jtag_newtap,
800 .help = "Create a new TAP instance named basename.tap_type, "
801 "and appends it to the scan chain.",
802 .usage = "basename tap_type '-irlen' count "
803 "['-enable'|'-disable'] "
804 "['-expected_id' number] "
805 "['-ignore-version'] "
806 "['-ignore-bypass'] "
807 "['-ircapture' number] "
808 "['-mask' number]",
809 },
810 {
811 .name = "tapisenabled",
812 .mode = COMMAND_EXEC,
813 .jim_handler = jim_jtag_tap_enabler,
814 .help = "Returns a Tcl boolean (0/1) indicating whether "
815 "the TAP is enabled (1) or not (0).",
816 .usage = "tap_name",
817 },
818 {
819 .name = "tapenable",
820 .mode = COMMAND_EXEC,
821 .jim_handler = jim_jtag_tap_enabler,
822 .help = "Try to enable the specified TAP using the "
823 "'tap-enable' TAP event.",
824 .usage = "tap_name",
825 },
826 {
827 .name = "tapdisable",
828 .mode = COMMAND_EXEC,
829 .jim_handler = jim_jtag_tap_enabler,
830 .help = "Try to disable the specified TAP using the "
831 "'tap-disable' TAP event.",
832 .usage = "tap_name",
833 },
834 {
835 .name = "configure",
836 .mode = COMMAND_ANY,
837 .jim_handler = jim_jtag_configure,
838 .help = "Provide a Tcl handler for the specified "
839 "TAP event.",
840 .usage = "tap_name '-event' event_name handler",
841 },
842 {
843 .name = "cget",
844 .mode = COMMAND_EXEC,
845 .jim_handler = jim_jtag_configure,
846 .help = "Return any Tcl handler for the specified "
847 "TAP event.",
848 .usage = "tap_name '-event' event_name",
849 },
850 {
851 .name = "names",
852 .mode = COMMAND_ANY,
853 .handler = handle_jtag_names,
854 .help = "Returns list of all JTAG tap names.",
855 .usage = "",
856 },
857 {
858 .chain = jtag_command_handlers_to_move,
859 },
860 COMMAND_REGISTRATION_DONE
861 };
862
863 void jtag_notify_event(enum jtag_event event)
864 {
865 struct jtag_tap *tap;
866
867 for (tap = jtag_all_taps(); tap; tap = tap->next_tap)
868 jtag_tap_handle_event(tap, event);
869 }
870
871
872 COMMAND_HANDLER(handle_scan_chain_command)
873 {
874 struct jtag_tap *tap;
875 char expected_id[12];
876
877 tap = jtag_all_taps();
878 command_print(CMD,
879 " TapName Enabled IdCode Expected IrLen IrCap IrMask");
880 command_print(CMD,
881 "-- ------------------- -------- ---------- ---------- ----- ----- ------");
882
883 while (tap) {
884 uint32_t expected, expected_mask, ii;
885
886 snprintf(expected_id, sizeof(expected_id), "0x%08x",
887 (unsigned)((tap->expected_ids_cnt > 0)
888 ? tap->expected_ids[0]
889 : 0));
890 if (tap->ignore_version)
891 expected_id[2] = '*';
892
893 expected = buf_get_u32(tap->expected, 0, tap->ir_length);
894 expected_mask = buf_get_u32(tap->expected_mask, 0, tap->ir_length);
895
896 command_print(CMD,
897 "%2d %-18s %c 0x%08x %s %5d 0x%02x 0x%02x",
898 tap->abs_chain_position,
899 tap->dotted_name,
900 tap->enabled ? 'Y' : 'n',
901 (unsigned int)(tap->idcode),
902 expected_id,
903 (unsigned int)(tap->ir_length),
904 (unsigned int)(expected),
905 (unsigned int)(expected_mask));
906
907 for (ii = 1; ii < tap->expected_ids_cnt; ii++) {
908 snprintf(expected_id, sizeof(expected_id), "0x%08x",
909 (unsigned) tap->expected_ids[ii]);
910 if (tap->ignore_version)
911 expected_id[2] = '*';
912
913 command_print(CMD,
914 " %s",
915 expected_id);
916 }
917
918 tap = tap->next_tap;
919 }
920
921 return ERROR_OK;
922 }
923
924 COMMAND_HANDLER(handle_jtag_ntrst_delay_command)
925 {
926 if (CMD_ARGC > 1)
927 return ERROR_COMMAND_SYNTAX_ERROR;
928 if (CMD_ARGC == 1) {
929 unsigned delay;
930 COMMAND_PARSE_NUMBER(uint, CMD_ARGV[0], delay);
931
932 jtag_set_ntrst_delay(delay);
933 }
934 command_print(CMD, "jtag_ntrst_delay: %u", jtag_get_ntrst_delay());
935 return ERROR_OK;
936 }
937
938 COMMAND_HANDLER(handle_jtag_ntrst_assert_width_command)
939 {
940 if (CMD_ARGC > 1)
941 return ERROR_COMMAND_SYNTAX_ERROR;
942 if (CMD_ARGC == 1) {
943 unsigned delay;
944 COMMAND_PARSE_NUMBER(uint, CMD_ARGV[0], delay);
945
946 jtag_set_ntrst_assert_width(delay);
947 }
948 command_print(CMD, "jtag_ntrst_assert_width: %u", jtag_get_ntrst_assert_width());
949 return ERROR_OK;
950 }
951
952 COMMAND_HANDLER(handle_jtag_rclk_command)
953 {
954 if (CMD_ARGC > 1)
955 return ERROR_COMMAND_SYNTAX_ERROR;
956
957 int retval = ERROR_OK;
958 if (CMD_ARGC == 1) {
959 unsigned khz = 0;
960 COMMAND_PARSE_NUMBER(uint, CMD_ARGV[0], khz);
961
962 retval = adapter_config_rclk(khz);
963 if (retval != ERROR_OK)
964 return retval;
965 }
966
967 int cur_khz = adapter_get_speed_khz();
968 retval = adapter_get_speed_readable(&cur_khz);
969 if (retval != ERROR_OK)
970 return retval;
971
972 if (cur_khz)
973 command_print(CMD, "RCLK not supported - fallback to %d kHz", cur_khz);
974 else
975 command_print(CMD, "RCLK - adaptive");
976
977 return retval;
978 }
979
980 COMMAND_HANDLER(handle_runtest_command)
981 {
982 if (CMD_ARGC != 1)
983 return ERROR_COMMAND_SYNTAX_ERROR;
984
985 unsigned num_clocks;
986 COMMAND_PARSE_NUMBER(uint, CMD_ARGV[0], num_clocks);
987
988 jtag_add_runtest(num_clocks, TAP_IDLE);
989 return jtag_execute_queue();
990 }
991
992 /*
993 * For "irscan" or "drscan" commands, the "end" (really, "next") state
994 * should be stable ... and *NOT* a shift state, otherwise free-running
995 * jtag clocks could change the values latched by the update state.
996 * Not surprisingly, this is the same constraint as SVF; the "irscan"
997 * and "drscan" commands are a write-only subset of what SVF provides.
998 */
999
1000 COMMAND_HANDLER(handle_irscan_command)
1001 {
1002 int i;
1003 struct scan_field *fields;
1004 struct jtag_tap *tap = NULL;
1005 tap_state_t endstate;
1006
1007 if ((CMD_ARGC < 2) || (CMD_ARGC % 2))
1008 return ERROR_COMMAND_SYNTAX_ERROR;
1009
1010 /* optional "-endstate" "statename" at the end of the arguments,
1011 * so that e.g. IRPAUSE can let us load the data register before
1012 * entering RUN/IDLE to execute the instruction we load here.
1013 */
1014 endstate = TAP_IDLE;
1015
1016 if (CMD_ARGC >= 4) {
1017 /* have at least one pair of numbers.
1018 * is last pair the magic text? */
1019 if (strcmp("-endstate", CMD_ARGV[CMD_ARGC - 2]) == 0) {
1020 endstate = tap_state_by_name(CMD_ARGV[CMD_ARGC - 1]);
1021 if (endstate == TAP_INVALID)
1022 return ERROR_COMMAND_SYNTAX_ERROR;
1023 if (!scan_is_safe(endstate))
1024 LOG_WARNING("unstable irscan endstate \"%s\"",
1025 CMD_ARGV[CMD_ARGC - 1]);
1026 CMD_ARGC -= 2;
1027 }
1028 }
1029
1030 int num_fields = CMD_ARGC / 2;
1031 if (num_fields > 1) {
1032 /* we really should be looking at plain_ir_scan if we want
1033 * anything more fancy.
1034 */
1035 LOG_ERROR("Specify a single value for tap");
1036 return ERROR_COMMAND_SYNTAX_ERROR;
1037 }
1038
1039 fields = calloc(num_fields, sizeof(*fields));
1040
1041 int retval;
1042 for (i = 0; i < num_fields; i++) {
1043 tap = jtag_tap_by_string(CMD_ARGV[i*2]);
1044 if (!tap) {
1045 free(fields);
1046 command_print(CMD, "Tap: %s unknown", CMD_ARGV[i*2]);
1047
1048 return ERROR_FAIL;
1049 }
1050 uint64_t value;
1051 retval = parse_u64(CMD_ARGV[i * 2 + 1], &value);
1052 if (retval != ERROR_OK)
1053 goto error_return;
1054
1055 int field_size = tap->ir_length;
1056 fields[i].num_bits = field_size;
1057 uint8_t *v = calloc(1, DIV_ROUND_UP(field_size, 8));
1058 if (!v) {
1059 LOG_ERROR("Out of memory");
1060 goto error_return;
1061 }
1062
1063 buf_set_u64(v, 0, field_size, value);
1064 fields[i].out_value = v;
1065 fields[i].in_value = NULL;
1066 }
1067
1068 /* did we have an endstate? */
1069 jtag_add_ir_scan(tap, fields, endstate);
1070
1071 retval = jtag_execute_queue();
1072
1073 error_return:
1074 for (i = 0; i < num_fields; i++)
1075 free((void *)fields[i].out_value);
1076
1077 free(fields);
1078
1079 return retval;
1080 }
1081
1082 COMMAND_HANDLER(handle_verify_ircapture_command)
1083 {
1084 if (CMD_ARGC > 1)
1085 return ERROR_COMMAND_SYNTAX_ERROR;
1086
1087 if (CMD_ARGC == 1) {
1088 bool enable;
1089 COMMAND_PARSE_ENABLE(CMD_ARGV[0], enable);
1090 jtag_set_verify_capture_ir(enable);
1091 }
1092
1093 const char *status = jtag_will_verify_capture_ir() ? "enabled" : "disabled";
1094 command_print(CMD, "verify Capture-IR is %s", status);
1095
1096 return ERROR_OK;
1097 }
1098
1099 COMMAND_HANDLER(handle_verify_jtag_command)
1100 {
1101 if (CMD_ARGC > 1)
1102 return ERROR_COMMAND_SYNTAX_ERROR;
1103
1104 if (CMD_ARGC == 1) {
1105 bool enable;
1106 COMMAND_PARSE_ENABLE(CMD_ARGV[0], enable);
1107 jtag_set_verify(enable);
1108 }
1109
1110 const char *status = jtag_will_verify() ? "enabled" : "disabled";
1111 command_print(CMD, "verify jtag capture is %s", status);
1112
1113 return ERROR_OK;
1114 }
1115
1116 COMMAND_HANDLER(handle_tms_sequence_command)
1117 {
1118 if (CMD_ARGC > 1)
1119 return ERROR_COMMAND_SYNTAX_ERROR;
1120
1121 if (CMD_ARGC == 1) {
1122 bool use_new_table;
1123 if (strcmp(CMD_ARGV[0], "short") == 0)
1124 use_new_table = true;
1125 else if (strcmp(CMD_ARGV[0], "long") == 0)
1126 use_new_table = false;
1127 else
1128 return ERROR_COMMAND_SYNTAX_ERROR;
1129
1130 tap_use_new_tms_table(use_new_table);
1131 }
1132
1133 command_print(CMD, "tms sequence is %s",
1134 tap_uses_new_tms_table() ? "short" : "long");
1135
1136 return ERROR_OK;
1137 }
1138
1139 COMMAND_HANDLER(handle_jtag_flush_queue_sleep)
1140 {
1141 if (CMD_ARGC != 1)
1142 return ERROR_COMMAND_SYNTAX_ERROR;
1143
1144 int sleep_ms;
1145 COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], sleep_ms);
1146
1147 jtag_set_flush_queue_sleep(sleep_ms);
1148
1149 return ERROR_OK;
1150 }
1151
1152 COMMAND_HANDLER(handle_wait_srst_deassert)
1153 {
1154 if (CMD_ARGC != 1)
1155 return ERROR_COMMAND_SYNTAX_ERROR;
1156
1157 int timeout_ms;
1158 COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], timeout_ms);
1159 if ((timeout_ms <= 0) || (timeout_ms > 100000)) {
1160 LOG_ERROR("Timeout must be an integer between 0 and 100000");
1161 return ERROR_FAIL;
1162 }
1163
1164 LOG_USER("Waiting for srst assert + deassert for at most %dms", timeout_ms);
1165 int asserted_yet;
1166 int64_t then = timeval_ms();
1167 while (jtag_srst_asserted(&asserted_yet) == ERROR_OK) {
1168 if ((timeval_ms() - then) > timeout_ms) {
1169 LOG_ERROR("Timed out");
1170 return ERROR_FAIL;
1171 }
1172 if (asserted_yet)
1173 break;
1174 }
1175 while (jtag_srst_asserted(&asserted_yet) == ERROR_OK) {
1176 if ((timeval_ms() - then) > timeout_ms) {
1177 LOG_ERROR("Timed out");
1178 return ERROR_FAIL;
1179 }
1180 if (!asserted_yet)
1181 break;
1182 }
1183
1184 return ERROR_OK;
1185 }
1186
1187 static const struct command_registration jtag_command_handlers[] = {
1188
1189 {
1190 .name = "jtag_flush_queue_sleep",
1191 .handler = handle_jtag_flush_queue_sleep,
1192 .mode = COMMAND_ANY,
1193 .help = "For debug purposes(simulate long delays of interface) "
1194 "to test performance or change in behavior. Default 0ms.",
1195 .usage = "[sleep in ms]",
1196 },
1197 {
1198 .name = "jtag_rclk",
1199 .handler = handle_jtag_rclk_command,
1200 .mode = COMMAND_ANY,
1201 .help = "With an argument, change to to use adaptive clocking "
1202 "if possible; else to use the fallback speed. "
1203 "With or without argument, display current setting.",
1204 .usage = "[fallback_speed_khz]",
1205 },
1206 {
1207 .name = "jtag_ntrst_delay",
1208 .handler = handle_jtag_ntrst_delay_command,
1209 .mode = COMMAND_ANY,
1210 .help = "delay after deasserting trst in ms",
1211 .usage = "[milliseconds]",
1212 },
1213 {
1214 .name = "jtag_ntrst_assert_width",
1215 .handler = handle_jtag_ntrst_assert_width_command,
1216 .mode = COMMAND_ANY,
1217 .help = "delay after asserting trst in ms",
1218 .usage = "[milliseconds]",
1219 },
1220 {
1221 .name = "scan_chain",
1222 .handler = handle_scan_chain_command,
1223 .mode = COMMAND_ANY,
1224 .help = "print current scan chain configuration",
1225 .usage = ""
1226 },
1227 {
1228 .name = "runtest",
1229 .handler = handle_runtest_command,
1230 .mode = COMMAND_EXEC,
1231 .help = "Move to Run-Test/Idle, and issue TCK for num_cycles.",
1232 .usage = "num_cycles"
1233 },
1234 {
1235 .name = "irscan",
1236 .handler = handle_irscan_command,
1237 .mode = COMMAND_EXEC,
1238 .help = "Execute Instruction Register (IR) scan. The "
1239 "specified opcodes are put into each TAP's IR, "
1240 "and other TAPs are put in BYPASS.",
1241 .usage = "[tap_name instruction]* ['-endstate' state_name]",
1242 },
1243 {
1244 .name = "verify_ircapture",
1245 .handler = handle_verify_ircapture_command,
1246 .mode = COMMAND_ANY,
1247 .help = "Display or assign flag controlling whether to "
1248 "verify values captured during Capture-IR.",
1249 .usage = "['enable'|'disable']",
1250 },
1251 {
1252 .name = "verify_jtag",
1253 .handler = handle_verify_jtag_command,
1254 .mode = COMMAND_ANY,
1255 .help = "Display or assign flag controlling whether to "
1256 "verify values captured during IR and DR scans.",
1257 .usage = "['enable'|'disable']",
1258 },
1259 {
1260 .name = "tms_sequence",
1261 .handler = handle_tms_sequence_command,
1262 .mode = COMMAND_ANY,
1263 .help = "Display or change what style TMS sequences to use "
1264 "for JTAG state transitions: short (default) or "
1265 "long. Only for working around JTAG bugs.",
1266 /* Specifically for working around DRIVER bugs... */
1267 .usage = "['short'|'long']",
1268 },
1269 {
1270 .name = "wait_srst_deassert",
1271 .handler = handle_wait_srst_deassert,
1272 .mode = COMMAND_ANY,
1273 .help = "Wait for an SRST deassert. "
1274 "Useful for cases where you need something to happen within ms "
1275 "of an srst deassert. Timeout in ms",
1276 .usage = "ms",
1277 },
1278 {
1279 .name = "jtag",
1280 .mode = COMMAND_ANY,
1281 .help = "perform jtag tap actions",
1282 .usage = "",
1283
1284 .chain = jtag_subcommand_handlers,
1285 },
1286 {
1287 .chain = jtag_command_handlers_to_move,
1288 },
1289 COMMAND_REGISTRATION_DONE
1290 };
1291
1292 int jtag_register_commands(struct command_context *cmd_ctx)
1293 {
1294 return register_commands(cmd_ctx, NULL, jtag_command_handlers);
1295 }

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)