1 /***************************************************************************
2 * Copyright (C) 2005 by Dominic Rath *
3 * Dominic.Rath@gmx.de *
5 * Copyright (C) 2007-2010 Øyvind Harboe *
6 * oyvind.harboe@zylin.com *
8 * Copyright (C) 2009 SoftPLC Corporation *
12 * Copyright (C) 2009 Zachary T Welch *
13 * zw@superlucidity.net *
15 * This program is free software; you can redistribute it and/or modify *
16 * it under the terms of the GNU General Public License as published by *
17 * the Free Software Foundation; either version 2 of the License, or *
18 * (at your option) any later version. *
20 * This program is distributed in the hope that it will be useful, *
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
23 * GNU General Public License for more details. *
25 * You should have received a copy of the GNU General Public License *
26 * along with this program; if not, write to the *
27 * Free Software Foundation, Inc., *
28 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
29 ***************************************************************************/
35 #include "minidriver.h"
36 #include "interface.h"
37 #include "interfaces.h"
43 #include <helper/time_support.h>
47 * Holds support for accessing JTAG-specific mechanisms from TCl scripts.
50 static const Jim_Nvp nvp_jtag_tap_event
[] = {
51 { .value
= JTAG_TRST_ASSERTED
, .name
= "post-reset" },
52 { .value
= JTAG_TAP_EVENT_SETUP
, .name
= "setup" },
53 { .value
= JTAG_TAP_EVENT_ENABLE
, .name
= "tap-enable" },
54 { .value
= JTAG_TAP_EVENT_DISABLE
, .name
= "tap-disable" },
56 { .name
= NULL
, .value
= -1 }
59 extern struct jtag_interface
*jtag_interface
;
61 struct jtag_tap
*jtag_tap_by_jim_obj(Jim_Interp
*interp
, Jim_Obj
*o
)
63 const char *cp
= Jim_GetString(o
, NULL
);
64 struct jtag_tap
*t
= cp
? jtag_tap_by_string(cp
) : NULL
;
68 Jim_SetResultFormatted(interp
, "Tap '%s' could not be found", cp
);
72 static bool scan_is_safe(tap_state_t state
)
86 static int Jim_Command_drscan(Jim_Interp
*interp
, int argc
, Jim_Obj
*const *args
)
89 struct scan_field
*fields
;
98 * args[3] = hex string
99 * ... repeat num bits and hex string ...
102 * args[N-2] = "-endstate"
103 * args[N-1] = statename
105 if ((argc
< 4) || ((argc
% 2) != 0))
107 Jim_WrongNumArgs(interp
, 1, args
, "wrong arguments");
113 script_debug(interp
, "drscan", argc
, args
);
115 /* validate arguments as numbers */
117 for (i
= 2; i
< argc
; i
+= 2)
122 e
= Jim_GetLong(interp
, args
[i
], &bits
);
123 /* If valid - try next arg */
128 /* Not valid.. are we at the end? */
129 if (((i
+ 2) != argc
)) {
130 /* nope, then error */
134 /* it could be: "-endstate FOO"
135 * e.g. DRPAUSE so we can issue more instructions
136 * before entering RUN/IDLE and executing them.
139 /* get arg as a string. */
140 cp
= Jim_GetString(args
[i
], NULL
);
141 /* is it the magic? */
142 if (0 == strcmp("-endstate", cp
)) {
143 /* is the statename valid? */
144 cp
= Jim_GetString(args
[i
+ 1], NULL
);
146 /* see if it is a valid state name */
147 endstate
= tap_state_by_name(cp
);
149 /* update the error message */
150 Jim_SetResultFormatted(interp
,"endstate: %s invalid", cp
);
152 if (!scan_is_safe(endstate
))
153 LOG_WARNING("drscan with unsafe "
154 "endstate \"%s\"", cp
);
156 /* valid - so clear the error */
158 /* and remove the last 2 args */
163 /* Still an error? */
165 return e
; /* too bad */
167 } /* validate args */
169 tap
= jtag_tap_by_jim_obj(interp
, args
[1]);
174 num_fields
= (argc
-2)/2;
175 fields
= malloc(sizeof(struct scan_field
) * num_fields
);
176 for (i
= 2; i
< argc
; i
+= 2)
182 Jim_GetLong(interp
, args
[i
], &bits
);
183 str
= Jim_GetString(args
[i
+ 1], &len
);
185 fields
[field_count
].num_bits
= bits
;
186 void * t
= malloc(DIV_ROUND_UP(bits
, 8));
187 fields
[field_count
].out_value
= t
;
188 str_to_buf(str
, len
, t
, bits
, 0);
189 fields
[field_count
].in_value
= t
;
193 jtag_add_dr_scan(tap
, num_fields
, fields
, endstate
);
195 retval
= jtag_execute_queue();
196 if (retval
!= ERROR_OK
)
198 Jim_SetResultString(interp
, "drscan: jtag execute failed",-1);
203 Jim_Obj
*list
= Jim_NewListObj(interp
, NULL
, 0);
204 for (i
= 2; i
< argc
; i
+= 2)
209 Jim_GetLong(interp
, args
[i
], &bits
);
210 str
= buf_to_str(fields
[field_count
].in_value
, bits
, 16);
211 free((void *)fields
[field_count
].out_value
);
213 Jim_ListAppendElement(interp
, list
, Jim_NewStringObj(interp
, str
, strlen(str
)));
218 Jim_SetResult(interp
, list
);
226 static int Jim_Command_pathmove(Jim_Interp
*interp
, int argc
, Jim_Obj
*const *args
)
228 tap_state_t states
[8];
230 if ((argc
< 2) || ((size_t)argc
> (ARRAY_SIZE(states
) + 1)))
232 Jim_WrongNumArgs(interp
, 1, args
, "wrong arguments");
236 script_debug(interp
, "pathmove", argc
, args
);
239 for (i
= 0; i
< argc
-1; i
++)
242 cp
= Jim_GetString(args
[i
+ 1], NULL
);
243 states
[i
] = tap_state_by_name(cp
);
246 /* update the error message */
247 Jim_SetResultFormatted(interp
,"endstate: %s invalid", cp
);
252 if ((jtag_add_statemove(states
[0]) != ERROR_OK
) || (jtag_execute_queue()!= ERROR_OK
))
254 Jim_SetResultString(interp
, "pathmove: jtag execute failed",-1);
258 jtag_add_pathmove(argc
-2, states
+ 1);
260 if (jtag_execute_queue()!= ERROR_OK
)
262 Jim_SetResultString(interp
, "pathmove: failed",-1);
270 static int Jim_Command_flush_count(Jim_Interp
*interp
, int argc
, Jim_Obj
*const *args
)
272 script_debug(interp
, "flush_count", argc
, args
);
274 Jim_SetResult(interp
, Jim_NewIntObj(interp
, jtag_get_flush_queue_count()));
279 /* REVISIT Just what about these should "move" ... ?
280 * These registrations, into the main JTAG table?
282 * There's a minor compatibility issue, these all show up twice;
283 * that's not desirable:
284 * - jtag drscan ... NOT DOCUMENTED!
287 * The "irscan" command (for example) doesn't show twice.
289 static const struct command_registration jtag_command_handlers_to_move
[] = {
292 .mode
= COMMAND_EXEC
,
293 .jim_handler
= Jim_Command_drscan
,
294 .help
= "Execute Data Register (DR) scan for one TAP. "
295 "Other TAPs must be in BYPASS mode.",
296 .usage
= "tap_name [num_bits value]* ['-endstate' state_name]",
299 .name
= "flush_count",
300 .mode
= COMMAND_EXEC
,
301 .jim_handler
= Jim_Command_flush_count
,
302 .help
= "Returns the number of times the JTAG queue "
307 .mode
= COMMAND_EXEC
,
308 .jim_handler
= Jim_Command_pathmove
,
309 .usage
= "start_state state1 [state2 [state3 ...]]",
310 .help
= "Move JTAG state machine from current state "
311 "(start_state) to state1, then state2, state3, etc.",
313 COMMAND_REGISTRATION_DONE
317 enum jtag_tap_cfg_param
{
321 static Jim_Nvp nvp_config_opts
[] = {
322 { .name
= "-event", .value
= JCFG_EVENT
},
324 { .name
= NULL
, .value
= -1 }
327 static int jtag_tap_configure_event(Jim_GetOptInfo
*goi
, struct jtag_tap
* tap
)
331 Jim_WrongNumArgs(goi
->interp
, goi
->argc
, goi
->argv
, "-event <event-name> ...");
336 int e
= Jim_GetOpt_Nvp(goi
, nvp_jtag_tap_event
, &n
);
339 Jim_GetOpt_NvpUnknown(goi
, nvp_jtag_tap_event
, 1);
343 if (goi
->isconfigure
) {
344 if (goi
->argc
!= 1) {
345 Jim_WrongNumArgs(goi
->interp
, goi
->argc
, goi
->argv
, "-event <event-name> <event-body>");
349 if (goi
->argc
!= 0) {
350 Jim_WrongNumArgs(goi
->interp
, goi
->argc
, goi
->argv
, "-event <event-name>");
355 struct jtag_tap_event_action
*jteap
= tap
->event_action
;
356 /* replace existing event body */
360 if (jteap
->event
== (enum jtag_event
)n
->value
)
368 Jim_SetEmptyResult(goi
->interp
);
370 if (goi
->isconfigure
)
373 jteap
= calloc(1, sizeof(*jteap
));
374 else if (NULL
!= jteap
->body
)
375 Jim_DecrRefCount(goi
->interp
, jteap
->body
);
377 jteap
->interp
= goi
->interp
;
378 jteap
->event
= n
->value
;
381 Jim_GetOpt_Obj(goi
, &o
);
382 jteap
->body
= Jim_DuplicateObj(goi
->interp
, o
);
383 Jim_IncrRefCount(jteap
->body
);
387 /* add to head of event list */
388 jteap
->next
= tap
->event_action
;
389 tap
->event_action
= jteap
;
394 jteap
->interp
= goi
->interp
;
395 Jim_SetResult(goi
->interp
,
396 Jim_DuplicateObj(goi
->interp
, jteap
->body
));
401 static int jtag_tap_configure_cmd(Jim_GetOptInfo
*goi
, struct jtag_tap
* tap
)
403 /* parse config or cget options */
404 while (goi
->argc
> 0)
406 Jim_SetEmptyResult (goi
->interp
);
409 int e
= Jim_GetOpt_Nvp(goi
, nvp_config_opts
, &n
);
412 Jim_GetOpt_NvpUnknown(goi
, nvp_config_opts
, 0);
419 e
= jtag_tap_configure_event(goi
, tap
);
424 Jim_SetResultFormatted(goi
->interp
, "unknown event: %s", n
->name
);
432 static int is_bad_irval(int ir_length
, jim_wide w
)
442 static int jim_newtap_expected_id(Jim_Nvp
*n
, Jim_GetOptInfo
*goi
,
443 struct jtag_tap
*pTap
)
446 int e
= Jim_GetOpt_Wide(goi
, &w
);
448 Jim_SetResultFormatted(goi
->interp
, "option: %s bad parameter", n
->name
);
452 unsigned expected_len
= sizeof(uint32_t) * pTap
->expected_ids_cnt
;
453 uint32_t *new_expected_ids
= malloc(expected_len
+ sizeof(uint32_t));
454 if (new_expected_ids
== NULL
)
456 Jim_SetResultFormatted(goi
->interp
, "no memory");
460 memcpy(new_expected_ids
, pTap
->expected_ids
, expected_len
);
462 new_expected_ids
[pTap
->expected_ids_cnt
] = w
;
464 free(pTap
->expected_ids
);
465 pTap
->expected_ids
= new_expected_ids
;
466 pTap
->expected_ids_cnt
++;
471 #define NTAP_OPT_IRLEN 0
472 #define NTAP_OPT_IRMASK 1
473 #define NTAP_OPT_IRCAPTURE 2
474 #define NTAP_OPT_ENABLED 3
475 #define NTAP_OPT_DISABLED 4
476 #define NTAP_OPT_EXPECTED_ID 5
477 #define NTAP_OPT_VERSION 6
479 static int jim_newtap_ir_param(Jim_Nvp
*n
, Jim_GetOptInfo
*goi
,
480 struct jtag_tap
*pTap
)
483 int e
= Jim_GetOpt_Wide(goi
, &w
);
486 Jim_SetResultFormatted(goi
->interp
,
487 "option: %s bad parameter", n
->name
);
488 free((void *)pTap
->dotted_name
);
493 if (w
> (jim_wide
) (8 * sizeof(pTap
->ir_capture_value
)))
495 LOG_WARNING("%s: huge IR length %d",
496 pTap
->dotted_name
, (int) w
);
500 case NTAP_OPT_IRMASK
:
501 if (is_bad_irval(pTap
->ir_length
, w
))
503 LOG_ERROR("%s: IR mask %x too big",
509 LOG_WARNING("%s: nonstandard IR mask", pTap
->dotted_name
);
510 pTap
->ir_capture_mask
= w
;
512 case NTAP_OPT_IRCAPTURE
:
513 if (is_bad_irval(pTap
->ir_length
, w
))
515 LOG_ERROR("%s: IR capture %x too big",
516 pTap
->dotted_name
, (int) w
);
520 LOG_WARNING("%s: nonstandard IR value",
522 pTap
->ir_capture_value
= w
;
530 static int jim_newtap_cmd(Jim_GetOptInfo
*goi
)
532 struct jtag_tap
*pTap
;
537 const Jim_Nvp opts
[] = {
538 { .name
= "-irlen" , .value
= NTAP_OPT_IRLEN
},
539 { .name
= "-irmask" , .value
= NTAP_OPT_IRMASK
},
540 { .name
= "-ircapture" , .value
= NTAP_OPT_IRCAPTURE
},
541 { .name
= "-enable" , .value
= NTAP_OPT_ENABLED
},
542 { .name
= "-disable" , .value
= NTAP_OPT_DISABLED
},
543 { .name
= "-expected-id" , .value
= NTAP_OPT_EXPECTED_ID
},
544 { .name
= "-ignore-version" , .value
= NTAP_OPT_VERSION
},
545 { .name
= NULL
, .value
= -1 },
548 pTap
= calloc(1, sizeof(struct jtag_tap
));
550 Jim_SetResultFormatted(goi
->interp
, "no memory");
555 * we expect CHIP + TAP + OPTIONS
558 Jim_SetResultFormatted(goi
->interp
, "Missing CHIP TAP OPTIONS ....");
562 Jim_GetOpt_String(goi
, &cp
, NULL
);
563 pTap
->chip
= strdup(cp
);
565 Jim_GetOpt_String(goi
, &cp
, NULL
);
566 pTap
->tapname
= strdup(cp
);
568 /* name + dot + name + null */
569 x
= strlen(pTap
->chip
) + 1 + strlen(pTap
->tapname
) + 1;
571 sprintf(cp
, "%s.%s", pTap
->chip
, pTap
->tapname
);
572 pTap
->dotted_name
= cp
;
574 LOG_DEBUG("Creating New Tap, Chip: %s, Tap: %s, Dotted: %s, %d params",
575 pTap
->chip
, pTap
->tapname
, pTap
->dotted_name
, goi
->argc
);
577 /* IEEE specifies that the two LSBs of an IR scan are 01, so make
578 * that the default. The "-irlen" and "-irmask" options are only
579 * needed to cope with nonstandard TAPs, or to specify more bits.
581 pTap
->ir_capture_mask
= 0x03;
582 pTap
->ir_capture_value
= 0x01;
585 e
= Jim_GetOpt_Nvp(goi
, opts
, &n
);
587 Jim_GetOpt_NvpUnknown(goi
, opts
, 0);
588 free((void *)pTap
->dotted_name
);
592 LOG_DEBUG("Processing option: %s", n
->name
);
594 case NTAP_OPT_ENABLED
:
595 pTap
->disabled_after_reset
= false;
597 case NTAP_OPT_DISABLED
:
598 pTap
->disabled_after_reset
= true;
600 case NTAP_OPT_EXPECTED_ID
:
601 e
= jim_newtap_expected_id(n
, goi
, pTap
);
604 free((void *)pTap
->dotted_name
);
610 case NTAP_OPT_IRMASK
:
611 case NTAP_OPT_IRCAPTURE
:
612 e
= jim_newtap_ir_param(n
, goi
, pTap
);
615 free((void *)pTap
->dotted_name
);
620 case NTAP_OPT_VERSION
:
621 pTap
->ignore_version
= true;
623 } /* switch (n->value) */
624 } /* while (goi->argc) */
626 /* default is enabled-after-reset */
627 pTap
->enabled
= !pTap
->disabled_after_reset
;
629 /* Did all the required option bits get cleared? */
630 if (pTap
->ir_length
!= 0)
636 Jim_SetResultFormatted(goi
->interp
,
637 "newtap: %s missing IR length",
643 static void jtag_tap_handle_event(struct jtag_tap
*tap
, enum jtag_event e
)
645 struct jtag_tap_event_action
* jteap
;
647 for (jteap
= tap
->event_action
; jteap
!= NULL
; jteap
= jteap
->next
)
649 if (jteap
->event
!= e
)
652 Jim_Nvp
*nvp
= Jim_Nvp_value2name_simple(nvp_jtag_tap_event
, e
);
653 LOG_DEBUG("JTAG tap: %s event: %d (%s)\n\taction: %s",
654 tap
->dotted_name
, e
, nvp
->name
,
655 Jim_GetString(jteap
->body
, NULL
));
657 if (Jim_EvalObj(jteap
->interp
, jteap
->body
) != JIM_OK
)
659 Jim_MakeErrorMessage(jteap
->interp
);
660 LOG_USER("%s", Jim_GetString(Jim_GetResult(jteap
->interp
), NULL
));
666 case JTAG_TAP_EVENT_ENABLE
:
667 case JTAG_TAP_EVENT_DISABLE
:
668 /* NOTE: we currently assume the handlers
669 * can't fail. Right here is where we should
670 * really be verifying the scan chains ...
672 tap
->enabled
= (e
== JTAG_TAP_EVENT_ENABLE
);
673 LOG_INFO("JTAG tap: %s %s", tap
->dotted_name
,
674 tap
->enabled
? "enabled" : "disabled");
682 static int jim_jtag_arp_init(Jim_Interp
*interp
, int argc
, Jim_Obj
*const *argv
)
685 Jim_GetOpt_Setup(&goi
, interp
, argc
-1, argv
+ 1);
687 Jim_WrongNumArgs(goi
.interp
, 1, goi
.argv
-1, "(no params)");
690 struct command_context
*context
= current_command_context(interp
);
691 int e
= jtag_init_inner(context
);
693 Jim_Obj
*eObj
= Jim_NewIntObj(goi
.interp
, e
);
694 Jim_SetResultFormatted(goi
.interp
, "error: %#s", eObj
);
695 Jim_FreeNewObj(goi
.interp
, eObj
);
701 static int jim_jtag_arp_init_reset(Jim_Interp
*interp
, int argc
, Jim_Obj
*const *argv
)
704 Jim_GetOpt_Setup(&goi
, interp
, argc
-1, argv
+ 1);
706 Jim_WrongNumArgs(goi
.interp
, 1, goi
.argv
-1, "(no params)");
709 struct command_context
*context
= current_command_context(interp
);
710 int e
= jtag_init_reset(context
);
712 Jim_Obj
*eObj
= Jim_NewIntObj(goi
.interp
, e
);
713 Jim_SetResultFormatted(goi
.interp
, "error: %#s", eObj
);
714 Jim_FreeNewObj(goi
.interp
, eObj
);
720 int jim_jtag_newtap(Jim_Interp
*interp
, int argc
, Jim_Obj
*const *argv
)
723 Jim_GetOpt_Setup(&goi
, interp
, argc
-1, argv
+ 1);
724 return jim_newtap_cmd(&goi
);
727 static bool jtag_tap_enable(struct jtag_tap
*t
)
731 jtag_tap_handle_event(t
, JTAG_TAP_EVENT_ENABLE
);
735 /* FIXME add JTAG sanity checks, w/o TLR
736 * - scan chain length grew by one (this)
737 * - IDs and IR lengths are as expected
739 jtag_call_event_callbacks(JTAG_TAP_EVENT_ENABLE
);
742 static bool jtag_tap_disable(struct jtag_tap
*t
)
746 jtag_tap_handle_event(t
, JTAG_TAP_EVENT_DISABLE
);
750 /* FIXME add JTAG sanity checks, w/o TLR
751 * - scan chain length shrank by one (this)
752 * - IDs and IR lengths are as expected
754 jtag_call_event_callbacks(JTAG_TAP_EVENT_DISABLE
);
758 static int jim_jtag_tap_enabler(Jim_Interp
*interp
, int argc
, Jim_Obj
*const *argv
)
760 const char *cmd_name
= Jim_GetString(argv
[0], NULL
);
762 Jim_GetOpt_Setup(&goi
, interp
, argc
-1, argv
+ 1);
764 Jim_SetResultFormatted(goi
.interp
, "usage: %s <name>", cmd_name
);
770 t
= jtag_tap_by_jim_obj(goi
.interp
, goi
.argv
[0]);
774 if (strcasecmp(cmd_name
, "tapisenabled") == 0) {
775 // do nothing, just return the value
776 } else if (strcasecmp(cmd_name
, "tapenable") == 0) {
777 if (!jtag_tap_enable(t
)){
778 LOG_WARNING("failed to enable tap %s", t
->dotted_name
);
781 } else if (strcasecmp(cmd_name
, "tapdisable") == 0) {
782 if (!jtag_tap_disable(t
)){
783 LOG_WARNING("failed to disable tap %s", t
->dotted_name
);
787 LOG_ERROR("command '%s' unknown", cmd_name
);
791 Jim_SetResult(goi
.interp
, Jim_NewIntObj(goi
.interp
, e
));
795 static int jim_jtag_configure(Jim_Interp
*interp
, int argc
, Jim_Obj
*const *argv
)
797 const char *cmd_name
= Jim_GetString(argv
[0], NULL
);
799 Jim_GetOpt_Setup(&goi
, interp
, argc
-1, argv
+ 1);
800 goi
.isconfigure
= !strcmp(cmd_name
, "configure");
801 if (goi
.argc
< 2 + goi
.isconfigure
) {
802 Jim_WrongNumArgs(goi
.interp
, 0, NULL
,
803 "<tap_name> <attribute> ...");
810 Jim_GetOpt_Obj(&goi
, &o
);
811 t
= jtag_tap_by_jim_obj(goi
.interp
, o
);
816 return jtag_tap_configure_cmd(&goi
, t
);
819 static int jim_jtag_names(Jim_Interp
*interp
, int argc
, Jim_Obj
*const *argv
)
822 Jim_GetOpt_Setup(&goi
, interp
, argc
-1, argv
+ 1);
824 Jim_WrongNumArgs(goi
.interp
, 1, goi
.argv
, "Too many parameters");
827 Jim_SetResult(goi
.interp
, Jim_NewListObj(goi
.interp
, NULL
, 0));
828 struct jtag_tap
*tap
;
830 for (tap
= jtag_all_taps(); tap
; tap
= tap
->next_tap
) {
831 Jim_ListAppendElement(goi
.interp
,
832 Jim_GetResult(goi
.interp
),
833 Jim_NewStringObj(goi
.interp
,
834 tap
->dotted_name
, -1));
839 COMMAND_HANDLER(handle_jtag_init_command
)
842 return ERROR_COMMAND_SYNTAX_ERROR
;
844 static bool jtag_initialized
= false;
845 if (jtag_initialized
)
847 LOG_INFO("'jtag init' has already been called");
850 jtag_initialized
= true;
852 LOG_DEBUG("Initializing jtag devices...");
853 return jtag_init(CMD_CTX
);
856 static const struct command_registration jtag_subcommand_handlers
[] = {
860 .handler
= handle_jtag_init_command
,
861 .help
= "initialize jtag scan chain",
866 .jim_handler
= jim_jtag_arp_init
,
867 .help
= "Validates JTAG scan chain against the list of "
868 "declared TAPs using just the four standard JTAG "
872 .name
= "arp_init-reset",
874 .jim_handler
= jim_jtag_arp_init_reset
,
875 .help
= "Uses TRST and SRST to try resetting everything on "
876 "the JTAG scan chain, then performs 'jtag arp_init'."
880 .mode
= COMMAND_CONFIG
,
881 .jim_handler
= jim_jtag_newtap
,
882 .help
= "Create a new TAP instance named basename.tap_type, "
883 "and appends it to the scan chain.",
884 .usage
= "basename tap_type '-irlen' count "
885 "['-enable'|'-disable'] "
886 "['-expected_id' number] "
887 "['-ignore-version'] "
888 "['-ircapture' number] "
892 .name
= "tapisenabled",
893 .mode
= COMMAND_EXEC
,
894 .jim_handler
= jim_jtag_tap_enabler
,
895 .help
= "Returns a Tcl boolean (0/1) indicating whether "
896 "the TAP is enabled (1) or not (0).",
901 .mode
= COMMAND_EXEC
,
902 .jim_handler
= jim_jtag_tap_enabler
,
903 .help
= "Try to enable the specified TAP using the "
904 "'tap-enable' TAP event.",
908 .name
= "tapdisable",
909 .mode
= COMMAND_EXEC
,
910 .jim_handler
= jim_jtag_tap_enabler
,
911 .help
= "Try to disable the specified TAP using the "
912 "'tap-disable' TAP event.",
917 .mode
= COMMAND_EXEC
,
918 .jim_handler
= jim_jtag_configure
,
919 .help
= "Provide a Tcl handler for the specified "
921 .usage
= "tap_name '-event' event_name handler",
925 .mode
= COMMAND_EXEC
,
926 .jim_handler
= jim_jtag_configure
,
927 .help
= "Return any Tcl handler for the specified "
929 .usage
= "tap_name '-event' event_name",
934 .jim_handler
= jim_jtag_names
,
935 .help
= "Returns list of all JTAG tap names.",
938 .chain
= jtag_command_handlers_to_move
,
940 COMMAND_REGISTRATION_DONE
943 void jtag_notify_event(enum jtag_event event
)
945 struct jtag_tap
*tap
;
947 for (tap
= jtag_all_taps(); tap
; tap
= tap
->next_tap
)
948 jtag_tap_handle_event(tap
, event
);
952 COMMAND_HANDLER(handle_scan_chain_command
)
954 struct jtag_tap
*tap
;
955 char expected_id
[12];
957 tap
= jtag_all_taps();
958 command_print(CMD_CTX
,
959 " TapName Enabled IdCode Expected IrLen IrCap IrMask");
960 command_print(CMD_CTX
,
961 "-- ------------------- -------- ---------- ---------- ----- ----- ------");
964 uint32_t expected
, expected_mask
, ii
;
966 snprintf(expected_id
, sizeof expected_id
, "0x%08x",
967 (unsigned)((tap
->expected_ids_cnt
> 0)
968 ? tap
->expected_ids
[0]
970 if (tap
->ignore_version
)
971 expected_id
[2] = '*';
973 expected
= buf_get_u32(tap
->expected
, 0, tap
->ir_length
);
974 expected_mask
= buf_get_u32(tap
->expected_mask
, 0, tap
->ir_length
);
976 command_print(CMD_CTX
,
977 "%2d %-18s %c 0x%08x %s %5d 0x%02x 0x%02x",
978 tap
->abs_chain_position
,
980 tap
->enabled
? 'Y' : 'n',
981 (unsigned int)(tap
->idcode
),
983 (unsigned int)(tap
->ir_length
),
984 (unsigned int)(expected
),
985 (unsigned int)(expected_mask
));
987 for (ii
= 1; ii
< tap
->expected_ids_cnt
; ii
++) {
988 snprintf(expected_id
, sizeof expected_id
, "0x%08x",
989 (unsigned) tap
->expected_ids
[1]);
990 if (tap
->ignore_version
)
991 expected_id
[2] = '*';
993 command_print(CMD_CTX
,
1004 COMMAND_HANDLER(handle_jtag_ntrst_delay_command
)
1007 return ERROR_COMMAND_SYNTAX_ERROR
;
1011 COMMAND_PARSE_NUMBER(uint
, CMD_ARGV
[0], delay
);
1013 jtag_set_ntrst_delay(delay
);
1015 command_print(CMD_CTX
, "jtag_ntrst_delay: %u", jtag_get_ntrst_delay());
1019 COMMAND_HANDLER(handle_jtag_ntrst_assert_width_command
)
1022 return ERROR_COMMAND_SYNTAX_ERROR
;
1026 COMMAND_PARSE_NUMBER(uint
, CMD_ARGV
[0], delay
);
1028 jtag_set_ntrst_assert_width(delay
);
1030 command_print(CMD_CTX
, "jtag_ntrst_assert_width: %u", jtag_get_ntrst_assert_width());
1034 COMMAND_HANDLER(handle_jtag_rclk_command
)
1037 return ERROR_COMMAND_SYNTAX_ERROR
;
1039 int retval
= ERROR_OK
;
1043 COMMAND_PARSE_NUMBER(uint
, CMD_ARGV
[0], khz
);
1045 retval
= jtag_config_rclk(khz
);
1046 if (ERROR_OK
!= retval
)
1050 int cur_khz
= jtag_get_speed_khz();
1051 retval
= jtag_get_speed_readable(&cur_khz
);
1052 if (ERROR_OK
!= retval
)
1056 command_print(CMD_CTX
, "RCLK not supported - fallback to %d kHz", cur_khz
);
1058 command_print(CMD_CTX
, "RCLK - adaptive");
1063 COMMAND_HANDLER(handle_jtag_reset_command
)
1066 return ERROR_COMMAND_SYNTAX_ERROR
;
1069 if (CMD_ARGV
[0][0] == '1')
1071 else if (CMD_ARGV
[0][0] == '0')
1074 return ERROR_COMMAND_SYNTAX_ERROR
;
1077 if (CMD_ARGV
[1][0] == '1')
1079 else if (CMD_ARGV
[1][0] == '0')
1082 return ERROR_COMMAND_SYNTAX_ERROR
;
1084 if (adapter_init(CMD_CTX
) != ERROR_OK
)
1085 return ERROR_JTAG_INIT_FAILED
;
1087 jtag_add_reset(trst
, srst
);
1088 return jtag_execute_queue();
1091 COMMAND_HANDLER(handle_runtest_command
)
1094 return ERROR_COMMAND_SYNTAX_ERROR
;
1096 unsigned num_clocks
;
1097 COMMAND_PARSE_NUMBER(uint
, CMD_ARGV
[0], num_clocks
);
1099 jtag_add_runtest(num_clocks
, TAP_IDLE
);
1100 return jtag_execute_queue();
1104 * For "irscan" or "drscan" commands, the "end" (really, "next") state
1105 * should be stable ... and *NOT* a shift state, otherwise free-running
1106 * jtag clocks could change the values latched by the update state.
1107 * Not surprisingly, this is the same constraint as SVF; the "irscan"
1108 * and "drscan" commands are a write-only subset of what SVF provides.
1111 COMMAND_HANDLER(handle_irscan_command
)
1114 struct scan_field
*fields
;
1115 struct jtag_tap
*tap
= NULL
;
1116 tap_state_t endstate
;
1118 if ((CMD_ARGC
< 2) || (CMD_ARGC
% 2))
1120 return ERROR_COMMAND_SYNTAX_ERROR
;
1123 /* optional "-endstate" "statename" at the end of the arguments,
1124 * so that e.g. IRPAUSE can let us load the data register before
1125 * entering RUN/IDLE to execute the instruction we load here.
1127 endstate
= TAP_IDLE
;
1129 if (CMD_ARGC
>= 4) {
1130 /* have at least one pair of numbers. */
1131 /* is last pair the magic text? */
1132 if (strcmp("-endstate", CMD_ARGV
[CMD_ARGC
- 2]) == 0) {
1133 endstate
= tap_state_by_name(CMD_ARGV
[CMD_ARGC
- 1]);
1134 if (endstate
== TAP_INVALID
)
1135 return ERROR_COMMAND_SYNTAX_ERROR
;
1136 if (!scan_is_safe(endstate
))
1137 LOG_WARNING("unstable irscan endstate \"%s\"",
1138 CMD_ARGV
[CMD_ARGC
- 1]);
1143 int num_fields
= CMD_ARGC
/ 2;
1146 /* we really should be looking at plain_ir_scan if we want
1147 * anything more fancy.
1149 LOG_ERROR("Specify a single value for tap");
1150 return ERROR_COMMAND_SYNTAX_ERROR
;
1153 size_t fields_len
= sizeof(struct scan_field
) * num_fields
;
1154 fields
= malloc(fields_len
);
1155 memset(fields
, 0, fields_len
);
1158 for (i
= 0; i
< num_fields
; i
++)
1160 tap
= jtag_tap_by_string(CMD_ARGV
[i
*2]);
1164 for (j
= 0; j
< i
; j
++)
1165 free((void *)fields
[j
].out_value
);
1167 command_print(CMD_CTX
, "Tap: %s unknown", CMD_ARGV
[i
*2]);
1171 int field_size
= tap
->ir_length
;
1172 fields
[i
].num_bits
= field_size
;
1173 fields
[i
].out_value
= malloc(DIV_ROUND_UP(field_size
, 8));
1176 retval
= parse_u32(CMD_ARGV
[i
* 2 + 1], &value
);
1177 if (ERROR_OK
!= retval
)
1179 void *v
= (void *)fields
[i
].out_value
;
1180 buf_set_u32(v
, 0, field_size
, value
);
1181 fields
[i
].in_value
= NULL
;
1184 /* did we have an endstate? */
1185 jtag_add_ir_scan(tap
, fields
, endstate
);
1187 retval
= jtag_execute_queue();
1190 for (i
= 0; i
< num_fields
; i
++)
1192 if (NULL
!= fields
[i
].out_value
)
1193 free((void *)fields
[i
].out_value
);
1202 COMMAND_HANDLER(handle_verify_ircapture_command
)
1205 return ERROR_COMMAND_SYNTAX_ERROR
;
1210 COMMAND_PARSE_ENABLE(CMD_ARGV
[0], enable
);
1211 jtag_set_verify_capture_ir(enable
);
1214 const char *status
= jtag_will_verify_capture_ir() ? "enabled": "disabled";
1215 command_print(CMD_CTX
, "verify Capture-IR is %s", status
);
1220 COMMAND_HANDLER(handle_verify_jtag_command
)
1223 return ERROR_COMMAND_SYNTAX_ERROR
;
1228 COMMAND_PARSE_ENABLE(CMD_ARGV
[0], enable
);
1229 jtag_set_verify(enable
);
1232 const char *status
= jtag_will_verify() ? "enabled": "disabled";
1233 command_print(CMD_CTX
, "verify jtag capture is %s", status
);
1238 COMMAND_HANDLER(handle_tms_sequence_command
)
1241 return ERROR_COMMAND_SYNTAX_ERROR
;
1246 if (strcmp(CMD_ARGV
[0], "short") == 0)
1247 use_new_table
= true;
1248 else if (strcmp(CMD_ARGV
[0], "long") == 0)
1249 use_new_table
= false;
1251 return ERROR_COMMAND_SYNTAX_ERROR
;
1253 tap_use_new_tms_table(use_new_table
);
1256 command_print(CMD_CTX
, "tms sequence is %s",
1257 tap_uses_new_tms_table() ? "short": "long");
1262 COMMAND_HANDLER(handle_jtag_flush_queue_sleep
)
1265 return ERROR_COMMAND_SYNTAX_ERROR
;
1268 COMMAND_PARSE_NUMBER(int, CMD_ARGV
[0], sleep_ms
);
1270 jtag_set_flush_queue_sleep(sleep_ms
);
1275 COMMAND_HANDLER(handle_wait_srst_deassert
)
1278 return ERROR_COMMAND_SYNTAX_ERROR
;
1281 COMMAND_PARSE_NUMBER(int, CMD_ARGV
[0], timeout_ms
);
1282 if ((timeout_ms
<= 0) || (timeout_ms
> 100000))
1284 LOG_ERROR("Timeout must be an integer between 0 and 100000");
1288 LOG_USER("Waiting for srst assert + deassert for at most %dms", timeout_ms
);
1290 long long then
= timeval_ms();
1291 while (jtag_srst_asserted(&asserted_yet
) == ERROR_OK
)
1293 if ((timeval_ms() - then
) > timeout_ms
)
1295 LOG_ERROR("Timed out");
1301 while (jtag_srst_asserted(&asserted_yet
) == ERROR_OK
)
1303 if ((timeval_ms() - then
) > timeout_ms
)
1305 LOG_ERROR("Timed out");
1317 static const struct command_registration jtag_command_handlers
[] = {
1320 .name
= "jtag_flush_queue_sleep",
1321 .handler
= handle_jtag_flush_queue_sleep
,
1322 .mode
= COMMAND_ANY
,
1323 .help
= "For debug purposes(simulate long delays of interface) "
1324 "to test performance or change in behavior. Default 0ms.",
1325 .usage
= "[sleep in ms]",
1328 .name
= "jtag_rclk",
1329 .handler
= handle_jtag_rclk_command
,
1330 .mode
= COMMAND_ANY
,
1331 .help
= "With an argument, change to to use adaptive clocking "
1332 "if possible; else to use the fallback speed. "
1333 "With or without argument, display current setting.",
1334 .usage
= "[fallback_speed_khz]",
1337 .name
= "jtag_ntrst_delay",
1338 .handler
= handle_jtag_ntrst_delay_command
,
1339 .mode
= COMMAND_ANY
,
1340 .help
= "delay after deasserting trst in ms",
1341 .usage
= "[milliseconds]",
1344 .name
= "jtag_ntrst_assert_width",
1345 .handler
= handle_jtag_ntrst_assert_width_command
,
1346 .mode
= COMMAND_ANY
,
1347 .help
= "delay after asserting trst in ms",
1348 .usage
= "[milliseconds]",
1351 .name
= "scan_chain",
1352 .handler
= handle_scan_chain_command
,
1353 .mode
= COMMAND_ANY
,
1354 .help
= "print current scan chain configuration",
1357 .name
= "jtag_reset",
1358 .handler
= handle_jtag_reset_command
,
1359 .mode
= COMMAND_EXEC
,
1360 .help
= "Set reset line values. Value '1' is active, "
1361 "value '0' is inactive.",
1362 .usage
= "trst_active srst_active",
1366 .handler
= handle_runtest_command
,
1367 .mode
= COMMAND_EXEC
,
1368 .help
= "Move to Run-Test/Idle, and issue TCK for num_cycles.",
1369 .usage
= "num_cycles"
1373 .handler
= handle_irscan_command
,
1374 .mode
= COMMAND_EXEC
,
1375 .help
= "Execute Instruction Register (DR) scan. The "
1376 "specified opcodes are put into each TAP's IR, "
1377 "and other TAPs are put in BYPASS.",
1378 .usage
= "[tap_name instruction]* ['-endstate' state_name]",
1381 .name
= "verify_ircapture",
1382 .handler
= handle_verify_ircapture_command
,
1383 .mode
= COMMAND_ANY
,
1384 .help
= "Display or assign flag controlling whether to "
1385 "verify values captured during Capture-IR.",
1386 .usage
= "['enable'|'disable']",
1389 .name
= "verify_jtag",
1390 .handler
= handle_verify_jtag_command
,
1391 .mode
= COMMAND_ANY
,
1392 .help
= "Display or assign flag controlling whether to "
1393 "verify values captured during IR and DR scans.",
1394 .usage
= "['enable'|'disable']",
1397 .name
= "tms_sequence",
1398 .handler
= handle_tms_sequence_command
,
1399 .mode
= COMMAND_ANY
,
1400 .help
= "Display or change what style TMS sequences to use "
1401 "for JTAG state transitions: short (default) or "
1402 "long. Only for working around JTAG bugs.",
1403 /* Specifically for working around DRIVER bugs... */
1404 .usage
= "['short'|'long']",
1407 .name
= "wait_srst_deassert",
1408 .handler
= handle_wait_srst_deassert
,
1409 .mode
= COMMAND_ANY
,
1410 .help
= "Wait for an SRST deassert. "
1411 "Useful for cases where you need something to happen within ms "
1412 "of an srst deassert. Timeout in ms ",
1417 .mode
= COMMAND_ANY
,
1418 .help
= "perform jtag tap actions",
1420 .chain
= jtag_subcommand_handlers
,
1423 .chain
= jtag_command_handlers_to_move
,
1425 COMMAND_REGISTRATION_DONE
1428 int jtag_register_commands(struct command_context
*cmd_ctx
)
1430 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)