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 jtag_interface_t
*jtag_interface
;
55 static int handle_interface_list_command(struct command_context_s
*cmd_ctx
,
56 char *cmd
, char **args
, int argc
);
57 static int handle_interface_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
58 static int handle_jtag_speed_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
59 static int handle_jtag_khz_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
60 static int handle_jtag_rclk_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
61 static int handle_jtag_device_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
62 static int handle_reset_config_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
63 static int handle_jtag_nsrst_delay_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
64 static int handle_jtag_ntrst_delay_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
65 static int handle_jtag_nsrst_assert_width_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
66 static int handle_jtag_ntrst_assert_width_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
68 static int handle_scan_chain_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
70 static int handle_jtag_reset_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
71 static int handle_runtest_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
72 static int handle_irscan_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
73 static int Jim_Command_drscan(Jim_Interp
*interp
, int argc
, Jim_Obj
*const *argv
);
74 static int Jim_Command_pathmove(Jim_Interp
*interp
, int argc
, Jim_Obj
*const *argv
);
75 static int Jim_Command_flush_count(Jim_Interp
*interp
, int argc
, Jim_Obj
*const *args
);
77 static int handle_verify_ircapture_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
78 static int handle_verify_jtag_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
79 static int handle_tms_sequence_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
82 enum jtag_tap_cfg_param
{
86 static Jim_Nvp nvp_config_opts
[] = {
87 { .name
= "-event", .value
= JCFG_EVENT
},
89 { .name
= NULL
, .value
= -1 }
92 static int jtag_tap_configure_cmd(Jim_GetOptInfo
*goi
, jtag_tap_t
* tap
)
98 /* parse config or cget options */
99 while (goi
->argc
> 0) {
100 Jim_SetEmptyResult (goi
->interp
);
102 e
= Jim_GetOpt_Nvp(goi
, nvp_config_opts
, &n
);
104 Jim_GetOpt_NvpUnknown(goi
, nvp_config_opts
, 0);
110 if (goi
->argc
== 0) {
111 Jim_WrongNumArgs(goi
->interp
, goi
->argc
, goi
->argv
, "-event ?event-name? ...");
115 e
= Jim_GetOpt_Nvp(goi
, nvp_jtag_tap_event
, &n
);
117 Jim_GetOpt_NvpUnknown(goi
, nvp_jtag_tap_event
, 1);
121 if (goi
->isconfigure
) {
122 if (goi
->argc
!= 1) {
123 Jim_WrongNumArgs(goi
->interp
, goi
->argc
, goi
->argv
, "-event ?event-name? ?EVENT-BODY?");
127 if (goi
->argc
!= 0) {
128 Jim_WrongNumArgs(goi
->interp
, goi
->argc
, goi
->argv
, "-event ?event-name?");
134 jtag_tap_event_action_t
*jteap
;
136 jteap
= tap
->event_action
;
137 /* replace existing? */
139 if (jteap
->event
== (enum jtag_event
)n
->value
) {
145 if (goi
->isconfigure
) {
149 jteap
= calloc(1, sizeof (*jteap
));
152 jteap
->event
= n
->value
;
153 Jim_GetOpt_Obj(goi
, &o
);
155 Jim_DecrRefCount(interp
, jteap
->body
);
157 jteap
->body
= Jim_DuplicateObj(goi
->interp
, o
);
158 Jim_IncrRefCount(jteap
->body
);
162 /* add to head of event list */
163 jteap
->next
= tap
->event_action
;
164 tap
->event_action
= jteap
;
166 Jim_SetEmptyResult(goi
->interp
);
170 Jim_SetEmptyResult(goi
->interp
);
172 Jim_SetResult(goi
->interp
, Jim_DuplicateObj(goi
->interp
, jteap
->body
));
179 } /* while (goi->argc) */
184 static int is_bad_irval(int ir_length
, jim_wide w
)
194 static int jim_newtap_cmd(Jim_GetOptInfo
*goi
)
203 const Jim_Nvp opts
[] = {
204 #define NTAP_OPT_IRLEN 0
205 { .name
= "-irlen" , .value
= NTAP_OPT_IRLEN
},
206 #define NTAP_OPT_IRMASK 1
207 { .name
= "-irmask" , .value
= NTAP_OPT_IRMASK
},
208 #define NTAP_OPT_IRCAPTURE 2
209 { .name
= "-ircapture" , .value
= NTAP_OPT_IRCAPTURE
},
210 #define NTAP_OPT_ENABLED 3
211 { .name
= "-enable" , .value
= NTAP_OPT_ENABLED
},
212 #define NTAP_OPT_DISABLED 4
213 { .name
= "-disable" , .value
= NTAP_OPT_DISABLED
},
214 #define NTAP_OPT_EXPECTED_ID 5
215 { .name
= "-expected-id" , .value
= NTAP_OPT_EXPECTED_ID
},
216 { .name
= NULL
, .value
= -1 },
219 pTap
= calloc(1, sizeof(jtag_tap_t
));
221 Jim_SetResult_sprintf(goi
->interp
, "no memory");
226 * we expect CHIP + TAP + OPTIONS
229 Jim_SetResult_sprintf(goi
->interp
, "Missing CHIP TAP OPTIONS ....");
233 Jim_GetOpt_String(goi
, &cp
, NULL
);
234 pTap
->chip
= strdup(cp
);
236 Jim_GetOpt_String(goi
, &cp
, NULL
);
237 pTap
->tapname
= strdup(cp
);
239 /* name + dot + name + null */
240 x
= strlen(pTap
->chip
) + 1 + strlen(pTap
->tapname
) + 1;
242 sprintf(cp
, "%s.%s", pTap
->chip
, pTap
->tapname
);
243 pTap
->dotted_name
= cp
;
245 LOG_DEBUG("Creating New Tap, Chip: %s, Tap: %s, Dotted: %s, %d params",
246 pTap
->chip
, pTap
->tapname
, pTap
->dotted_name
, goi
->argc
);
248 /* IEEE specifies that the two LSBs of an IR scan are 01, so make
249 * that the default. The "-irlen" and "-irmask" options are only
250 * needed to cope with nonstandard TAPs, or to specify more bits.
252 pTap
->ir_capture_mask
= 0x03;
253 pTap
->ir_capture_value
= 0x01;
255 /* clear flags for "required options" them as we find them */
259 e
= Jim_GetOpt_Nvp(goi
, opts
, &n
);
261 Jim_GetOpt_NvpUnknown(goi
, opts
, 0);
262 free((void *)pTap
->dotted_name
);
266 LOG_DEBUG("Processing option: %s", n
->name
);
268 case NTAP_OPT_ENABLED
:
269 pTap
->disabled_after_reset
= false;
271 case NTAP_OPT_DISABLED
:
272 pTap
->disabled_after_reset
= true;
274 case NTAP_OPT_EXPECTED_ID
:
276 uint32_t *new_expected_ids
;
278 e
= Jim_GetOpt_Wide(goi
, &w
);
280 Jim_SetResult_sprintf(goi
->interp
, "option: %s bad parameter", n
->name
);
281 free((void *)pTap
->dotted_name
);
286 new_expected_ids
= malloc(sizeof(uint32_t) * (pTap
->expected_ids_cnt
+ 1));
287 if (new_expected_ids
== NULL
) {
288 Jim_SetResult_sprintf(goi
->interp
, "no memory");
289 free((void *)pTap
->dotted_name
);
294 memcpy(new_expected_ids
, pTap
->expected_ids
, sizeof(uint32_t) * pTap
->expected_ids_cnt
);
296 new_expected_ids
[pTap
->expected_ids_cnt
] = w
;
298 free(pTap
->expected_ids
);
299 pTap
->expected_ids
= new_expected_ids
;
300 pTap
->expected_ids_cnt
++;
304 case NTAP_OPT_IRMASK
:
305 case NTAP_OPT_IRCAPTURE
:
306 e
= Jim_GetOpt_Wide(goi
, &w
);
308 Jim_SetResult_sprintf(goi
->interp
, "option: %s bad parameter", n
->name
);
309 free((void *)pTap
->dotted_name
);
315 if (w
> (jim_wide
) (8 * sizeof(pTap
->ir_capture_value
)))
316 LOG_WARNING("%s: huge IR length %d",
322 case NTAP_OPT_IRMASK
:
323 if (is_bad_irval(pTap
->ir_length
, w
)) {
324 LOG_ERROR("%s: IR mask %x too big",
327 free((void *)pTap
->dotted_name
);
332 LOG_WARNING("%s: nonstandard IR mask",
334 pTap
->ir_capture_mask
= w
;
336 case NTAP_OPT_IRCAPTURE
:
337 if (is_bad_irval(pTap
->ir_length
, w
)) {
338 LOG_ERROR("%s: IR capture %x too big",
341 free((void *)pTap
->dotted_name
);
346 LOG_WARNING("%s: nonstandard IR value",
348 pTap
->ir_capture_value
= w
;
351 } /* switch (n->value) */
352 } /* while (goi->argc) */
354 /* default is enabled-after-reset */
355 pTap
->enabled
= !pTap
->disabled_after_reset
;
357 /* Did all the required option bits get cleared? */
364 Jim_SetResult_sprintf(goi
->interp
,
365 "newtap: %s missing required parameters",
371 static void jtag_tap_handle_event(jtag_tap_t
*tap
, enum jtag_event e
)
373 jtag_tap_event_action_t
* jteap
;
375 for (jteap
= tap
->event_action
; jteap
!= NULL
; jteap
= jteap
->next
) {
376 if (jteap
->event
== e
) {
377 LOG_DEBUG("JTAG tap: %s event: %d (%s)\n\taction: %s",
380 Jim_Nvp_value2name_simple(nvp_jtag_tap_event
, e
)->name
,
381 Jim_GetString(jteap
->body
, NULL
));
382 if (Jim_EvalObj(interp
, jteap
->body
) != JIM_OK
) {
383 Jim_PrintErrorMessage(interp
);
385 case JTAG_TAP_EVENT_ENABLE
:
386 case JTAG_TAP_EVENT_DISABLE
:
387 /* NOTE: we currently assume the handlers
388 * can't fail. Right here is where we should
389 * really be verifying the scan chains ...
391 tap
->enabled
= (e
== JTAG_TAP_EVENT_ENABLE
);
392 LOG_INFO("JTAG tap: %s %s", tap
->dotted_name
,
393 tap
->enabled
? "enabled" : "disabled");
403 static int jim_jtag_command(Jim_Interp
*interp
, int argc
, Jim_Obj
*const *argv
)
409 struct command_context_s
*context
;
417 JTAG_CMD_TAPISENABLED
,
423 const Jim_Nvp jtag_cmds
[] = {
424 { .name
= "interface" , .value
= JTAG_CMD_INTERFACE
},
425 { .name
= "arp_init-reset", .value
= JTAG_CMD_INIT_RESET
},
426 { .name
= "newtap" , .value
= JTAG_CMD_NEWTAP
},
427 { .name
= "tapisenabled" , .value
= JTAG_CMD_TAPISENABLED
},
428 { .name
= "tapenable" , .value
= JTAG_CMD_TAPENABLE
},
429 { .name
= "tapdisable" , .value
= JTAG_CMD_TAPDISABLE
},
430 { .name
= "configure" , .value
= JTAG_CMD_CONFIGURE
},
431 { .name
= "cget" , .value
= JTAG_CMD_CGET
},
432 { .name
= "names" , .value
= JTAG_CMD_NAMES
},
434 { .name
= NULL
, .value
= -1 },
437 context
= Jim_GetAssocData(interp
, "context");
438 /* go past the command */
439 Jim_GetOpt_Setup(&goi
, interp
, argc
-1, argv
+ 1);
441 e
= Jim_GetOpt_Nvp(&goi
, jtag_cmds
, &n
);
443 Jim_GetOpt_NvpUnknown(&goi
, jtag_cmds
, 0);
446 Jim_SetEmptyResult(goi
.interp
);
448 case JTAG_CMD_INTERFACE
:
449 /* return the name of the interface */
450 /* TCL code might need to know the exact type... */
451 /* FUTURE: we allow this as a means to "set" the interface. */
453 Jim_WrongNumArgs(goi
.interp
, 1, goi
.argv
-1, "(no params)");
456 Jim_SetResultString(goi
.interp
, jtag_interface
->name
, -1);
458 case JTAG_CMD_INIT_RESET
:
460 Jim_WrongNumArgs(goi
.interp
, 1, goi
.argv
-1, "(no params)");
463 e
= jtag_init_reset(context
);
465 Jim_SetResult_sprintf(goi
.interp
, "error: %d", e
);
469 case JTAG_CMD_NEWTAP
:
470 return jim_newtap_cmd(&goi
);
472 case JTAG_CMD_TAPISENABLED
:
473 case JTAG_CMD_TAPENABLE
:
474 case JTAG_CMD_TAPDISABLE
:
476 Jim_SetResultString(goi
.interp
, "Too many parameters",-1);
483 t
= jtag_tap_by_jim_obj(goi
.interp
, goi
.argv
[0]);
488 case JTAG_CMD_TAPISENABLED
:
490 case JTAG_CMD_TAPENABLE
:
493 jtag_tap_handle_event(t
, JTAG_TAP_EVENT_ENABLE
);
497 /* FIXME add JTAG sanity checks, w/o TLR
498 * - scan chain length grew by one (this)
499 * - IDs and IR lengths are as expected
502 jtag_call_event_callbacks(JTAG_TAP_EVENT_ENABLE
);
504 case JTAG_CMD_TAPDISABLE
:
507 jtag_tap_handle_event(t
, JTAG_TAP_EVENT_DISABLE
);
511 /* FIXME add JTAG sanity checks, w/o TLR
512 * - scan chain length shrank by one (this)
513 * - IDs and IR lengths are as expected
516 jtag_call_event_callbacks(JTAG_TAP_EVENT_DISABLE
);
520 Jim_SetResult(goi
.interp
, Jim_NewIntObj(goi
.interp
, e
));
527 Jim_WrongNumArgs(goi
.interp
, 0, NULL
,
528 "cget tap_name queryparm");
535 Jim_GetOpt_Obj(&goi
, &o
);
536 t
= jtag_tap_by_jim_obj(goi
.interp
, o
);
542 return jtag_tap_configure_cmd(&goi
, t
);
546 case JTAG_CMD_CONFIGURE
:
548 Jim_WrongNumArgs(goi
.interp
, 0, NULL
,
549 "configure tap_name attribute value ...");
556 Jim_GetOpt_Obj(&goi
, &o
);
557 t
= jtag_tap_by_jim_obj(goi
.interp
, o
);
563 return jtag_tap_configure_cmd(&goi
, t
);
569 Jim_WrongNumArgs(goi
.interp
, 1, goi
.argv
, "Too many parameters");
572 Jim_SetResult(goi
.interp
, Jim_NewListObj(goi
.interp
, NULL
, 0));
576 for (tap
= jtag_all_taps(); tap
; tap
= tap
->next_tap
) {
577 Jim_ListAppendElement(goi
.interp
,
578 Jim_GetResult(goi
.interp
),
579 Jim_NewStringObj(goi
.interp
,
580 tap
->dotted_name
, -1));
592 void jtag_notify_event(enum jtag_event event
)
596 for (tap
= jtag_all_taps(); tap
; tap
= tap
->next_tap
)
597 jtag_tap_handle_event(tap
, event
);
601 int jtag_register_commands(struct command_context_s
*cmd_ctx
)
603 register_jim(cmd_ctx
, "jtag", jim_jtag_command
, "perform jtag tap actions");
605 register_command(cmd_ctx
, NULL
, "interface", handle_interface_command
,
606 COMMAND_CONFIG
, "try to configure interface");
607 register_command(cmd_ctx
, NULL
,
608 "interface_list", &handle_interface_list_command
,
609 COMMAND_ANY
, "list all built-in interfaces");
610 register_command(cmd_ctx
, NULL
, "jtag_speed", handle_jtag_speed_command
,
611 COMMAND_ANY
, "(DEPRECATED) set jtag speed (if supported)");
612 register_command(cmd_ctx
, NULL
, "jtag_khz", handle_jtag_khz_command
,
613 COMMAND_ANY
, "set maximum jtag speed (if supported); "
614 "parameter is maximum khz, or 0 for adaptive clocking (RTCK).");
615 register_command(cmd_ctx
, NULL
, "jtag_rclk", handle_jtag_rclk_command
,
616 COMMAND_ANY
, "fallback_speed_khz - set JTAG speed to RCLK or use fallback speed");
617 register_command(cmd_ctx
, NULL
, "jtag_device", handle_jtag_device_command
,
618 COMMAND_CONFIG
, "(DEPRECATED) jtag_device <ir_length> <ir_expected> <ir_mask>");
619 register_command(cmd_ctx
, NULL
, "reset_config", handle_reset_config_command
,
621 "[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]");
622 register_command(cmd_ctx
, NULL
, "jtag_nsrst_delay", handle_jtag_nsrst_delay_command
,
623 COMMAND_ANY
, "jtag_nsrst_delay <ms> - delay after deasserting srst in ms");
624 register_command(cmd_ctx
, NULL
, "jtag_ntrst_delay", handle_jtag_ntrst_delay_command
,
625 COMMAND_ANY
, "jtag_ntrst_delay <ms> - delay after deasserting trst in ms");
626 register_command(cmd_ctx
, NULL
, "jtag_nsrst_assert_width", handle_jtag_nsrst_assert_width_command
,
627 COMMAND_ANY
, "jtag_nsrst_assert_width <ms> - delay after asserting srst in ms");
628 register_command(cmd_ctx
, NULL
, "jtag_ntrst_assert_width", handle_jtag_ntrst_assert_width_command
,
629 COMMAND_ANY
, "jtag_ntrst_assert_width <ms> - delay after asserting trst in ms");
631 register_command(cmd_ctx
, NULL
, "scan_chain", handle_scan_chain_command
,
632 COMMAND_EXEC
, "print current scan chain configuration");
634 register_command(cmd_ctx
, NULL
, "jtag_reset", handle_jtag_reset_command
,
635 COMMAND_EXEC
, "toggle reset lines <trst> <srst>");
636 register_command(cmd_ctx
, NULL
, "runtest", handle_runtest_command
,
637 COMMAND_EXEC
, "move to Run-Test/Idle, and execute <num_cycles>");
638 register_command(cmd_ctx
, NULL
, "irscan", handle_irscan_command
,
639 COMMAND_EXEC
, "execute IR scan <device> <instr> [dev2] [instr2] ...");
640 register_jim(cmd_ctx
, "drscan", Jim_Command_drscan
, "execute DR scan <device> <num_bits> <value> <num_bits1> <value2> ...");
641 register_jim(cmd_ctx
, "flush_count", Jim_Command_flush_count
, "returns number of times the JTAG queue has been flushed");
642 register_jim(cmd_ctx
, "pathmove", Jim_Command_pathmove
, "move JTAG to state1 then to state2, state3, etc. <state1>,<state2>,<stat3>...");
644 register_command(cmd_ctx
, NULL
, "verify_ircapture", handle_verify_ircapture_command
,
645 COMMAND_ANY
, "verify value captured during Capture-IR <enable | disable>");
646 register_command(cmd_ctx
, NULL
, "verify_jtag", handle_verify_jtag_command
,
647 COMMAND_ANY
, "verify value capture <enable | disable>");
648 register_command(cmd_ctx
, NULL
, "tms_sequence", handle_tms_sequence_command
,
649 COMMAND_ANY
, "choose short(default) or long tms_sequence <short | long>");
653 static int default_khz(int khz
, int *jtag_speed
)
655 LOG_ERROR("Translation from khz to jtag_speed not implemented");
659 static int default_speed_div(int speed
, int *khz
)
661 LOG_ERROR("Translation from jtag_speed to khz not implemented");
665 static int default_power_dropout(int *dropout
)
667 *dropout
= 0; /* by default we can't detect power dropout */
671 static int default_srst_asserted(int *srst_asserted
)
673 *srst_asserted
= 0; /* by default we can't detect srst asserted */
677 static int handle_interface_command(struct command_context_s
*cmd_ctx
,
678 char *cmd
, char **args
, int argc
)
680 /* check whether the interface is already configured */
683 LOG_WARNING("Interface already configured, ignoring");
687 /* interface name is a mandatory argument */
688 if (argc
!= 1 || args
[0][0] == '\0')
689 return ERROR_COMMAND_SYNTAX_ERROR
;
691 for (unsigned i
= 0; NULL
!= jtag_interfaces
[i
]; i
++)
693 if (strcmp(args
[0], jtag_interfaces
[i
]->name
) != 0)
696 int retval
= jtag_interfaces
[i
]->register_commands(cmd_ctx
);
697 if (ERROR_OK
!= retval
)
700 jtag_interface
= jtag_interfaces
[i
];
702 if (jtag_interface
->khz
== NULL
)
703 jtag_interface
->khz
= default_khz
;
704 if (jtag_interface
->speed_div
== NULL
)
705 jtag_interface
->speed_div
= default_speed_div
;
706 if (jtag_interface
->power_dropout
== NULL
)
707 jtag_interface
->power_dropout
= default_power_dropout
;
708 if (jtag_interface
->srst_asserted
== NULL
)
709 jtag_interface
->srst_asserted
= default_srst_asserted
;
714 /* no valid interface was found (i.e. the configuration option,
715 * didn't match one of the compiled-in interfaces
717 LOG_ERROR("The specified JTAG interface was not found (%s)", args
[0]);
718 handle_interface_list_command(cmd_ctx
, cmd
, args
, argc
);
719 return ERROR_JTAG_INVALID_INTERFACE
;
722 static int handle_interface_list_command(struct command_context_s
*cmd_ctx
,
723 char *cmd
, char **args
, int argc
)
725 if (strcmp(cmd
, "interface_list") == 0 && argc
> 0)
726 return ERROR_COMMAND_SYNTAX_ERROR
;
728 command_print(cmd_ctx
, "The following JTAG interfaces are available:");
729 for (unsigned i
= 0; NULL
!= jtag_interfaces
[i
]; i
++)
731 const char *name
= jtag_interfaces
[i
]->name
;
732 command_print(cmd_ctx
, "%u: %s", i
+ 1, name
);
738 static int handle_jtag_device_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
742 Jim_Obj
*newargs
[ 10 ];
746 * argv[ 0] = ir length
747 * argv[ 1] = ir capture
749 * argv[ 3] = not actually used by anything but in the docs
753 command_print(cmd_ctx
, "OLD DEPRECATED SYNTAX: Please use the NEW syntax");
756 command_print(cmd_ctx
, "OLD SYNTAX: DEPRECATED - translating to new syntax");
757 command_print(cmd_ctx
, "jtag newtap CHIP TAP -irlen %s -ircapture %s -irvalue %s",
761 command_print(cmd_ctx
, "Example: STM32 has 2 taps, the cortexM3(len4) + boundaryscan(len5)");
762 command_print(cmd_ctx
, "jtag newtap stm32 cortexm3 ....., thus creating the tap: \"stm32.cortexm3\"");
763 command_print(cmd_ctx
, "jtag newtap stm32 boundary ....., and the tap: \"stm32.boundary\"");
764 command_print(cmd_ctx
, "And then refer to the taps by the dotted name.");
766 newargs
[0] = Jim_NewStringObj(interp
, "jtag", -1);
767 newargs
[1] = Jim_NewStringObj(interp
, "newtap", -1);
768 sprintf(buf
, "chip%d", jtag_tap_count());
769 newargs
[2] = Jim_NewStringObj(interp
, buf
, -1);
770 sprintf(buf
, "tap%d", jtag_tap_count());
771 newargs
[3] = Jim_NewStringObj(interp
, buf
, -1);
772 newargs
[4] = Jim_NewStringObj(interp
, "-irlen", -1);
773 newargs
[5] = Jim_NewStringObj(interp
, args
[0], -1);
774 newargs
[6] = Jim_NewStringObj(interp
, "-ircapture", -1);
775 newargs
[7] = Jim_NewStringObj(interp
, args
[1], -1);
776 newargs
[8] = Jim_NewStringObj(interp
, "-irmask", -1);
777 newargs
[9] = Jim_NewStringObj(interp
, args
[2], -1);
779 command_print(cmd_ctx
, "NEW COMMAND:");
780 sprintf(buf
, "%s %s %s %s %s %s %s %s %s %s",
781 Jim_GetString(newargs
[0], NULL
),
782 Jim_GetString(newargs
[1], NULL
),
783 Jim_GetString(newargs
[2], NULL
),
784 Jim_GetString(newargs
[3], NULL
),
785 Jim_GetString(newargs
[4], NULL
),
786 Jim_GetString(newargs
[5], NULL
),
787 Jim_GetString(newargs
[6], NULL
),
788 Jim_GetString(newargs
[7], NULL
),
789 Jim_GetString(newargs
[8], NULL
),
790 Jim_GetString(newargs
[9], NULL
));
792 e
= jim_jtag_command(interp
, 10, newargs
);
794 command_print(cmd_ctx
, "%s", Jim_GetString(Jim_GetResult(interp
), NULL
));
799 static int handle_scan_chain_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
803 tap
= jtag_all_taps();
804 command_print(cmd_ctx
, " TapName | Enabled | IdCode Expected IrLen IrCap IrMask Instr ");
805 command_print(cmd_ctx
, "---|--------------------|---------|------------|------------|------|------|------|---------");
808 uint32_t expected
, expected_mask
, cur_instr
, ii
;
809 expected
= buf_get_u32(tap
->expected
, 0, tap
->ir_length
);
810 expected_mask
= buf_get_u32(tap
->expected_mask
, 0, tap
->ir_length
);
811 cur_instr
= buf_get_u32(tap
->cur_instr
, 0, tap
->ir_length
);
813 command_print(cmd_ctx
,
814 "%2d | %-18s | %c | 0x%08x | 0x%08x | 0x%02x | 0x%02x | 0x%02x | 0x%02x",
815 tap
->abs_chain_position
,
817 tap
->enabled
? 'Y' : 'n',
818 (unsigned int)(tap
->idcode
),
819 (unsigned int)(tap
->expected_ids_cnt
> 0 ? tap
->expected_ids
[0] : 0),
820 (unsigned int)(tap
->ir_length
),
821 (unsigned int)(expected
),
822 (unsigned int)(expected_mask
),
823 (unsigned int)(cur_instr
));
825 for (ii
= 1; ii
< tap
->expected_ids_cnt
; ii
++) {
826 command_print(cmd_ctx
, " | | | | 0x%08x | | | | ",
827 (unsigned int)(tap
->expected_ids
[ii
]));
836 static int handle_reset_config_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
842 return ERROR_COMMAND_SYNTAX_ERROR
;
844 /* Original versions cared about the order of these tokens:
845 * reset_config signals [combination [trst_type [srst_type]]]
846 * They also clobbered the previous configuration even on error.
848 * Here we don't care about the order, and only change values
849 * which have been explicitly specified.
851 for (; argc
; argc
--, args
++) {
855 m
= RESET_SRST_GATES_JTAG
;
857 if (strcmp(*args
, "srst_gates_jtag") == 0)
859 tmp
= RESET_SRST_GATES_JTAG
;
864 m
= RESET_HAS_TRST
| RESET_HAS_SRST
;
865 if (strcmp(*args
, "none") == 0)
867 else if (strcmp(*args
, "trst_only") == 0)
868 tmp
= RESET_HAS_TRST
;
869 else if (strcmp(*args
, "srst_only") == 0)
870 tmp
= RESET_HAS_SRST
;
871 else if (strcmp(*args
, "trst_and_srst") == 0)
872 tmp
= RESET_HAS_TRST
| RESET_HAS_SRST
;
876 LOG_ERROR("extra reset_config %s spec (%s)",
878 return ERROR_INVALID_ARGUMENTS
;
883 /* combination (options for broken wiring) */
884 m
= RESET_SRST_PULLS_TRST
| RESET_TRST_PULLS_SRST
;
885 if (strcmp(*args
, "separate") == 0)
886 /* separate reset lines - default */;
887 else if (strcmp(*args
, "srst_pulls_trst") == 0)
888 tmp
|= RESET_SRST_PULLS_TRST
;
889 else if (strcmp(*args
, "trst_pulls_srst") == 0)
890 tmp
|= RESET_TRST_PULLS_SRST
;
891 else if (strcmp(*args
, "combined") == 0)
892 tmp
|= RESET_SRST_PULLS_TRST
| RESET_TRST_PULLS_SRST
;
896 LOG_ERROR("extra reset_config %s spec (%s)",
897 "combination", *args
);
898 return ERROR_INVALID_ARGUMENTS
;
903 /* trst_type (NOP without HAS_TRST) */
904 m
= RESET_TRST_OPEN_DRAIN
;
905 if (strcmp(*args
, "trst_open_drain") == 0)
906 tmp
|= RESET_TRST_OPEN_DRAIN
;
907 else if (strcmp(*args
, "trst_push_pull") == 0)
908 /* push/pull from adapter - default */;
912 LOG_ERROR("extra reset_config %s spec (%s)",
914 return ERROR_INVALID_ARGUMENTS
;
919 /* srst_type (NOP without HAS_SRST) */
920 m
|= RESET_SRST_PUSH_PULL
;
921 if (strcmp(*args
, "srst_push_pull") == 0)
922 tmp
|= RESET_SRST_PUSH_PULL
;
923 else if (strcmp(*args
, "srst_open_drain") == 0)
924 /* open drain from adapter - default */;
928 LOG_ERROR("extra reset_config %s spec (%s)",
930 return ERROR_INVALID_ARGUMENTS
;
935 /* caller provided nonsense; fail */
936 LOG_ERROR("unknown reset_config flag (%s)", *args
);
937 return ERROR_INVALID_ARGUMENTS
;
940 /* Remember the bits which were specified (mask)
941 * and their new values (new_cfg).
947 /* clear previous values of those bits, save new values */
948 enum reset_types old_cfg
= jtag_get_reset_config();
951 jtag_set_reset_config(new_cfg
);
956 static int handle_jtag_nsrst_delay_command(struct command_context_s
*cmd_ctx
,
957 char *cmd
, char **args
, int argc
)
960 return ERROR_COMMAND_SYNTAX_ERROR
;
964 int retval
= parse_uint(args
[0], &delay
);
965 if (ERROR_OK
!= retval
)
967 jtag_set_nsrst_delay(delay
);
969 command_print(cmd_ctx
, "jtag_nsrst_delay: %u", jtag_get_nsrst_delay());
973 static int handle_jtag_ntrst_delay_command(struct command_context_s
*cmd_ctx
,
974 char *cmd
, char **args
, int argc
)
977 return ERROR_COMMAND_SYNTAX_ERROR
;
981 int retval
= parse_uint(args
[0], &delay
);
982 if (ERROR_OK
!= retval
)
984 jtag_set_ntrst_delay(delay
);
986 command_print(cmd_ctx
, "jtag_ntrst_delay: %u", jtag_get_ntrst_delay());
990 static int handle_jtag_nsrst_assert_width_command(struct command_context_s
*cmd_ctx
,
991 char *cmd
, char **args
, int argc
)
994 return ERROR_COMMAND_SYNTAX_ERROR
;
998 int retval
= parse_uint(args
[0], &delay
);
999 if (ERROR_OK
!= retval
)
1001 jtag_set_nsrst_assert_width(delay
);
1003 command_print(cmd_ctx
, "jtag_nsrst_assert_width: %u", jtag_get_nsrst_assert_width());
1007 static int handle_jtag_ntrst_assert_width_command(struct command_context_s
*cmd_ctx
,
1008 char *cmd
, char **args
, int argc
)
1011 return ERROR_COMMAND_SYNTAX_ERROR
;
1015 int retval
= parse_uint(args
[0], &delay
);
1016 if (ERROR_OK
!= retval
)
1018 jtag_set_ntrst_assert_width(delay
);
1020 command_print(cmd_ctx
, "jtag_ntrst_assert_width: %u", jtag_get_ntrst_assert_width());
1024 static int handle_jtag_speed_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1026 int retval
= ERROR_OK
;
1028 command_print(cmd_ctx
, "OLD SYNTAX: DEPRECATED - "
1029 "use jtag_khz, not jtag_speed");
1032 return ERROR_COMMAND_SYNTAX_ERROR
;
1035 LOG_DEBUG("handle jtag speed");
1037 unsigned cur_speed
= 0;
1038 int retval
= parse_uint(args
[0], &cur_speed
);
1039 if (ERROR_OK
!= retval
)
1041 retval
= jtag_config_speed(cur_speed
);
1044 command_print(cmd_ctx
, "jtag_speed: %d", jtag_get_speed());
1049 static int handle_jtag_khz_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1052 return ERROR_COMMAND_SYNTAX_ERROR
;
1054 int retval
= ERROR_OK
;
1058 int retval
= parse_uint(args
[0], &khz
);
1059 if (ERROR_OK
!= retval
)
1061 retval
= jtag_config_khz(khz
);
1062 if (ERROR_OK
!= retval
)
1066 int cur_speed
= jtag_get_speed_khz();
1067 retval
= jtag_get_speed_readable(&cur_speed
);
1068 if (ERROR_OK
!= retval
)
1072 command_print(cmd_ctx
, "%d kHz", cur_speed
);
1074 command_print(cmd_ctx
, "RCLK - adaptive");
1079 static int handle_jtag_rclk_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1082 return ERROR_COMMAND_SYNTAX_ERROR
;
1084 int retval
= ERROR_OK
;
1088 int retval
= parse_uint(args
[0], &khz
);
1089 if (ERROR_OK
!= retval
)
1091 retval
= jtag_config_rclk(khz
);
1092 if (ERROR_OK
!= retval
)
1096 int cur_khz
= jtag_get_speed_khz();
1097 retval
= jtag_get_speed_readable(&cur_khz
);
1098 if (ERROR_OK
!= retval
)
1102 command_print(cmd_ctx
, "RCLK not supported - fallback to %d kHz", cur_khz
);
1104 command_print(cmd_ctx
, "RCLK - adaptive");
1109 static int handle_jtag_reset_command(struct command_context_s
*cmd_ctx
,
1110 char *cmd
, char **args
, int argc
)
1113 return ERROR_COMMAND_SYNTAX_ERROR
;
1116 if (args
[0][0] == '1')
1118 else if (args
[0][0] == '0')
1121 return ERROR_COMMAND_SYNTAX_ERROR
;
1124 if (args
[1][0] == '1')
1126 else if (args
[1][0] == '0')
1129 return ERROR_COMMAND_SYNTAX_ERROR
;
1131 if (jtag_interface_init(cmd_ctx
) != ERROR_OK
)
1132 return ERROR_JTAG_INIT_FAILED
;
1134 jtag_add_reset(trst
, srst
);
1135 return jtag_execute_queue();
1138 static int handle_runtest_command(struct command_context_s
*cmd_ctx
,
1139 char *cmd
, char **args
, int argc
)
1142 return ERROR_COMMAND_SYNTAX_ERROR
;
1144 unsigned num_clocks
;
1145 int retval
= parse_uint(args
[0], &num_clocks
);
1146 if (ERROR_OK
!= retval
)
1149 jtag_add_runtest(num_clocks
, TAP_IDLE
);
1150 return jtag_execute_queue();
1154 * For "irscan" or "drscan" commands, the "end" (really, "next") state
1155 * should be stable ... and *NOT* a shift state, otherwise free-running
1156 * jtag clocks could change the values latched by the update state.
1158 static bool scan_is_safe(tap_state_t state
)
1173 static int handle_irscan_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1176 scan_field_t
*fields
;
1178 tap_state_t endstate
;
1180 if ((argc
< 2) || (argc
% 2))
1182 return ERROR_COMMAND_SYNTAX_ERROR
;
1185 /* optional "-endstate" "statename" at the end of the arguments,
1186 * so that e.g. IRPAUSE can let us load the data register before
1187 * entering RUN/IDLE to execute the instruction we load here.
1189 endstate
= TAP_IDLE
;
1192 /* have at least one pair of numbers. */
1193 /* is last pair the magic text? */
1194 if (0 == strcmp("-endstate", args
[ argc
- 2 ])) {
1197 cpA
= args
[ argc
-1 ];
1198 for (endstate
= 0 ; endstate
< TAP_NUM_STATES
; endstate
++) {
1199 cpS
= tap_state_name(endstate
);
1200 if (0 == strcmp(cpA
, cpS
)) {
1204 if (endstate
>= TAP_NUM_STATES
) {
1205 return ERROR_COMMAND_SYNTAX_ERROR
;
1207 if (!scan_is_safe(endstate
))
1208 LOG_WARNING("irscan with unsafe "
1209 "endstate \"%s\"", cpA
);
1210 /* found - remove the last 2 args */
1216 int num_fields
= argc
/ 2;
1217 size_t fields_len
= sizeof(scan_field_t
) * num_fields
;
1218 fields
= malloc(fields_len
);
1219 memset(fields
, 0, fields_len
);
1222 for (i
= 0; i
< num_fields
; i
++)
1224 tap
= jtag_tap_by_string(args
[i
*2]);
1228 for (j
= 0; j
< i
; j
++)
1229 free(fields
[j
].out_value
);
1231 command_print(cmd_ctx
, "Tap: %s unknown", args
[i
*2]);
1235 int field_size
= tap
->ir_length
;
1236 fields
[i
].tap
= tap
;
1237 fields
[i
].num_bits
= field_size
;
1238 fields
[i
].out_value
= malloc(CEIL(field_size
, 8));
1241 retval
= parse_u32(args
[i
* 2 + 1], &value
);
1242 if (ERROR_OK
!= retval
)
1244 buf_set_u32(fields
[i
].out_value
, 0, field_size
, value
);
1245 fields
[i
].in_value
= NULL
;
1248 /* did we have an endstate? */
1249 jtag_add_ir_scan(num_fields
, fields
, endstate
);
1251 retval
= jtag_execute_queue();
1254 for (i
= 0; i
< num_fields
; i
++)
1256 if (NULL
!= fields
[i
].out_value
)
1257 free(fields
[i
].out_value
);
1265 static int Jim_Command_drscan(Jim_Interp
*interp
, int argc
, Jim_Obj
*const *args
)
1268 scan_field_t
*fields
;
1270 int field_count
= 0;
1273 tap_state_t endstate
;
1276 * args[2] = num_bits
1277 * args[3] = hex string
1278 * ... repeat num bits and hex string ...
1281 * args[N-2] = "-endstate"
1282 * args[N-1] = statename
1284 if ((argc
< 4) || ((argc
% 2) != 0))
1286 Jim_WrongNumArgs(interp
, 1, args
, "wrong arguments");
1290 endstate
= TAP_IDLE
;
1292 script_debug(interp
, "drscan", argc
, args
);
1294 /* validate arguments as numbers */
1296 for (i
= 2; i
< argc
; i
+= 2)
1301 e
= Jim_GetLong(interp
, args
[i
], &bits
);
1302 /* If valid - try next arg */
1307 /* Not valid.. are we at the end? */
1308 if (((i
+ 2) != argc
)) {
1309 /* nope, then error */
1313 /* it could be: "-endstate FOO"
1314 * e.g. DRPAUSE so we can issue more instructions
1315 * before entering RUN/IDLE and executing them.
1318 /* get arg as a string. */
1319 cp
= Jim_GetString(args
[i
], NULL
);
1320 /* is it the magic? */
1321 if (0 == strcmp("-endstate", cp
)) {
1322 /* is the statename valid? */
1323 cp
= Jim_GetString(args
[i
+ 1], NULL
);
1325 /* see if it is a valid state name */
1326 endstate
= tap_state_by_name(cp
);
1328 /* update the error message */
1329 Jim_SetResult_sprintf(interp
,"endstate: %s invalid", cp
);
1331 if (!scan_is_safe(endstate
))
1332 LOG_WARNING("drscan with unsafe "
1333 "endstate \"%s\"", cp
);
1335 /* valid - so clear the error */
1337 /* and remove the last 2 args */
1342 /* Still an error? */
1344 return e
; /* too bad */
1346 } /* validate args */
1348 tap
= jtag_tap_by_jim_obj(interp
, args
[1]);
1353 num_fields
= (argc
-2)/2;
1354 fields
= malloc(sizeof(scan_field_t
) * num_fields
);
1355 for (i
= 2; i
< argc
; i
+= 2)
1361 Jim_GetLong(interp
, args
[i
], &bits
);
1362 str
= Jim_GetString(args
[i
+ 1], &len
);
1364 fields
[field_count
].tap
= tap
;
1365 fields
[field_count
].num_bits
= bits
;
1366 fields
[field_count
].out_value
= malloc(CEIL(bits
, 8));
1367 str_to_buf(str
, len
, fields
[field_count
].out_value
, bits
, 0);
1368 fields
[field_count
].in_value
= fields
[field_count
].out_value
;
1372 jtag_add_dr_scan(num_fields
, fields
, endstate
);
1374 retval
= jtag_execute_queue();
1375 if (retval
!= ERROR_OK
)
1377 Jim_SetResultString(interp
, "drscan: jtag execute failed",-1);
1382 Jim_Obj
*list
= Jim_NewListObj(interp
, NULL
, 0);
1383 for (i
= 2; i
< argc
; i
+= 2)
1388 Jim_GetLong(interp
, args
[i
], &bits
);
1389 str
= buf_to_str(fields
[field_count
].in_value
, bits
, 16);
1390 free(fields
[field_count
].out_value
);
1392 Jim_ListAppendElement(interp
, list
, Jim_NewStringObj(interp
, str
, strlen(str
)));
1397 Jim_SetResult(interp
, list
);
1405 static int Jim_Command_pathmove(Jim_Interp
*interp
, int argc
, Jim_Obj
*const *args
)
1407 tap_state_t states
[8];
1409 if ((argc
< 2) || ((size_t)argc
> (sizeof(states
)/sizeof(*states
) + 1)))
1411 Jim_WrongNumArgs(interp
, 1, args
, "wrong arguments");
1415 script_debug(interp
, "pathmove", argc
, args
);
1418 for (i
= 0; i
< argc
-1; i
++)
1421 cp
= Jim_GetString(args
[i
+ 1], NULL
);
1422 states
[i
] = tap_state_by_name(cp
);
1425 /* update the error message */
1426 Jim_SetResult_sprintf(interp
,"endstate: %s invalid", cp
);
1431 if ((jtag_add_statemove(states
[0]) != ERROR_OK
) || (jtag_execute_queue()!= ERROR_OK
))
1433 Jim_SetResultString(interp
, "pathmove: jtag execute failed",-1);
1437 jtag_add_pathmove(argc
-2, states
+ 1);
1439 if (jtag_execute_queue()!= ERROR_OK
)
1441 Jim_SetResultString(interp
, "pathmove: failed",-1);
1449 static int Jim_Command_flush_count(Jim_Interp
*interp
, int argc
, Jim_Obj
*const *args
)
1451 script_debug(interp
, "flush_count", argc
, args
);
1453 Jim_SetResult(interp
, Jim_NewIntObj(interp
, jtag_get_flush_queue_count()));
1459 static int handle_verify_ircapture_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1462 return ERROR_COMMAND_SYNTAX_ERROR
;
1466 if (strcmp(args
[0], "enable") == 0)
1467 jtag_set_verify_capture_ir(true);
1468 else if (strcmp(args
[0], "disable") == 0)
1469 jtag_set_verify_capture_ir(false);
1471 return ERROR_COMMAND_SYNTAX_ERROR
;
1474 const char *status
= jtag_will_verify_capture_ir() ? "enabled": "disabled";
1475 command_print(cmd_ctx
, "verify Capture-IR is %s", status
);
1480 static int handle_verify_jtag_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1483 return ERROR_COMMAND_SYNTAX_ERROR
;
1487 if (strcmp(args
[0], "enable") == 0)
1488 jtag_set_verify(true);
1489 else if (strcmp(args
[0], "disable") == 0)
1490 jtag_set_verify(false);
1492 return ERROR_COMMAND_SYNTAX_ERROR
;
1495 const char *status
= jtag_will_verify() ? "enabled": "disabled";
1496 command_print(cmd_ctx
, "verify jtag capture is %s", status
);
1501 static int handle_tms_sequence_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1504 return ERROR_COMMAND_SYNTAX_ERROR
;
1509 if (strcmp(args
[0], "short") == 0)
1510 use_new_table
= true;
1511 else if (strcmp(args
[0], "long") == 0)
1512 use_new_table
= false;
1514 return ERROR_COMMAND_SYNTAX_ERROR
;
1516 tap_use_new_tms_table(use_new_table
);
1519 command_print(cmd_ctx
, "tms sequence is %s",
1520 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)