jtag: rewrite jim_jtag_configure() 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/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 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 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_set_event(struct command_context *cmd_ctx, struct jtag_tap *tap,
270 const struct nvp *event, Jim_Obj *body)
271 {
272 struct jtag_tap_event_action *jteap = tap->event_action;
273
274 while (jteap) {
275 if (jteap->event == (enum jtag_event)event->value)
276 break;
277 jteap = jteap->next;
278 }
279
280 if (!jteap) {
281 jteap = calloc(1, sizeof(*jteap));
282 if (!jteap) {
283 LOG_ERROR("Out of memory");
284 return ERROR_FAIL;
285 }
286
287 /* add to head of event list */
288 jteap->next = tap->event_action;
289 tap->event_action = jteap;
290 } else {
291 Jim_DecrRefCount(cmd_ctx->interp, jteap->body);
292 }
293
294 jteap->interp = cmd_ctx->interp;
295 jteap->event = (enum jtag_event)event->value;
296 jteap->body = Jim_DuplicateObj(cmd_ctx->interp, body);
297 Jim_IncrRefCount(jteap->body);
298
299 return ERROR_OK;
300 }
301
302 __COMMAND_HANDLER(handle_jtag_configure)
303 {
304 bool is_configure = !strcmp(CMD_NAME, "configure");
305
306 if (CMD_ARGC < (is_configure ? 3 : 2))
307 return ERROR_COMMAND_SYNTAX_ERROR;
308
309 /* FIXME: rework jtag_tap_by_jim_obj */
310 struct jtag_tap *tap = jtag_tap_by_jim_obj(CMD_CTX->interp, CMD_JIMTCL_ARGV[0]);
311 if (!tap)
312 return ERROR_FAIL;
313
314 for (unsigned int i = 1; i < CMD_ARGC; i++) {
315 const struct nvp *n = nvp_name2value(nvp_config_opts, CMD_ARGV[i]);
316 switch (n->value) {
317 case JCFG_EVENT:
318 if (i + (is_configure ? 3 : 2) >= CMD_ARGC) {
319 command_print(CMD, "wrong # args: should be \"-event <event-name>%s\"",
320 is_configure ? " <event-body>" : "");
321 return ERROR_COMMAND_ARGUMENT_INVALID;
322 }
323
324 const struct nvp *event = nvp_name2value(nvp_jtag_tap_event, CMD_ARGV[i + 1]);
325 if (!event->name) {
326 nvp_unknown_command_print(CMD, nvp_jtag_tap_event, CMD_ARGV[i], CMD_ARGV[i + 1]);
327 return ERROR_COMMAND_ARGUMENT_INVALID;
328 }
329
330 if (is_configure) {
331 int retval = jtag_tap_set_event(CMD_CTX, tap, event, CMD_JIMTCL_ARGV[i + 2]);
332 if (retval != ERROR_OK)
333 return retval;
334 } else {
335 struct jtag_tap_event_action *jteap = tap->event_action;
336 while (jteap) {
337 if (jteap->event == (enum jtag_event)event->value) {
338 command_print(CMD, "%s", Jim_GetString(jteap->body, NULL));
339 break;
340 }
341 jteap = jteap->next;
342 }
343 }
344
345 i += is_configure ? 2 : 1;
346 break;
347 case JCFG_IDCODE:
348 if (is_configure) {
349 command_print(CMD, "not settable: %s", n->name);
350 return ERROR_COMMAND_ARGUMENT_INVALID;
351 }
352 command_print(CMD, "0x%08x", tap->idcode);
353 break;
354 default:
355 nvp_unknown_command_print(CMD, nvp_config_opts, NULL, CMD_ARGV[i]);
356 return ERROR_COMMAND_ARGUMENT_INVALID;
357 }
358 }
359 return ERROR_OK;
360 }
361
362 #define NTAP_OPT_IRLEN 0
363 #define NTAP_OPT_IRMASK 1
364 #define NTAP_OPT_IRCAPTURE 2
365 #define NTAP_OPT_ENABLED 3
366 #define NTAP_OPT_DISABLED 4
367 #define NTAP_OPT_EXPECTED_ID 5
368 #define NTAP_OPT_VERSION 6
369 #define NTAP_OPT_BYPASS 7
370 #define NTAP_OPT_IRBYPASS 8
371
372 static const struct nvp jtag_newtap_opts[] = {
373 { .name = "-irlen", .value = NTAP_OPT_IRLEN },
374 { .name = "-irmask", .value = NTAP_OPT_IRMASK },
375 { .name = "-ircapture", .value = NTAP_OPT_IRCAPTURE },
376 { .name = "-enable", .value = NTAP_OPT_ENABLED },
377 { .name = "-disable", .value = NTAP_OPT_DISABLED },
378 { .name = "-expected-id", .value = NTAP_OPT_EXPECTED_ID },
379 { .name = "-ignore-version", .value = NTAP_OPT_VERSION },
380 { .name = "-ignore-bypass", .value = NTAP_OPT_BYPASS },
381 { .name = "-ir-bypass", .value = NTAP_OPT_IRBYPASS },
382 { .name = NULL, .value = -1 },
383 };
384
385 static COMMAND_HELPER(handle_jtag_newtap_args, struct jtag_tap *tap)
386 {
387 /* we expect CHIP + TAP + OPTIONS */
388 if (CMD_ARGC < 2)
389 return ERROR_COMMAND_SYNTAX_ERROR;
390
391 tap->chip = strdup(CMD_ARGV[0]);
392 tap->tapname = strdup(CMD_ARGV[1]);
393 tap->dotted_name = alloc_printf("%s.%s", CMD_ARGV[0], CMD_ARGV[1]);
394 if (!tap->chip || !tap->tapname || !tap->dotted_name) {
395 LOG_ERROR("Out of memory");
396 return ERROR_FAIL;
397 }
398 CMD_ARGC -= 2;
399 CMD_ARGV += 2;
400
401 LOG_DEBUG("Creating New Tap, Chip: %s, Tap: %s, Dotted: %s, %d params",
402 tap->chip, tap->tapname, tap->dotted_name, CMD_ARGC);
403
404 /*
405 * IEEE specifies that the two LSBs of an IR scan are 01, so make
406 * that the default. The "-ircapture" and "-irmask" options are only
407 * needed to cope with nonstandard TAPs, or to specify more bits.
408 */
409 tap->ir_capture_mask = 0x03;
410 tap->ir_capture_value = 0x01;
411
412 while (CMD_ARGC) {
413 const struct nvp *n = nvp_name2value(jtag_newtap_opts, CMD_ARGV[0]);
414 CMD_ARGC--;
415 CMD_ARGV++;
416 switch (n->value) {
417 case NTAP_OPT_ENABLED:
418 tap->disabled_after_reset = false;
419 break;
420
421 case NTAP_OPT_DISABLED:
422 tap->disabled_after_reset = true;
423 break;
424
425 case NTAP_OPT_EXPECTED_ID:
426 if (!CMD_ARGC)
427 return ERROR_COMMAND_ARGUMENT_INVALID;
428
429 tap->expected_ids = realloc(tap->expected_ids,
430 (tap->expected_ids_cnt + 1) * sizeof(uint32_t));
431 if (!tap->expected_ids) {
432 LOG_ERROR("Out of memory");
433 return ERROR_FAIL;
434 }
435
436 uint32_t id;
437 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], id);
438 CMD_ARGC--;
439 CMD_ARGV++;
440 tap->expected_ids[tap->expected_ids_cnt++] = id;
441
442 break;
443
444 case NTAP_OPT_IRLEN:
445 if (!CMD_ARGC)
446 return ERROR_COMMAND_ARGUMENT_INVALID;
447
448 COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], tap->ir_length);
449 CMD_ARGC--;
450 CMD_ARGV++;
451 if (tap->ir_length > (int)(8 * sizeof(tap->ir_capture_value)))
452 LOG_WARNING("%s: huge IR length %d", tap->dotted_name, tap->ir_length);
453 break;
454
455 case NTAP_OPT_IRMASK:
456 if (!CMD_ARGC)
457 return ERROR_COMMAND_ARGUMENT_INVALID;
458
459 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], tap->ir_capture_mask);
460 CMD_ARGC--;
461 CMD_ARGV++;
462 if ((tap->ir_capture_mask & 3) != 3)
463 LOG_WARNING("%s: nonstandard IR mask", tap->dotted_name);
464 break;
465
466 case NTAP_OPT_IRCAPTURE:
467 if (!CMD_ARGC)
468 return ERROR_COMMAND_ARGUMENT_INVALID;
469
470 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], tap->ir_capture_value);
471 CMD_ARGC--;
472 CMD_ARGV++;
473 if ((tap->ir_capture_value & 3) != 1)
474 LOG_WARNING("%s: nonstandard IR value", tap->dotted_name);
475 break;
476
477 case NTAP_OPT_VERSION:
478 tap->ignore_version = true;
479 break;
480
481 case NTAP_OPT_BYPASS:
482 tap->ignore_bypass = true;
483 break;
484
485 case NTAP_OPT_IRBYPASS:
486 if (!CMD_ARGC)
487 return ERROR_COMMAND_ARGUMENT_INVALID;
488
489 COMMAND_PARSE_NUMBER(u64, CMD_ARGV[0], tap->ir_bypass_value);
490 CMD_ARGC--;
491 CMD_ARGV++;
492 break;
493
494 default:
495 nvp_unknown_command_print(CMD, jtag_newtap_opts, NULL, CMD_ARGV[-1]);
496 return ERROR_COMMAND_ARGUMENT_INVALID;
497 }
498 }
499
500 /* default is enabled-after-reset */
501 tap->enabled = !tap->disabled_after_reset;
502
503 if (transport_is_jtag() && tap->ir_length == 0) {
504 command_print(CMD, "newtap: %s missing IR length", tap->dotted_name);
505 return ERROR_COMMAND_ARGUMENT_INVALID;
506 }
507
508 return ERROR_OK;
509 }
510
511 __COMMAND_HANDLER(handle_jtag_newtap)
512 {
513 struct jtag_tap *tap = calloc(1, sizeof(struct jtag_tap));
514 if (!tap) {
515 LOG_ERROR("Out of memory");
516 return ERROR_FAIL;
517 }
518
519 int retval = CALL_COMMAND_HANDLER(handle_jtag_newtap_args, tap);
520 if (retval != ERROR_OK) {
521 free(tap->chip);
522 free(tap->tapname);
523 free(tap->dotted_name);
524 free(tap->expected_ids);
525 free(tap);
526 return retval;
527 }
528
529 jtag_tap_init(tap);
530 return ERROR_OK;
531 }
532
533 static void jtag_tap_handle_event(struct jtag_tap *tap, enum jtag_event e)
534 {
535 struct jtag_tap_event_action *jteap;
536 int retval;
537
538 for (jteap = tap->event_action; jteap; jteap = jteap->next) {
539 if (jteap->event != e)
540 continue;
541
542 const struct nvp *nvp = nvp_value2name(nvp_jtag_tap_event, e);
543 LOG_DEBUG("JTAG tap: %s event: %d (%s)\n\taction: %s",
544 tap->dotted_name, e, nvp->name,
545 Jim_GetString(jteap->body, NULL));
546
547 retval = Jim_EvalObj(jteap->interp, jteap->body);
548 if (retval == JIM_RETURN)
549 retval = jteap->interp->returnCode;
550
551 if (retval != JIM_OK) {
552 Jim_MakeErrorMessage(jteap->interp);
553 LOG_USER("%s", Jim_GetString(Jim_GetResult(jteap->interp), NULL));
554 continue;
555 }
556
557 switch (e) {
558 case JTAG_TAP_EVENT_ENABLE:
559 case JTAG_TAP_EVENT_DISABLE:
560 /* NOTE: we currently assume the handlers
561 * can't fail. Right here is where we should
562 * really be verifying the scan chains ...
563 */
564 tap->enabled = (e == JTAG_TAP_EVENT_ENABLE);
565 LOG_INFO("JTAG tap: %s %s", tap->dotted_name,
566 tap->enabled ? "enabled" : "disabled");
567 break;
568 default:
569 break;
570 }
571 }
572 }
573
574 COMMAND_HANDLER(handle_jtag_arp_init)
575 {
576 if (CMD_ARGC != 0)
577 return ERROR_COMMAND_SYNTAX_ERROR;
578
579 return jtag_init_inner(CMD_CTX);
580 }
581
582 COMMAND_HANDLER(handle_jtag_arp_init_reset)
583 {
584 if (CMD_ARGC != 0)
585 return ERROR_COMMAND_SYNTAX_ERROR;
586
587 if (transport_is_jtag())
588 return jtag_init_reset(CMD_CTX);
589
590 if (transport_is_swd())
591 return swd_init_reset(CMD_CTX);
592
593 return ERROR_OK;
594 }
595
596 static bool jtag_tap_enable(struct jtag_tap *t)
597 {
598 if (t->enabled)
599 return true;
600 jtag_tap_handle_event(t, JTAG_TAP_EVENT_ENABLE);
601 if (!t->enabled)
602 return false;
603
604 /* FIXME add JTAG sanity checks, w/o TLR
605 * - scan chain length grew by one (this)
606 * - IDs and IR lengths are as expected
607 */
608 jtag_call_event_callbacks(JTAG_TAP_EVENT_ENABLE);
609 return true;
610 }
611 static bool jtag_tap_disable(struct jtag_tap *t)
612 {
613 if (!t->enabled)
614 return true;
615 jtag_tap_handle_event(t, JTAG_TAP_EVENT_DISABLE);
616 if (t->enabled)
617 return false;
618
619 /* FIXME add JTAG sanity checks, w/o TLR
620 * - scan chain length shrank by one (this)
621 * - IDs and IR lengths are as expected
622 */
623 jtag_call_event_callbacks(JTAG_TAP_EVENT_DISABLE);
624 return true;
625 }
626
627 __COMMAND_HANDLER(handle_jtag_tap_enabler)
628 {
629 if (CMD_ARGC != 1)
630 return ERROR_COMMAND_SYNTAX_ERROR;
631
632 struct jtag_tap *t = jtag_tap_by_string(CMD_ARGV[0]);
633 if (!t) {
634 command_print(CMD, "Tap '%s' could not be found", CMD_ARGV[0]);
635 return ERROR_COMMAND_ARGUMENT_INVALID;
636 }
637
638 if (strcmp(CMD_NAME, "tapisenabled") == 0) {
639 /* do nothing, just return the value */
640 } else if (strcmp(CMD_NAME, "tapenable") == 0) {
641 if (!jtag_tap_enable(t)) {
642 command_print(CMD, "failed to enable tap %s", t->dotted_name);
643 return ERROR_FAIL;
644 }
645 } else if (strcmp(CMD_NAME, "tapdisable") == 0) {
646 if (!jtag_tap_disable(t)) {
647 command_print(CMD, "failed to disable tap %s", t->dotted_name);
648 return ERROR_FAIL;
649 }
650 } else {
651 command_print(CMD, "command '%s' unknown", CMD_NAME);
652 return ERROR_FAIL;
653 }
654
655 command_print(CMD, "%d", t->enabled ? 1 : 0);
656 return ERROR_OK;
657 }
658
659 COMMAND_HANDLER(handle_jtag_names)
660 {
661 if (CMD_ARGC != 0)
662 return ERROR_COMMAND_SYNTAX_ERROR;
663
664 for (struct jtag_tap *tap = jtag_all_taps(); tap; tap = tap->next_tap)
665 command_print(CMD, "%s", tap->dotted_name);
666
667 return ERROR_OK;
668 }
669
670 COMMAND_HANDLER(handle_jtag_init_command)
671 {
672 if (CMD_ARGC != 0)
673 return ERROR_COMMAND_SYNTAX_ERROR;
674
675 static bool jtag_initialized;
676 if (jtag_initialized) {
677 LOG_INFO("'jtag init' has already been called");
678 return ERROR_OK;
679 }
680 jtag_initialized = true;
681
682 LOG_DEBUG("Initializing jtag devices...");
683 return jtag_init(CMD_CTX);
684 }
685
686 static const struct command_registration jtag_subcommand_handlers[] = {
687 {
688 .name = "init",
689 .mode = COMMAND_ANY,
690 .handler = handle_jtag_init_command,
691 .help = "initialize jtag scan chain",
692 .usage = ""
693 },
694 {
695 .name = "arp_init",
696 .mode = COMMAND_ANY,
697 .handler = handle_jtag_arp_init,
698 .help = "Validates JTAG scan chain against the list of "
699 "declared TAPs using just the four standard JTAG "
700 "signals.",
701 .usage = "",
702 },
703 {
704 .name = "arp_init-reset",
705 .mode = COMMAND_ANY,
706 .handler = handle_jtag_arp_init_reset,
707 .help = "Uses TRST and SRST to try resetting everything on "
708 "the JTAG scan chain, then performs 'jtag arp_init'.",
709 .usage = "",
710 },
711 {
712 .name = "newtap",
713 .mode = COMMAND_CONFIG,
714 .handler = handle_jtag_newtap,
715 .help = "Create a new TAP instance named basename.tap_type, "
716 "and appends it to the scan chain.",
717 .usage = "basename tap_type '-irlen' count "
718 "['-enable'|'-disable'] "
719 "['-expected_id' number] "
720 "['-ignore-version'] "
721 "['-ignore-bypass'] "
722 "['-ircapture' number] "
723 "['-ir-bypass' number] "
724 "['-mask' number]",
725 },
726 {
727 .name = "tapisenabled",
728 .mode = COMMAND_EXEC,
729 .handler = handle_jtag_tap_enabler,
730 .help = "Returns a Tcl boolean (0/1) indicating whether "
731 "the TAP is enabled (1) or not (0).",
732 .usage = "tap_name",
733 },
734 {
735 .name = "tapenable",
736 .mode = COMMAND_EXEC,
737 .handler = handle_jtag_tap_enabler,
738 .help = "Try to enable the specified TAP using the "
739 "'tap-enable' TAP event.",
740 .usage = "tap_name",
741 },
742 {
743 .name = "tapdisable",
744 .mode = COMMAND_EXEC,
745 .handler = handle_jtag_tap_enabler,
746 .help = "Try to disable the specified TAP using the "
747 "'tap-disable' TAP event.",
748 .usage = "tap_name",
749 },
750 {
751 .name = "configure",
752 .mode = COMMAND_ANY,
753 .handler = handle_jtag_configure,
754 .help = "Provide a Tcl handler for the specified "
755 "TAP event.",
756 .usage = "tap_name '-event' event_name handler",
757 },
758 {
759 .name = "cget",
760 .mode = COMMAND_EXEC,
761 .handler = handle_jtag_configure,
762 .help = "Return any Tcl handler for the specified "
763 "TAP event.",
764 .usage = "tap_name '-event' event_name",
765 },
766 {
767 .name = "names",
768 .mode = COMMAND_ANY,
769 .handler = handle_jtag_names,
770 .help = "Returns list of all JTAG tap names.",
771 .usage = "",
772 },
773 {
774 .chain = jtag_command_handlers_to_move,
775 },
776 COMMAND_REGISTRATION_DONE
777 };
778
779 void jtag_notify_event(enum jtag_event event)
780 {
781 struct jtag_tap *tap;
782
783 for (tap = jtag_all_taps(); tap; tap = tap->next_tap)
784 jtag_tap_handle_event(tap, event);
785 }
786
787
788 COMMAND_HANDLER(handle_scan_chain_command)
789 {
790 struct jtag_tap *tap;
791 char expected_id[12];
792
793 tap = jtag_all_taps();
794 command_print(CMD,
795 " TapName Enabled IdCode Expected IrLen IrCap IrMask");
796 command_print(CMD,
797 "-- ------------------- -------- ---------- ---------- ----- ----- ------");
798
799 while (tap) {
800 uint32_t expected, expected_mask, ii;
801
802 snprintf(expected_id, sizeof(expected_id), "0x%08x",
803 (unsigned)((tap->expected_ids_cnt > 0)
804 ? tap->expected_ids[0]
805 : 0));
806 if (tap->ignore_version)
807 expected_id[2] = '*';
808
809 expected = buf_get_u32(tap->expected, 0, tap->ir_length);
810 expected_mask = buf_get_u32(tap->expected_mask, 0, tap->ir_length);
811
812 command_print(CMD,
813 "%2d %-18s %c 0x%08x %s %5d 0x%02x 0x%02x",
814 tap->abs_chain_position,
815 tap->dotted_name,
816 tap->enabled ? 'Y' : 'n',
817 (unsigned int)(tap->idcode),
818 expected_id,
819 (unsigned int)(tap->ir_length),
820 (unsigned int)(expected),
821 (unsigned int)(expected_mask));
822
823 for (ii = 1; ii < tap->expected_ids_cnt; ii++) {
824 snprintf(expected_id, sizeof(expected_id), "0x%08x",
825 (unsigned) tap->expected_ids[ii]);
826 if (tap->ignore_version)
827 expected_id[2] = '*';
828
829 command_print(CMD,
830 " %s",
831 expected_id);
832 }
833
834 tap = tap->next_tap;
835 }
836
837 return ERROR_OK;
838 }
839
840 COMMAND_HANDLER(handle_jtag_ntrst_delay_command)
841 {
842 if (CMD_ARGC > 1)
843 return ERROR_COMMAND_SYNTAX_ERROR;
844 if (CMD_ARGC == 1) {
845 unsigned delay;
846 COMMAND_PARSE_NUMBER(uint, CMD_ARGV[0], delay);
847
848 jtag_set_ntrst_delay(delay);
849 }
850 command_print(CMD, "jtag_ntrst_delay: %u", jtag_get_ntrst_delay());
851 return ERROR_OK;
852 }
853
854 COMMAND_HANDLER(handle_jtag_ntrst_assert_width_command)
855 {
856 if (CMD_ARGC > 1)
857 return ERROR_COMMAND_SYNTAX_ERROR;
858 if (CMD_ARGC == 1) {
859 unsigned delay;
860 COMMAND_PARSE_NUMBER(uint, CMD_ARGV[0], delay);
861
862 jtag_set_ntrst_assert_width(delay);
863 }
864 command_print(CMD, "jtag_ntrst_assert_width: %u", jtag_get_ntrst_assert_width());
865 return ERROR_OK;
866 }
867
868 COMMAND_HANDLER(handle_jtag_rclk_command)
869 {
870 if (CMD_ARGC > 1)
871 return ERROR_COMMAND_SYNTAX_ERROR;
872
873 int retval = ERROR_OK;
874 if (CMD_ARGC == 1) {
875 unsigned khz = 0;
876 COMMAND_PARSE_NUMBER(uint, CMD_ARGV[0], khz);
877
878 retval = adapter_config_rclk(khz);
879 if (retval != ERROR_OK)
880 return retval;
881 }
882
883 int cur_khz = adapter_get_speed_khz();
884 retval = adapter_get_speed_readable(&cur_khz);
885 if (retval != ERROR_OK)
886 return retval;
887
888 if (cur_khz)
889 command_print(CMD, "RCLK not supported - fallback to %d kHz", cur_khz);
890 else
891 command_print(CMD, "RCLK - adaptive");
892
893 return retval;
894 }
895
896 COMMAND_HANDLER(handle_runtest_command)
897 {
898 if (CMD_ARGC != 1)
899 return ERROR_COMMAND_SYNTAX_ERROR;
900
901 unsigned num_clocks;
902 COMMAND_PARSE_NUMBER(uint, CMD_ARGV[0], num_clocks);
903
904 jtag_add_runtest(num_clocks, TAP_IDLE);
905 return jtag_execute_queue();
906 }
907
908 /*
909 * For "irscan" or "drscan" commands, the "end" (really, "next") state
910 * should be stable ... and *NOT* a shift state, otherwise free-running
911 * jtag clocks could change the values latched by the update state.
912 * Not surprisingly, this is the same constraint as SVF; the "irscan"
913 * and "drscan" commands are a write-only subset of what SVF provides.
914 */
915
916 COMMAND_HANDLER(handle_irscan_command)
917 {
918 int i;
919 struct scan_field *fields;
920 struct jtag_tap *tap = NULL;
921 tap_state_t endstate;
922
923 if ((CMD_ARGC < 2) || (CMD_ARGC % 2))
924 return ERROR_COMMAND_SYNTAX_ERROR;
925
926 /* optional "-endstate" "statename" at the end of the arguments,
927 * so that e.g. IRPAUSE can let us load the data register before
928 * entering RUN/IDLE to execute the instruction we load here.
929 */
930 endstate = TAP_IDLE;
931
932 if (CMD_ARGC >= 4) {
933 /* have at least one pair of numbers.
934 * is last pair the magic text? */
935 if (strcmp("-endstate", CMD_ARGV[CMD_ARGC - 2]) == 0) {
936 endstate = tap_state_by_name(CMD_ARGV[CMD_ARGC - 1]);
937 if (endstate == TAP_INVALID)
938 return ERROR_COMMAND_SYNTAX_ERROR;
939 if (!scan_is_safe(endstate))
940 LOG_WARNING("unstable irscan endstate \"%s\"",
941 CMD_ARGV[CMD_ARGC - 1]);
942 CMD_ARGC -= 2;
943 }
944 }
945
946 int num_fields = CMD_ARGC / 2;
947 if (num_fields > 1) {
948 /* we really should be looking at plain_ir_scan if we want
949 * anything more fancy.
950 */
951 LOG_ERROR("Specify a single value for tap");
952 return ERROR_COMMAND_SYNTAX_ERROR;
953 }
954
955 fields = calloc(num_fields, sizeof(*fields));
956
957 int retval;
958 for (i = 0; i < num_fields; i++) {
959 tap = jtag_tap_by_string(CMD_ARGV[i*2]);
960 if (!tap) {
961 free(fields);
962 command_print(CMD, "Tap: %s unknown", CMD_ARGV[i*2]);
963
964 return ERROR_FAIL;
965 }
966 uint64_t value;
967 retval = parse_u64(CMD_ARGV[i * 2 + 1], &value);
968 if (retval != ERROR_OK)
969 goto error_return;
970
971 int field_size = tap->ir_length;
972 fields[i].num_bits = field_size;
973 uint8_t *v = calloc(1, DIV_ROUND_UP(field_size, 8));
974 if (!v) {
975 LOG_ERROR("Out of memory");
976 goto error_return;
977 }
978
979 buf_set_u64(v, 0, field_size, value);
980 fields[i].out_value = v;
981 fields[i].in_value = NULL;
982 }
983
984 /* did we have an endstate? */
985 jtag_add_ir_scan(tap, fields, endstate);
986
987 retval = jtag_execute_queue();
988
989 error_return:
990 for (i = 0; i < num_fields; i++)
991 free((void *)fields[i].out_value);
992
993 free(fields);
994
995 return retval;
996 }
997
998 COMMAND_HANDLER(handle_verify_ircapture_command)
999 {
1000 if (CMD_ARGC > 1)
1001 return ERROR_COMMAND_SYNTAX_ERROR;
1002
1003 if (CMD_ARGC == 1) {
1004 bool enable;
1005 COMMAND_PARSE_ENABLE(CMD_ARGV[0], enable);
1006 jtag_set_verify_capture_ir(enable);
1007 }
1008
1009 const char *status = jtag_will_verify_capture_ir() ? "enabled" : "disabled";
1010 command_print(CMD, "verify Capture-IR is %s", status);
1011
1012 return ERROR_OK;
1013 }
1014
1015 COMMAND_HANDLER(handle_verify_jtag_command)
1016 {
1017 if (CMD_ARGC > 1)
1018 return ERROR_COMMAND_SYNTAX_ERROR;
1019
1020 if (CMD_ARGC == 1) {
1021 bool enable;
1022 COMMAND_PARSE_ENABLE(CMD_ARGV[0], enable);
1023 jtag_set_verify(enable);
1024 }
1025
1026 const char *status = jtag_will_verify() ? "enabled" : "disabled";
1027 command_print(CMD, "verify jtag capture is %s", status);
1028
1029 return ERROR_OK;
1030 }
1031
1032 COMMAND_HANDLER(handle_tms_sequence_command)
1033 {
1034 if (CMD_ARGC > 1)
1035 return ERROR_COMMAND_SYNTAX_ERROR;
1036
1037 if (CMD_ARGC == 1) {
1038 bool use_new_table;
1039 if (strcmp(CMD_ARGV[0], "short") == 0)
1040 use_new_table = true;
1041 else if (strcmp(CMD_ARGV[0], "long") == 0)
1042 use_new_table = false;
1043 else
1044 return ERROR_COMMAND_SYNTAX_ERROR;
1045
1046 tap_use_new_tms_table(use_new_table);
1047 }
1048
1049 command_print(CMD, "tms sequence is %s",
1050 tap_uses_new_tms_table() ? "short" : "long");
1051
1052 return ERROR_OK;
1053 }
1054
1055 COMMAND_HANDLER(handle_jtag_flush_queue_sleep)
1056 {
1057 if (CMD_ARGC != 1)
1058 return ERROR_COMMAND_SYNTAX_ERROR;
1059
1060 int sleep_ms;
1061 COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], sleep_ms);
1062
1063 jtag_set_flush_queue_sleep(sleep_ms);
1064
1065 return ERROR_OK;
1066 }
1067
1068 COMMAND_HANDLER(handle_wait_srst_deassert)
1069 {
1070 if (CMD_ARGC != 1)
1071 return ERROR_COMMAND_SYNTAX_ERROR;
1072
1073 int timeout_ms;
1074 COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], timeout_ms);
1075 if ((timeout_ms <= 0) || (timeout_ms > 100000)) {
1076 LOG_ERROR("Timeout must be an integer between 0 and 100000");
1077 return ERROR_FAIL;
1078 }
1079
1080 LOG_USER("Waiting for srst assert + deassert for at most %dms", timeout_ms);
1081 int asserted_yet;
1082 int64_t then = timeval_ms();
1083 while (jtag_srst_asserted(&asserted_yet) == ERROR_OK) {
1084 if ((timeval_ms() - then) > timeout_ms) {
1085 LOG_ERROR("Timed out");
1086 return ERROR_FAIL;
1087 }
1088 if (asserted_yet)
1089 break;
1090 }
1091 while (jtag_srst_asserted(&asserted_yet) == ERROR_OK) {
1092 if ((timeval_ms() - then) > timeout_ms) {
1093 LOG_ERROR("Timed out");
1094 return ERROR_FAIL;
1095 }
1096 if (!asserted_yet)
1097 break;
1098 }
1099
1100 return ERROR_OK;
1101 }
1102
1103 static const struct command_registration jtag_command_handlers[] = {
1104
1105 {
1106 .name = "jtag_flush_queue_sleep",
1107 .handler = handle_jtag_flush_queue_sleep,
1108 .mode = COMMAND_ANY,
1109 .help = "For debug purposes(simulate long delays of interface) "
1110 "to test performance or change in behavior. Default 0ms.",
1111 .usage = "[sleep in ms]",
1112 },
1113 {
1114 .name = "jtag_rclk",
1115 .handler = handle_jtag_rclk_command,
1116 .mode = COMMAND_ANY,
1117 .help = "With an argument, change to to use adaptive clocking "
1118 "if possible; else to use the fallback speed. "
1119 "With or without argument, display current setting.",
1120 .usage = "[fallback_speed_khz]",
1121 },
1122 {
1123 .name = "jtag_ntrst_delay",
1124 .handler = handle_jtag_ntrst_delay_command,
1125 .mode = COMMAND_ANY,
1126 .help = "delay after deasserting trst in ms",
1127 .usage = "[milliseconds]",
1128 },
1129 {
1130 .name = "jtag_ntrst_assert_width",
1131 .handler = handle_jtag_ntrst_assert_width_command,
1132 .mode = COMMAND_ANY,
1133 .help = "delay after asserting trst in ms",
1134 .usage = "[milliseconds]",
1135 },
1136 {
1137 .name = "scan_chain",
1138 .handler = handle_scan_chain_command,
1139 .mode = COMMAND_ANY,
1140 .help = "print current scan chain configuration",
1141 .usage = ""
1142 },
1143 {
1144 .name = "runtest",
1145 .handler = handle_runtest_command,
1146 .mode = COMMAND_EXEC,
1147 .help = "Move to Run-Test/Idle, and issue TCK for num_cycles.",
1148 .usage = "num_cycles"
1149 },
1150 {
1151 .name = "irscan",
1152 .handler = handle_irscan_command,
1153 .mode = COMMAND_EXEC,
1154 .help = "Execute Instruction Register (IR) scan. The "
1155 "specified opcodes are put into each TAP's IR, "
1156 "and other TAPs are put in BYPASS.",
1157 .usage = "[tap_name instruction]* ['-endstate' state_name]",
1158 },
1159 {
1160 .name = "verify_ircapture",
1161 .handler = handle_verify_ircapture_command,
1162 .mode = COMMAND_ANY,
1163 .help = "Display or assign flag controlling whether to "
1164 "verify values captured during Capture-IR.",
1165 .usage = "['enable'|'disable']",
1166 },
1167 {
1168 .name = "verify_jtag",
1169 .handler = handle_verify_jtag_command,
1170 .mode = COMMAND_ANY,
1171 .help = "Display or assign flag controlling whether to "
1172 "verify values captured during IR and DR scans.",
1173 .usage = "['enable'|'disable']",
1174 },
1175 {
1176 .name = "tms_sequence",
1177 .handler = handle_tms_sequence_command,
1178 .mode = COMMAND_ANY,
1179 .help = "Display or change what style TMS sequences to use "
1180 "for JTAG state transitions: short (default) or "
1181 "long. Only for working around JTAG bugs.",
1182 /* Specifically for working around DRIVER bugs... */
1183 .usage = "['short'|'long']",
1184 },
1185 {
1186 .name = "wait_srst_deassert",
1187 .handler = handle_wait_srst_deassert,
1188 .mode = COMMAND_ANY,
1189 .help = "Wait for an SRST deassert. "
1190 "Useful for cases where you need something to happen within ms "
1191 "of an srst deassert. Timeout in ms",
1192 .usage = "ms",
1193 },
1194 {
1195 .name = "jtag",
1196 .mode = COMMAND_ANY,
1197 .help = "perform jtag tap actions",
1198 .usage = "",
1199
1200 .chain = jtag_subcommand_handlers,
1201 },
1202 {
1203 .chain = jtag_command_handlers_to_move,
1204 },
1205 COMMAND_REGISTRATION_DONE
1206 };
1207
1208 int jtag_register_commands(struct command_context *cmd_ctx)
1209 {
1210 return register_commands(cmd_ctx, NULL, jtag_command_handlers);
1211 }

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)