1 // SPDX-License-Identifier: GPL-2.0-or-later
3 /***************************************************************************
4 * Copyright (C) 2005 by Dominic Rath *
5 * Dominic.Rath@gmx.de *
7 * Copyright (C) 2007-2010 Øyvind Harboe *
8 * oyvind.harboe@zylin.com *
10 * Copyright (C) 2009 SoftPLC Corporation *
11 * http://softplc.com *
14 * Copyright (C) 2009 Zachary T Welch *
15 * zw@superlucidity.net *
16 ***************************************************************************/
25 #include "minidriver.h"
26 #include "interface.h"
27 #include "interfaces.h"
34 #include <helper/time_support.h>
35 #include "transport/transport.h"
39 * Holds support for accessing JTAG-specific mechanisms from TCl scripts.
42 static const struct jim_nvp nvp_jtag_tap_event
[] = {
43 { .value
= JTAG_TRST_ASSERTED
, .name
= "post-reset" },
44 { .value
= JTAG_TAP_EVENT_SETUP
, .name
= "setup" },
45 { .value
= JTAG_TAP_EVENT_ENABLE
, .name
= "tap-enable" },
46 { .value
= JTAG_TAP_EVENT_DISABLE
, .name
= "tap-disable" },
48 { .name
= NULL
, .value
= -1 }
51 struct jtag_tap
*jtag_tap_by_jim_obj(Jim_Interp
*interp
, Jim_Obj
*o
)
53 const char *cp
= Jim_GetString(o
, NULL
);
54 struct jtag_tap
*t
= cp
? jtag_tap_by_string(cp
) : NULL
;
58 Jim_SetResultFormatted(interp
, "Tap '%s' could not be found", cp
);
62 static bool scan_is_safe(tap_state_t state
)
75 static int jim_command_drscan(Jim_Interp
*interp
, int argc
, Jim_Obj
* const *args
)
78 struct scan_field
*fields
;
87 * args[3] = hex string
88 * ... repeat num bits and hex string ...
91 * args[N-2] = "-endstate"
92 * args[N-1] = statename
94 if ((argc
< 4) || ((argc
% 2) != 0)) {
95 Jim_WrongNumArgs(interp
, 1, args
, "wrong arguments");
101 /* validate arguments as numbers */
103 for (i
= 2; i
< argc
; i
+= 2) {
107 e
= Jim_GetLong(interp
, args
[i
], &bits
);
108 /* If valid - try next arg */
112 /* Not valid.. are we at the end? */
113 if (((i
+ 2) != argc
)) {
114 /* nope, then error */
118 /* it could be: "-endstate FOO"
119 * e.g. DRPAUSE so we can issue more instructions
120 * before entering RUN/IDLE and executing them.
123 /* get arg as a string. */
124 cp
= Jim_GetString(args
[i
], NULL
);
125 /* is it the magic? */
126 if (strcmp("-endstate", cp
) == 0) {
127 /* is the statename valid? */
128 cp
= Jim_GetString(args
[i
+ 1], NULL
);
130 /* see if it is a valid state name */
131 endstate
= tap_state_by_name(cp
);
133 /* update the error message */
134 Jim_SetResultFormatted(interp
, "endstate: %s invalid", cp
);
136 if (!scan_is_safe(endstate
))
137 LOG_WARNING("drscan with unsafe "
138 "endstate \"%s\"", cp
);
140 /* valid - so clear the error */
142 /* and remove the last 2 args */
147 /* Still an error? */
149 return e
; /* too bad */
150 } /* validate args */
154 tap
= jtag_tap_by_jim_obj(interp
, args
[1]);
158 num_fields
= (argc
-2)/2;
159 if (num_fields
<= 0) {
160 Jim_SetResultString(interp
, "drscan: no scan fields supplied", -1);
163 fields
= malloc(sizeof(struct scan_field
) * num_fields
);
164 for (i
= 2; i
< argc
; i
+= 2) {
169 Jim_GetLong(interp
, args
[i
], &bits
);
170 str
= Jim_GetString(args
[i
+ 1], &len
);
172 fields
[field_count
].num_bits
= bits
;
173 void *t
= malloc(DIV_ROUND_UP(bits
, 8));
174 fields
[field_count
].out_value
= t
;
175 str_to_buf(str
, len
, t
, bits
, 0);
176 fields
[field_count
].in_value
= t
;
180 jtag_add_dr_scan(tap
, num_fields
, fields
, endstate
);
182 retval
= jtag_execute_queue();
183 if (retval
!= ERROR_OK
) {
184 Jim_SetResultString(interp
, "drscan: jtag execute failed", -1);
186 for (i
= 0; i
< field_count
; i
++)
187 free(fields
[i
].in_value
);
194 Jim_Obj
*list
= Jim_NewListObj(interp
, NULL
, 0);
195 for (i
= 2; i
< argc
; i
+= 2) {
199 Jim_GetLong(interp
, args
[i
], &bits
);
200 str
= buf_to_hex_str(fields
[field_count
].in_value
, bits
);
201 free(fields
[field_count
].in_value
);
203 Jim_ListAppendElement(interp
, list
, Jim_NewStringObj(interp
, str
, strlen(str
)));
208 Jim_SetResult(interp
, list
);
216 static int jim_command_pathmove(Jim_Interp
*interp
, int argc
, Jim_Obj
* const *args
)
218 tap_state_t states
[8];
220 if ((argc
< 2) || ((size_t)argc
> (ARRAY_SIZE(states
) + 1))) {
221 Jim_WrongNumArgs(interp
, 1, args
, "wrong arguments");
226 for (i
= 0; i
< argc
-1; i
++) {
228 cp
= Jim_GetString(args
[i
+ 1], NULL
);
229 states
[i
] = tap_state_by_name(cp
);
231 /* update the error message */
232 Jim_SetResultFormatted(interp
, "endstate: %s invalid", cp
);
237 if ((jtag_add_statemove(states
[0]) != ERROR_OK
) || (jtag_execute_queue() != ERROR_OK
)) {
238 Jim_SetResultString(interp
, "pathmove: jtag execute failed", -1);
242 jtag_add_pathmove(argc
- 2, states
+ 1);
244 if (jtag_execute_queue() != ERROR_OK
) {
245 Jim_SetResultString(interp
, "pathmove: failed", -1);
253 static int jim_command_flush_count(Jim_Interp
*interp
, int argc
, Jim_Obj
* const *args
)
255 Jim_SetResult(interp
, Jim_NewIntObj(interp
, jtag_get_flush_queue_count()));
260 /* REVISIT Just what about these should "move" ... ?
261 * These registrations, into the main JTAG table?
263 * There's a minor compatibility issue, these all show up twice;
264 * that's not desirable:
265 * - jtag drscan ... NOT DOCUMENTED!
268 * The "irscan" command (for example) doesn't show twice.
270 static const struct command_registration jtag_command_handlers_to_move
[] = {
273 .mode
= COMMAND_EXEC
,
274 .jim_handler
= jim_command_drscan
,
275 .help
= "Execute Data Register (DR) scan for one TAP. "
276 "Other TAPs must be in BYPASS mode.",
277 .usage
= "tap_name [num_bits value]* ['-endstate' state_name]",
280 .name
= "flush_count",
281 .mode
= COMMAND_EXEC
,
282 .jim_handler
= jim_command_flush_count
,
283 .help
= "Returns the number of times the JTAG queue "
288 .mode
= COMMAND_EXEC
,
289 .jim_handler
= jim_command_pathmove
,
290 .usage
= "start_state state1 [state2 [state3 ...]]",
291 .help
= "Move JTAG state machine from current state "
292 "(start_state) to state1, then state2, state3, etc.",
294 COMMAND_REGISTRATION_DONE
298 enum jtag_tap_cfg_param
{
303 static struct jim_nvp nvp_config_opts
[] = {
304 { .name
= "-event", .value
= JCFG_EVENT
},
305 { .name
= "-idcode", .value
= JCFG_IDCODE
},
307 { .name
= NULL
, .value
= -1 }
310 static int jtag_tap_configure_event(struct jim_getopt_info
*goi
, struct jtag_tap
*tap
)
312 if (goi
->argc
== 0) {
313 Jim_WrongNumArgs(goi
->interp
, goi
->argc
, goi
->argv
, "-event <event-name> ...");
318 int e
= jim_getopt_nvp(goi
, nvp_jtag_tap_event
, &n
);
320 jim_getopt_nvp_unknown(goi
, nvp_jtag_tap_event
, 1);
324 if (goi
->isconfigure
) {
325 if (goi
->argc
!= 1) {
326 Jim_WrongNumArgs(goi
->interp
,
329 "-event <event-name> <event-body>");
333 if (goi
->argc
!= 0) {
334 Jim_WrongNumArgs(goi
->interp
, goi
->argc
, goi
->argv
, "-event <event-name>");
339 struct jtag_tap_event_action
*jteap
= tap
->event_action
;
340 /* replace existing event body */
343 if (jteap
->event
== (enum jtag_event
)n
->value
) {
350 Jim_SetEmptyResult(goi
->interp
);
352 if (goi
->isconfigure
) {
354 jteap
= calloc(1, sizeof(*jteap
));
355 else if (jteap
->body
)
356 Jim_DecrRefCount(goi
->interp
, jteap
->body
);
358 jteap
->interp
= goi
->interp
;
359 jteap
->event
= n
->value
;
362 jim_getopt_obj(goi
, &o
);
363 jteap
->body
= Jim_DuplicateObj(goi
->interp
, o
);
364 Jim_IncrRefCount(jteap
->body
);
367 /* add to head of event list */
368 jteap
->next
= tap
->event_action
;
369 tap
->event_action
= jteap
;
372 jteap
->interp
= goi
->interp
;
373 Jim_SetResult(goi
->interp
,
374 Jim_DuplicateObj(goi
->interp
, jteap
->body
));
379 static int jtag_tap_configure_cmd(struct jim_getopt_info
*goi
, struct jtag_tap
*tap
)
381 /* parse config or cget options */
382 while (goi
->argc
> 0) {
383 Jim_SetEmptyResult(goi
->interp
);
386 int e
= jim_getopt_nvp(goi
, nvp_config_opts
, &n
);
388 jim_getopt_nvp_unknown(goi
, nvp_config_opts
, 0);
394 e
= jtag_tap_configure_event(goi
, tap
);
399 if (goi
->isconfigure
) {
400 Jim_SetResultFormatted(goi
->interp
,
401 "not settable: %s", n
->name
);
404 if (goi
->argc
!= 0) {
405 Jim_WrongNumArgs(goi
->interp
,
406 goi
->argc
, goi
->argv
,
411 Jim_SetResult(goi
->interp
, Jim_NewIntObj(goi
->interp
, tap
->idcode
));
414 Jim_SetResultFormatted(goi
->interp
, "unknown value: %s", n
->name
);
422 static int is_bad_irval(int ir_length
, jim_wide w
)
432 static int jim_newtap_expected_id(struct jim_nvp
*n
, struct jim_getopt_info
*goi
,
433 struct jtag_tap
*tap
)
436 int e
= jim_getopt_wide(goi
, &w
);
438 Jim_SetResultFormatted(goi
->interp
, "option: %s bad parameter", n
->name
);
442 uint32_t *p
= realloc(tap
->expected_ids
,
443 (tap
->expected_ids_cnt
+ 1) * sizeof(uint32_t));
445 Jim_SetResultFormatted(goi
->interp
, "no memory");
449 tap
->expected_ids
= p
;
450 tap
->expected_ids
[tap
->expected_ids_cnt
++] = w
;
455 #define NTAP_OPT_IRLEN 0
456 #define NTAP_OPT_IRMASK 1
457 #define NTAP_OPT_IRCAPTURE 2
458 #define NTAP_OPT_ENABLED 3
459 #define NTAP_OPT_DISABLED 4
460 #define NTAP_OPT_EXPECTED_ID 5
461 #define NTAP_OPT_VERSION 6
462 #define NTAP_OPT_BYPASS 7
464 static int jim_newtap_ir_param(struct jim_nvp
*n
, struct jim_getopt_info
*goi
,
465 struct jtag_tap
*tap
)
468 int e
= jim_getopt_wide(goi
, &w
);
470 Jim_SetResultFormatted(goi
->interp
,
471 "option: %s bad parameter", n
->name
);
476 if (w
> (jim_wide
) (8 * sizeof(tap
->ir_capture_value
))) {
477 LOG_WARNING("%s: huge IR length %d",
478 tap
->dotted_name
, (int) w
);
482 case NTAP_OPT_IRMASK
:
483 if (is_bad_irval(tap
->ir_length
, w
)) {
484 LOG_ERROR("%s: IR mask %x too big",
490 LOG_WARNING("%s: nonstandard IR mask", tap
->dotted_name
);
491 tap
->ir_capture_mask
= w
;
493 case NTAP_OPT_IRCAPTURE
:
494 if (is_bad_irval(tap
->ir_length
, w
)) {
495 LOG_ERROR("%s: IR capture %x too big",
496 tap
->dotted_name
, (int) w
);
500 LOG_WARNING("%s: nonstandard IR value",
502 tap
->ir_capture_value
= w
;
510 static int jim_newtap_cmd(struct jim_getopt_info
*goi
)
512 struct jtag_tap
*tap
;
517 const struct jim_nvp opts
[] = {
518 { .name
= "-irlen", .value
= NTAP_OPT_IRLEN
},
519 { .name
= "-irmask", .value
= NTAP_OPT_IRMASK
},
520 { .name
= "-ircapture", .value
= NTAP_OPT_IRCAPTURE
},
521 { .name
= "-enable", .value
= NTAP_OPT_ENABLED
},
522 { .name
= "-disable", .value
= NTAP_OPT_DISABLED
},
523 { .name
= "-expected-id", .value
= NTAP_OPT_EXPECTED_ID
},
524 { .name
= "-ignore-version", .value
= NTAP_OPT_VERSION
},
525 { .name
= "-ignore-bypass", .value
= NTAP_OPT_BYPASS
},
526 { .name
= NULL
, .value
= -1 },
529 tap
= calloc(1, sizeof(struct jtag_tap
));
531 Jim_SetResultFormatted(goi
->interp
, "no memory");
536 * we expect CHIP + TAP + OPTIONS
539 Jim_SetResultFormatted(goi
->interp
, "Missing CHIP TAP OPTIONS ....");
545 jim_getopt_string(goi
, &tmp
, NULL
);
546 tap
->chip
= strdup(tmp
);
548 jim_getopt_string(goi
, &tmp
, NULL
);
549 tap
->tapname
= strdup(tmp
);
551 /* name + dot + name + null */
552 x
= strlen(tap
->chip
) + 1 + strlen(tap
->tapname
) + 1;
554 sprintf(cp
, "%s.%s", tap
->chip
, tap
->tapname
);
555 tap
->dotted_name
= cp
;
557 LOG_DEBUG("Creating New Tap, Chip: %s, Tap: %s, Dotted: %s, %d params",
558 tap
->chip
, tap
->tapname
, tap
->dotted_name
, goi
->argc
);
560 if (!transport_is_jtag()) {
561 /* SWD doesn't require any JTAG tap parameters */
567 /* IEEE specifies that the two LSBs of an IR scan are 01, so make
568 * that the default. The "-ircapture" and "-irmask" options are only
569 * needed to cope with nonstandard TAPs, or to specify more bits.
571 tap
->ir_capture_mask
= 0x03;
572 tap
->ir_capture_value
= 0x01;
575 e
= jim_getopt_nvp(goi
, opts
, &n
);
577 jim_getopt_nvp_unknown(goi
, opts
, 0);
582 LOG_DEBUG("Processing option: %s", n
->name
);
584 case NTAP_OPT_ENABLED
:
585 tap
->disabled_after_reset
= false;
587 case NTAP_OPT_DISABLED
:
588 tap
->disabled_after_reset
= true;
590 case NTAP_OPT_EXPECTED_ID
:
591 e
= jim_newtap_expected_id(n
, goi
, tap
);
599 case NTAP_OPT_IRMASK
:
600 case NTAP_OPT_IRCAPTURE
:
601 e
= jim_newtap_ir_param(n
, goi
, tap
);
608 case NTAP_OPT_VERSION
:
609 tap
->ignore_version
= true;
611 case NTAP_OPT_BYPASS
:
612 tap
->ignore_bypass
= true;
614 } /* switch (n->value) */
615 } /* while (goi->argc) */
617 /* default is enabled-after-reset */
618 tap
->enabled
= !tap
->disabled_after_reset
;
620 /* Did all the required option bits get cleared? */
621 if (tap
->ir_length
!= 0) {
626 Jim_SetResultFormatted(goi
->interp
,
627 "newtap: %s missing IR length",
633 static void jtag_tap_handle_event(struct jtag_tap
*tap
, enum jtag_event e
)
635 struct jtag_tap_event_action
*jteap
;
638 for (jteap
= tap
->event_action
; jteap
; jteap
= jteap
->next
) {
639 if (jteap
->event
!= e
)
642 struct jim_nvp
*nvp
= jim_nvp_value2name_simple(nvp_jtag_tap_event
, e
);
643 LOG_DEBUG("JTAG tap: %s event: %d (%s)\n\taction: %s",
644 tap
->dotted_name
, e
, nvp
->name
,
645 Jim_GetString(jteap
->body
, NULL
));
647 retval
= Jim_EvalObj(jteap
->interp
, jteap
->body
);
648 if (retval
== JIM_RETURN
)
649 retval
= jteap
->interp
->returnCode
;
651 if (retval
!= JIM_OK
) {
652 Jim_MakeErrorMessage(jteap
->interp
);
653 LOG_USER("%s", Jim_GetString(Jim_GetResult(jteap
->interp
), NULL
));
658 case JTAG_TAP_EVENT_ENABLE
:
659 case JTAG_TAP_EVENT_DISABLE
:
660 /* NOTE: we currently assume the handlers
661 * can't fail. Right here is where we should
662 * really be verifying the scan chains ...
664 tap
->enabled
= (e
== JTAG_TAP_EVENT_ENABLE
);
665 LOG_INFO("JTAG tap: %s %s", tap
->dotted_name
,
666 tap
->enabled
? "enabled" : "disabled");
674 static int jim_jtag_arp_init(Jim_Interp
*interp
, int argc
, Jim_Obj
*const *argv
)
676 struct jim_getopt_info goi
;
677 jim_getopt_setup(&goi
, interp
, argc
-1, argv
+ 1);
679 Jim_WrongNumArgs(goi
.interp
, 1, goi
.argv
-1, "(no params)");
682 struct command_context
*context
= current_command_context(interp
);
683 int e
= jtag_init_inner(context
);
685 Jim_Obj
*obj
= Jim_NewIntObj(goi
.interp
, e
);
686 Jim_SetResultFormatted(goi
.interp
, "error: %#s", obj
);
692 static int jim_jtag_arp_init_reset(Jim_Interp
*interp
, int argc
, Jim_Obj
*const *argv
)
695 struct jim_getopt_info goi
;
696 jim_getopt_setup(&goi
, interp
, argc
-1, argv
+ 1);
698 Jim_WrongNumArgs(goi
.interp
, 1, goi
.argv
-1, "(no params)");
701 struct command_context
*context
= current_command_context(interp
);
702 if (transport_is_jtag())
703 e
= jtag_init_reset(context
);
704 else if (transport_is_swd())
705 e
= swd_init_reset(context
);
708 Jim_Obj
*obj
= Jim_NewIntObj(goi
.interp
, e
);
709 Jim_SetResultFormatted(goi
.interp
, "error: %#s", obj
);
715 int jim_jtag_newtap(Jim_Interp
*interp
, int argc
, Jim_Obj
*const *argv
)
717 struct jim_getopt_info goi
;
718 jim_getopt_setup(&goi
, interp
, argc
-1, argv
+ 1);
719 return jim_newtap_cmd(&goi
);
722 static bool jtag_tap_enable(struct jtag_tap
*t
)
726 jtag_tap_handle_event(t
, JTAG_TAP_EVENT_ENABLE
);
730 /* FIXME add JTAG sanity checks, w/o TLR
731 * - scan chain length grew by one (this)
732 * - IDs and IR lengths are as expected
734 jtag_call_event_callbacks(JTAG_TAP_EVENT_ENABLE
);
737 static bool jtag_tap_disable(struct jtag_tap
*t
)
741 jtag_tap_handle_event(t
, JTAG_TAP_EVENT_DISABLE
);
745 /* FIXME add JTAG sanity checks, w/o TLR
746 * - scan chain length shrank by one (this)
747 * - IDs and IR lengths are as expected
749 jtag_call_event_callbacks(JTAG_TAP_EVENT_DISABLE
);
753 int jim_jtag_tap_enabler(Jim_Interp
*interp
, int argc
, Jim_Obj
*const *argv
)
755 struct command
*c
= jim_to_command(interp
);
756 const char *cmd_name
= c
->name
;
757 struct jim_getopt_info goi
;
758 jim_getopt_setup(&goi
, interp
, argc
-1, argv
+ 1);
760 Jim_SetResultFormatted(goi
.interp
, "usage: %s <name>", cmd_name
);
766 t
= jtag_tap_by_jim_obj(goi
.interp
, goi
.argv
[0]);
770 if (strcasecmp(cmd_name
, "tapisenabled") == 0) {
771 /* do nothing, just return the value */
772 } else if (strcasecmp(cmd_name
, "tapenable") == 0) {
773 if (!jtag_tap_enable(t
)) {
774 LOG_WARNING("failed to enable tap %s", t
->dotted_name
);
777 } else if (strcasecmp(cmd_name
, "tapdisable") == 0) {
778 if (!jtag_tap_disable(t
)) {
779 LOG_WARNING("failed to disable tap %s", t
->dotted_name
);
783 LOG_ERROR("command '%s' unknown", cmd_name
);
787 Jim_SetResult(goi
.interp
, Jim_NewIntObj(goi
.interp
, e
));
791 int jim_jtag_configure(Jim_Interp
*interp
, int argc
, Jim_Obj
*const *argv
)
793 struct command
*c
= jim_to_command(interp
);
794 const char *cmd_name
= c
->name
;
795 struct jim_getopt_info goi
;
796 jim_getopt_setup(&goi
, interp
, argc
-1, argv
+ 1);
797 goi
.isconfigure
= !strcmp(cmd_name
, "configure");
798 if (goi
.argc
< 2 + goi
.isconfigure
) {
799 Jim_WrongNumArgs(goi
.interp
, 0, NULL
,
800 "<tap_name> <attribute> ...");
807 jim_getopt_obj(&goi
, &o
);
808 t
= jtag_tap_by_jim_obj(goi
.interp
, o
);
812 return jtag_tap_configure_cmd(&goi
, t
);
815 static int jim_jtag_names(Jim_Interp
*interp
, int argc
, Jim_Obj
*const *argv
)
817 struct jim_getopt_info goi
;
818 jim_getopt_setup(&goi
, interp
, argc
-1, argv
+ 1);
820 Jim_WrongNumArgs(goi
.interp
, 1, goi
.argv
, "Too many parameters");
823 Jim_SetResult(goi
.interp
, Jim_NewListObj(goi
.interp
, NULL
, 0));
824 struct jtag_tap
*tap
;
826 for (tap
= jtag_all_taps(); tap
; tap
= tap
->next_tap
) {
827 Jim_ListAppendElement(goi
.interp
,
828 Jim_GetResult(goi
.interp
),
829 Jim_NewStringObj(goi
.interp
,
830 tap
->dotted_name
, -1));
835 COMMAND_HANDLER(handle_jtag_init_command
)
838 return ERROR_COMMAND_SYNTAX_ERROR
;
840 static bool jtag_initialized
;
841 if (jtag_initialized
) {
842 LOG_INFO("'jtag init' has already been called");
845 jtag_initialized
= true;
847 LOG_DEBUG("Initializing jtag devices...");
848 return jtag_init(CMD_CTX
);
851 static const struct command_registration jtag_subcommand_handlers
[] = {
855 .handler
= handle_jtag_init_command
,
856 .help
= "initialize jtag scan chain",
862 .jim_handler
= jim_jtag_arp_init
,
863 .help
= "Validates JTAG scan chain against the list of "
864 "declared TAPs using just the four standard JTAG "
868 .name
= "arp_init-reset",
870 .jim_handler
= jim_jtag_arp_init_reset
,
871 .help
= "Uses TRST and SRST to try resetting everything on "
872 "the JTAG scan chain, then performs 'jtag arp_init'."
876 .mode
= COMMAND_CONFIG
,
877 .jim_handler
= jim_jtag_newtap
,
878 .help
= "Create a new TAP instance named basename.tap_type, "
879 "and appends it to the scan chain.",
880 .usage
= "basename tap_type '-irlen' count "
881 "['-enable'|'-disable'] "
882 "['-expected_id' number] "
883 "['-ignore-version'] "
884 "['-ignore-bypass'] "
885 "['-ircapture' number] "
889 .name
= "tapisenabled",
890 .mode
= COMMAND_EXEC
,
891 .jim_handler
= jim_jtag_tap_enabler
,
892 .help
= "Returns a Tcl boolean (0/1) indicating whether "
893 "the TAP is enabled (1) or not (0).",
898 .mode
= COMMAND_EXEC
,
899 .jim_handler
= jim_jtag_tap_enabler
,
900 .help
= "Try to enable the specified TAP using the "
901 "'tap-enable' TAP event.",
905 .name
= "tapdisable",
906 .mode
= COMMAND_EXEC
,
907 .jim_handler
= jim_jtag_tap_enabler
,
908 .help
= "Try to disable the specified TAP using the "
909 "'tap-disable' TAP event.",
915 .jim_handler
= jim_jtag_configure
,
916 .help
= "Provide a Tcl handler for the specified "
918 .usage
= "tap_name '-event' event_name handler",
922 .mode
= COMMAND_EXEC
,
923 .jim_handler
= jim_jtag_configure
,
924 .help
= "Return any Tcl handler for the specified "
926 .usage
= "tap_name '-event' event_name",
931 .jim_handler
= jim_jtag_names
,
932 .help
= "Returns list of all JTAG tap names.",
935 .chain
= jtag_command_handlers_to_move
,
937 COMMAND_REGISTRATION_DONE
940 void jtag_notify_event(enum jtag_event event
)
942 struct jtag_tap
*tap
;
944 for (tap
= jtag_all_taps(); tap
; tap
= tap
->next_tap
)
945 jtag_tap_handle_event(tap
, event
);
949 COMMAND_HANDLER(handle_scan_chain_command
)
951 struct jtag_tap
*tap
;
952 char expected_id
[12];
954 tap
= jtag_all_taps();
956 " TapName Enabled IdCode Expected IrLen IrCap IrMask");
958 "-- ------------------- -------- ---------- ---------- ----- ----- ------");
961 uint32_t expected
, expected_mask
, ii
;
963 snprintf(expected_id
, sizeof(expected_id
), "0x%08x",
964 (unsigned)((tap
->expected_ids_cnt
> 0)
965 ? tap
->expected_ids
[0]
967 if (tap
->ignore_version
)
968 expected_id
[2] = '*';
970 expected
= buf_get_u32(tap
->expected
, 0, tap
->ir_length
);
971 expected_mask
= buf_get_u32(tap
->expected_mask
, 0, tap
->ir_length
);
974 "%2d %-18s %c 0x%08x %s %5d 0x%02x 0x%02x",
975 tap
->abs_chain_position
,
977 tap
->enabled
? 'Y' : 'n',
978 (unsigned int)(tap
->idcode
),
980 (unsigned int)(tap
->ir_length
),
981 (unsigned int)(expected
),
982 (unsigned int)(expected_mask
));
984 for (ii
= 1; ii
< tap
->expected_ids_cnt
; ii
++) {
985 snprintf(expected_id
, sizeof(expected_id
), "0x%08x",
986 (unsigned) tap
->expected_ids
[ii
]);
987 if (tap
->ignore_version
)
988 expected_id
[2] = '*';
1001 COMMAND_HANDLER(handle_jtag_ntrst_delay_command
)
1004 return ERROR_COMMAND_SYNTAX_ERROR
;
1005 if (CMD_ARGC
== 1) {
1007 COMMAND_PARSE_NUMBER(uint
, CMD_ARGV
[0], delay
);
1009 jtag_set_ntrst_delay(delay
);
1011 command_print(CMD
, "jtag_ntrst_delay: %u", jtag_get_ntrst_delay());
1015 COMMAND_HANDLER(handle_jtag_ntrst_assert_width_command
)
1018 return ERROR_COMMAND_SYNTAX_ERROR
;
1019 if (CMD_ARGC
== 1) {
1021 COMMAND_PARSE_NUMBER(uint
, CMD_ARGV
[0], delay
);
1023 jtag_set_ntrst_assert_width(delay
);
1025 command_print(CMD
, "jtag_ntrst_assert_width: %u", jtag_get_ntrst_assert_width());
1029 COMMAND_HANDLER(handle_jtag_rclk_command
)
1032 return ERROR_COMMAND_SYNTAX_ERROR
;
1034 int retval
= ERROR_OK
;
1035 if (CMD_ARGC
== 1) {
1037 COMMAND_PARSE_NUMBER(uint
, CMD_ARGV
[0], khz
);
1039 retval
= adapter_config_rclk(khz
);
1040 if (retval
!= ERROR_OK
)
1044 int cur_khz
= adapter_get_speed_khz();
1045 retval
= adapter_get_speed_readable(&cur_khz
);
1046 if (retval
!= ERROR_OK
)
1050 command_print(CMD
, "RCLK not supported - fallback to %d kHz", cur_khz
);
1052 command_print(CMD
, "RCLK - adaptive");
1057 COMMAND_HANDLER(handle_runtest_command
)
1060 return ERROR_COMMAND_SYNTAX_ERROR
;
1062 unsigned num_clocks
;
1063 COMMAND_PARSE_NUMBER(uint
, CMD_ARGV
[0], num_clocks
);
1065 jtag_add_runtest(num_clocks
, TAP_IDLE
);
1066 return jtag_execute_queue();
1070 * For "irscan" or "drscan" commands, the "end" (really, "next") state
1071 * should be stable ... and *NOT* a shift state, otherwise free-running
1072 * jtag clocks could change the values latched by the update state.
1073 * Not surprisingly, this is the same constraint as SVF; the "irscan"
1074 * and "drscan" commands are a write-only subset of what SVF provides.
1077 COMMAND_HANDLER(handle_irscan_command
)
1080 struct scan_field
*fields
;
1081 struct jtag_tap
*tap
= NULL
;
1082 tap_state_t endstate
;
1084 if ((CMD_ARGC
< 2) || (CMD_ARGC
% 2))
1085 return ERROR_COMMAND_SYNTAX_ERROR
;
1087 /* optional "-endstate" "statename" at the end of the arguments,
1088 * so that e.g. IRPAUSE can let us load the data register before
1089 * entering RUN/IDLE to execute the instruction we load here.
1091 endstate
= TAP_IDLE
;
1093 if (CMD_ARGC
>= 4) {
1094 /* have at least one pair of numbers.
1095 * is last pair the magic text? */
1096 if (strcmp("-endstate", CMD_ARGV
[CMD_ARGC
- 2]) == 0) {
1097 endstate
= tap_state_by_name(CMD_ARGV
[CMD_ARGC
- 1]);
1098 if (endstate
== TAP_INVALID
)
1099 return ERROR_COMMAND_SYNTAX_ERROR
;
1100 if (!scan_is_safe(endstate
))
1101 LOG_WARNING("unstable irscan endstate \"%s\"",
1102 CMD_ARGV
[CMD_ARGC
- 1]);
1107 int num_fields
= CMD_ARGC
/ 2;
1108 if (num_fields
> 1) {
1109 /* we really should be looking at plain_ir_scan if we want
1110 * anything more fancy.
1112 LOG_ERROR("Specify a single value for tap");
1113 return ERROR_COMMAND_SYNTAX_ERROR
;
1116 fields
= calloc(num_fields
, sizeof(*fields
));
1119 for (i
= 0; i
< num_fields
; i
++) {
1120 tap
= jtag_tap_by_string(CMD_ARGV
[i
*2]);
1123 command_print(CMD
, "Tap: %s unknown", CMD_ARGV
[i
*2]);
1128 retval
= parse_u64(CMD_ARGV
[i
* 2 + 1], &value
);
1129 if (retval
!= ERROR_OK
)
1132 int field_size
= tap
->ir_length
;
1133 fields
[i
].num_bits
= field_size
;
1134 uint8_t *v
= calloc(1, DIV_ROUND_UP(field_size
, 8));
1136 LOG_ERROR("Out of memory");
1140 buf_set_u64(v
, 0, field_size
, value
);
1141 fields
[i
].out_value
= v
;
1142 fields
[i
].in_value
= NULL
;
1145 /* did we have an endstate? */
1146 jtag_add_ir_scan(tap
, fields
, endstate
);
1148 retval
= jtag_execute_queue();
1151 for (i
= 0; i
< num_fields
; i
++)
1152 free((void *)fields
[i
].out_value
);
1159 COMMAND_HANDLER(handle_verify_ircapture_command
)
1162 return ERROR_COMMAND_SYNTAX_ERROR
;
1164 if (CMD_ARGC
== 1) {
1166 COMMAND_PARSE_ENABLE(CMD_ARGV
[0], enable
);
1167 jtag_set_verify_capture_ir(enable
);
1170 const char *status
= jtag_will_verify_capture_ir() ? "enabled" : "disabled";
1171 command_print(CMD
, "verify Capture-IR is %s", status
);
1176 COMMAND_HANDLER(handle_verify_jtag_command
)
1179 return ERROR_COMMAND_SYNTAX_ERROR
;
1181 if (CMD_ARGC
== 1) {
1183 COMMAND_PARSE_ENABLE(CMD_ARGV
[0], enable
);
1184 jtag_set_verify(enable
);
1187 const char *status
= jtag_will_verify() ? "enabled" : "disabled";
1188 command_print(CMD
, "verify jtag capture is %s", status
);
1193 COMMAND_HANDLER(handle_tms_sequence_command
)
1196 return ERROR_COMMAND_SYNTAX_ERROR
;
1198 if (CMD_ARGC
== 1) {
1200 if (strcmp(CMD_ARGV
[0], "short") == 0)
1201 use_new_table
= true;
1202 else if (strcmp(CMD_ARGV
[0], "long") == 0)
1203 use_new_table
= false;
1205 return ERROR_COMMAND_SYNTAX_ERROR
;
1207 tap_use_new_tms_table(use_new_table
);
1210 command_print(CMD
, "tms sequence is %s",
1211 tap_uses_new_tms_table() ? "short" : "long");
1216 COMMAND_HANDLER(handle_jtag_flush_queue_sleep
)
1219 return ERROR_COMMAND_SYNTAX_ERROR
;
1222 COMMAND_PARSE_NUMBER(int, CMD_ARGV
[0], sleep_ms
);
1224 jtag_set_flush_queue_sleep(sleep_ms
);
1229 COMMAND_HANDLER(handle_wait_srst_deassert
)
1232 return ERROR_COMMAND_SYNTAX_ERROR
;
1235 COMMAND_PARSE_NUMBER(int, CMD_ARGV
[0], timeout_ms
);
1236 if ((timeout_ms
<= 0) || (timeout_ms
> 100000)) {
1237 LOG_ERROR("Timeout must be an integer between 0 and 100000");
1241 LOG_USER("Waiting for srst assert + deassert for at most %dms", timeout_ms
);
1243 int64_t then
= timeval_ms();
1244 while (jtag_srst_asserted(&asserted_yet
) == ERROR_OK
) {
1245 if ((timeval_ms() - then
) > timeout_ms
) {
1246 LOG_ERROR("Timed out");
1252 while (jtag_srst_asserted(&asserted_yet
) == ERROR_OK
) {
1253 if ((timeval_ms() - then
) > timeout_ms
) {
1254 LOG_ERROR("Timed out");
1264 static const struct command_registration jtag_command_handlers
[] = {
1267 .name
= "jtag_flush_queue_sleep",
1268 .handler
= handle_jtag_flush_queue_sleep
,
1269 .mode
= COMMAND_ANY
,
1270 .help
= "For debug purposes(simulate long delays of interface) "
1271 "to test performance or change in behavior. Default 0ms.",
1272 .usage
= "[sleep in ms]",
1275 .name
= "jtag_rclk",
1276 .handler
= handle_jtag_rclk_command
,
1277 .mode
= COMMAND_ANY
,
1278 .help
= "With an argument, change to to use adaptive clocking "
1279 "if possible; else to use the fallback speed. "
1280 "With or without argument, display current setting.",
1281 .usage
= "[fallback_speed_khz]",
1284 .name
= "jtag_ntrst_delay",
1285 .handler
= handle_jtag_ntrst_delay_command
,
1286 .mode
= COMMAND_ANY
,
1287 .help
= "delay after deasserting trst in ms",
1288 .usage
= "[milliseconds]",
1291 .name
= "jtag_ntrst_assert_width",
1292 .handler
= handle_jtag_ntrst_assert_width_command
,
1293 .mode
= COMMAND_ANY
,
1294 .help
= "delay after asserting trst in ms",
1295 .usage
= "[milliseconds]",
1298 .name
= "scan_chain",
1299 .handler
= handle_scan_chain_command
,
1300 .mode
= COMMAND_ANY
,
1301 .help
= "print current scan chain configuration",
1306 .handler
= handle_runtest_command
,
1307 .mode
= COMMAND_EXEC
,
1308 .help
= "Move to Run-Test/Idle, and issue TCK for num_cycles.",
1309 .usage
= "num_cycles"
1313 .handler
= handle_irscan_command
,
1314 .mode
= COMMAND_EXEC
,
1315 .help
= "Execute Instruction Register (IR) scan. The "
1316 "specified opcodes are put into each TAP's IR, "
1317 "and other TAPs are put in BYPASS.",
1318 .usage
= "[tap_name instruction]* ['-endstate' state_name]",
1321 .name
= "verify_ircapture",
1322 .handler
= handle_verify_ircapture_command
,
1323 .mode
= COMMAND_ANY
,
1324 .help
= "Display or assign flag controlling whether to "
1325 "verify values captured during Capture-IR.",
1326 .usage
= "['enable'|'disable']",
1329 .name
= "verify_jtag",
1330 .handler
= handle_verify_jtag_command
,
1331 .mode
= COMMAND_ANY
,
1332 .help
= "Display or assign flag controlling whether to "
1333 "verify values captured during IR and DR scans.",
1334 .usage
= "['enable'|'disable']",
1337 .name
= "tms_sequence",
1338 .handler
= handle_tms_sequence_command
,
1339 .mode
= COMMAND_ANY
,
1340 .help
= "Display or change what style TMS sequences to use "
1341 "for JTAG state transitions: short (default) or "
1342 "long. Only for working around JTAG bugs.",
1343 /* Specifically for working around DRIVER bugs... */
1344 .usage
= "['short'|'long']",
1347 .name
= "wait_srst_deassert",
1348 .handler
= handle_wait_srst_deassert
,
1349 .mode
= COMMAND_ANY
,
1350 .help
= "Wait for an SRST deassert. "
1351 "Useful for cases where you need something to happen within ms "
1352 "of an srst deassert. Timeout in ms",
1357 .mode
= COMMAND_ANY
,
1358 .help
= "perform jtag tap actions",
1361 .chain
= jtag_subcommand_handlers
,
1364 .chain
= jtag_command_handlers_to_move
,
1366 COMMAND_REGISTRATION_DONE
1369 int jtag_register_commands(struct command_context
*cmd_ctx
)
1371 return register_commands(cmd_ctx
, NULL
, jtag_command_handlers
);
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)