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);
252 COMMAND_HANDLER(handle_jtag_flush_count
)
255 return ERROR_COMMAND_SYNTAX_ERROR
;
257 int count
= jtag_get_flush_queue_count();
258 command_print_sameline(CMD
, "%d", count
);
263 /* REVISIT Just what about these should "move" ... ?
264 * These registrations, into the main JTAG table?
266 * There's a minor compatibility issue, these all show up twice;
267 * that's not desirable:
268 * - jtag drscan ... NOT DOCUMENTED!
271 * The "irscan" command (for example) doesn't show twice.
273 static const struct command_registration jtag_command_handlers_to_move
[] = {
276 .mode
= COMMAND_EXEC
,
277 .jim_handler
= jim_command_drscan
,
278 .help
= "Execute Data Register (DR) scan for one TAP. "
279 "Other TAPs must be in BYPASS mode.",
280 .usage
= "tap_name [num_bits value]* ['-endstate' state_name]",
283 .name
= "flush_count",
284 .mode
= COMMAND_EXEC
,
285 .handler
= handle_jtag_flush_count
,
286 .help
= "Returns the number of times the JTAG queue "
292 .mode
= COMMAND_EXEC
,
293 .jim_handler
= jim_command_pathmove
,
294 .usage
= "start_state state1 [state2 [state3 ...]]",
295 .help
= "Move JTAG state machine from current state "
296 "(start_state) to state1, then state2, state3, etc.",
298 COMMAND_REGISTRATION_DONE
302 enum jtag_tap_cfg_param
{
307 static struct jim_nvp nvp_config_opts
[] = {
308 { .name
= "-event", .value
= JCFG_EVENT
},
309 { .name
= "-idcode", .value
= JCFG_IDCODE
},
311 { .name
= NULL
, .value
= -1 }
314 static int jtag_tap_configure_event(struct jim_getopt_info
*goi
, struct jtag_tap
*tap
)
316 if (goi
->argc
== 0) {
317 Jim_WrongNumArgs(goi
->interp
, goi
->argc
, goi
->argv
, "-event <event-name> ...");
322 int e
= jim_getopt_nvp(goi
, nvp_jtag_tap_event
, &n
);
324 jim_getopt_nvp_unknown(goi
, nvp_jtag_tap_event
, 1);
328 if (goi
->isconfigure
) {
329 if (goi
->argc
!= 1) {
330 Jim_WrongNumArgs(goi
->interp
,
333 "-event <event-name> <event-body>");
337 if (goi
->argc
!= 0) {
338 Jim_WrongNumArgs(goi
->interp
, goi
->argc
, goi
->argv
, "-event <event-name>");
343 struct jtag_tap_event_action
*jteap
= tap
->event_action
;
344 /* replace existing event body */
347 if (jteap
->event
== (enum jtag_event
)n
->value
) {
354 Jim_SetEmptyResult(goi
->interp
);
356 if (goi
->isconfigure
) {
358 jteap
= calloc(1, sizeof(*jteap
));
359 else if (jteap
->body
)
360 Jim_DecrRefCount(goi
->interp
, jteap
->body
);
362 jteap
->interp
= goi
->interp
;
363 jteap
->event
= n
->value
;
366 jim_getopt_obj(goi
, &o
);
367 jteap
->body
= Jim_DuplicateObj(goi
->interp
, o
);
368 Jim_IncrRefCount(jteap
->body
);
371 /* add to head of event list */
372 jteap
->next
= tap
->event_action
;
373 tap
->event_action
= jteap
;
376 jteap
->interp
= goi
->interp
;
377 Jim_SetResult(goi
->interp
,
378 Jim_DuplicateObj(goi
->interp
, jteap
->body
));
383 static int jtag_tap_configure_cmd(struct jim_getopt_info
*goi
, struct jtag_tap
*tap
)
385 /* parse config or cget options */
386 while (goi
->argc
> 0) {
387 Jim_SetEmptyResult(goi
->interp
);
390 int e
= jim_getopt_nvp(goi
, nvp_config_opts
, &n
);
392 jim_getopt_nvp_unknown(goi
, nvp_config_opts
, 0);
398 e
= jtag_tap_configure_event(goi
, tap
);
403 if (goi
->isconfigure
) {
404 Jim_SetResultFormatted(goi
->interp
,
405 "not settable: %s", n
->name
);
408 if (goi
->argc
!= 0) {
409 Jim_WrongNumArgs(goi
->interp
,
410 goi
->argc
, goi
->argv
,
415 Jim_SetResult(goi
->interp
, Jim_NewIntObj(goi
->interp
, tap
->idcode
));
418 Jim_SetResultFormatted(goi
->interp
, "unknown value: %s", n
->name
);
426 static int is_bad_irval(int ir_length
, jim_wide w
)
436 static int jim_newtap_expected_id(struct jim_nvp
*n
, struct jim_getopt_info
*goi
,
437 struct jtag_tap
*tap
)
440 int e
= jim_getopt_wide(goi
, &w
);
442 Jim_SetResultFormatted(goi
->interp
, "option: %s bad parameter", n
->name
);
446 uint32_t *p
= realloc(tap
->expected_ids
,
447 (tap
->expected_ids_cnt
+ 1) * sizeof(uint32_t));
449 Jim_SetResultFormatted(goi
->interp
, "no memory");
453 tap
->expected_ids
= p
;
454 tap
->expected_ids
[tap
->expected_ids_cnt
++] = w
;
459 #define NTAP_OPT_IRLEN 0
460 #define NTAP_OPT_IRMASK 1
461 #define NTAP_OPT_IRCAPTURE 2
462 #define NTAP_OPT_ENABLED 3
463 #define NTAP_OPT_DISABLED 4
464 #define NTAP_OPT_EXPECTED_ID 5
465 #define NTAP_OPT_VERSION 6
466 #define NTAP_OPT_BYPASS 7
468 static int jim_newtap_ir_param(struct jim_nvp
*n
, struct jim_getopt_info
*goi
,
469 struct jtag_tap
*tap
)
472 int e
= jim_getopt_wide(goi
, &w
);
474 Jim_SetResultFormatted(goi
->interp
,
475 "option: %s bad parameter", n
->name
);
480 if (w
> (jim_wide
) (8 * sizeof(tap
->ir_capture_value
))) {
481 LOG_WARNING("%s: huge IR length %d",
482 tap
->dotted_name
, (int) w
);
486 case NTAP_OPT_IRMASK
:
487 if (is_bad_irval(tap
->ir_length
, w
)) {
488 LOG_ERROR("%s: IR mask %x too big",
494 LOG_WARNING("%s: nonstandard IR mask", tap
->dotted_name
);
495 tap
->ir_capture_mask
= w
;
497 case NTAP_OPT_IRCAPTURE
:
498 if (is_bad_irval(tap
->ir_length
, w
)) {
499 LOG_ERROR("%s: IR capture %x too big",
500 tap
->dotted_name
, (int) w
);
504 LOG_WARNING("%s: nonstandard IR value",
506 tap
->ir_capture_value
= w
;
514 static int jim_newtap_cmd(struct jim_getopt_info
*goi
)
516 struct jtag_tap
*tap
;
521 const struct jim_nvp opts
[] = {
522 { .name
= "-irlen", .value
= NTAP_OPT_IRLEN
},
523 { .name
= "-irmask", .value
= NTAP_OPT_IRMASK
},
524 { .name
= "-ircapture", .value
= NTAP_OPT_IRCAPTURE
},
525 { .name
= "-enable", .value
= NTAP_OPT_ENABLED
},
526 { .name
= "-disable", .value
= NTAP_OPT_DISABLED
},
527 { .name
= "-expected-id", .value
= NTAP_OPT_EXPECTED_ID
},
528 { .name
= "-ignore-version", .value
= NTAP_OPT_VERSION
},
529 { .name
= "-ignore-bypass", .value
= NTAP_OPT_BYPASS
},
530 { .name
= NULL
, .value
= -1 },
533 tap
= calloc(1, sizeof(struct jtag_tap
));
535 Jim_SetResultFormatted(goi
->interp
, "no memory");
540 * we expect CHIP + TAP + OPTIONS
543 Jim_SetResultFormatted(goi
->interp
, "Missing CHIP TAP OPTIONS ....");
549 jim_getopt_string(goi
, &tmp
, NULL
);
550 tap
->chip
= strdup(tmp
);
552 jim_getopt_string(goi
, &tmp
, NULL
);
553 tap
->tapname
= strdup(tmp
);
555 /* name + dot + name + null */
556 x
= strlen(tap
->chip
) + 1 + strlen(tap
->tapname
) + 1;
558 sprintf(cp
, "%s.%s", tap
->chip
, tap
->tapname
);
559 tap
->dotted_name
= cp
;
561 LOG_DEBUG("Creating New Tap, Chip: %s, Tap: %s, Dotted: %s, %d params",
562 tap
->chip
, tap
->tapname
, tap
->dotted_name
, goi
->argc
);
564 /* IEEE specifies that the two LSBs of an IR scan are 01, so make
565 * that the default. The "-ircapture" and "-irmask" options are only
566 * needed to cope with nonstandard TAPs, or to specify more bits.
568 tap
->ir_capture_mask
= 0x03;
569 tap
->ir_capture_value
= 0x01;
572 e
= jim_getopt_nvp(goi
, opts
, &n
);
574 jim_getopt_nvp_unknown(goi
, opts
, 0);
579 LOG_DEBUG("Processing option: %s", n
->name
);
581 case NTAP_OPT_ENABLED
:
582 tap
->disabled_after_reset
= false;
584 case NTAP_OPT_DISABLED
:
585 tap
->disabled_after_reset
= true;
587 case NTAP_OPT_EXPECTED_ID
:
588 e
= jim_newtap_expected_id(n
, goi
, tap
);
596 case NTAP_OPT_IRMASK
:
597 case NTAP_OPT_IRCAPTURE
:
598 e
= jim_newtap_ir_param(n
, goi
, tap
);
605 case NTAP_OPT_VERSION
:
606 tap
->ignore_version
= true;
608 case NTAP_OPT_BYPASS
:
609 tap
->ignore_bypass
= true;
611 } /* switch (n->value) */
612 } /* while (goi->argc) */
614 /* default is enabled-after-reset */
615 tap
->enabled
= !tap
->disabled_after_reset
;
617 /* Did all the required option bits get cleared? */
618 if (!transport_is_jtag() || tap
->ir_length
!= 0) {
623 Jim_SetResultFormatted(goi
->interp
,
624 "newtap: %s missing IR length",
630 static void jtag_tap_handle_event(struct jtag_tap
*tap
, enum jtag_event e
)
632 struct jtag_tap_event_action
*jteap
;
635 for (jteap
= tap
->event_action
; jteap
; jteap
= jteap
->next
) {
636 if (jteap
->event
!= e
)
639 struct jim_nvp
*nvp
= jim_nvp_value2name_simple(nvp_jtag_tap_event
, e
);
640 LOG_DEBUG("JTAG tap: %s event: %d (%s)\n\taction: %s",
641 tap
->dotted_name
, e
, nvp
->name
,
642 Jim_GetString(jteap
->body
, NULL
));
644 retval
= Jim_EvalObj(jteap
->interp
, jteap
->body
);
645 if (retval
== JIM_RETURN
)
646 retval
= jteap
->interp
->returnCode
;
648 if (retval
!= JIM_OK
) {
649 Jim_MakeErrorMessage(jteap
->interp
);
650 LOG_USER("%s", Jim_GetString(Jim_GetResult(jteap
->interp
), NULL
));
655 case JTAG_TAP_EVENT_ENABLE
:
656 case JTAG_TAP_EVENT_DISABLE
:
657 /* NOTE: we currently assume the handlers
658 * can't fail. Right here is where we should
659 * really be verifying the scan chains ...
661 tap
->enabled
= (e
== JTAG_TAP_EVENT_ENABLE
);
662 LOG_INFO("JTAG tap: %s %s", tap
->dotted_name
,
663 tap
->enabled
? "enabled" : "disabled");
671 COMMAND_HANDLER(handle_jtag_arp_init
)
674 return ERROR_COMMAND_SYNTAX_ERROR
;
676 return jtag_init_inner(CMD_CTX
);
679 COMMAND_HANDLER(handle_jtag_arp_init_reset
)
682 return ERROR_COMMAND_SYNTAX_ERROR
;
684 if (transport_is_jtag())
685 return jtag_init_reset(CMD_CTX
);
687 if (transport_is_swd())
688 return swd_init_reset(CMD_CTX
);
693 int jim_jtag_newtap(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);
697 return jim_newtap_cmd(&goi
);
700 static bool jtag_tap_enable(struct jtag_tap
*t
)
704 jtag_tap_handle_event(t
, JTAG_TAP_EVENT_ENABLE
);
708 /* FIXME add JTAG sanity checks, w/o TLR
709 * - scan chain length grew by one (this)
710 * - IDs and IR lengths are as expected
712 jtag_call_event_callbacks(JTAG_TAP_EVENT_ENABLE
);
715 static bool jtag_tap_disable(struct jtag_tap
*t
)
719 jtag_tap_handle_event(t
, JTAG_TAP_EVENT_DISABLE
);
723 /* FIXME add JTAG sanity checks, w/o TLR
724 * - scan chain length shrank by one (this)
725 * - IDs and IR lengths are as expected
727 jtag_call_event_callbacks(JTAG_TAP_EVENT_DISABLE
);
731 int jim_jtag_tap_enabler(Jim_Interp
*interp
, int argc
, Jim_Obj
*const *argv
)
733 struct command
*c
= jim_to_command(interp
);
734 const char *cmd_name
= c
->name
;
735 struct jim_getopt_info goi
;
736 jim_getopt_setup(&goi
, interp
, argc
-1, argv
+ 1);
738 Jim_SetResultFormatted(goi
.interp
, "usage: %s <name>", cmd_name
);
744 t
= jtag_tap_by_jim_obj(goi
.interp
, goi
.argv
[0]);
748 if (strcasecmp(cmd_name
, "tapisenabled") == 0) {
749 /* do nothing, just return the value */
750 } else if (strcasecmp(cmd_name
, "tapenable") == 0) {
751 if (!jtag_tap_enable(t
)) {
752 LOG_WARNING("failed to enable tap %s", t
->dotted_name
);
755 } else if (strcasecmp(cmd_name
, "tapdisable") == 0) {
756 if (!jtag_tap_disable(t
)) {
757 LOG_WARNING("failed to disable tap %s", t
->dotted_name
);
761 LOG_ERROR("command '%s' unknown", cmd_name
);
765 Jim_SetResult(goi
.interp
, Jim_NewIntObj(goi
.interp
, e
));
769 int jim_jtag_configure(Jim_Interp
*interp
, int argc
, Jim_Obj
*const *argv
)
771 struct command
*c
= jim_to_command(interp
);
772 const char *cmd_name
= c
->name
;
773 struct jim_getopt_info goi
;
774 jim_getopt_setup(&goi
, interp
, argc
-1, argv
+ 1);
775 goi
.isconfigure
= !strcmp(cmd_name
, "configure");
776 if (goi
.argc
< 2 + goi
.isconfigure
) {
777 Jim_WrongNumArgs(goi
.interp
, 0, NULL
,
778 "<tap_name> <attribute> ...");
785 jim_getopt_obj(&goi
, &o
);
786 t
= jtag_tap_by_jim_obj(goi
.interp
, o
);
790 return jtag_tap_configure_cmd(&goi
, t
);
793 COMMAND_HANDLER(handle_jtag_names
)
796 return ERROR_COMMAND_SYNTAX_ERROR
;
798 for (struct jtag_tap
*tap
= jtag_all_taps(); tap
; tap
= tap
->next_tap
)
799 command_print(CMD
, "%s", tap
->dotted_name
);
804 COMMAND_HANDLER(handle_jtag_init_command
)
807 return ERROR_COMMAND_SYNTAX_ERROR
;
809 static bool jtag_initialized
;
810 if (jtag_initialized
) {
811 LOG_INFO("'jtag init' has already been called");
814 jtag_initialized
= true;
816 LOG_DEBUG("Initializing jtag devices...");
817 return jtag_init(CMD_CTX
);
820 static const struct command_registration jtag_subcommand_handlers
[] = {
824 .handler
= handle_jtag_init_command
,
825 .help
= "initialize jtag scan chain",
831 .handler
= handle_jtag_arp_init
,
832 .help
= "Validates JTAG scan chain against the list of "
833 "declared TAPs using just the four standard JTAG "
838 .name
= "arp_init-reset",
840 .handler
= handle_jtag_arp_init_reset
,
841 .help
= "Uses TRST and SRST to try resetting everything on "
842 "the JTAG scan chain, then performs 'jtag arp_init'.",
847 .mode
= COMMAND_CONFIG
,
848 .jim_handler
= jim_jtag_newtap
,
849 .help
= "Create a new TAP instance named basename.tap_type, "
850 "and appends it to the scan chain.",
851 .usage
= "basename tap_type '-irlen' count "
852 "['-enable'|'-disable'] "
853 "['-expected_id' number] "
854 "['-ignore-version'] "
855 "['-ignore-bypass'] "
856 "['-ircapture' number] "
860 .name
= "tapisenabled",
861 .mode
= COMMAND_EXEC
,
862 .jim_handler
= jim_jtag_tap_enabler
,
863 .help
= "Returns a Tcl boolean (0/1) indicating whether "
864 "the TAP is enabled (1) or not (0).",
869 .mode
= COMMAND_EXEC
,
870 .jim_handler
= jim_jtag_tap_enabler
,
871 .help
= "Try to enable the specified TAP using the "
872 "'tap-enable' TAP event.",
876 .name
= "tapdisable",
877 .mode
= COMMAND_EXEC
,
878 .jim_handler
= jim_jtag_tap_enabler
,
879 .help
= "Try to disable the specified TAP using the "
880 "'tap-disable' TAP event.",
886 .jim_handler
= jim_jtag_configure
,
887 .help
= "Provide a Tcl handler for the specified "
889 .usage
= "tap_name '-event' event_name handler",
893 .mode
= COMMAND_EXEC
,
894 .jim_handler
= jim_jtag_configure
,
895 .help
= "Return any Tcl handler for the specified "
897 .usage
= "tap_name '-event' event_name",
902 .handler
= handle_jtag_names
,
903 .help
= "Returns list of all JTAG tap names.",
907 .chain
= jtag_command_handlers_to_move
,
909 COMMAND_REGISTRATION_DONE
912 void jtag_notify_event(enum jtag_event event
)
914 struct jtag_tap
*tap
;
916 for (tap
= jtag_all_taps(); tap
; tap
= tap
->next_tap
)
917 jtag_tap_handle_event(tap
, event
);
921 COMMAND_HANDLER(handle_scan_chain_command
)
923 struct jtag_tap
*tap
;
924 char expected_id
[12];
926 tap
= jtag_all_taps();
928 " TapName Enabled IdCode Expected IrLen IrCap IrMask");
930 "-- ------------------- -------- ---------- ---------- ----- ----- ------");
933 uint32_t expected
, expected_mask
, ii
;
935 snprintf(expected_id
, sizeof(expected_id
), "0x%08x",
936 (unsigned)((tap
->expected_ids_cnt
> 0)
937 ? tap
->expected_ids
[0]
939 if (tap
->ignore_version
)
940 expected_id
[2] = '*';
942 expected
= buf_get_u32(tap
->expected
, 0, tap
->ir_length
);
943 expected_mask
= buf_get_u32(tap
->expected_mask
, 0, tap
->ir_length
);
946 "%2d %-18s %c 0x%08x %s %5d 0x%02x 0x%02x",
947 tap
->abs_chain_position
,
949 tap
->enabled
? 'Y' : 'n',
950 (unsigned int)(tap
->idcode
),
952 (unsigned int)(tap
->ir_length
),
953 (unsigned int)(expected
),
954 (unsigned int)(expected_mask
));
956 for (ii
= 1; ii
< tap
->expected_ids_cnt
; ii
++) {
957 snprintf(expected_id
, sizeof(expected_id
), "0x%08x",
958 (unsigned) tap
->expected_ids
[ii
]);
959 if (tap
->ignore_version
)
960 expected_id
[2] = '*';
973 COMMAND_HANDLER(handle_jtag_ntrst_delay_command
)
976 return ERROR_COMMAND_SYNTAX_ERROR
;
979 COMMAND_PARSE_NUMBER(uint
, CMD_ARGV
[0], delay
);
981 jtag_set_ntrst_delay(delay
);
983 command_print(CMD
, "jtag_ntrst_delay: %u", jtag_get_ntrst_delay());
987 COMMAND_HANDLER(handle_jtag_ntrst_assert_width_command
)
990 return ERROR_COMMAND_SYNTAX_ERROR
;
993 COMMAND_PARSE_NUMBER(uint
, CMD_ARGV
[0], delay
);
995 jtag_set_ntrst_assert_width(delay
);
997 command_print(CMD
, "jtag_ntrst_assert_width: %u", jtag_get_ntrst_assert_width());
1001 COMMAND_HANDLER(handle_jtag_rclk_command
)
1004 return ERROR_COMMAND_SYNTAX_ERROR
;
1006 int retval
= ERROR_OK
;
1007 if (CMD_ARGC
== 1) {
1009 COMMAND_PARSE_NUMBER(uint
, CMD_ARGV
[0], khz
);
1011 retval
= adapter_config_rclk(khz
);
1012 if (retval
!= ERROR_OK
)
1016 int cur_khz
= adapter_get_speed_khz();
1017 retval
= adapter_get_speed_readable(&cur_khz
);
1018 if (retval
!= ERROR_OK
)
1022 command_print(CMD
, "RCLK not supported - fallback to %d kHz", cur_khz
);
1024 command_print(CMD
, "RCLK - adaptive");
1029 COMMAND_HANDLER(handle_runtest_command
)
1032 return ERROR_COMMAND_SYNTAX_ERROR
;
1034 unsigned num_clocks
;
1035 COMMAND_PARSE_NUMBER(uint
, CMD_ARGV
[0], num_clocks
);
1037 jtag_add_runtest(num_clocks
, TAP_IDLE
);
1038 return jtag_execute_queue();
1042 * For "irscan" or "drscan" commands, the "end" (really, "next") state
1043 * should be stable ... and *NOT* a shift state, otherwise free-running
1044 * jtag clocks could change the values latched by the update state.
1045 * Not surprisingly, this is the same constraint as SVF; the "irscan"
1046 * and "drscan" commands are a write-only subset of what SVF provides.
1049 COMMAND_HANDLER(handle_irscan_command
)
1052 struct scan_field
*fields
;
1053 struct jtag_tap
*tap
= NULL
;
1054 tap_state_t endstate
;
1056 if ((CMD_ARGC
< 2) || (CMD_ARGC
% 2))
1057 return ERROR_COMMAND_SYNTAX_ERROR
;
1059 /* optional "-endstate" "statename" at the end of the arguments,
1060 * so that e.g. IRPAUSE can let us load the data register before
1061 * entering RUN/IDLE to execute the instruction we load here.
1063 endstate
= TAP_IDLE
;
1065 if (CMD_ARGC
>= 4) {
1066 /* have at least one pair of numbers.
1067 * is last pair the magic text? */
1068 if (strcmp("-endstate", CMD_ARGV
[CMD_ARGC
- 2]) == 0) {
1069 endstate
= tap_state_by_name(CMD_ARGV
[CMD_ARGC
- 1]);
1070 if (endstate
== TAP_INVALID
)
1071 return ERROR_COMMAND_SYNTAX_ERROR
;
1072 if (!scan_is_safe(endstate
))
1073 LOG_WARNING("unstable irscan endstate \"%s\"",
1074 CMD_ARGV
[CMD_ARGC
- 1]);
1079 int num_fields
= CMD_ARGC
/ 2;
1080 if (num_fields
> 1) {
1081 /* we really should be looking at plain_ir_scan if we want
1082 * anything more fancy.
1084 LOG_ERROR("Specify a single value for tap");
1085 return ERROR_COMMAND_SYNTAX_ERROR
;
1088 fields
= calloc(num_fields
, sizeof(*fields
));
1091 for (i
= 0; i
< num_fields
; i
++) {
1092 tap
= jtag_tap_by_string(CMD_ARGV
[i
*2]);
1095 command_print(CMD
, "Tap: %s unknown", CMD_ARGV
[i
*2]);
1100 retval
= parse_u64(CMD_ARGV
[i
* 2 + 1], &value
);
1101 if (retval
!= ERROR_OK
)
1104 int field_size
= tap
->ir_length
;
1105 fields
[i
].num_bits
= field_size
;
1106 uint8_t *v
= calloc(1, DIV_ROUND_UP(field_size
, 8));
1108 LOG_ERROR("Out of memory");
1112 buf_set_u64(v
, 0, field_size
, value
);
1113 fields
[i
].out_value
= v
;
1114 fields
[i
].in_value
= NULL
;
1117 /* did we have an endstate? */
1118 jtag_add_ir_scan(tap
, fields
, endstate
);
1120 retval
= jtag_execute_queue();
1123 for (i
= 0; i
< num_fields
; i
++)
1124 free((void *)fields
[i
].out_value
);
1131 COMMAND_HANDLER(handle_verify_ircapture_command
)
1134 return ERROR_COMMAND_SYNTAX_ERROR
;
1136 if (CMD_ARGC
== 1) {
1138 COMMAND_PARSE_ENABLE(CMD_ARGV
[0], enable
);
1139 jtag_set_verify_capture_ir(enable
);
1142 const char *status
= jtag_will_verify_capture_ir() ? "enabled" : "disabled";
1143 command_print(CMD
, "verify Capture-IR is %s", status
);
1148 COMMAND_HANDLER(handle_verify_jtag_command
)
1151 return ERROR_COMMAND_SYNTAX_ERROR
;
1153 if (CMD_ARGC
== 1) {
1155 COMMAND_PARSE_ENABLE(CMD_ARGV
[0], enable
);
1156 jtag_set_verify(enable
);
1159 const char *status
= jtag_will_verify() ? "enabled" : "disabled";
1160 command_print(CMD
, "verify jtag capture is %s", status
);
1165 COMMAND_HANDLER(handle_tms_sequence_command
)
1168 return ERROR_COMMAND_SYNTAX_ERROR
;
1170 if (CMD_ARGC
== 1) {
1172 if (strcmp(CMD_ARGV
[0], "short") == 0)
1173 use_new_table
= true;
1174 else if (strcmp(CMD_ARGV
[0], "long") == 0)
1175 use_new_table
= false;
1177 return ERROR_COMMAND_SYNTAX_ERROR
;
1179 tap_use_new_tms_table(use_new_table
);
1182 command_print(CMD
, "tms sequence is %s",
1183 tap_uses_new_tms_table() ? "short" : "long");
1188 COMMAND_HANDLER(handle_jtag_flush_queue_sleep
)
1191 return ERROR_COMMAND_SYNTAX_ERROR
;
1194 COMMAND_PARSE_NUMBER(int, CMD_ARGV
[0], sleep_ms
);
1196 jtag_set_flush_queue_sleep(sleep_ms
);
1201 COMMAND_HANDLER(handle_wait_srst_deassert
)
1204 return ERROR_COMMAND_SYNTAX_ERROR
;
1207 COMMAND_PARSE_NUMBER(int, CMD_ARGV
[0], timeout_ms
);
1208 if ((timeout_ms
<= 0) || (timeout_ms
> 100000)) {
1209 LOG_ERROR("Timeout must be an integer between 0 and 100000");
1213 LOG_USER("Waiting for srst assert + deassert for at most %dms", timeout_ms
);
1215 int64_t then
= timeval_ms();
1216 while (jtag_srst_asserted(&asserted_yet
) == ERROR_OK
) {
1217 if ((timeval_ms() - then
) > timeout_ms
) {
1218 LOG_ERROR("Timed out");
1224 while (jtag_srst_asserted(&asserted_yet
) == ERROR_OK
) {
1225 if ((timeval_ms() - then
) > timeout_ms
) {
1226 LOG_ERROR("Timed out");
1236 static const struct command_registration jtag_command_handlers
[] = {
1239 .name
= "jtag_flush_queue_sleep",
1240 .handler
= handle_jtag_flush_queue_sleep
,
1241 .mode
= COMMAND_ANY
,
1242 .help
= "For debug purposes(simulate long delays of interface) "
1243 "to test performance or change in behavior. Default 0ms.",
1244 .usage
= "[sleep in ms]",
1247 .name
= "jtag_rclk",
1248 .handler
= handle_jtag_rclk_command
,
1249 .mode
= COMMAND_ANY
,
1250 .help
= "With an argument, change to to use adaptive clocking "
1251 "if possible; else to use the fallback speed. "
1252 "With or without argument, display current setting.",
1253 .usage
= "[fallback_speed_khz]",
1256 .name
= "jtag_ntrst_delay",
1257 .handler
= handle_jtag_ntrst_delay_command
,
1258 .mode
= COMMAND_ANY
,
1259 .help
= "delay after deasserting trst in ms",
1260 .usage
= "[milliseconds]",
1263 .name
= "jtag_ntrst_assert_width",
1264 .handler
= handle_jtag_ntrst_assert_width_command
,
1265 .mode
= COMMAND_ANY
,
1266 .help
= "delay after asserting trst in ms",
1267 .usage
= "[milliseconds]",
1270 .name
= "scan_chain",
1271 .handler
= handle_scan_chain_command
,
1272 .mode
= COMMAND_ANY
,
1273 .help
= "print current scan chain configuration",
1278 .handler
= handle_runtest_command
,
1279 .mode
= COMMAND_EXEC
,
1280 .help
= "Move to Run-Test/Idle, and issue TCK for num_cycles.",
1281 .usage
= "num_cycles"
1285 .handler
= handle_irscan_command
,
1286 .mode
= COMMAND_EXEC
,
1287 .help
= "Execute Instruction Register (IR) scan. The "
1288 "specified opcodes are put into each TAP's IR, "
1289 "and other TAPs are put in BYPASS.",
1290 .usage
= "[tap_name instruction]* ['-endstate' state_name]",
1293 .name
= "verify_ircapture",
1294 .handler
= handle_verify_ircapture_command
,
1295 .mode
= COMMAND_ANY
,
1296 .help
= "Display or assign flag controlling whether to "
1297 "verify values captured during Capture-IR.",
1298 .usage
= "['enable'|'disable']",
1301 .name
= "verify_jtag",
1302 .handler
= handle_verify_jtag_command
,
1303 .mode
= COMMAND_ANY
,
1304 .help
= "Display or assign flag controlling whether to "
1305 "verify values captured during IR and DR scans.",
1306 .usage
= "['enable'|'disable']",
1309 .name
= "tms_sequence",
1310 .handler
= handle_tms_sequence_command
,
1311 .mode
= COMMAND_ANY
,
1312 .help
= "Display or change what style TMS sequences to use "
1313 "for JTAG state transitions: short (default) or "
1314 "long. Only for working around JTAG bugs.",
1315 /* Specifically for working around DRIVER bugs... */
1316 .usage
= "['short'|'long']",
1319 .name
= "wait_srst_deassert",
1320 .handler
= handle_wait_srst_deassert
,
1321 .mode
= COMMAND_ANY
,
1322 .help
= "Wait for an SRST deassert. "
1323 "Useful for cases where you need something to happen within ms "
1324 "of an srst deassert. Timeout in ms",
1329 .mode
= COMMAND_ANY
,
1330 .help
= "perform jtag tap actions",
1333 .chain
= jtag_subcommand_handlers
,
1336 .chain
= jtag_command_handlers_to_move
,
1338 COMMAND_REGISTRATION_DONE
1341 int jtag_register_commands(struct command_context
*cmd_ctx
)
1343 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)