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_TAP_EVENT_POST_RESET
, .name
= "post-reset" },
45 { .value
= JTAG_TAP_EVENT_ENABLE
, .name
= "tap-enable" },
46 { .value
= JTAG_TAP_EVENT_DISABLE
, .name
= "tap-disable" },
48 { .name
= NULL
, .value
= -1 }
51 extern jtag_interface_t
*jtag_interface
;
54 static int handle_interface_list_command(struct command_context_s
*cmd_ctx
,
55 char *cmd
, char **args
, int argc
);
56 static int handle_interface_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
57 static int handle_jtag_speed_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
58 static int handle_jtag_khz_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
59 static int handle_jtag_rclk_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
60 static int handle_jtag_device_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
61 static int handle_reset_config_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
62 static int handle_jtag_nsrst_delay_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
63 static int handle_jtag_ntrst_delay_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
64 static int handle_jtag_nsrst_assert_width_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
65 static int handle_jtag_ntrst_assert_width_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
67 static int handle_scan_chain_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
69 static int handle_jtag_reset_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
70 static int handle_runtest_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
71 static int handle_irscan_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
72 static int Jim_Command_drscan(Jim_Interp
*interp
, int argc
, Jim_Obj
*const *argv
);
73 static int Jim_Command_pathmove(Jim_Interp
*interp
, int argc
, Jim_Obj
*const *argv
);
74 static int Jim_Command_flush_count(Jim_Interp
*interp
, int argc
, Jim_Obj
*const *args
);
76 static int handle_verify_ircapture_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
77 static int handle_verify_jtag_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
78 static int handle_tms_sequence_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
81 enum jtag_tap_cfg_param
{
85 static Jim_Nvp nvp_config_opts
[] = {
86 { .name
= "-event", .value
= JCFG_EVENT
},
88 { .name
= NULL
, .value
= -1 }
91 static int jtag_tap_configure_cmd(Jim_GetOptInfo
*goi
, jtag_tap_t
* tap
)
97 /* parse config or cget options */
98 while (goi
->argc
> 0) {
99 Jim_SetEmptyResult (goi
->interp
);
101 e
= Jim_GetOpt_Nvp(goi
, nvp_config_opts
, &n
);
103 Jim_GetOpt_NvpUnknown(goi
, nvp_config_opts
, 0);
109 if (goi
->argc
== 0) {
110 Jim_WrongNumArgs(goi
->interp
, goi
->argc
, goi
->argv
, "-event ?event-name? ...");
114 e
= Jim_GetOpt_Nvp(goi
, nvp_jtag_tap_event
, &n
);
116 Jim_GetOpt_NvpUnknown(goi
, nvp_jtag_tap_event
, 1);
120 if (goi
->isconfigure
) {
121 if (goi
->argc
!= 1) {
122 Jim_WrongNumArgs(goi
->interp
, goi
->argc
, goi
->argv
, "-event ?event-name? ?EVENT-BODY?");
126 if (goi
->argc
!= 0) {
127 Jim_WrongNumArgs(goi
->interp
, goi
->argc
, goi
->argv
, "-event ?event-name?");
133 jtag_tap_event_action_t
*jteap
;
135 jteap
= tap
->event_action
;
136 /* replace existing? */
138 if (jteap
->event
== (enum jtag_event
)n
->value
) {
144 if (goi
->isconfigure
) {
148 jteap
= calloc(1, sizeof (*jteap
));
151 jteap
->event
= n
->value
;
152 Jim_GetOpt_Obj(goi
, &o
);
154 Jim_DecrRefCount(interp
, jteap
->body
);
156 jteap
->body
= Jim_DuplicateObj(goi
->interp
, o
);
157 Jim_IncrRefCount(jteap
->body
);
161 /* add to head of event list */
162 jteap
->next
= tap
->event_action
;
163 tap
->event_action
= jteap
;
165 Jim_SetEmptyResult(goi
->interp
);
169 Jim_SetEmptyResult(goi
->interp
);
171 Jim_SetResult(goi
->interp
, Jim_DuplicateObj(goi
->interp
, jteap
->body
));
178 } /* while (goi->argc) */
183 static int is_bad_irval(int ir_length
, jim_wide w
)
193 static int jim_newtap_cmd(Jim_GetOptInfo
*goi
)
202 const Jim_Nvp opts
[] = {
203 #define NTAP_OPT_IRLEN 0
204 { .name
= "-irlen" , .value
= NTAP_OPT_IRLEN
},
205 #define NTAP_OPT_IRMASK 1
206 { .name
= "-irmask" , .value
= NTAP_OPT_IRMASK
},
207 #define NTAP_OPT_IRCAPTURE 2
208 { .name
= "-ircapture" , .value
= NTAP_OPT_IRCAPTURE
},
209 #define NTAP_OPT_ENABLED 3
210 { .name
= "-enable" , .value
= NTAP_OPT_ENABLED
},
211 #define NTAP_OPT_DISABLED 4
212 { .name
= "-disable" , .value
= NTAP_OPT_DISABLED
},
213 #define NTAP_OPT_EXPECTED_ID 5
214 { .name
= "-expected-id" , .value
= NTAP_OPT_EXPECTED_ID
},
215 { .name
= NULL
, .value
= -1 },
218 pTap
= calloc(1, sizeof(jtag_tap_t
));
220 Jim_SetResult_sprintf(goi
->interp
, "no memory");
225 * we expect CHIP + TAP + OPTIONS
228 Jim_SetResult_sprintf(goi
->interp
, "Missing CHIP TAP OPTIONS ....");
232 Jim_GetOpt_String(goi
, &cp
, NULL
);
233 pTap
->chip
= strdup(cp
);
235 Jim_GetOpt_String(goi
, &cp
, NULL
);
236 pTap
->tapname
= strdup(cp
);
238 /* name + dot + name + null */
239 x
= strlen(pTap
->chip
) + 1 + strlen(pTap
->tapname
) + 1;
241 sprintf(cp
, "%s.%s", pTap
->chip
, pTap
->tapname
);
242 pTap
->dotted_name
= cp
;
244 LOG_DEBUG("Creating New Tap, Chip: %s, Tap: %s, Dotted: %s, %d params",
245 pTap
->chip
, pTap
->tapname
, pTap
->dotted_name
, goi
->argc
);
247 /* IEEE specifies that the two LSBs of an IR scan are 01, so make
248 * that the default. The "-irlen" and "-irmask" options are only
249 * needed to cope with nonstandard TAPs, or to specify more bits.
251 pTap
->ir_capture_mask
= 0x03;
252 pTap
->ir_capture_value
= 0x01;
254 /* clear flags for "required options" them as we find them */
258 e
= Jim_GetOpt_Nvp(goi
, opts
, &n
);
260 Jim_GetOpt_NvpUnknown(goi
, opts
, 0);
261 free((void *)pTap
->dotted_name
);
265 LOG_DEBUG("Processing option: %s", n
->name
);
267 case NTAP_OPT_ENABLED
:
268 pTap
->disabled_after_reset
= false;
270 case NTAP_OPT_DISABLED
:
271 pTap
->disabled_after_reset
= true;
273 case NTAP_OPT_EXPECTED_ID
:
275 uint32_t *new_expected_ids
;
277 e
= Jim_GetOpt_Wide(goi
, &w
);
279 Jim_SetResult_sprintf(goi
->interp
, "option: %s bad parameter", n
->name
);
280 free((void *)pTap
->dotted_name
);
285 new_expected_ids
= malloc(sizeof(uint32_t) * (pTap
->expected_ids_cnt
+ 1));
286 if (new_expected_ids
== NULL
) {
287 Jim_SetResult_sprintf(goi
->interp
, "no memory");
288 free((void *)pTap
->dotted_name
);
293 memcpy(new_expected_ids
, pTap
->expected_ids
, sizeof(uint32_t) * pTap
->expected_ids_cnt
);
295 new_expected_ids
[pTap
->expected_ids_cnt
] = w
;
297 free(pTap
->expected_ids
);
298 pTap
->expected_ids
= new_expected_ids
;
299 pTap
->expected_ids_cnt
++;
303 case NTAP_OPT_IRMASK
:
304 case NTAP_OPT_IRCAPTURE
:
305 e
= Jim_GetOpt_Wide(goi
, &w
);
307 Jim_SetResult_sprintf(goi
->interp
, "option: %s bad parameter", n
->name
);
308 free((void *)pTap
->dotted_name
);
314 if (w
> (jim_wide
) (8 * sizeof(pTap
->ir_capture_value
)))
315 LOG_WARNING("%s: huge IR length %d",
321 case NTAP_OPT_IRMASK
:
322 if (is_bad_irval(pTap
->ir_length
, w
)) {
323 LOG_ERROR("%s: IR mask %x too big",
326 free((void *)pTap
->dotted_name
);
331 LOG_WARNING("%s: nonstandard IR mask",
333 pTap
->ir_capture_mask
= w
;
335 case NTAP_OPT_IRCAPTURE
:
336 if (is_bad_irval(pTap
->ir_length
, w
)) {
337 LOG_ERROR("%s: IR capture %x too big",
340 free((void *)pTap
->dotted_name
);
345 LOG_WARNING("%s: nonstandard IR value",
347 pTap
->ir_capture_value
= w
;
350 } /* switch (n->value) */
351 } /* while (goi->argc) */
353 /* default is enabled-after-reset */
354 pTap
->enabled
= !pTap
->disabled_after_reset
;
356 /* Did all the required option bits get cleared? */
363 Jim_SetResult_sprintf(goi
->interp
,
364 "newtap: %s missing required parameters",
370 static void jtag_tap_handle_event(jtag_tap_t
*tap
, enum jtag_event e
)
372 jtag_tap_event_action_t
* jteap
;
374 for (jteap
= tap
->event_action
; jteap
!= NULL
; jteap
= jteap
->next
) {
375 if (jteap
->event
== e
) {
376 LOG_DEBUG("JTAG tap: %s event: %d (%s) action: %s\n",
379 Jim_Nvp_value2name_simple(nvp_jtag_tap_event
, e
)->name
,
380 Jim_GetString(jteap
->body
, NULL
));
381 if (Jim_EvalObj(interp
, jteap
->body
) != JIM_OK
) {
382 Jim_PrintErrorMessage(interp
);
384 case JTAG_TAP_EVENT_ENABLE
:
385 case JTAG_TAP_EVENT_DISABLE
:
386 /* NOTE: we currently assume the handlers
387 * can't fail. That presumes later code
388 * will be verifying the scan chains ...
390 tap
->enabled
= (e
== JTAG_TAP_EVENT_ENABLE
);
400 static int jim_jtag_command(Jim_Interp
*interp
, int argc
, Jim_Obj
*const *argv
)
406 struct command_context_s
*context
;
414 JTAG_CMD_TAPISENABLED
,
420 const Jim_Nvp jtag_cmds
[] = {
421 { .name
= "interface" , .value
= JTAG_CMD_INTERFACE
},
422 { .name
= "arp_init-reset", .value
= JTAG_CMD_INIT_RESET
},
423 { .name
= "newtap" , .value
= JTAG_CMD_NEWTAP
},
424 { .name
= "tapisenabled" , .value
= JTAG_CMD_TAPISENABLED
},
425 { .name
= "tapenable" , .value
= JTAG_CMD_TAPENABLE
},
426 { .name
= "tapdisable" , .value
= JTAG_CMD_TAPDISABLE
},
427 { .name
= "configure" , .value
= JTAG_CMD_CONFIGURE
},
428 { .name
= "cget" , .value
= JTAG_CMD_CGET
},
429 { .name
= "names" , .value
= JTAG_CMD_NAMES
},
431 { .name
= NULL
, .value
= -1 },
434 context
= Jim_GetAssocData(interp
, "context");
435 /* go past the command */
436 Jim_GetOpt_Setup(&goi
, interp
, argc
-1, argv
+ 1);
438 e
= Jim_GetOpt_Nvp(&goi
, jtag_cmds
, &n
);
440 Jim_GetOpt_NvpUnknown(&goi
, jtag_cmds
, 0);
443 Jim_SetEmptyResult(goi
.interp
);
445 case JTAG_CMD_INTERFACE
:
446 /* return the name of the interface */
447 /* TCL code might need to know the exact type... */
448 /* FUTURE: we allow this as a means to "set" the interface. */
450 Jim_WrongNumArgs(goi
.interp
, 1, goi
.argv
-1, "(no params)");
453 Jim_SetResultString(goi
.interp
, jtag_interface
->name
, -1);
455 case JTAG_CMD_INIT_RESET
:
457 Jim_WrongNumArgs(goi
.interp
, 1, goi
.argv
-1, "(no params)");
460 e
= jtag_init_reset(context
);
462 Jim_SetResult_sprintf(goi
.interp
, "error: %d", e
);
466 case JTAG_CMD_NEWTAP
:
467 return jim_newtap_cmd(&goi
);
469 case JTAG_CMD_TAPISENABLED
:
470 case JTAG_CMD_TAPENABLE
:
471 case JTAG_CMD_TAPDISABLE
:
473 Jim_SetResultString(goi
.interp
, "Too many parameters",-1);
480 t
= jtag_tap_by_jim_obj(goi
.interp
, goi
.argv
[0]);
485 case JTAG_CMD_TAPISENABLED
:
487 case JTAG_CMD_TAPENABLE
:
490 jtag_tap_handle_event(t
, JTAG_TAP_EVENT_ENABLE
);
494 /* FIXME add JTAG sanity checks, w/o TLR
495 * - scan chain length grew by one (this)
496 * - IDs and IR lengths are as expected
499 jtag_call_event_callbacks(JTAG_TAP_EVENT_ENABLE
);
501 case JTAG_CMD_TAPDISABLE
:
504 jtag_tap_handle_event(t
, JTAG_TAP_EVENT_DISABLE
);
508 /* FIXME add JTAG sanity checks, w/o TLR
509 * - scan chain length shrank by one (this)
510 * - IDs and IR lengths are as expected
513 jtag_call_event_callbacks(JTAG_TAP_EVENT_DISABLE
);
517 Jim_SetResult(goi
.interp
, Jim_NewIntObj(goi
.interp
, e
));
524 Jim_WrongNumArgs(goi
.interp
, 0, NULL
,
525 "cget tap_name queryparm");
532 Jim_GetOpt_Obj(&goi
, &o
);
533 t
= jtag_tap_by_jim_obj(goi
.interp
, o
);
539 return jtag_tap_configure_cmd(&goi
, t
);
543 case JTAG_CMD_CONFIGURE
:
545 Jim_WrongNumArgs(goi
.interp
, 0, NULL
,
546 "configure tap_name attribute value ...");
553 Jim_GetOpt_Obj(&goi
, &o
);
554 t
= jtag_tap_by_jim_obj(goi
.interp
, o
);
560 return jtag_tap_configure_cmd(&goi
, t
);
566 Jim_WrongNumArgs(goi
.interp
, 1, goi
.argv
, "Too many parameters");
569 Jim_SetResult(goi
.interp
, Jim_NewListObj(goi
.interp
, NULL
, 0));
573 for (tap
= jtag_all_taps(); tap
; tap
= tap
->next_tap
) {
574 Jim_ListAppendElement(goi
.interp
,
575 Jim_GetResult(goi
.interp
),
576 Jim_NewStringObj(goi
.interp
,
577 tap
->dotted_name
, -1));
589 void jtag_notify_reset(void)
592 for (tap
= jtag_all_taps(); tap
; tap
= tap
->next_tap
)
594 jtag_tap_handle_event(tap
, JTAG_TAP_EVENT_POST_RESET
);
599 int jtag_register_commands(struct command_context_s
*cmd_ctx
)
601 register_jim(cmd_ctx
, "jtag", jim_jtag_command
, "perform jtag tap actions");
603 register_command(cmd_ctx
, NULL
, "interface", handle_interface_command
,
604 COMMAND_CONFIG
, "try to configure interface");
605 register_command(cmd_ctx
, NULL
,
606 "interface_list", &handle_interface_list_command
,
607 COMMAND_ANY
, "list all built-in interfaces");
608 register_command(cmd_ctx
, NULL
, "jtag_speed", handle_jtag_speed_command
,
609 COMMAND_ANY
, "(DEPRECATED) set jtag speed (if supported)");
610 register_command(cmd_ctx
, NULL
, "jtag_khz", handle_jtag_khz_command
,
611 COMMAND_ANY
, "set maximum jtag speed (if supported); "
612 "parameter is maximum khz, or 0 for adaptive clocking (RTCK).");
613 register_command(cmd_ctx
, NULL
, "jtag_rclk", handle_jtag_rclk_command
,
614 COMMAND_ANY
, "fallback_speed_khz - set JTAG speed to RCLK or use fallback speed");
615 register_command(cmd_ctx
, NULL
, "jtag_device", handle_jtag_device_command
,
616 COMMAND_CONFIG
, "(DEPRECATED) jtag_device <ir_length> <ir_expected> <ir_mask>");
617 register_command(cmd_ctx
, NULL
, "reset_config", handle_reset_config_command
,
619 "[none/trst_only/srst_only/trst_and_srst] [srst_pulls_trst/trst_pulls_srst] [combined/separate] [trst_push_pull/trst_open_drain] [srst_push_pull/srst_open_drain]");
620 register_command(cmd_ctx
, NULL
, "jtag_nsrst_delay", handle_jtag_nsrst_delay_command
,
621 COMMAND_ANY
, "jtag_nsrst_delay <ms> - delay after deasserting srst in ms");
622 register_command(cmd_ctx
, NULL
, "jtag_ntrst_delay", handle_jtag_ntrst_delay_command
,
623 COMMAND_ANY
, "jtag_ntrst_delay <ms> - delay after deasserting trst in ms");
624 register_command(cmd_ctx
, NULL
, "jtag_nsrst_assert_width", handle_jtag_nsrst_assert_width_command
,
625 COMMAND_ANY
, "jtag_nsrst_assert_width <ms> - delay after asserting srst in ms");
626 register_command(cmd_ctx
, NULL
, "jtag_ntrst_assert_width", handle_jtag_ntrst_assert_width_command
,
627 COMMAND_ANY
, "jtag_ntrst_assert_width <ms> - delay after asserting trst in ms");
629 register_command(cmd_ctx
, NULL
, "scan_chain", handle_scan_chain_command
,
630 COMMAND_EXEC
, "print current scan chain configuration");
632 register_command(cmd_ctx
, NULL
, "jtag_reset", handle_jtag_reset_command
,
633 COMMAND_EXEC
, "toggle reset lines <trst> <srst>");
634 register_command(cmd_ctx
, NULL
, "runtest", handle_runtest_command
,
635 COMMAND_EXEC
, "move to Run-Test/Idle, and execute <num_cycles>");
636 register_command(cmd_ctx
, NULL
, "irscan", handle_irscan_command
,
637 COMMAND_EXEC
, "execute IR scan <device> <instr> [dev2] [instr2] ...");
638 register_jim(cmd_ctx
, "drscan", Jim_Command_drscan
, "execute DR scan <device> <num_bits> <value> <num_bits1> <value2> ...");
639 register_jim(cmd_ctx
, "flush_count", Jim_Command_flush_count
, "returns number of times the JTAG queue has been flushed");
640 register_jim(cmd_ctx
, "pathmove", Jim_Command_pathmove
, "move JTAG to state1 then to state2, state3, etc. <state1>,<state2>,<stat3>...");
642 register_command(cmd_ctx
, NULL
, "verify_ircapture", handle_verify_ircapture_command
,
643 COMMAND_ANY
, "verify value captured during Capture-IR <enable | disable>");
644 register_command(cmd_ctx
, NULL
, "verify_jtag", handle_verify_jtag_command
,
645 COMMAND_ANY
, "verify value capture <enable | disable>");
646 register_command(cmd_ctx
, NULL
, "tms_sequence", handle_tms_sequence_command
,
647 COMMAND_ANY
, "choose short(default) or long tms_sequence <short | long>");
651 static int default_khz(int khz
, int *jtag_speed
)
653 LOG_ERROR("Translation from khz to jtag_speed not implemented");
657 static int default_speed_div(int speed
, int *khz
)
659 LOG_ERROR("Translation from jtag_speed to khz not implemented");
663 static int default_power_dropout(int *dropout
)
665 *dropout
= 0; /* by default we can't detect power dropout */
669 static int default_srst_asserted(int *srst_asserted
)
671 *srst_asserted
= 0; /* by default we can't detect srst asserted */
675 static int handle_interface_command(struct command_context_s
*cmd_ctx
,
676 char *cmd
, char **args
, int argc
)
678 /* check whether the interface is already configured */
681 LOG_WARNING("Interface already configured, ignoring");
685 /* interface name is a mandatory argument */
686 if (argc
!= 1 || args
[0][0] == '\0')
687 return ERROR_COMMAND_SYNTAX_ERROR
;
689 for (unsigned i
= 0; NULL
!= jtag_interfaces
[i
]; i
++)
691 if (strcmp(args
[0], jtag_interfaces
[i
]->name
) != 0)
694 int retval
= jtag_interfaces
[i
]->register_commands(cmd_ctx
);
695 if (ERROR_OK
!= retval
)
698 jtag_interface
= jtag_interfaces
[i
];
700 if (jtag_interface
->khz
== NULL
)
701 jtag_interface
->khz
= default_khz
;
702 if (jtag_interface
->speed_div
== NULL
)
703 jtag_interface
->speed_div
= default_speed_div
;
704 if (jtag_interface
->power_dropout
== NULL
)
705 jtag_interface
->power_dropout
= default_power_dropout
;
706 if (jtag_interface
->srst_asserted
== NULL
)
707 jtag_interface
->srst_asserted
= default_srst_asserted
;
712 /* no valid interface was found (i.e. the configuration option,
713 * didn't match one of the compiled-in interfaces
715 LOG_ERROR("The specified JTAG interface was not found (%s)", args
[0]);
716 handle_interface_list_command(cmd_ctx
, cmd
, args
, argc
);
717 return ERROR_JTAG_INVALID_INTERFACE
;
720 static int handle_interface_list_command(struct command_context_s
*cmd_ctx
,
721 char *cmd
, char **args
, int argc
)
723 if (strcmp(cmd
, "interface_list") == 0 && argc
> 0)
724 return ERROR_COMMAND_SYNTAX_ERROR
;
726 command_print(cmd_ctx
, "The following JTAG interfaces are available:");
727 for (unsigned i
= 0; NULL
!= jtag_interfaces
[i
]; i
++)
729 const char *name
= jtag_interfaces
[i
]->name
;
730 command_print(cmd_ctx
, "%u: %s", i
+ 1, name
);
736 static int handle_jtag_device_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
740 Jim_Obj
*newargs
[ 10 ];
744 * argv[ 0] = ir length
745 * argv[ 1] = ir capture
747 * argv[ 3] = not actually used by anything but in the docs
751 command_print(cmd_ctx
, "OLD DEPRECATED SYNTAX: Please use the NEW syntax");
754 command_print(cmd_ctx
, "OLD SYNTAX: DEPRECATED - translating to new syntax");
755 command_print(cmd_ctx
, "jtag newtap CHIP TAP -irlen %s -ircapture %s -irvalue %s",
759 command_print(cmd_ctx
, "Example: STM32 has 2 taps, the cortexM3(len4) + boundaryscan(len5)");
760 command_print(cmd_ctx
, "jtag newtap stm32 cortexm3 ....., thus creating the tap: \"stm32.cortexm3\"");
761 command_print(cmd_ctx
, "jtag newtap stm32 boundary ....., and the tap: \"stm32.boundary\"");
762 command_print(cmd_ctx
, "And then refer to the taps by the dotted name.");
764 newargs
[0] = Jim_NewStringObj(interp
, "jtag", -1);
765 newargs
[1] = Jim_NewStringObj(interp
, "newtap", -1);
766 sprintf(buf
, "chip%d", jtag_tap_count());
767 newargs
[2] = Jim_NewStringObj(interp
, buf
, -1);
768 sprintf(buf
, "tap%d", jtag_tap_count());
769 newargs
[3] = Jim_NewStringObj(interp
, buf
, -1);
770 newargs
[4] = Jim_NewStringObj(interp
, "-irlen", -1);
771 newargs
[5] = Jim_NewStringObj(interp
, args
[0], -1);
772 newargs
[6] = Jim_NewStringObj(interp
, "-ircapture", -1);
773 newargs
[7] = Jim_NewStringObj(interp
, args
[1], -1);
774 newargs
[8] = Jim_NewStringObj(interp
, "-irmask", -1);
775 newargs
[9] = Jim_NewStringObj(interp
, args
[2], -1);
777 command_print(cmd_ctx
, "NEW COMMAND:");
778 sprintf(buf
, "%s %s %s %s %s %s %s %s %s %s",
779 Jim_GetString(newargs
[0], NULL
),
780 Jim_GetString(newargs
[1], NULL
),
781 Jim_GetString(newargs
[2], NULL
),
782 Jim_GetString(newargs
[3], NULL
),
783 Jim_GetString(newargs
[4], NULL
),
784 Jim_GetString(newargs
[5], NULL
),
785 Jim_GetString(newargs
[6], NULL
),
786 Jim_GetString(newargs
[7], NULL
),
787 Jim_GetString(newargs
[8], NULL
),
788 Jim_GetString(newargs
[9], NULL
));
790 e
= jim_jtag_command(interp
, 10, newargs
);
792 command_print(cmd_ctx
, "%s", Jim_GetString(Jim_GetResult(interp
), NULL
));
797 static int handle_scan_chain_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
801 tap
= jtag_all_taps();
802 command_print(cmd_ctx
, " TapName | Enabled | IdCode Expected IrLen IrCap IrMask Instr ");
803 command_print(cmd_ctx
, "---|--------------------|---------|------------|------------|------|------|------|---------");
806 uint32_t expected
, expected_mask
, cur_instr
, ii
;
807 expected
= buf_get_u32(tap
->expected
, 0, tap
->ir_length
);
808 expected_mask
= buf_get_u32(tap
->expected_mask
, 0, tap
->ir_length
);
809 cur_instr
= buf_get_u32(tap
->cur_instr
, 0, tap
->ir_length
);
811 command_print(cmd_ctx
,
812 "%2d | %-18s | %c | 0x%08x | 0x%08x | 0x%02x | 0x%02x | 0x%02x | 0x%02x",
813 tap
->abs_chain_position
,
815 tap
->enabled
? 'Y' : 'n',
816 (unsigned int)(tap
->idcode
),
817 (unsigned int)(tap
->expected_ids_cnt
> 0 ? tap
->expected_ids
[0] : 0),
818 (unsigned int)(tap
->ir_length
),
819 (unsigned int)(expected
),
820 (unsigned int)(expected_mask
),
821 (unsigned int)(cur_instr
));
823 for (ii
= 1; ii
< tap
->expected_ids_cnt
; ii
++) {
824 command_print(cmd_ctx
, " | | | | 0x%08x | | | | ",
825 (unsigned int)(tap
->expected_ids
[ii
]));
834 static int handle_reset_config_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
840 return ERROR_COMMAND_SYNTAX_ERROR
;
842 /* Original versions cared about the order of these tokens:
843 * reset_config signals [combination [trst_type [srst_type]]]
844 * They also clobbered the previous configuration even on error.
846 * Here we don't care about the order, and only change values
847 * which have been explicitly specified.
849 for (; argc
; argc
--, args
++) {
853 m
= RESET_SRST_GATES_JTAG
;
855 if (strcmp(*args
, "srst_gates_jtag") == 0)
857 tmp
= RESET_SRST_GATES_JTAG
;
862 m
= RESET_HAS_TRST
| RESET_HAS_SRST
;
863 if (strcmp(*args
, "none") == 0)
865 else if (strcmp(*args
, "trst_only") == 0)
866 tmp
= RESET_HAS_TRST
;
867 else if (strcmp(*args
, "srst_only") == 0)
868 tmp
= RESET_HAS_SRST
;
869 else if (strcmp(*args
, "trst_and_srst") == 0)
870 tmp
= RESET_HAS_TRST
| RESET_HAS_SRST
;
874 LOG_ERROR("extra reset_config %s spec (%s)",
876 return ERROR_INVALID_ARGUMENTS
;
881 /* combination (options for broken wiring) */
882 m
= RESET_SRST_PULLS_TRST
| RESET_TRST_PULLS_SRST
;
883 if (strcmp(*args
, "separate") == 0)
884 /* separate reset lines - default */;
885 else if (strcmp(*args
, "srst_pulls_trst") == 0)
886 tmp
|= RESET_SRST_PULLS_TRST
;
887 else if (strcmp(*args
, "trst_pulls_srst") == 0)
888 tmp
|= RESET_TRST_PULLS_SRST
;
889 else if (strcmp(*args
, "combined") == 0)
890 tmp
|= RESET_SRST_PULLS_TRST
| RESET_TRST_PULLS_SRST
;
894 LOG_ERROR("extra reset_config %s spec (%s)",
895 "combination", *args
);
896 return ERROR_INVALID_ARGUMENTS
;
901 /* trst_type (NOP without HAS_TRST) */
902 m
= RESET_TRST_OPEN_DRAIN
;
903 if (strcmp(*args
, "trst_open_drain") == 0)
904 tmp
|= RESET_TRST_OPEN_DRAIN
;
905 else if (strcmp(*args
, "trst_push_pull") == 0)
906 /* push/pull from adapter - default */;
910 LOG_ERROR("extra reset_config %s spec (%s)",
912 return ERROR_INVALID_ARGUMENTS
;
917 /* srst_type (NOP without HAS_SRST) */
918 m
|= RESET_SRST_PUSH_PULL
;
919 if (strcmp(*args
, "srst_push_pull") == 0)
920 tmp
|= RESET_SRST_PUSH_PULL
;
921 else if (strcmp(*args
, "srst_open_drain") == 0)
922 /* open drain from adapter - default */;
926 LOG_ERROR("extra reset_config %s spec (%s)",
928 return ERROR_INVALID_ARGUMENTS
;
933 /* caller provided nonsense; fail */
934 LOG_ERROR("unknown reset_config flag (%s)", *args
);
935 return ERROR_INVALID_ARGUMENTS
;
938 /* Remember the bits which were specified (mask)
939 * and their new values (new_cfg).
945 /* clear previous values of those bits, save new values */
946 enum reset_types old_cfg
= jtag_get_reset_config();
949 jtag_set_reset_config(new_cfg
);
954 static int handle_jtag_nsrst_delay_command(struct command_context_s
*cmd_ctx
,
955 char *cmd
, char **args
, int argc
)
958 return ERROR_COMMAND_SYNTAX_ERROR
;
962 int retval
= parse_uint(args
[0], &delay
);
963 if (ERROR_OK
!= retval
)
965 jtag_set_nsrst_delay(delay
);
967 command_print(cmd_ctx
, "jtag_nsrst_delay: %u", jtag_get_nsrst_delay());
971 static int handle_jtag_ntrst_delay_command(struct command_context_s
*cmd_ctx
,
972 char *cmd
, char **args
, int argc
)
975 return ERROR_COMMAND_SYNTAX_ERROR
;
979 int retval
= parse_uint(args
[0], &delay
);
980 if (ERROR_OK
!= retval
)
982 jtag_set_ntrst_delay(delay
);
984 command_print(cmd_ctx
, "jtag_ntrst_delay: %u", jtag_get_ntrst_delay());
988 static int handle_jtag_nsrst_assert_width_command(struct command_context_s
*cmd_ctx
,
989 char *cmd
, char **args
, int argc
)
992 return ERROR_COMMAND_SYNTAX_ERROR
;
996 int retval
= parse_uint(args
[0], &delay
);
997 if (ERROR_OK
!= retval
)
999 jtag_set_nsrst_assert_width(delay
);
1001 command_print(cmd_ctx
, "jtag_nsrst_assert_width: %u", jtag_get_nsrst_assert_width());
1005 static int handle_jtag_ntrst_assert_width_command(struct command_context_s
*cmd_ctx
,
1006 char *cmd
, char **args
, int argc
)
1009 return ERROR_COMMAND_SYNTAX_ERROR
;
1013 int retval
= parse_uint(args
[0], &delay
);
1014 if (ERROR_OK
!= retval
)
1016 jtag_set_ntrst_assert_width(delay
);
1018 command_print(cmd_ctx
, "jtag_ntrst_assert_width: %u", jtag_get_ntrst_assert_width());
1022 static int handle_jtag_speed_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1024 int retval
= ERROR_OK
;
1026 command_print(cmd_ctx
, "OLD SYNTAX: DEPRECATED - "
1027 "use jtag_khz, not jtag_speed");
1030 return ERROR_COMMAND_SYNTAX_ERROR
;
1033 LOG_DEBUG("handle jtag speed");
1035 unsigned cur_speed
= 0;
1036 int retval
= parse_uint(args
[0], &cur_speed
);
1037 if (ERROR_OK
!= retval
)
1039 retval
= jtag_config_speed(cur_speed
);
1042 command_print(cmd_ctx
, "jtag_speed: %d", jtag_get_speed());
1047 static int handle_jtag_khz_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1050 return ERROR_COMMAND_SYNTAX_ERROR
;
1052 int retval
= ERROR_OK
;
1056 int retval
= parse_uint(args
[0], &khz
);
1057 if (ERROR_OK
!= retval
)
1059 retval
= jtag_config_khz(khz
);
1060 if (ERROR_OK
!= retval
)
1064 int cur_speed
= jtag_get_speed_khz();
1065 retval
= jtag_get_speed_readable(&cur_speed
);
1066 if (ERROR_OK
!= retval
)
1070 command_print(cmd_ctx
, "%d kHz", cur_speed
);
1072 command_print(cmd_ctx
, "RCLK - adaptive");
1077 static int handle_jtag_rclk_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1080 return ERROR_COMMAND_SYNTAX_ERROR
;
1082 int retval
= ERROR_OK
;
1086 int retval
= parse_uint(args
[0], &khz
);
1087 if (ERROR_OK
!= retval
)
1089 retval
= jtag_config_rclk(khz
);
1090 if (ERROR_OK
!= retval
)
1094 int cur_khz
= jtag_get_speed_khz();
1095 retval
= jtag_get_speed_readable(&cur_khz
);
1096 if (ERROR_OK
!= retval
)
1100 command_print(cmd_ctx
, "RCLK not supported - fallback to %d kHz", cur_khz
);
1102 command_print(cmd_ctx
, "RCLK - adaptive");
1107 static int handle_jtag_reset_command(struct command_context_s
*cmd_ctx
,
1108 char *cmd
, char **args
, int argc
)
1111 return ERROR_COMMAND_SYNTAX_ERROR
;
1114 if (args
[0][0] == '1')
1116 else if (args
[0][0] == '0')
1119 return ERROR_COMMAND_SYNTAX_ERROR
;
1122 if (args
[1][0] == '1')
1124 else if (args
[1][0] == '0')
1127 return ERROR_COMMAND_SYNTAX_ERROR
;
1129 if (jtag_interface_init(cmd_ctx
) != ERROR_OK
)
1130 return ERROR_JTAG_INIT_FAILED
;
1132 jtag_add_reset(trst
, srst
);
1133 return jtag_execute_queue();
1136 static int handle_runtest_command(struct command_context_s
*cmd_ctx
,
1137 char *cmd
, char **args
, int argc
)
1140 return ERROR_COMMAND_SYNTAX_ERROR
;
1142 unsigned num_clocks
;
1143 int retval
= parse_uint(args
[0], &num_clocks
);
1144 if (ERROR_OK
!= retval
)
1147 jtag_add_runtest(num_clocks
, TAP_IDLE
);
1148 return jtag_execute_queue();
1152 * For "irscan" or "drscan" commands, the "end" (really, "next") state
1153 * should be stable ... and *NOT* a shift state, otherwise free-running
1154 * jtag clocks could change the values latched by the update state.
1156 static bool scan_is_safe(tap_state_t state
)
1171 static int handle_irscan_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1174 scan_field_t
*fields
;
1176 tap_state_t endstate
;
1178 if ((argc
< 2) || (argc
% 2))
1180 return ERROR_COMMAND_SYNTAX_ERROR
;
1183 /* optional "-endstate" "statename" at the end of the arguments,
1184 * so that e.g. IRPAUSE can let us load the data register before
1185 * entering RUN/IDLE to execute the instruction we load here.
1187 endstate
= TAP_IDLE
;
1190 /* have at least one pair of numbers. */
1191 /* is last pair the magic text? */
1192 if (0 == strcmp("-endstate", args
[ argc
- 2 ])) {
1195 cpA
= args
[ argc
-1 ];
1196 for (endstate
= 0 ; endstate
< TAP_NUM_STATES
; endstate
++) {
1197 cpS
= tap_state_name(endstate
);
1198 if (0 == strcmp(cpA
, cpS
)) {
1202 if (endstate
>= TAP_NUM_STATES
) {
1203 return ERROR_COMMAND_SYNTAX_ERROR
;
1205 if (!scan_is_safe(endstate
))
1206 LOG_WARNING("irscan with unsafe "
1207 "endstate \"%s\"", cpA
);
1208 /* found - remove the last 2 args */
1214 int num_fields
= argc
/ 2;
1215 size_t fields_len
= sizeof(scan_field_t
) * num_fields
;
1216 fields
= malloc(fields_len
);
1217 memset(fields
, 0, fields_len
);
1220 for (i
= 0; i
< num_fields
; i
++)
1222 tap
= jtag_tap_by_string(args
[i
*2]);
1226 for (j
= 0; j
< i
; j
++)
1227 free(fields
[j
].out_value
);
1229 command_print(cmd_ctx
, "Tap: %s unknown", args
[i
*2]);
1233 int field_size
= tap
->ir_length
;
1234 fields
[i
].tap
= tap
;
1235 fields
[i
].num_bits
= field_size
;
1236 fields
[i
].out_value
= malloc(CEIL(field_size
, 8));
1239 retval
= parse_u32(args
[i
* 2 + 1], &value
);
1240 if (ERROR_OK
!= retval
)
1242 buf_set_u32(fields
[i
].out_value
, 0, field_size
, value
);
1243 fields
[i
].in_value
= NULL
;
1246 /* did we have an endstate? */
1247 jtag_add_ir_scan(num_fields
, fields
, endstate
);
1249 retval
= jtag_execute_queue();
1252 for (i
= 0; i
< num_fields
; i
++)
1254 if (NULL
!= fields
[i
].out_value
)
1255 free(fields
[i
].out_value
);
1263 static int Jim_Command_drscan(Jim_Interp
*interp
, int argc
, Jim_Obj
*const *args
)
1266 scan_field_t
*fields
;
1268 int field_count
= 0;
1271 tap_state_t endstate
;
1274 * args[2] = num_bits
1275 * args[3] = hex string
1276 * ... repeat num bits and hex string ...
1279 * args[N-2] = "-endstate"
1280 * args[N-1] = statename
1282 if ((argc
< 4) || ((argc
% 2) != 0))
1284 Jim_WrongNumArgs(interp
, 1, args
, "wrong arguments");
1288 endstate
= TAP_IDLE
;
1290 script_debug(interp
, "drscan", argc
, args
);
1292 /* validate arguments as numbers */
1294 for (i
= 2; i
< argc
; i
+= 2)
1299 e
= Jim_GetLong(interp
, args
[i
], &bits
);
1300 /* If valid - try next arg */
1305 /* Not valid.. are we at the end? */
1306 if (((i
+ 2) != argc
)) {
1307 /* nope, then error */
1311 /* it could be: "-endstate FOO"
1312 * e.g. DRPAUSE so we can issue more instructions
1313 * before entering RUN/IDLE and executing them.
1316 /* get arg as a string. */
1317 cp
= Jim_GetString(args
[i
], NULL
);
1318 /* is it the magic? */
1319 if (0 == strcmp("-endstate", cp
)) {
1320 /* is the statename valid? */
1321 cp
= Jim_GetString(args
[i
+ 1], NULL
);
1323 /* see if it is a valid state name */
1324 endstate
= tap_state_by_name(cp
);
1326 /* update the error message */
1327 Jim_SetResult_sprintf(interp
,"endstate: %s invalid", cp
);
1329 if (!scan_is_safe(endstate
))
1330 LOG_WARNING("drscan with unsafe "
1331 "endstate \"%s\"", cp
);
1333 /* valid - so clear the error */
1335 /* and remove the last 2 args */
1340 /* Still an error? */
1342 return e
; /* too bad */
1344 } /* validate args */
1346 tap
= jtag_tap_by_jim_obj(interp
, args
[1]);
1351 num_fields
= (argc
-2)/2;
1352 fields
= malloc(sizeof(scan_field_t
) * num_fields
);
1353 for (i
= 2; i
< argc
; i
+= 2)
1359 Jim_GetLong(interp
, args
[i
], &bits
);
1360 str
= Jim_GetString(args
[i
+ 1], &len
);
1362 fields
[field_count
].tap
= tap
;
1363 fields
[field_count
].num_bits
= bits
;
1364 fields
[field_count
].out_value
= malloc(CEIL(bits
, 8));
1365 str_to_buf(str
, len
, fields
[field_count
].out_value
, bits
, 0);
1366 fields
[field_count
].in_value
= fields
[field_count
].out_value
;
1370 jtag_add_dr_scan(num_fields
, fields
, endstate
);
1372 retval
= jtag_execute_queue();
1373 if (retval
!= ERROR_OK
)
1375 Jim_SetResultString(interp
, "drscan: jtag execute failed",-1);
1380 Jim_Obj
*list
= Jim_NewListObj(interp
, NULL
, 0);
1381 for (i
= 2; i
< argc
; i
+= 2)
1386 Jim_GetLong(interp
, args
[i
], &bits
);
1387 str
= buf_to_str(fields
[field_count
].in_value
, bits
, 16);
1388 free(fields
[field_count
].out_value
);
1390 Jim_ListAppendElement(interp
, list
, Jim_NewStringObj(interp
, str
, strlen(str
)));
1395 Jim_SetResult(interp
, list
);
1403 static int Jim_Command_pathmove(Jim_Interp
*interp
, int argc
, Jim_Obj
*const *args
)
1405 tap_state_t states
[8];
1407 if ((argc
< 2) || ((size_t)argc
> (sizeof(states
)/sizeof(*states
) + 1)))
1409 Jim_WrongNumArgs(interp
, 1, args
, "wrong arguments");
1413 script_debug(interp
, "pathmove", argc
, args
);
1416 for (i
= 0; i
< argc
-1; i
++)
1419 cp
= Jim_GetString(args
[i
+ 1], NULL
);
1420 states
[i
] = tap_state_by_name(cp
);
1423 /* update the error message */
1424 Jim_SetResult_sprintf(interp
,"endstate: %s invalid", cp
);
1429 if ((jtag_add_statemove(states
[0]) != ERROR_OK
) || (jtag_execute_queue()!= ERROR_OK
))
1431 Jim_SetResultString(interp
, "pathmove: jtag execute failed",-1);
1435 jtag_add_pathmove(argc
-2, states
+ 1);
1437 if (jtag_execute_queue()!= ERROR_OK
)
1439 Jim_SetResultString(interp
, "pathmove: failed",-1);
1447 static int Jim_Command_flush_count(Jim_Interp
*interp
, int argc
, Jim_Obj
*const *args
)
1449 script_debug(interp
, "flush_count", argc
, args
);
1451 Jim_SetResult(interp
, Jim_NewIntObj(interp
, jtag_get_flush_queue_count()));
1457 static int handle_verify_ircapture_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1460 return ERROR_COMMAND_SYNTAX_ERROR
;
1464 if (strcmp(args
[0], "enable") == 0)
1465 jtag_set_verify_capture_ir(true);
1466 else if (strcmp(args
[0], "disable") == 0)
1467 jtag_set_verify_capture_ir(false);
1469 return ERROR_COMMAND_SYNTAX_ERROR
;
1472 const char *status
= jtag_will_verify_capture_ir() ? "enabled": "disabled";
1473 command_print(cmd_ctx
, "verify Capture-IR is %s", status
);
1478 static int handle_verify_jtag_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1481 return ERROR_COMMAND_SYNTAX_ERROR
;
1485 if (strcmp(args
[0], "enable") == 0)
1486 jtag_set_verify(true);
1487 else if (strcmp(args
[0], "disable") == 0)
1488 jtag_set_verify(false);
1490 return ERROR_COMMAND_SYNTAX_ERROR
;
1493 const char *status
= jtag_will_verify() ? "enabled": "disabled";
1494 command_print(cmd_ctx
, "verify jtag capture is %s", status
);
1499 static int handle_tms_sequence_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1502 return ERROR_COMMAND_SYNTAX_ERROR
;
1507 if (strcmp(args
[0], "short") == 0)
1508 use_new_table
= true;
1509 else if (strcmp(args
[0], "long") == 0)
1510 use_new_table
= false;
1512 return ERROR_COMMAND_SYNTAX_ERROR
;
1514 tap_use_new_tms_table(use_new_table
);
1517 command_print(cmd_ctx
, "tms sequence is %s",
1518 tap_uses_new_tms_table() ? "short": "long");
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)