1 /***************************************************************************
2 * Copyright (C) 2005 by Dominic Rath *
3 * Dominic.Rath@gmx.de *
5 * Copyright (C) 2007,2008 Ø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 static const Jim_Nvp nvp_jtag_tap_event
[] = {
44 { .value
= JTAG_TRST_ASSERTED
, .name
= "post-reset" },
45 { .value
= JTAG_TAP_EVENT_SETUP
, .name
= "setup" },
46 { .value
= JTAG_TAP_EVENT_ENABLE
, .name
= "tap-enable" },
47 { .value
= JTAG_TAP_EVENT_DISABLE
, .name
= "tap-disable" },
49 { .name
= NULL
, .value
= -1 }
52 extern struct jtag_interface
*jtag_interface
;
54 struct jtag_tap
*jtag_tap_by_jim_obj(Jim_Interp
*interp
, Jim_Obj
*o
)
56 const char *cp
= Jim_GetString(o
, NULL
);
57 struct jtag_tap
*t
= cp
? jtag_tap_by_string(cp
) : NULL
;
61 Jim_SetResult_sprintf(interp
, "Tap '%s' could not be found", cp
);
65 static bool scan_is_safe(tap_state_t state
)
79 static int Jim_Command_drscan(Jim_Interp
*interp
, int argc
, Jim_Obj
*const *args
)
82 struct scan_field
*fields
;
91 * args[3] = hex string
92 * ... repeat num bits and hex string ...
95 * args[N-2] = "-endstate"
96 * args[N-1] = statename
98 if ((argc
< 4) || ((argc
% 2) != 0))
100 Jim_WrongNumArgs(interp
, 1, args
, "wrong arguments");
106 script_debug(interp
, "drscan", argc
, args
);
108 /* validate arguments as numbers */
110 for (i
= 2; i
< argc
; i
+= 2)
115 e
= Jim_GetLong(interp
, args
[i
], &bits
);
116 /* If valid - try next arg */
121 /* Not valid.. are we at the end? */
122 if (((i
+ 2) != argc
)) {
123 /* nope, then error */
127 /* it could be: "-endstate FOO"
128 * e.g. DRPAUSE so we can issue more instructions
129 * before entering RUN/IDLE and executing them.
132 /* get arg as a string. */
133 cp
= Jim_GetString(args
[i
], NULL
);
134 /* is it the magic? */
135 if (0 == strcmp("-endstate", cp
)) {
136 /* is the statename valid? */
137 cp
= Jim_GetString(args
[i
+ 1], NULL
);
139 /* see if it is a valid state name */
140 endstate
= tap_state_by_name(cp
);
142 /* update the error message */
143 Jim_SetResult_sprintf(interp
,"endstate: %s invalid", cp
);
145 if (!scan_is_safe(endstate
))
146 LOG_WARNING("drscan with unsafe "
147 "endstate \"%s\"", cp
);
149 /* valid - so clear the error */
151 /* and remove the last 2 args */
156 /* Still an error? */
158 return e
; /* too bad */
160 } /* validate args */
162 tap
= jtag_tap_by_jim_obj(interp
, args
[1]);
167 num_fields
= (argc
-2)/2;
168 fields
= malloc(sizeof(struct scan_field
) * num_fields
);
169 for (i
= 2; i
< argc
; i
+= 2)
175 Jim_GetLong(interp
, args
[i
], &bits
);
176 str
= Jim_GetString(args
[i
+ 1], &len
);
178 fields
[field_count
].tap
= tap
;
179 fields
[field_count
].num_bits
= bits
;
180 fields
[field_count
].out_value
= malloc(DIV_ROUND_UP(bits
, 8));
181 str_to_buf(str
, len
, fields
[field_count
].out_value
, bits
, 0);
182 fields
[field_count
].in_value
= fields
[field_count
].out_value
;
186 jtag_add_dr_scan(num_fields
, fields
, endstate
);
188 retval
= jtag_execute_queue();
189 if (retval
!= ERROR_OK
)
191 Jim_SetResultString(interp
, "drscan: jtag execute failed",-1);
196 Jim_Obj
*list
= Jim_NewListObj(interp
, NULL
, 0);
197 for (i
= 2; i
< argc
; i
+= 2)
202 Jim_GetLong(interp
, args
[i
], &bits
);
203 str
= buf_to_str(fields
[field_count
].in_value
, bits
, 16);
204 free(fields
[field_count
].out_value
);
206 Jim_ListAppendElement(interp
, list
, Jim_NewStringObj(interp
, str
, strlen(str
)));
211 Jim_SetResult(interp
, list
);
219 static int Jim_Command_pathmove(Jim_Interp
*interp
, int argc
, Jim_Obj
*const *args
)
221 tap_state_t states
[8];
223 if ((argc
< 2) || ((size_t)argc
> (ARRAY_SIZE(states
) + 1)))
225 Jim_WrongNumArgs(interp
, 1, args
, "wrong arguments");
229 script_debug(interp
, "pathmove", argc
, args
);
232 for (i
= 0; i
< argc
-1; i
++)
235 cp
= Jim_GetString(args
[i
+ 1], NULL
);
236 states
[i
] = tap_state_by_name(cp
);
239 /* update the error message */
240 Jim_SetResult_sprintf(interp
,"endstate: %s invalid", cp
);
245 if ((jtag_add_statemove(states
[0]) != ERROR_OK
) || (jtag_execute_queue()!= ERROR_OK
))
247 Jim_SetResultString(interp
, "pathmove: jtag execute failed",-1);
251 jtag_add_pathmove(argc
-2, states
+ 1);
253 if (jtag_execute_queue()!= ERROR_OK
)
255 Jim_SetResultString(interp
, "pathmove: failed",-1);
263 static int Jim_Command_flush_count(Jim_Interp
*interp
, int argc
, Jim_Obj
*const *args
)
265 script_debug(interp
, "flush_count", argc
, args
);
267 Jim_SetResult(interp
, Jim_NewIntObj(interp
, jtag_get_flush_queue_count()));
272 static const struct command_registration jtag_command_handlers_to_move
[] = {
275 .mode
= COMMAND_EXEC
,
276 .jim_handler
= &Jim_Command_drscan
,
277 .help
= "execute DR scan <device> "
278 "<num_bits> <value> <num_bits1> <value2> ...",
281 .name
= "flush_count",
282 .mode
= COMMAND_EXEC
,
283 .jim_handler
= &Jim_Command_flush_count
,
284 .help
= "returns number of times the JTAG queue has been flushed",
288 .mode
= COMMAND_EXEC
,
289 .jim_handler
= &Jim_Command_pathmove
,
290 .usage
= "<state1>,<state2>,<state3>... ",
291 .help
= "move JTAG to state1 then to state2, state3, etc.",
293 COMMAND_REGISTRATION_DONE
297 enum jtag_tap_cfg_param
{
301 static Jim_Nvp nvp_config_opts
[] = {
302 { .name
= "-event", .value
= JCFG_EVENT
},
304 { .name
= NULL
, .value
= -1 }
307 static int jtag_tap_configure_event(Jim_GetOptInfo
*goi
, struct jtag_tap
* tap
)
311 Jim_WrongNumArgs(goi
->interp
, goi
->argc
, goi
->argv
, "-event <event-name> ...");
316 int e
= Jim_GetOpt_Nvp(goi
, nvp_jtag_tap_event
, &n
);
319 Jim_GetOpt_NvpUnknown(goi
, nvp_jtag_tap_event
, 1);
323 if (goi
->isconfigure
) {
324 if (goi
->argc
!= 1) {
325 Jim_WrongNumArgs(goi
->interp
, goi
->argc
, goi
->argv
, "-event <event-name> <event-body>");
329 if (goi
->argc
!= 0) {
330 Jim_WrongNumArgs(goi
->interp
, goi
->argc
, goi
->argv
, "-event <event-name>");
335 struct jtag_tap_event_action
*jteap
= tap
->event_action
;
336 /* replace existing event body */
340 if (jteap
->event
== (enum jtag_event
)n
->value
)
348 Jim_SetEmptyResult(goi
->interp
);
350 if (goi
->isconfigure
)
353 jteap
= calloc(1, sizeof(*jteap
));
354 else if (NULL
!= jteap
->body
)
355 Jim_DecrRefCount(goi
->interp
, jteap
->body
);
357 jteap
->interp
= goi
->interp
;
358 jteap
->event
= n
->value
;
361 Jim_GetOpt_Obj(goi
, &o
);
362 jteap
->body
= Jim_DuplicateObj(goi
->interp
, o
);
363 Jim_IncrRefCount(jteap
->body
);
367 /* add to head of event list */
368 jteap
->next
= tap
->event_action
;
369 tap
->event_action
= jteap
;
374 jteap
->interp
= goi
->interp
;
375 Jim_SetResult(goi
->interp
,
376 Jim_DuplicateObj(goi
->interp
, jteap
->body
));
381 static int jtag_tap_configure_cmd(Jim_GetOptInfo
*goi
, struct jtag_tap
* tap
)
383 /* parse config or cget options */
384 while (goi
->argc
> 0)
386 Jim_SetEmptyResult (goi
->interp
);
389 int e
= Jim_GetOpt_Nvp(goi
, nvp_config_opts
, &n
);
392 Jim_GetOpt_NvpUnknown(goi
, nvp_config_opts
, 0);
399 e
= jtag_tap_configure_event(goi
, tap
);
404 Jim_SetResult_sprintf(goi
->interp
, "unknown event: %s", n
->name
);
412 static int is_bad_irval(int ir_length
, jim_wide w
)
422 static int jim_newtap_expected_id(Jim_Nvp
*n
, Jim_GetOptInfo
*goi
,
423 struct jtag_tap
*pTap
)
426 int e
= Jim_GetOpt_Wide(goi
, &w
);
428 Jim_SetResult_sprintf(goi
->interp
, "option: %s bad parameter", n
->name
);
432 unsigned expected_len
= sizeof(uint32_t) * pTap
->expected_ids_cnt
;
433 uint32_t *new_expected_ids
= malloc(expected_len
+ sizeof(uint32_t));
434 if (new_expected_ids
== NULL
)
436 Jim_SetResult_sprintf(goi
->interp
, "no memory");
440 memcpy(new_expected_ids
, pTap
->expected_ids
, expected_len
);
442 new_expected_ids
[pTap
->expected_ids_cnt
] = w
;
444 free(pTap
->expected_ids
);
445 pTap
->expected_ids
= new_expected_ids
;
446 pTap
->expected_ids_cnt
++;
451 #define NTAP_OPT_IRLEN 0
452 #define NTAP_OPT_IRMASK 1
453 #define NTAP_OPT_IRCAPTURE 2
454 #define NTAP_OPT_ENABLED 3
455 #define NTAP_OPT_DISABLED 4
456 #define NTAP_OPT_EXPECTED_ID 5
457 #define NTAP_OPT_VERSION 6
459 static int jim_newtap_ir_param(Jim_Nvp
*n
, Jim_GetOptInfo
*goi
,
460 struct jtag_tap
*pTap
)
463 int e
= Jim_GetOpt_Wide(goi
, &w
);
466 Jim_SetResult_sprintf(goi
->interp
,
467 "option: %s bad parameter", n
->name
);
468 free((void *)pTap
->dotted_name
);
473 if (w
> (jim_wide
) (8 * sizeof(pTap
->ir_capture_value
)))
475 LOG_WARNING("%s: huge IR length %d",
476 pTap
->dotted_name
, (int) w
);
480 case NTAP_OPT_IRMASK
:
481 if (is_bad_irval(pTap
->ir_length
, w
))
483 LOG_ERROR("%s: IR mask %x too big",
489 LOG_WARNING("%s: nonstandard IR mask", pTap
->dotted_name
);
490 pTap
->ir_capture_mask
= w
;
492 case NTAP_OPT_IRCAPTURE
:
493 if (is_bad_irval(pTap
->ir_length
, w
))
495 LOG_ERROR("%s: IR capture %x too big",
496 pTap
->dotted_name
, (int) w
);
500 LOG_WARNING("%s: nonstandard IR value",
502 pTap
->ir_capture_value
= w
;
510 static int jim_newtap_cmd(Jim_GetOptInfo
*goi
)
512 struct jtag_tap
*pTap
;
517 const 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
= NULL
, .value
= -1 },
528 pTap
= calloc(1, sizeof(struct jtag_tap
));
530 Jim_SetResult_sprintf(goi
->interp
, "no memory");
535 * we expect CHIP + TAP + OPTIONS
538 Jim_SetResult_sprintf(goi
->interp
, "Missing CHIP TAP OPTIONS ....");
542 Jim_GetOpt_String(goi
, &cp
, NULL
);
543 pTap
->chip
= strdup(cp
);
545 Jim_GetOpt_String(goi
, &cp
, NULL
);
546 pTap
->tapname
= strdup(cp
);
548 /* name + dot + name + null */
549 x
= strlen(pTap
->chip
) + 1 + strlen(pTap
->tapname
) + 1;
551 sprintf(cp
, "%s.%s", pTap
->chip
, pTap
->tapname
);
552 pTap
->dotted_name
= cp
;
554 LOG_DEBUG("Creating New Tap, Chip: %s, Tap: %s, Dotted: %s, %d params",
555 pTap
->chip
, pTap
->tapname
, pTap
->dotted_name
, goi
->argc
);
557 /* IEEE specifies that the two LSBs of an IR scan are 01, so make
558 * that the default. The "-irlen" and "-irmask" options are only
559 * needed to cope with nonstandard TAPs, or to specify more bits.
561 pTap
->ir_capture_mask
= 0x03;
562 pTap
->ir_capture_value
= 0x01;
565 e
= Jim_GetOpt_Nvp(goi
, opts
, &n
);
567 Jim_GetOpt_NvpUnknown(goi
, opts
, 0);
568 free((void *)pTap
->dotted_name
);
572 LOG_DEBUG("Processing option: %s", n
->name
);
574 case NTAP_OPT_ENABLED
:
575 pTap
->disabled_after_reset
= false;
577 case NTAP_OPT_DISABLED
:
578 pTap
->disabled_after_reset
= true;
580 case NTAP_OPT_EXPECTED_ID
:
581 e
= jim_newtap_expected_id(n
, goi
, pTap
);
584 free((void *)pTap
->dotted_name
);
590 case NTAP_OPT_IRMASK
:
591 case NTAP_OPT_IRCAPTURE
:
592 e
= jim_newtap_ir_param(n
, goi
, pTap
);
595 free((void *)pTap
->dotted_name
);
600 case NTAP_OPT_VERSION
:
601 pTap
->ignore_version
= true;
603 } /* switch (n->value) */
604 } /* while (goi->argc) */
606 /* default is enabled-after-reset */
607 pTap
->enabled
= !pTap
->disabled_after_reset
;
609 /* Did all the required option bits get cleared? */
610 if (pTap
->ir_length
!= 0)
616 Jim_SetResult_sprintf(goi
->interp
,
617 "newtap: %s missing IR length",
623 static void jtag_tap_handle_event(struct jtag_tap
*tap
, enum jtag_event e
)
625 struct jtag_tap_event_action
* jteap
;
627 for (jteap
= tap
->event_action
; jteap
!= NULL
; jteap
= jteap
->next
)
629 if (jteap
->event
!= e
)
632 Jim_Nvp
*nvp
= Jim_Nvp_value2name_simple(nvp_jtag_tap_event
, e
);
633 LOG_DEBUG("JTAG tap: %s event: %d (%s)\n\taction: %s",
634 tap
->dotted_name
, e
, nvp
->name
,
635 Jim_GetString(jteap
->body
, NULL
));
637 if (Jim_EvalObj(jteap
->interp
, jteap
->body
) != JIM_OK
)
639 Jim_PrintErrorMessage(jteap
->interp
);
645 case JTAG_TAP_EVENT_ENABLE
:
646 case JTAG_TAP_EVENT_DISABLE
:
647 /* NOTE: we currently assume the handlers
648 * can't fail. Right here is where we should
649 * really be verifying the scan chains ...
651 tap
->enabled
= (e
== JTAG_TAP_EVENT_ENABLE
);
652 LOG_INFO("JTAG tap: %s %s", tap
->dotted_name
,
653 tap
->enabled
? "enabled" : "disabled");
661 static int jim_jtag_interface(Jim_Interp
*interp
, int argc
, Jim_Obj
*const *argv
)
664 Jim_GetOpt_Setup(&goi
, interp
, argc
-1, argv
+ 1);
666 /* return the name of the interface */
667 /* TCL code might need to know the exact type... */
668 /* FUTURE: we allow this as a means to "set" the interface. */
670 Jim_WrongNumArgs(goi
.interp
, 1, goi
.argv
-1, "(no params)");
673 const char *name
= jtag_interface
? jtag_interface
->name
: NULL
;
674 Jim_SetResultString(goi
.interp
, name
? : "undefined", -1);
678 static int jim_jtag_arp_init(Jim_Interp
*interp
, int argc
, Jim_Obj
*const *argv
)
681 Jim_GetOpt_Setup(&goi
, interp
, argc
-1, argv
+ 1);
683 Jim_WrongNumArgs(goi
.interp
, 1, goi
.argv
-1, "(no params)");
686 struct command_context
*context
= Jim_GetAssocData(interp
, "context");
687 int e
= jtag_init_inner(context
);
689 Jim_SetResult_sprintf(goi
.interp
, "error: %d", e
);
695 static int jim_jtag_arp_init_reset(Jim_Interp
*interp
, int argc
, Jim_Obj
*const *argv
)
698 Jim_GetOpt_Setup(&goi
, interp
, argc
-1, argv
+ 1);
700 Jim_WrongNumArgs(goi
.interp
, 1, goi
.argv
-1, "(no params)");
703 struct command_context
*context
= Jim_GetAssocData(interp
, "context");
704 int e
= jtag_init_reset(context
);
706 Jim_SetResult_sprintf(goi
.interp
, "error: %d", e
);
712 static int jim_jtag_newtap(Jim_Interp
*interp
, int argc
, Jim_Obj
*const *argv
)
715 Jim_GetOpt_Setup(&goi
, interp
, argc
-1, argv
+ 1);
716 return jim_newtap_cmd(&goi
);
719 static bool jtag_tap_enable(struct jtag_tap
*t
)
723 jtag_tap_handle_event(t
, JTAG_TAP_EVENT_ENABLE
);
727 /* FIXME add JTAG sanity checks, w/o TLR
728 * - scan chain length grew by one (this)
729 * - IDs and IR lengths are as expected
731 jtag_call_event_callbacks(JTAG_TAP_EVENT_ENABLE
);
734 static bool jtag_tap_disable(struct jtag_tap
*t
)
738 jtag_tap_handle_event(t
, JTAG_TAP_EVENT_DISABLE
);
742 /* FIXME add JTAG sanity checks, w/o TLR
743 * - scan chain length shrank by one (this)
744 * - IDs and IR lengths are as expected
746 jtag_call_event_callbacks(JTAG_TAP_EVENT_DISABLE
);
750 static int jim_jtag_tap_enabler(Jim_Interp
*interp
, int argc
, Jim_Obj
*const *argv
)
752 const char *cmd_name
= Jim_GetString(argv
[0], NULL
);
754 Jim_GetOpt_Setup(&goi
, interp
, argc
-1, argv
+ 1);
756 Jim_SetResult_sprintf(goi
.interp
, "usage: %s <name>", cmd_name
);
762 t
= jtag_tap_by_jim_obj(goi
.interp
, goi
.argv
[0]);
766 if (strcasecmp(cmd_name
, "tapisenabled") == 0) {
767 // do nothing, just return the value
768 } else if (strcasecmp(cmd_name
, "tapenable") == 0) {
769 if (!jtag_tap_enable(t
))
770 LOG_WARNING("failed to disable tap");
771 } else if (strcasecmp(cmd_name
, "tapdisable") == 0) {
772 if (!jtag_tap_disable(t
))
773 LOG_WARNING("failed to disable tap");
775 LOG_ERROR("command '%s' unknown", cmd_name
);
779 Jim_SetResult(goi
.interp
, Jim_NewIntObj(goi
.interp
, e
));
783 static int jim_jtag_configure(Jim_Interp
*interp
, int argc
, Jim_Obj
*const *argv
)
785 const char *cmd_name
= Jim_GetString(argv
[0], NULL
);
787 Jim_GetOpt_Setup(&goi
, interp
, argc
-1, argv
+ 1);
788 goi
.isconfigure
= !strcmp(cmd_name
, "configure");
789 if (goi
.argc
< 2 + goi
.isconfigure
) {
790 Jim_WrongNumArgs(goi
.interp
, 0, NULL
,
791 "<tap_name> <attribute> ...");
798 Jim_GetOpt_Obj(&goi
, &o
);
799 t
= jtag_tap_by_jim_obj(goi
.interp
, o
);
804 return jtag_tap_configure_cmd(&goi
, t
);
807 static int jim_jtag_names(Jim_Interp
*interp
, int argc
, Jim_Obj
*const *argv
)
810 Jim_GetOpt_Setup(&goi
, interp
, argc
-1, argv
+ 1);
812 Jim_WrongNumArgs(goi
.interp
, 1, goi
.argv
, "Too many parameters");
815 Jim_SetResult(goi
.interp
, Jim_NewListObj(goi
.interp
, NULL
, 0));
816 struct jtag_tap
*tap
;
818 for (tap
= jtag_all_taps(); tap
; tap
= tap
->next_tap
) {
819 Jim_ListAppendElement(goi
.interp
,
820 Jim_GetResult(goi
.interp
),
821 Jim_NewStringObj(goi
.interp
,
822 tap
->dotted_name
, -1));
827 COMMAND_HANDLER(handle_jtag_init_command
)
830 return ERROR_COMMAND_SYNTAX_ERROR
;
832 static bool jtag_initialized
= false;
833 if (jtag_initialized
)
835 LOG_INFO("'jtag init' has already been called");
838 jtag_initialized
= true;
840 LOG_DEBUG("Initializing jtag devices...");
841 return jtag_init(CMD_CTX
);
844 static const struct command_registration jtag_subcommand_handlers
[] = {
848 .handler
= &handle_jtag_init_command
,
849 .help
= "initialize jtag scan chain",
854 .jim_handler
= &jim_jtag_interface
,
855 .help
= "Returns the selected interface",
860 .jim_handler
= &jim_jtag_arp_init
,
863 .name
= "arp_init-reset",
865 .jim_handler
= &jim_jtag_arp_init_reset
,
869 .mode
= COMMAND_CONFIG
,
870 .jim_handler
= &jim_jtag_newtap
,
871 .help
= "Create a new TAP instance",
872 .usage
= "<name> <type> -irlen <count> [-ircapture <count>] "
873 "[-irmask <count>] [-enable|-disable]",
876 .name
= "tapisenabled",
877 .mode
= COMMAND_EXEC
,
878 .jim_handler
= &jim_jtag_tap_enabler
,
879 .help
= "Returns a integer indicating TAP state (0/1)",
884 .mode
= COMMAND_EXEC
,
885 .jim_handler
= &jim_jtag_tap_enabler
,
886 .help
= "Enable the specified TAP",
890 .name
= "tapdisable",
891 .mode
= COMMAND_EXEC
,
892 .jim_handler
= &jim_jtag_tap_enabler
,
893 .help
= "Enable the specified TAP",
898 .mode
= COMMAND_EXEC
,
899 .jim_handler
= &jim_jtag_configure
,
900 .help
= "Enable the specified TAP",
901 .usage
= "<name> [<key> <value> ...]",
905 .mode
= COMMAND_EXEC
,
906 .jim_handler
= &jim_jtag_configure
,
907 .help
= "Enable the specified TAP",
908 .usage
= "<name> [<key> <value> ...]",
913 .jim_handler
= &jim_jtag_names
,
914 .help
= "Returns list of all JTAG tap names",
917 .chain
= jtag_command_handlers_to_move
,
919 COMMAND_REGISTRATION_DONE
922 void jtag_notify_event(enum jtag_event event
)
924 struct jtag_tap
*tap
;
926 for (tap
= jtag_all_taps(); tap
; tap
= tap
->next_tap
)
927 jtag_tap_handle_event(tap
, event
);
931 static int default_khz(int khz
, int *jtag_speed
)
933 LOG_ERROR("Translation from khz to jtag_speed not implemented");
937 static int default_speed_div(int speed
, int *khz
)
939 LOG_ERROR("Translation from jtag_speed to khz not implemented");
943 static int default_power_dropout(int *dropout
)
945 *dropout
= 0; /* by default we can't detect power dropout */
949 static int default_srst_asserted(int *srst_asserted
)
951 *srst_asserted
= 0; /* by default we can't detect srst asserted */
955 COMMAND_HANDLER(handle_interface_list_command
)
957 if (strcmp(CMD_NAME
, "interface_list") == 0 && CMD_ARGC
> 0)
958 return ERROR_COMMAND_SYNTAX_ERROR
;
960 command_print(CMD_CTX
, "The following JTAG interfaces are available:");
961 for (unsigned i
= 0; NULL
!= jtag_interfaces
[i
]; i
++)
963 const char *name
= jtag_interfaces
[i
]->name
;
964 command_print(CMD_CTX
, "%u: %s", i
+ 1, name
);
970 COMMAND_HANDLER(handle_interface_command
)
972 /* check whether the interface is already configured */
975 LOG_WARNING("Interface already configured, ignoring");
979 /* interface name is a mandatory argument */
980 if (CMD_ARGC
!= 1 || CMD_ARGV
[0][0] == '\0')
981 return ERROR_COMMAND_SYNTAX_ERROR
;
983 for (unsigned i
= 0; NULL
!= jtag_interfaces
[i
]; i
++)
985 if (strcmp(CMD_ARGV
[0], jtag_interfaces
[i
]->name
) != 0)
988 if (NULL
!= jtag_interfaces
[i
]->commands
)
990 int retval
= register_commands(CMD_CTX
, NULL
,
991 jtag_interfaces
[i
]->commands
);
992 if (ERROR_OK
!= retval
)
996 jtag_interface
= jtag_interfaces
[i
];
998 if (jtag_interface
->khz
== NULL
)
999 jtag_interface
->khz
= default_khz
;
1000 if (jtag_interface
->speed_div
== NULL
)
1001 jtag_interface
->speed_div
= default_speed_div
;
1002 if (jtag_interface
->power_dropout
== NULL
)
1003 jtag_interface
->power_dropout
= default_power_dropout
;
1004 if (jtag_interface
->srst_asserted
== NULL
)
1005 jtag_interface
->srst_asserted
= default_srst_asserted
;
1010 /* no valid interface was found (i.e. the configuration option,
1011 * didn't match one of the compiled-in interfaces
1013 LOG_ERROR("The specified JTAG interface was not found (%s)", CMD_ARGV
[0]);
1014 CALL_COMMAND_HANDLER(handle_interface_list_command
);
1015 return ERROR_JTAG_INVALID_INTERFACE
;
1018 COMMAND_HANDLER(handle_scan_chain_command
)
1020 struct jtag_tap
*tap
;
1021 char expected_id
[12];
1023 tap
= jtag_all_taps();
1024 command_print(CMD_CTX
, " TapName | Enabled | IdCode Expected IrLen IrCap IrMask Instr ");
1025 command_print(CMD_CTX
, "---|--------------------|---------|------------|------------|------|------|------|---------");
1028 uint32_t expected
, expected_mask
, cur_instr
, ii
;
1030 snprintf(expected_id
, sizeof expected_id
, "0x%08x",
1031 (unsigned)((tap
->expected_ids_cnt
> 0)
1032 ? tap
->expected_ids
[0]
1034 if (tap
->ignore_version
)
1035 expected_id
[2] = '*';
1037 expected
= buf_get_u32(tap
->expected
, 0, tap
->ir_length
);
1038 expected_mask
= buf_get_u32(tap
->expected_mask
, 0, tap
->ir_length
);
1039 cur_instr
= buf_get_u32(tap
->cur_instr
, 0, tap
->ir_length
);
1041 command_print(CMD_CTX
,
1042 "%2d | %-18s | %c | 0x%08x | %s | 0x%02x | 0x%02x | 0x%02x | 0x%02x",
1043 tap
->abs_chain_position
,
1045 tap
->enabled
? 'Y' : 'n',
1046 (unsigned int)(tap
->idcode
),
1048 (unsigned int)(tap
->ir_length
),
1049 (unsigned int)(expected
),
1050 (unsigned int)(expected_mask
),
1051 (unsigned int)(cur_instr
));
1053 for (ii
= 1; ii
< tap
->expected_ids_cnt
; ii
++) {
1054 snprintf(expected_id
, sizeof expected_id
, "0x%08x",
1055 (unsigned) tap
->expected_ids
[1]);
1056 if (tap
->ignore_version
)
1057 expected_id
[2] = '*';
1059 command_print(CMD_CTX
,
1060 " | | | | %s | | | | ",
1064 tap
= tap
->next_tap
;
1070 COMMAND_HANDLER(handle_reset_config_command
)
1075 /* Original versions cared about the order of these tokens:
1076 * reset_config signals [combination [trst_type [srst_type]]]
1077 * They also clobbered the previous configuration even on error.
1079 * Here we don't care about the order, and only change values
1080 * which have been explicitly specified.
1082 for (; CMD_ARGC
; CMD_ARGC
--, CMD_ARGV
++) {
1087 m
= RESET_SRST_NO_GATING
;
1088 if (strcmp(*CMD_ARGV
, "srst_gates_jtag") == 0)
1089 /* default: don't use JTAG while SRST asserted */;
1090 else if (strcmp(*CMD_ARGV
, "srst_nogate") == 0)
1091 tmp
= RESET_SRST_NO_GATING
;
1095 LOG_ERROR("extra reset_config %s spec (%s)",
1096 "gating", *CMD_ARGV
);
1097 return ERROR_INVALID_ARGUMENTS
;
1103 m
= RESET_HAS_TRST
| RESET_HAS_SRST
;
1104 if (strcmp(*CMD_ARGV
, "none") == 0)
1106 else if (strcmp(*CMD_ARGV
, "trst_only") == 0)
1107 tmp
= RESET_HAS_TRST
;
1108 else if (strcmp(*CMD_ARGV
, "srst_only") == 0)
1109 tmp
= RESET_HAS_SRST
;
1110 else if (strcmp(*CMD_ARGV
, "trst_and_srst") == 0)
1111 tmp
= RESET_HAS_TRST
| RESET_HAS_SRST
;
1115 LOG_ERROR("extra reset_config %s spec (%s)",
1116 "signal", *CMD_ARGV
);
1117 return ERROR_INVALID_ARGUMENTS
;
1122 /* combination (options for broken wiring) */
1123 m
= RESET_SRST_PULLS_TRST
| RESET_TRST_PULLS_SRST
;
1124 if (strcmp(*CMD_ARGV
, "separate") == 0)
1125 /* separate reset lines - default */;
1126 else if (strcmp(*CMD_ARGV
, "srst_pulls_trst") == 0)
1127 tmp
|= RESET_SRST_PULLS_TRST
;
1128 else if (strcmp(*CMD_ARGV
, "trst_pulls_srst") == 0)
1129 tmp
|= RESET_TRST_PULLS_SRST
;
1130 else if (strcmp(*CMD_ARGV
, "combined") == 0)
1131 tmp
|= RESET_SRST_PULLS_TRST
| RESET_TRST_PULLS_SRST
;
1135 LOG_ERROR("extra reset_config %s spec (%s)",
1136 "combination", *CMD_ARGV
);
1137 return ERROR_INVALID_ARGUMENTS
;
1142 /* trst_type (NOP without HAS_TRST) */
1143 m
= RESET_TRST_OPEN_DRAIN
;
1144 if (strcmp(*CMD_ARGV
, "trst_open_drain") == 0)
1145 tmp
|= RESET_TRST_OPEN_DRAIN
;
1146 else if (strcmp(*CMD_ARGV
, "trst_push_pull") == 0)
1147 /* push/pull from adapter - default */;
1151 LOG_ERROR("extra reset_config %s spec (%s)",
1152 "trst_type", *CMD_ARGV
);
1153 return ERROR_INVALID_ARGUMENTS
;
1158 /* srst_type (NOP without HAS_SRST) */
1159 m
|= RESET_SRST_PUSH_PULL
;
1160 if (strcmp(*CMD_ARGV
, "srst_push_pull") == 0)
1161 tmp
|= RESET_SRST_PUSH_PULL
;
1162 else if (strcmp(*CMD_ARGV
, "srst_open_drain") == 0)
1163 /* open drain from adapter - default */;
1167 LOG_ERROR("extra reset_config %s spec (%s)",
1168 "srst_type", *CMD_ARGV
);
1169 return ERROR_INVALID_ARGUMENTS
;
1174 /* caller provided nonsense; fail */
1175 LOG_ERROR("unknown reset_config flag (%s)", *CMD_ARGV
);
1176 return ERROR_INVALID_ARGUMENTS
;
1179 /* Remember the bits which were specified (mask)
1180 * and their new values (new_cfg).
1186 /* clear previous values of those bits, save new values */
1188 int old_cfg
= jtag_get_reset_config();
1192 jtag_set_reset_config(new_cfg
);
1194 new_cfg
= jtag_get_reset_config();
1198 * Display the (now-)current reset mode
1202 /* minimal JTAG has neither SRST nor TRST (so that's the default) */
1203 switch (new_cfg
& (RESET_HAS_TRST
| RESET_HAS_SRST
)) {
1204 case RESET_HAS_SRST
:
1205 modes
[0] = "srst_only";
1207 case RESET_HAS_TRST
:
1208 modes
[0] = "trst_only";
1210 case RESET_TRST_AND_SRST
:
1211 modes
[0] = "trst_and_srst";
1218 /* normally SRST and TRST are decoupled; but bugs happen ... */
1219 switch (new_cfg
& (RESET_SRST_PULLS_TRST
| RESET_TRST_PULLS_SRST
)) {
1220 case RESET_SRST_PULLS_TRST
:
1221 modes
[1] = "srst_pulls_trst";
1223 case RESET_TRST_PULLS_SRST
:
1224 modes
[1] = "trst_pulls_srst";
1226 case RESET_SRST_PULLS_TRST
| RESET_TRST_PULLS_SRST
:
1227 modes
[1] = "combined";
1230 modes
[1] = "separate";
1234 /* TRST-less connectors include Altera, Xilinx, and minimal JTAG */
1235 if (new_cfg
& RESET_HAS_TRST
) {
1236 if (new_cfg
& RESET_TRST_OPEN_DRAIN
)
1237 modes
[3] = " trst_open_drain";
1239 modes
[3] = " trst_push_pull";
1243 /* SRST-less connectors include TI-14, Xilinx, and minimal JTAG */
1244 if (new_cfg
& RESET_HAS_SRST
) {
1245 if (new_cfg
& RESET_SRST_NO_GATING
)
1246 modes
[2] = " srst_nogate";
1248 modes
[2] = " srst_gates_jtag";
1250 if (new_cfg
& RESET_SRST_PUSH_PULL
)
1251 modes
[4] = " srst_push_pull";
1253 modes
[4] = " srst_open_drain";
1259 command_print(CMD_CTX
, "%s %s%s%s%s",
1261 modes
[2], modes
[3], modes
[4]);
1266 COMMAND_HANDLER(handle_jtag_nsrst_delay_command
)
1269 return ERROR_COMMAND_SYNTAX_ERROR
;
1273 COMMAND_PARSE_NUMBER(uint
, CMD_ARGV
[0], delay
);
1275 jtag_set_nsrst_delay(delay
);
1277 command_print(CMD_CTX
, "jtag_nsrst_delay: %u", jtag_get_nsrst_delay());
1281 COMMAND_HANDLER(handle_jtag_ntrst_delay_command
)
1284 return ERROR_COMMAND_SYNTAX_ERROR
;
1288 COMMAND_PARSE_NUMBER(uint
, CMD_ARGV
[0], delay
);
1290 jtag_set_ntrst_delay(delay
);
1292 command_print(CMD_CTX
, "jtag_ntrst_delay: %u", jtag_get_ntrst_delay());
1296 COMMAND_HANDLER(handle_jtag_nsrst_assert_width_command
)
1299 return ERROR_COMMAND_SYNTAX_ERROR
;
1303 COMMAND_PARSE_NUMBER(uint
, CMD_ARGV
[0], delay
);
1305 jtag_set_nsrst_assert_width(delay
);
1307 command_print(CMD_CTX
, "jtag_nsrst_assert_width: %u", jtag_get_nsrst_assert_width());
1311 COMMAND_HANDLER(handle_jtag_ntrst_assert_width_command
)
1314 return ERROR_COMMAND_SYNTAX_ERROR
;
1318 COMMAND_PARSE_NUMBER(uint
, CMD_ARGV
[0], delay
);
1320 jtag_set_ntrst_assert_width(delay
);
1322 command_print(CMD_CTX
, "jtag_ntrst_assert_width: %u", jtag_get_ntrst_assert_width());
1326 COMMAND_HANDLER(handle_jtag_khz_command
)
1329 return ERROR_COMMAND_SYNTAX_ERROR
;
1331 int retval
= ERROR_OK
;
1335 COMMAND_PARSE_NUMBER(uint
, CMD_ARGV
[0], khz
);
1337 retval
= jtag_config_khz(khz
);
1338 if (ERROR_OK
!= retval
)
1342 int cur_speed
= jtag_get_speed_khz();
1343 retval
= jtag_get_speed_readable(&cur_speed
);
1344 if (ERROR_OK
!= retval
)
1348 command_print(CMD_CTX
, "%d kHz", cur_speed
);
1350 command_print(CMD_CTX
, "RCLK - adaptive");
1355 COMMAND_HANDLER(handle_jtag_rclk_command
)
1358 return ERROR_COMMAND_SYNTAX_ERROR
;
1360 int retval
= ERROR_OK
;
1364 COMMAND_PARSE_NUMBER(uint
, CMD_ARGV
[0], khz
);
1366 retval
= jtag_config_rclk(khz
);
1367 if (ERROR_OK
!= retval
)
1371 int cur_khz
= jtag_get_speed_khz();
1372 retval
= jtag_get_speed_readable(&cur_khz
);
1373 if (ERROR_OK
!= retval
)
1377 command_print(CMD_CTX
, "RCLK not supported - fallback to %d kHz", cur_khz
);
1379 command_print(CMD_CTX
, "RCLK - adaptive");
1384 COMMAND_HANDLER(handle_jtag_reset_command
)
1387 return ERROR_COMMAND_SYNTAX_ERROR
;
1390 if (CMD_ARGV
[0][0] == '1')
1392 else if (CMD_ARGV
[0][0] == '0')
1395 return ERROR_COMMAND_SYNTAX_ERROR
;
1398 if (CMD_ARGV
[1][0] == '1')
1400 else if (CMD_ARGV
[1][0] == '0')
1403 return ERROR_COMMAND_SYNTAX_ERROR
;
1405 if (jtag_interface_init(CMD_CTX
) != ERROR_OK
)
1406 return ERROR_JTAG_INIT_FAILED
;
1408 jtag_add_reset(trst
, srst
);
1409 return jtag_execute_queue();
1412 COMMAND_HANDLER(handle_runtest_command
)
1415 return ERROR_COMMAND_SYNTAX_ERROR
;
1417 unsigned num_clocks
;
1418 COMMAND_PARSE_NUMBER(uint
, CMD_ARGV
[0], num_clocks
);
1420 jtag_add_runtest(num_clocks
, TAP_IDLE
);
1421 return jtag_execute_queue();
1425 * For "irscan" or "drscan" commands, the "end" (really, "next") state
1426 * should be stable ... and *NOT* a shift state, otherwise free-running
1427 * jtag clocks could change the values latched by the update state.
1428 * Not surprisingly, this is the same constraint as SVF; the "irscan"
1429 * and "drscan" commands are a write-only subset of what SVF provides.
1432 COMMAND_HANDLER(handle_irscan_command
)
1435 struct scan_field
*fields
;
1436 struct jtag_tap
*tap
;
1437 tap_state_t endstate
;
1439 if ((CMD_ARGC
< 2) || (CMD_ARGC
% 2))
1441 return ERROR_COMMAND_SYNTAX_ERROR
;
1444 /* optional "-endstate" "statename" at the end of the arguments,
1445 * so that e.g. IRPAUSE can let us load the data register before
1446 * entering RUN/IDLE to execute the instruction we load here.
1448 endstate
= TAP_IDLE
;
1450 if (CMD_ARGC
>= 4) {
1451 /* have at least one pair of numbers. */
1452 /* is last pair the magic text? */
1453 if (strcmp("-endstate", CMD_ARGV
[CMD_ARGC
- 2]) == 0) {
1454 endstate
= tap_state_by_name(CMD_ARGV
[CMD_ARGC
- 1]);
1455 if (endstate
== TAP_INVALID
)
1456 return ERROR_COMMAND_SYNTAX_ERROR
;
1457 if (!scan_is_safe(endstate
))
1458 LOG_WARNING("unstable irscan endstate \"%s\"",
1459 CMD_ARGV
[CMD_ARGC
- 1]);
1464 int num_fields
= CMD_ARGC
/ 2;
1465 size_t fields_len
= sizeof(struct scan_field
) * num_fields
;
1466 fields
= malloc(fields_len
);
1467 memset(fields
, 0, fields_len
);
1470 for (i
= 0; i
< num_fields
; i
++)
1472 tap
= jtag_tap_by_string(CMD_ARGV
[i
*2]);
1476 for (j
= 0; j
< i
; j
++)
1477 free(fields
[j
].out_value
);
1479 command_print(CMD_CTX
, "Tap: %s unknown", CMD_ARGV
[i
*2]);
1483 int field_size
= tap
->ir_length
;
1484 fields
[i
].tap
= tap
;
1485 fields
[i
].num_bits
= field_size
;
1486 fields
[i
].out_value
= malloc(DIV_ROUND_UP(field_size
, 8));
1489 retval
= parse_u32(CMD_ARGV
[i
* 2 + 1], &value
);
1490 if (ERROR_OK
!= retval
)
1492 buf_set_u32(fields
[i
].out_value
, 0, field_size
, value
);
1493 fields
[i
].in_value
= NULL
;
1496 /* did we have an endstate? */
1497 jtag_add_ir_scan(num_fields
, fields
, endstate
);
1499 retval
= jtag_execute_queue();
1502 for (i
= 0; i
< num_fields
; i
++)
1504 if (NULL
!= fields
[i
].out_value
)
1505 free(fields
[i
].out_value
);
1514 COMMAND_HANDLER(handle_verify_ircapture_command
)
1517 return ERROR_COMMAND_SYNTAX_ERROR
;
1522 COMMAND_PARSE_ENABLE(CMD_ARGV
[0], enable
);
1523 jtag_set_verify_capture_ir(enable
);
1526 const char *status
= jtag_will_verify_capture_ir() ? "enabled": "disabled";
1527 command_print(CMD_CTX
, "verify Capture-IR is %s", status
);
1532 COMMAND_HANDLER(handle_verify_jtag_command
)
1535 return ERROR_COMMAND_SYNTAX_ERROR
;
1540 COMMAND_PARSE_ENABLE(CMD_ARGV
[0], enable
);
1541 jtag_set_verify(enable
);
1544 const char *status
= jtag_will_verify() ? "enabled": "disabled";
1545 command_print(CMD_CTX
, "verify jtag capture is %s", status
);
1550 COMMAND_HANDLER(handle_tms_sequence_command
)
1553 return ERROR_COMMAND_SYNTAX_ERROR
;
1558 if (strcmp(CMD_ARGV
[0], "short") == 0)
1559 use_new_table
= true;
1560 else if (strcmp(CMD_ARGV
[0], "long") == 0)
1561 use_new_table
= false;
1563 return ERROR_COMMAND_SYNTAX_ERROR
;
1565 tap_use_new_tms_table(use_new_table
);
1568 command_print(CMD_CTX
, "tms sequence is %s",
1569 tap_uses_new_tms_table() ? "short": "long");
1574 static const struct command_registration jtag_command_handlers
[] = {
1576 .name
= "interface",
1577 .handler
= &handle_interface_command
,
1578 .mode
= COMMAND_CONFIG
,
1579 .help
= "select a JTAG interface",
1580 .usage
= "<driver_name>",
1583 .name
= "interface_list",
1584 .handler
= &handle_interface_list_command
,
1585 .mode
= COMMAND_ANY
,
1586 .help
= "list all built-in interfaces",
1590 .handler
= &handle_jtag_khz_command
,
1591 .mode
= COMMAND_ANY
,
1592 .help
= "set maximum jtag speed (if supported)",
1593 .usage
= "<khz:0=rtck>",
1596 .name
= "jtag_rclk",
1597 .handler
= &handle_jtag_rclk_command
,
1598 .mode
= COMMAND_ANY
,
1599 .help
= "set JTAG speed to RCLK or use fallback speed",
1600 .usage
= "<fallback_speed_khz>",
1603 .name
= "reset_config",
1604 .handler
= &handle_reset_config_command
,
1605 .mode
= COMMAND_ANY
,
1606 .help
= "configure JTAG reset behavior",
1607 .usage
= "[none|trst_only|srst_only|trst_and_srst] "
1608 "[srst_pulls_trst|trst_pulls_srst|combined|separate] "
1609 "[srst_gates_jtag|srst_nogate] "
1610 "[trst_push_pull|trst_open_drain] "
1611 "[srst_push_pull|srst_open_drain]",
1614 .name
= "jtag_nsrst_delay",
1615 .handler
= &handle_jtag_nsrst_delay_command
,
1616 .mode
= COMMAND_ANY
,
1617 .help
= "delay after deasserting srst in ms",
1621 .name
= "jtag_ntrst_delay",
1622 .handler
= &handle_jtag_ntrst_delay_command
,
1623 .mode
= COMMAND_ANY
,
1624 .help
= "delay after deasserting trst in ms",
1628 .name
= "jtag_nsrst_assert_width",
1629 .handler
= &handle_jtag_nsrst_assert_width_command
,
1630 .mode
= COMMAND_ANY
,
1631 .help
= "delay after asserting srst in ms",
1635 .name
= "jtag_ntrst_assert_width",
1636 .handler
= &handle_jtag_ntrst_assert_width_command
,
1637 .mode
= COMMAND_ANY
,
1638 .help
= "delay after asserting trst in ms",
1642 .name
= "scan_chain",
1643 .handler
= &handle_scan_chain_command
,
1644 .mode
= COMMAND_EXEC
,
1645 .help
= "print current scan chain configuration",
1648 .name
= "jtag_reset",
1649 .handler
= &handle_jtag_reset_command
,
1650 .mode
= COMMAND_EXEC
,
1651 .help
= "toggle reset lines",
1652 .usage
= "<trst> <srst>",
1656 .handler
= &handle_runtest_command
,
1657 .mode
= COMMAND_EXEC
,
1658 .help
= "move to Run-Test/Idle, and execute <num_cycles>",
1659 .usage
= "<num_cycles>"
1663 .handler
= &handle_irscan_command
,
1664 .mode
= COMMAND_EXEC
,
1665 .help
= "execute IR scan",
1666 .usage
= "<device> <instr> [dev2] [instr2] ...",
1669 .name
= "verify_ircapture",
1670 .handler
= &handle_verify_ircapture_command
,
1671 .mode
= COMMAND_ANY
,
1672 .help
= "verify value captured during Capture-IR",
1673 .usage
= "<enable | disable>",
1676 .name
= "verify_jtag",
1677 .handler
= &handle_verify_jtag_command
,
1678 .mode
= COMMAND_ANY
,
1679 .help
= "verify value capture",
1680 .usage
= "<enable | disable>",
1683 .name
= "tms_sequence",
1684 .handler
= &handle_tms_sequence_command
,
1685 .mode
= COMMAND_ANY
,
1686 .help
= "choose short(default) or long tms_sequence",
1687 .usage
= "<short | long>",
1691 .mode
= COMMAND_ANY
,
1692 .help
= "perform jtag tap actions",
1694 .chain
= jtag_subcommand_handlers
,
1697 .chain
= jtag_command_handlers_to_move
,
1699 COMMAND_REGISTRATION_DONE
1701 int jtag_register_commands(struct command_context
*cmd_ctx
)
1703 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)