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

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)