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

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)