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 COMMAND_HELPER(handle_jtag_command_drscan_fields
, struct scan_field
*fields
)
77 unsigned int field_count
= 0;
78 for (unsigned int i
= 1; i
< CMD_ARGC
; i
+= 2) {
80 COMMAND_PARSE_NUMBER(uint
, CMD_ARGV
[i
], bits
);
81 fields
[field_count
].num_bits
= bits
;
83 void *t
= malloc(DIV_ROUND_UP(bits
, 8));
85 LOG_ERROR("Out of memory");
88 fields
[field_count
].out_value
= t
;
89 str_to_buf(CMD_ARGV
[i
+ 1], strlen(CMD_ARGV
[i
+ 1]), t
, bits
, 0);
90 fields
[field_count
].in_value
= t
;
97 COMMAND_HANDLER(handle_jtag_command_drscan
)
100 * CMD_ARGV[0] = device
101 * CMD_ARGV[1] = num_bits
102 * CMD_ARGV[2] = hex string
103 * ... repeat num bits and hex string ...
106 * CMD_ARGV[CMD_ARGC-2] = "-endstate"
107 * CMD_ARGV[CMD_ARGC-1] = statename
110 if (CMD_ARGC
< 3 || (CMD_ARGC
% 2) != 1)
111 return ERROR_COMMAND_SYNTAX_ERROR
;
113 struct jtag_tap
*tap
= jtag_tap_by_string(CMD_ARGV
[0]);
115 command_print(CMD
, "Tap '%s' could not be found", CMD_ARGV
[0]);
116 return ERROR_COMMAND_ARGUMENT_INVALID
;
119 tap_state_t endstate
= TAP_IDLE
;
120 if (CMD_ARGC
> 3 && !strcmp("-endstate", CMD_ARGV
[CMD_ARGC
- 2])) {
121 const char *state_name
= CMD_ARGV
[CMD_ARGC
- 1];
122 endstate
= tap_state_by_name(state_name
);
124 command_print(CMD
, "endstate: %s invalid", state_name
);
125 return ERROR_COMMAND_ARGUMENT_INVALID
;
128 if (!scan_is_safe(endstate
))
129 LOG_WARNING("drscan with unsafe endstate \"%s\"", state_name
);
134 unsigned int num_fields
= (CMD_ARGC
- 1) / 2;
135 struct scan_field
*fields
= calloc(num_fields
, sizeof(struct scan_field
));
137 LOG_ERROR("Out of memory");
141 int retval
= CALL_COMMAND_HANDLER(handle_jtag_command_drscan_fields
, fields
);
142 if (retval
!= ERROR_OK
)
145 jtag_add_dr_scan(tap
, num_fields
, fields
, endstate
);
147 retval
= jtag_execute_queue();
148 if (retval
!= ERROR_OK
) {
149 command_print(CMD
, "drscan: jtag execute failed");
153 for (unsigned int i
= 0; i
< num_fields
; i
++) {
154 char *str
= buf_to_hex_str(fields
[i
].in_value
, fields
[i
].num_bits
);
155 command_print(CMD
, "%s", str
);
160 for (unsigned int i
= 0; i
< num_fields
; i
++)
161 free(fields
[i
].in_value
);
167 static int jim_command_pathmove(Jim_Interp
*interp
, int argc
, Jim_Obj
* const *args
)
169 tap_state_t states
[8];
171 if ((argc
< 2) || ((size_t)argc
> (ARRAY_SIZE(states
) + 1))) {
172 Jim_WrongNumArgs(interp
, 1, args
, "wrong arguments");
177 for (i
= 0; i
< argc
-1; i
++) {
179 cp
= Jim_GetString(args
[i
+ 1], NULL
);
180 states
[i
] = tap_state_by_name(cp
);
182 /* update the error message */
183 Jim_SetResultFormatted(interp
, "endstate: %s invalid", cp
);
188 if ((jtag_add_statemove(states
[0]) != ERROR_OK
) || (jtag_execute_queue() != ERROR_OK
)) {
189 Jim_SetResultString(interp
, "pathmove: jtag execute failed", -1);
193 jtag_add_pathmove(argc
- 2, states
+ 1);
195 if (jtag_execute_queue() != ERROR_OK
) {
196 Jim_SetResultString(interp
, "pathmove: failed", -1);
203 COMMAND_HANDLER(handle_jtag_flush_count
)
206 return ERROR_COMMAND_SYNTAX_ERROR
;
208 int count
= jtag_get_flush_queue_count();
209 command_print_sameline(CMD
, "%d", count
);
214 /* REVISIT Just what about these should "move" ... ?
215 * These registrations, into the main JTAG table?
217 * There's a minor compatibility issue, these all show up twice;
218 * that's not desirable:
219 * - jtag drscan ... NOT DOCUMENTED!
222 * The "irscan" command (for example) doesn't show twice.
224 static const struct command_registration jtag_command_handlers_to_move
[] = {
227 .mode
= COMMAND_EXEC
,
228 .handler
= handle_jtag_command_drscan
,
229 .help
= "Execute Data Register (DR) scan for one TAP. "
230 "Other TAPs must be in BYPASS mode.",
231 .usage
= "tap_name [num_bits value]* ['-endstate' state_name]",
234 .name
= "flush_count",
235 .mode
= COMMAND_EXEC
,
236 .handler
= handle_jtag_flush_count
,
237 .help
= "Returns the number of times the JTAG queue "
243 .mode
= COMMAND_EXEC
,
244 .jim_handler
= jim_command_pathmove
,
245 .usage
= "start_state state1 [state2 [state3 ...]]",
246 .help
= "Move JTAG state machine from current state "
247 "(start_state) to state1, then state2, state3, etc.",
249 COMMAND_REGISTRATION_DONE
253 enum jtag_tap_cfg_param
{
258 static struct jim_nvp nvp_config_opts
[] = {
259 { .name
= "-event", .value
= JCFG_EVENT
},
260 { .name
= "-idcode", .value
= JCFG_IDCODE
},
262 { .name
= NULL
, .value
= -1 }
265 static int jtag_tap_configure_event(struct jim_getopt_info
*goi
, struct jtag_tap
*tap
)
267 if (goi
->argc
== 0) {
268 Jim_WrongNumArgs(goi
->interp
, goi
->argc
, goi
->argv
, "-event <event-name> ...");
273 int e
= jim_getopt_nvp(goi
, nvp_jtag_tap_event
, &n
);
275 jim_getopt_nvp_unknown(goi
, nvp_jtag_tap_event
, 1);
279 if (goi
->isconfigure
) {
280 if (goi
->argc
!= 1) {
281 Jim_WrongNumArgs(goi
->interp
,
284 "-event <event-name> <event-body>");
288 if (goi
->argc
!= 0) {
289 Jim_WrongNumArgs(goi
->interp
, goi
->argc
, goi
->argv
, "-event <event-name>");
294 struct jtag_tap_event_action
*jteap
= tap
->event_action
;
295 /* replace existing event body */
298 if (jteap
->event
== (enum jtag_event
)n
->value
) {
305 Jim_SetEmptyResult(goi
->interp
);
307 if (goi
->isconfigure
) {
309 jteap
= calloc(1, sizeof(*jteap
));
310 else if (jteap
->body
)
311 Jim_DecrRefCount(goi
->interp
, jteap
->body
);
313 jteap
->interp
= goi
->interp
;
314 jteap
->event
= n
->value
;
317 jim_getopt_obj(goi
, &o
);
318 jteap
->body
= Jim_DuplicateObj(goi
->interp
, o
);
319 Jim_IncrRefCount(jteap
->body
);
322 /* add to head of event list */
323 jteap
->next
= tap
->event_action
;
324 tap
->event_action
= jteap
;
327 jteap
->interp
= goi
->interp
;
328 Jim_SetResult(goi
->interp
,
329 Jim_DuplicateObj(goi
->interp
, jteap
->body
));
334 static int jtag_tap_configure_cmd(struct jim_getopt_info
*goi
, struct jtag_tap
*tap
)
336 /* parse config or cget options */
337 while (goi
->argc
> 0) {
338 Jim_SetEmptyResult(goi
->interp
);
341 int e
= jim_getopt_nvp(goi
, nvp_config_opts
, &n
);
343 jim_getopt_nvp_unknown(goi
, nvp_config_opts
, 0);
349 e
= jtag_tap_configure_event(goi
, tap
);
354 if (goi
->isconfigure
) {
355 Jim_SetResultFormatted(goi
->interp
,
356 "not settable: %s", n
->name
);
359 if (goi
->argc
!= 0) {
360 Jim_WrongNumArgs(goi
->interp
,
361 goi
->argc
, goi
->argv
,
366 Jim_SetResult(goi
->interp
, Jim_NewIntObj(goi
->interp
, tap
->idcode
));
369 Jim_SetResultFormatted(goi
->interp
, "unknown value: %s", n
->name
);
377 static int is_bad_irval(int ir_length
, jim_wide w
)
387 static int jim_newtap_expected_id(struct jim_nvp
*n
, struct jim_getopt_info
*goi
,
388 struct jtag_tap
*tap
)
391 int e
= jim_getopt_wide(goi
, &w
);
393 Jim_SetResultFormatted(goi
->interp
, "option: %s bad parameter", n
->name
);
397 uint32_t *p
= realloc(tap
->expected_ids
,
398 (tap
->expected_ids_cnt
+ 1) * sizeof(uint32_t));
400 Jim_SetResultFormatted(goi
->interp
, "no memory");
404 tap
->expected_ids
= p
;
405 tap
->expected_ids
[tap
->expected_ids_cnt
++] = w
;
410 #define NTAP_OPT_IRLEN 0
411 #define NTAP_OPT_IRMASK 1
412 #define NTAP_OPT_IRCAPTURE 2
413 #define NTAP_OPT_ENABLED 3
414 #define NTAP_OPT_DISABLED 4
415 #define NTAP_OPT_EXPECTED_ID 5
416 #define NTAP_OPT_VERSION 6
417 #define NTAP_OPT_BYPASS 7
419 static int jim_newtap_ir_param(struct jim_nvp
*n
, struct jim_getopt_info
*goi
,
420 struct jtag_tap
*tap
)
423 int e
= jim_getopt_wide(goi
, &w
);
425 Jim_SetResultFormatted(goi
->interp
,
426 "option: %s bad parameter", n
->name
);
431 if (w
> (jim_wide
) (8 * sizeof(tap
->ir_capture_value
))) {
432 LOG_WARNING("%s: huge IR length %d",
433 tap
->dotted_name
, (int) w
);
437 case NTAP_OPT_IRMASK
:
438 if (is_bad_irval(tap
->ir_length
, w
)) {
439 LOG_ERROR("%s: IR mask %x too big",
445 LOG_WARNING("%s: nonstandard IR mask", tap
->dotted_name
);
446 tap
->ir_capture_mask
= w
;
448 case NTAP_OPT_IRCAPTURE
:
449 if (is_bad_irval(tap
->ir_length
, w
)) {
450 LOG_ERROR("%s: IR capture %x too big",
451 tap
->dotted_name
, (int) w
);
455 LOG_WARNING("%s: nonstandard IR value",
457 tap
->ir_capture_value
= w
;
465 static int jim_newtap_cmd(struct jim_getopt_info
*goi
)
467 struct jtag_tap
*tap
;
472 const struct jim_nvp opts
[] = {
473 { .name
= "-irlen", .value
= NTAP_OPT_IRLEN
},
474 { .name
= "-irmask", .value
= NTAP_OPT_IRMASK
},
475 { .name
= "-ircapture", .value
= NTAP_OPT_IRCAPTURE
},
476 { .name
= "-enable", .value
= NTAP_OPT_ENABLED
},
477 { .name
= "-disable", .value
= NTAP_OPT_DISABLED
},
478 { .name
= "-expected-id", .value
= NTAP_OPT_EXPECTED_ID
},
479 { .name
= "-ignore-version", .value
= NTAP_OPT_VERSION
},
480 { .name
= "-ignore-bypass", .value
= NTAP_OPT_BYPASS
},
481 { .name
= NULL
, .value
= -1 },
484 tap
= calloc(1, sizeof(struct jtag_tap
));
486 Jim_SetResultFormatted(goi
->interp
, "no memory");
491 * we expect CHIP + TAP + OPTIONS
494 Jim_SetResultFormatted(goi
->interp
, "Missing CHIP TAP OPTIONS ....");
500 jim_getopt_string(goi
, &tmp
, NULL
);
501 tap
->chip
= strdup(tmp
);
503 jim_getopt_string(goi
, &tmp
, NULL
);
504 tap
->tapname
= strdup(tmp
);
506 /* name + dot + name + null */
507 x
= strlen(tap
->chip
) + 1 + strlen(tap
->tapname
) + 1;
509 sprintf(cp
, "%s.%s", tap
->chip
, tap
->tapname
);
510 tap
->dotted_name
= cp
;
512 LOG_DEBUG("Creating New Tap, Chip: %s, Tap: %s, Dotted: %s, %d params",
513 tap
->chip
, tap
->tapname
, tap
->dotted_name
, goi
->argc
);
515 /* IEEE specifies that the two LSBs of an IR scan are 01, so make
516 * that the default. The "-ircapture" and "-irmask" options are only
517 * needed to cope with nonstandard TAPs, or to specify more bits.
519 tap
->ir_capture_mask
= 0x03;
520 tap
->ir_capture_value
= 0x01;
523 e
= jim_getopt_nvp(goi
, opts
, &n
);
525 jim_getopt_nvp_unknown(goi
, opts
, 0);
530 LOG_DEBUG("Processing option: %s", n
->name
);
532 case NTAP_OPT_ENABLED
:
533 tap
->disabled_after_reset
= false;
535 case NTAP_OPT_DISABLED
:
536 tap
->disabled_after_reset
= true;
538 case NTAP_OPT_EXPECTED_ID
:
539 e
= jim_newtap_expected_id(n
, goi
, tap
);
547 case NTAP_OPT_IRMASK
:
548 case NTAP_OPT_IRCAPTURE
:
549 e
= jim_newtap_ir_param(n
, goi
, tap
);
556 case NTAP_OPT_VERSION
:
557 tap
->ignore_version
= true;
559 case NTAP_OPT_BYPASS
:
560 tap
->ignore_bypass
= true;
562 } /* switch (n->value) */
563 } /* while (goi->argc) */
565 /* default is enabled-after-reset */
566 tap
->enabled
= !tap
->disabled_after_reset
;
568 /* Did all the required option bits get cleared? */
569 if (!transport_is_jtag() || tap
->ir_length
!= 0) {
574 Jim_SetResultFormatted(goi
->interp
,
575 "newtap: %s missing IR length",
581 static void jtag_tap_handle_event(struct jtag_tap
*tap
, enum jtag_event e
)
583 struct jtag_tap_event_action
*jteap
;
586 for (jteap
= tap
->event_action
; jteap
; jteap
= jteap
->next
) {
587 if (jteap
->event
!= e
)
590 struct jim_nvp
*nvp
= jim_nvp_value2name_simple(nvp_jtag_tap_event
, e
);
591 LOG_DEBUG("JTAG tap: %s event: %d (%s)\n\taction: %s",
592 tap
->dotted_name
, e
, nvp
->name
,
593 Jim_GetString(jteap
->body
, NULL
));
595 retval
= Jim_EvalObj(jteap
->interp
, jteap
->body
);
596 if (retval
== JIM_RETURN
)
597 retval
= jteap
->interp
->returnCode
;
599 if (retval
!= JIM_OK
) {
600 Jim_MakeErrorMessage(jteap
->interp
);
601 LOG_USER("%s", Jim_GetString(Jim_GetResult(jteap
->interp
), NULL
));
606 case JTAG_TAP_EVENT_ENABLE
:
607 case JTAG_TAP_EVENT_DISABLE
:
608 /* NOTE: we currently assume the handlers
609 * can't fail. Right here is where we should
610 * really be verifying the scan chains ...
612 tap
->enabled
= (e
== JTAG_TAP_EVENT_ENABLE
);
613 LOG_INFO("JTAG tap: %s %s", tap
->dotted_name
,
614 tap
->enabled
? "enabled" : "disabled");
622 COMMAND_HANDLER(handle_jtag_arp_init
)
625 return ERROR_COMMAND_SYNTAX_ERROR
;
627 return jtag_init_inner(CMD_CTX
);
630 COMMAND_HANDLER(handle_jtag_arp_init_reset
)
633 return ERROR_COMMAND_SYNTAX_ERROR
;
635 if (transport_is_jtag())
636 return jtag_init_reset(CMD_CTX
);
638 if (transport_is_swd())
639 return swd_init_reset(CMD_CTX
);
644 int jim_jtag_newtap(Jim_Interp
*interp
, int argc
, Jim_Obj
*const *argv
)
646 struct jim_getopt_info goi
;
647 jim_getopt_setup(&goi
, interp
, argc
-1, argv
+ 1);
648 return jim_newtap_cmd(&goi
);
651 static bool jtag_tap_enable(struct jtag_tap
*t
)
655 jtag_tap_handle_event(t
, JTAG_TAP_EVENT_ENABLE
);
659 /* FIXME add JTAG sanity checks, w/o TLR
660 * - scan chain length grew by one (this)
661 * - IDs and IR lengths are as expected
663 jtag_call_event_callbacks(JTAG_TAP_EVENT_ENABLE
);
666 static bool jtag_tap_disable(struct jtag_tap
*t
)
670 jtag_tap_handle_event(t
, JTAG_TAP_EVENT_DISABLE
);
674 /* FIXME add JTAG sanity checks, w/o TLR
675 * - scan chain length shrank by one (this)
676 * - IDs and IR lengths are as expected
678 jtag_call_event_callbacks(JTAG_TAP_EVENT_DISABLE
);
682 int jim_jtag_tap_enabler(Jim_Interp
*interp
, int argc
, Jim_Obj
*const *argv
)
684 struct command
*c
= jim_to_command(interp
);
685 const char *cmd_name
= c
->name
;
686 struct jim_getopt_info goi
;
687 jim_getopt_setup(&goi
, interp
, argc
-1, argv
+ 1);
689 Jim_SetResultFormatted(goi
.interp
, "usage: %s <name>", cmd_name
);
695 t
= jtag_tap_by_jim_obj(goi
.interp
, goi
.argv
[0]);
699 if (strcasecmp(cmd_name
, "tapisenabled") == 0) {
700 /* do nothing, just return the value */
701 } else if (strcasecmp(cmd_name
, "tapenable") == 0) {
702 if (!jtag_tap_enable(t
)) {
703 LOG_WARNING("failed to enable tap %s", t
->dotted_name
);
706 } else if (strcasecmp(cmd_name
, "tapdisable") == 0) {
707 if (!jtag_tap_disable(t
)) {
708 LOG_WARNING("failed to disable tap %s", t
->dotted_name
);
712 LOG_ERROR("command '%s' unknown", cmd_name
);
716 Jim_SetResult(goi
.interp
, Jim_NewIntObj(goi
.interp
, e
));
720 int jim_jtag_configure(Jim_Interp
*interp
, int argc
, Jim_Obj
*const *argv
)
722 struct command
*c
= jim_to_command(interp
);
723 const char *cmd_name
= c
->name
;
724 struct jim_getopt_info goi
;
725 jim_getopt_setup(&goi
, interp
, argc
-1, argv
+ 1);
726 goi
.isconfigure
= !strcmp(cmd_name
, "configure");
727 if (goi
.argc
< 2 + goi
.isconfigure
) {
728 Jim_WrongNumArgs(goi
.interp
, 0, NULL
,
729 "<tap_name> <attribute> ...");
736 jim_getopt_obj(&goi
, &o
);
737 t
= jtag_tap_by_jim_obj(goi
.interp
, o
);
741 return jtag_tap_configure_cmd(&goi
, t
);
744 COMMAND_HANDLER(handle_jtag_names
)
747 return ERROR_COMMAND_SYNTAX_ERROR
;
749 for (struct jtag_tap
*tap
= jtag_all_taps(); tap
; tap
= tap
->next_tap
)
750 command_print(CMD
, "%s", tap
->dotted_name
);
755 COMMAND_HANDLER(handle_jtag_init_command
)
758 return ERROR_COMMAND_SYNTAX_ERROR
;
760 static bool jtag_initialized
;
761 if (jtag_initialized
) {
762 LOG_INFO("'jtag init' has already been called");
765 jtag_initialized
= true;
767 LOG_DEBUG("Initializing jtag devices...");
768 return jtag_init(CMD_CTX
);
771 static const struct command_registration jtag_subcommand_handlers
[] = {
775 .handler
= handle_jtag_init_command
,
776 .help
= "initialize jtag scan chain",
782 .handler
= handle_jtag_arp_init
,
783 .help
= "Validates JTAG scan chain against the list of "
784 "declared TAPs using just the four standard JTAG "
789 .name
= "arp_init-reset",
791 .handler
= handle_jtag_arp_init_reset
,
792 .help
= "Uses TRST and SRST to try resetting everything on "
793 "the JTAG scan chain, then performs 'jtag arp_init'.",
798 .mode
= COMMAND_CONFIG
,
799 .jim_handler
= jim_jtag_newtap
,
800 .help
= "Create a new TAP instance named basename.tap_type, "
801 "and appends it to the scan chain.",
802 .usage
= "basename tap_type '-irlen' count "
803 "['-enable'|'-disable'] "
804 "['-expected_id' number] "
805 "['-ignore-version'] "
806 "['-ignore-bypass'] "
807 "['-ircapture' number] "
811 .name
= "tapisenabled",
812 .mode
= COMMAND_EXEC
,
813 .jim_handler
= jim_jtag_tap_enabler
,
814 .help
= "Returns a Tcl boolean (0/1) indicating whether "
815 "the TAP is enabled (1) or not (0).",
820 .mode
= COMMAND_EXEC
,
821 .jim_handler
= jim_jtag_tap_enabler
,
822 .help
= "Try to enable the specified TAP using the "
823 "'tap-enable' TAP event.",
827 .name
= "tapdisable",
828 .mode
= COMMAND_EXEC
,
829 .jim_handler
= jim_jtag_tap_enabler
,
830 .help
= "Try to disable the specified TAP using the "
831 "'tap-disable' TAP event.",
837 .jim_handler
= jim_jtag_configure
,
838 .help
= "Provide a Tcl handler for the specified "
840 .usage
= "tap_name '-event' event_name handler",
844 .mode
= COMMAND_EXEC
,
845 .jim_handler
= jim_jtag_configure
,
846 .help
= "Return any Tcl handler for the specified "
848 .usage
= "tap_name '-event' event_name",
853 .handler
= handle_jtag_names
,
854 .help
= "Returns list of all JTAG tap names.",
858 .chain
= jtag_command_handlers_to_move
,
860 COMMAND_REGISTRATION_DONE
863 void jtag_notify_event(enum jtag_event event
)
865 struct jtag_tap
*tap
;
867 for (tap
= jtag_all_taps(); tap
; tap
= tap
->next_tap
)
868 jtag_tap_handle_event(tap
, event
);
872 COMMAND_HANDLER(handle_scan_chain_command
)
874 struct jtag_tap
*tap
;
875 char expected_id
[12];
877 tap
= jtag_all_taps();
879 " TapName Enabled IdCode Expected IrLen IrCap IrMask");
881 "-- ------------------- -------- ---------- ---------- ----- ----- ------");
884 uint32_t expected
, expected_mask
, ii
;
886 snprintf(expected_id
, sizeof(expected_id
), "0x%08x",
887 (unsigned)((tap
->expected_ids_cnt
> 0)
888 ? tap
->expected_ids
[0]
890 if (tap
->ignore_version
)
891 expected_id
[2] = '*';
893 expected
= buf_get_u32(tap
->expected
, 0, tap
->ir_length
);
894 expected_mask
= buf_get_u32(tap
->expected_mask
, 0, tap
->ir_length
);
897 "%2d %-18s %c 0x%08x %s %5d 0x%02x 0x%02x",
898 tap
->abs_chain_position
,
900 tap
->enabled
? 'Y' : 'n',
901 (unsigned int)(tap
->idcode
),
903 (unsigned int)(tap
->ir_length
),
904 (unsigned int)(expected
),
905 (unsigned int)(expected_mask
));
907 for (ii
= 1; ii
< tap
->expected_ids_cnt
; ii
++) {
908 snprintf(expected_id
, sizeof(expected_id
), "0x%08x",
909 (unsigned) tap
->expected_ids
[ii
]);
910 if (tap
->ignore_version
)
911 expected_id
[2] = '*';
924 COMMAND_HANDLER(handle_jtag_ntrst_delay_command
)
927 return ERROR_COMMAND_SYNTAX_ERROR
;
930 COMMAND_PARSE_NUMBER(uint
, CMD_ARGV
[0], delay
);
932 jtag_set_ntrst_delay(delay
);
934 command_print(CMD
, "jtag_ntrst_delay: %u", jtag_get_ntrst_delay());
938 COMMAND_HANDLER(handle_jtag_ntrst_assert_width_command
)
941 return ERROR_COMMAND_SYNTAX_ERROR
;
944 COMMAND_PARSE_NUMBER(uint
, CMD_ARGV
[0], delay
);
946 jtag_set_ntrst_assert_width(delay
);
948 command_print(CMD
, "jtag_ntrst_assert_width: %u", jtag_get_ntrst_assert_width());
952 COMMAND_HANDLER(handle_jtag_rclk_command
)
955 return ERROR_COMMAND_SYNTAX_ERROR
;
957 int retval
= ERROR_OK
;
960 COMMAND_PARSE_NUMBER(uint
, CMD_ARGV
[0], khz
);
962 retval
= adapter_config_rclk(khz
);
963 if (retval
!= ERROR_OK
)
967 int cur_khz
= adapter_get_speed_khz();
968 retval
= adapter_get_speed_readable(&cur_khz
);
969 if (retval
!= ERROR_OK
)
973 command_print(CMD
, "RCLK not supported - fallback to %d kHz", cur_khz
);
975 command_print(CMD
, "RCLK - adaptive");
980 COMMAND_HANDLER(handle_runtest_command
)
983 return ERROR_COMMAND_SYNTAX_ERROR
;
986 COMMAND_PARSE_NUMBER(uint
, CMD_ARGV
[0], num_clocks
);
988 jtag_add_runtest(num_clocks
, TAP_IDLE
);
989 return jtag_execute_queue();
993 * For "irscan" or "drscan" commands, the "end" (really, "next") state
994 * should be stable ... and *NOT* a shift state, otherwise free-running
995 * jtag clocks could change the values latched by the update state.
996 * Not surprisingly, this is the same constraint as SVF; the "irscan"
997 * and "drscan" commands are a write-only subset of what SVF provides.
1000 COMMAND_HANDLER(handle_irscan_command
)
1003 struct scan_field
*fields
;
1004 struct jtag_tap
*tap
= NULL
;
1005 tap_state_t endstate
;
1007 if ((CMD_ARGC
< 2) || (CMD_ARGC
% 2))
1008 return ERROR_COMMAND_SYNTAX_ERROR
;
1010 /* optional "-endstate" "statename" at the end of the arguments,
1011 * so that e.g. IRPAUSE can let us load the data register before
1012 * entering RUN/IDLE to execute the instruction we load here.
1014 endstate
= TAP_IDLE
;
1016 if (CMD_ARGC
>= 4) {
1017 /* have at least one pair of numbers.
1018 * is last pair the magic text? */
1019 if (strcmp("-endstate", CMD_ARGV
[CMD_ARGC
- 2]) == 0) {
1020 endstate
= tap_state_by_name(CMD_ARGV
[CMD_ARGC
- 1]);
1021 if (endstate
== TAP_INVALID
)
1022 return ERROR_COMMAND_SYNTAX_ERROR
;
1023 if (!scan_is_safe(endstate
))
1024 LOG_WARNING("unstable irscan endstate \"%s\"",
1025 CMD_ARGV
[CMD_ARGC
- 1]);
1030 int num_fields
= CMD_ARGC
/ 2;
1031 if (num_fields
> 1) {
1032 /* we really should be looking at plain_ir_scan if we want
1033 * anything more fancy.
1035 LOG_ERROR("Specify a single value for tap");
1036 return ERROR_COMMAND_SYNTAX_ERROR
;
1039 fields
= calloc(num_fields
, sizeof(*fields
));
1042 for (i
= 0; i
< num_fields
; i
++) {
1043 tap
= jtag_tap_by_string(CMD_ARGV
[i
*2]);
1046 command_print(CMD
, "Tap: %s unknown", CMD_ARGV
[i
*2]);
1051 retval
= parse_u64(CMD_ARGV
[i
* 2 + 1], &value
);
1052 if (retval
!= ERROR_OK
)
1055 int field_size
= tap
->ir_length
;
1056 fields
[i
].num_bits
= field_size
;
1057 uint8_t *v
= calloc(1, DIV_ROUND_UP(field_size
, 8));
1059 LOG_ERROR("Out of memory");
1063 buf_set_u64(v
, 0, field_size
, value
);
1064 fields
[i
].out_value
= v
;
1065 fields
[i
].in_value
= NULL
;
1068 /* did we have an endstate? */
1069 jtag_add_ir_scan(tap
, fields
, endstate
);
1071 retval
= jtag_execute_queue();
1074 for (i
= 0; i
< num_fields
; i
++)
1075 free((void *)fields
[i
].out_value
);
1082 COMMAND_HANDLER(handle_verify_ircapture_command
)
1085 return ERROR_COMMAND_SYNTAX_ERROR
;
1087 if (CMD_ARGC
== 1) {
1089 COMMAND_PARSE_ENABLE(CMD_ARGV
[0], enable
);
1090 jtag_set_verify_capture_ir(enable
);
1093 const char *status
= jtag_will_verify_capture_ir() ? "enabled" : "disabled";
1094 command_print(CMD
, "verify Capture-IR is %s", status
);
1099 COMMAND_HANDLER(handle_verify_jtag_command
)
1102 return ERROR_COMMAND_SYNTAX_ERROR
;
1104 if (CMD_ARGC
== 1) {
1106 COMMAND_PARSE_ENABLE(CMD_ARGV
[0], enable
);
1107 jtag_set_verify(enable
);
1110 const char *status
= jtag_will_verify() ? "enabled" : "disabled";
1111 command_print(CMD
, "verify jtag capture is %s", status
);
1116 COMMAND_HANDLER(handle_tms_sequence_command
)
1119 return ERROR_COMMAND_SYNTAX_ERROR
;
1121 if (CMD_ARGC
== 1) {
1123 if (strcmp(CMD_ARGV
[0], "short") == 0)
1124 use_new_table
= true;
1125 else if (strcmp(CMD_ARGV
[0], "long") == 0)
1126 use_new_table
= false;
1128 return ERROR_COMMAND_SYNTAX_ERROR
;
1130 tap_use_new_tms_table(use_new_table
);
1133 command_print(CMD
, "tms sequence is %s",
1134 tap_uses_new_tms_table() ? "short" : "long");
1139 COMMAND_HANDLER(handle_jtag_flush_queue_sleep
)
1142 return ERROR_COMMAND_SYNTAX_ERROR
;
1145 COMMAND_PARSE_NUMBER(int, CMD_ARGV
[0], sleep_ms
);
1147 jtag_set_flush_queue_sleep(sleep_ms
);
1152 COMMAND_HANDLER(handle_wait_srst_deassert
)
1155 return ERROR_COMMAND_SYNTAX_ERROR
;
1158 COMMAND_PARSE_NUMBER(int, CMD_ARGV
[0], timeout_ms
);
1159 if ((timeout_ms
<= 0) || (timeout_ms
> 100000)) {
1160 LOG_ERROR("Timeout must be an integer between 0 and 100000");
1164 LOG_USER("Waiting for srst assert + deassert for at most %dms", timeout_ms
);
1166 int64_t then
= timeval_ms();
1167 while (jtag_srst_asserted(&asserted_yet
) == ERROR_OK
) {
1168 if ((timeval_ms() - then
) > timeout_ms
) {
1169 LOG_ERROR("Timed out");
1175 while (jtag_srst_asserted(&asserted_yet
) == ERROR_OK
) {
1176 if ((timeval_ms() - then
) > timeout_ms
) {
1177 LOG_ERROR("Timed out");
1187 static const struct command_registration jtag_command_handlers
[] = {
1190 .name
= "jtag_flush_queue_sleep",
1191 .handler
= handle_jtag_flush_queue_sleep
,
1192 .mode
= COMMAND_ANY
,
1193 .help
= "For debug purposes(simulate long delays of interface) "
1194 "to test performance or change in behavior. Default 0ms.",
1195 .usage
= "[sleep in ms]",
1198 .name
= "jtag_rclk",
1199 .handler
= handle_jtag_rclk_command
,
1200 .mode
= COMMAND_ANY
,
1201 .help
= "With an argument, change to to use adaptive clocking "
1202 "if possible; else to use the fallback speed. "
1203 "With or without argument, display current setting.",
1204 .usage
= "[fallback_speed_khz]",
1207 .name
= "jtag_ntrst_delay",
1208 .handler
= handle_jtag_ntrst_delay_command
,
1209 .mode
= COMMAND_ANY
,
1210 .help
= "delay after deasserting trst in ms",
1211 .usage
= "[milliseconds]",
1214 .name
= "jtag_ntrst_assert_width",
1215 .handler
= handle_jtag_ntrst_assert_width_command
,
1216 .mode
= COMMAND_ANY
,
1217 .help
= "delay after asserting trst in ms",
1218 .usage
= "[milliseconds]",
1221 .name
= "scan_chain",
1222 .handler
= handle_scan_chain_command
,
1223 .mode
= COMMAND_ANY
,
1224 .help
= "print current scan chain configuration",
1229 .handler
= handle_runtest_command
,
1230 .mode
= COMMAND_EXEC
,
1231 .help
= "Move to Run-Test/Idle, and issue TCK for num_cycles.",
1232 .usage
= "num_cycles"
1236 .handler
= handle_irscan_command
,
1237 .mode
= COMMAND_EXEC
,
1238 .help
= "Execute Instruction Register (IR) scan. The "
1239 "specified opcodes are put into each TAP's IR, "
1240 "and other TAPs are put in BYPASS.",
1241 .usage
= "[tap_name instruction]* ['-endstate' state_name]",
1244 .name
= "verify_ircapture",
1245 .handler
= handle_verify_ircapture_command
,
1246 .mode
= COMMAND_ANY
,
1247 .help
= "Display or assign flag controlling whether to "
1248 "verify values captured during Capture-IR.",
1249 .usage
= "['enable'|'disable']",
1252 .name
= "verify_jtag",
1253 .handler
= handle_verify_jtag_command
,
1254 .mode
= COMMAND_ANY
,
1255 .help
= "Display or assign flag controlling whether to "
1256 "verify values captured during IR and DR scans.",
1257 .usage
= "['enable'|'disable']",
1260 .name
= "tms_sequence",
1261 .handler
= handle_tms_sequence_command
,
1262 .mode
= COMMAND_ANY
,
1263 .help
= "Display or change what style TMS sequences to use "
1264 "for JTAG state transitions: short (default) or "
1265 "long. Only for working around JTAG bugs.",
1266 /* Specifically for working around DRIVER bugs... */
1267 .usage
= "['short'|'long']",
1270 .name
= "wait_srst_deassert",
1271 .handler
= handle_wait_srst_deassert
,
1272 .mode
= COMMAND_ANY
,
1273 .help
= "Wait for an SRST deassert. "
1274 "Useful for cases where you need something to happen within ms "
1275 "of an srst deassert. Timeout in ms",
1280 .mode
= COMMAND_ANY
,
1281 .help
= "perform jtag tap actions",
1284 .chain
= jtag_subcommand_handlers
,
1287 .chain
= jtag_command_handlers_to_move
,
1289 COMMAND_REGISTRATION_DONE
1292 int jtag_register_commands(struct command_context
*cmd_ctx
)
1294 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)