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) 2008 Peter Hettkamp *
9 * peter.hettkamp@htp-tel.de *
11 * Copyright (C) 2009 SoftPLC Corporation. http://softplc.com *
12 * Dick Hollenbeck <dick@softplc.com> *
14 * This program is free software; you can redistribute it and/or modify *
15 * it under the terms of the GNU General Public License as published by *
16 * the Free Software Foundation; either version 2 of the License, or *
17 * (at your option) any later version. *
19 * This program is distributed in the hope that it will be useful, *
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
22 * GNU General Public License for more details. *
24 * You should have received a copy of the GNU General Public License *
25 * along with this program. If not, see <http://www.gnu.org/licenses/>. *
26 ***************************************************************************/
28 /* The specification for SVF is available here:
29 * http://www.asset-intertech.com/support/svf.pdf
30 * Below, this document is referred to as the "SVF spec".
32 * The specification for XSVF is available here:
33 * http://www.xilinx.com/support/documentation/application_notes/xapp503.pdf
34 * Below, this document is referred to as the "XSVF spec".
42 #include <jtag/jtag.h>
45 /* XSVF commands, from appendix B of xapp503.pdf */
46 #define XCOMPLETE 0x00
54 #define XSETSDRMASKS 0x0A
69 /* XWAITSTATE is not in the xilinx XSVF spec, but the svf2xsvf.py translator
70 * generates this. Arguably it is needed because the XSVF XRUNTEST command
71 * was ill conceived and does not directly flow out of the SVF RUNTEST command.
72 * This XWAITSTATE does map directly from the SVF RUNTEST command.
74 #define XWAITSTATE 0x18
76 /* Lattice has extended the SVF file format, and Dick Hollenbeck's python based
77 * SVF2XSVF converter supports these 3 additional XSVF opcodes, LCOUNT, LDELAY, LSDR.
78 * Here is an example of usage of the 3 lattice opcode extensions:
80 ! Set the maximum loop count to 25.
82 ! Step to DRPAUSE give 5 clocks and wait for 1.00e + 000 SEC.
83 LDELAY DRPAUSE 5 TCK 1.00E-003 SEC;
84 ! Test for the completed status. Match means pass.
85 ! Loop back to LDELAY line if not match and loop count less than 25.
96 /* XSVF valid state values for the XSTATE command, from appendix B of xapp503.pdf */
97 #define XSV_RESET 0x00
99 #define XSV_DRSELECT 0x02
100 #define XSV_DRCAPTURE 0x03
101 #define XSV_DRSHIFT 0x04
102 #define XSV_DREXIT1 0x05
103 #define XSV_DRPAUSE 0x06
104 #define XSV_DREXIT2 0x07
105 #define XSV_DRUPDATE 0x08
106 #define XSV_IRSELECT 0x09
107 #define XSV_IRCAPTURE 0x0A
108 #define XSV_IRSHIFT 0x0B
109 #define XSV_IREXIT1 0x0C
110 #define XSV_IRPAUSE 0x0D
111 #define XSV_IREXIT2 0x0E
112 #define XSV_IRUPDATE 0x0F
114 /* arguments to XTRST */
118 #define XTRST_ABSENT 3
120 #define XSTATE_MAX_PATH 12
124 /* map xsvf tap state to an openocd "tap_state_t" */
125 static tap_state_t
xsvf_to_tap(int xsvf_state
)
129 switch (xsvf_state
) {
179 LOG_ERROR("UNKNOWN XSVF STATE 0x%02X", xsvf_state
);
186 static int xsvf_read_buffer(int num_bits
, int fd
, uint8_t *buf
)
190 for (num_bytes
= (num_bits
+ 7) / 8; num_bytes
> 0; num_bytes
--) {
191 /* reverse the order of bytes as they are read sequentially from file */
192 if (read(fd
, buf
+ num_bytes
- 1, 1) < 0)
193 return ERROR_XSVF_EOF
;
199 COMMAND_HANDLER(handle_xsvf_command
)
201 uint8_t *dr_out_buf
= NULL
; /* from host to device (TDI) */
202 uint8_t *dr_in_buf
= NULL
; /* from device to host (TDO) */
203 uint8_t *dr_in_mask
= NULL
;
206 int xruntest
= 0; /* number of TCK cycles OR *microseconds */
207 int xrepeat
= 0; /* number of retries */
209 tap_state_t xendir
= TAP_IDLE
; /* see page 8 of the SVF spec, initial
210 *xendir to be TAP_IDLE */
211 tap_state_t xenddr
= TAP_IDLE
;
215 long file_offset
= 0;
218 tap_state_t loop_state
= TAP_IDLE
;
224 int tdo_mismatch
= 0;
228 bool collecting_path
= false;
229 tap_state_t path
[XSTATE_MAX_PATH
];
230 unsigned pathlen
= 0;
232 /* a flag telling whether to clock TCK during waits,
233 * or simply sleep, controlled by virt2
235 int runtest_requires_tck
= 0;
237 /* use NULL to indicate a "plain" xsvf file which accounts for
238 * additional devices in the scan chain, otherwise the device
239 * that should be affected
241 struct jtag_tap
*tap
= NULL
;
244 return ERROR_COMMAND_SYNTAX_ERROR
;
246 /* we mess with CMD_ARGV starting point below, snapshot filename here */
247 const char *filename
= CMD_ARGV
[1];
249 if (strcmp(CMD_ARGV
[0], "plain") != 0) {
250 tap
= jtag_tap_by_string(CMD_ARGV
[0]);
252 command_print(CMD
, "Tap: %s unknown", CMD_ARGV
[0]);
257 xsvf_fd
= open(filename
, O_RDONLY
);
259 command_print(CMD
, "file \"%s\" not found", filename
);
263 /* if this argument is present, then interpret xruntest counts as TCK cycles rather than as
265 if ((CMD_ARGC
> 2) && (strcmp(CMD_ARGV
[2], "virt2") == 0)) {
266 runtest_requires_tck
= 1;
271 if ((CMD_ARGC
> 2) && (strcmp(CMD_ARGV
[2], "quiet") == 0))
274 LOG_WARNING("XSVF support in OpenOCD is limited. Consider using SVF instead");
275 LOG_USER("xsvf processing file: \"%s\"", filename
);
277 while (read(xsvf_fd
, &opcode
, 1) > 0) {
278 /* record the position of this opcode within the file */
279 file_offset
= lseek(xsvf_fd
, 0, SEEK_CUR
) - 1;
281 /* maybe collect another state for a pathmove();
282 * or terminate a path.
284 if (collecting_path
) {
289 /* ignore/show comments between XSTATE ops */
292 /* try to collect another transition */
293 if (pathlen
== XSTATE_MAX_PATH
) {
294 LOG_ERROR("XSVF: path too long");
299 if (read(xsvf_fd
, &uc
, 1) < 0) {
304 mystate
= xsvf_to_tap(uc
);
305 path
[pathlen
++] = mystate
;
307 LOG_DEBUG("XSTATE 0x%02X %s", uc
,
308 tap_state_name(mystate
));
310 /* If path is incomplete, collect more */
311 if (!svf_tap_state_is_stable(mystate
))
314 /* Else execute the path transitions we've
317 * NOTE: Punting on the saved path is not
318 * strictly correct, but we must to do this
319 * unless jtag_add_pathmove() stops rejecting
320 * paths containing RESET. This is probably
321 * harmless, since there aren't many options
322 * for going from a stable state to reset;
323 * at the worst, we may issue extra clocks
324 * once we get to RESET.
326 if (mystate
== TAP_RESET
) {
327 LOG_WARNING("XSVF: dodgey RESET");
333 /* Execute the path we collected
335 * NOTE: OpenOCD requires something that XSVF
336 * doesn't: the last TAP state in the path
337 * must be stable. In practice, tools that
338 * create XSVF seem to follow that rule too.
340 collecting_path
= false;
342 if (path
[0] == TAP_RESET
)
345 jtag_add_pathmove(pathlen
, path
);
347 result
= jtag_execute_queue();
348 if (result
!= ERROR_OK
) {
349 LOG_ERROR("XSVF: pathmove error %d", result
);
359 LOG_DEBUG("XCOMPLETE");
361 result
= jtag_execute_queue();
362 if (result
!= ERROR_OK
) {
369 LOG_DEBUG("XTDOMASK");
371 (xsvf_read_buffer(xsdrsize
, xsvf_fd
, dr_in_mask
) != ERROR_OK
))
377 uint8_t xruntest_buf
[4];
379 if (read(xsvf_fd
, xruntest_buf
, 4) < 0) {
384 xruntest
= be_to_h_u32(xruntest_buf
);
385 LOG_DEBUG("XRUNTEST %d 0x%08X", xruntest
, xruntest
);
393 if (read(xsvf_fd
, &myrepeat
, 1) < 0)
397 LOG_DEBUG("XREPEAT %d", xrepeat
);
404 uint8_t xsdrsize_buf
[4];
406 if (read(xsvf_fd
, xsdrsize_buf
, 4) < 0) {
411 xsdrsize
= be_to_h_u32(xsdrsize_buf
);
412 LOG_DEBUG("XSDRSIZE %d", xsdrsize
);
418 dr_out_buf
= malloc((xsdrsize
+ 7) / 8);
419 dr_in_buf
= malloc((xsdrsize
+ 7) / 8);
420 dr_in_mask
= malloc((xsdrsize
+ 7) / 8);
424 case XSDR
: /* these two are identical except for the dr_in_buf */
431 const char *op_name
= (opcode
== XSDR
? "XSDR" : "XSDRTDO");
433 if (xsvf_read_buffer(xsdrsize
, xsvf_fd
, dr_out_buf
) != ERROR_OK
) {
438 if (opcode
== XSDRTDO
) {
439 if (xsvf_read_buffer(xsdrsize
, xsvf_fd
,
440 dr_in_buf
) != ERROR_OK
) {
449 LOG_DEBUG("%s %d", op_name
, xsdrsize
);
451 for (attempt
= 0; attempt
< limit
; ++attempt
) {
452 struct scan_field field
;
455 /* perform the XC9500 exception handling sequence shown in xapp067.pdf and
456 * illustrated in pseudo code at end of this file. We start from state
462 * go to Run-Test/Idle
464 * This sequence should be harmless for other devices, and it
465 * will be skipped entirely if xrepeat is set to zero.
468 static tap_state_t exception_path
[] = {
476 jtag_add_pathmove(ARRAY_SIZE(exception_path
), exception_path
);
479 LOG_USER("%s mismatch, xsdrsize=%d retry=%d",
485 field
.num_bits
= xsdrsize
;
486 field
.out_value
= dr_out_buf
;
487 field
.in_value
= calloc(DIV_ROUND_UP(field
.num_bits
, 8), 1);
490 jtag_add_plain_dr_scan(field
.num_bits
,
495 jtag_add_dr_scan(tap
, 1, &field
, TAP_DRPAUSE
);
497 jtag_check_value_mask(&field
, dr_in_buf
, dr_in_mask
);
499 free(field
.in_value
);
501 /* LOG_DEBUG("FLUSHING QUEUE"); */
502 result
= jtag_execute_queue();
503 if (result
== ERROR_OK
) {
510 LOG_USER("%s mismatch", op_name
);
515 /* See page 19 of XSVF spec regarding opcode "XSDR" */
517 result
= svf_add_statemove(TAP_IDLE
);
518 if (result
!= ERROR_OK
)
521 if (runtest_requires_tck
)
522 jtag_add_clocks(xruntest
);
524 jtag_add_sleep(xruntest
);
525 } else if (xendir
!= TAP_DRPAUSE
) {
526 /* we are already in TAP_DRPAUSE */
527 result
= svf_add_statemove(xenddr
);
528 if (result
!= ERROR_OK
)
535 LOG_ERROR("unsupported XSETSDRMASKS");
540 LOG_ERROR("unsupported XSDRINC");
545 LOG_ERROR("unsupported XSDRB");
550 LOG_ERROR("unsupported XSDRC");
555 LOG_ERROR("unsupported XSDRE");
560 LOG_ERROR("unsupported XSDRTDOB");
565 LOG_ERROR("unsupported XSDRTDOC");
570 LOG_ERROR("unsupported XSDRTDOE");
578 if (read(xsvf_fd
, &uc
, 1) < 0) {
583 mystate
= xsvf_to_tap(uc
);
585 LOG_DEBUG("XSTATE 0x%02X %s", uc
, tap_state_name(mystate
));
587 if (mystate
== TAP_INVALID
) {
588 LOG_ERROR("XSVF: bad XSTATE %02x", uc
);
593 /* NOTE: the current state is SVF-stable! */
595 /* no change == NOP */
596 if (mystate
== cmd_queue_cur_state
597 && mystate
!= TAP_RESET
)
600 /* Hand off to SVF? */
601 if (svf_tap_state_is_stable(mystate
)) {
602 result
= svf_add_statemove(mystate
);
603 if (result
!= ERROR_OK
)
609 * A sequence of XSTATE transitions, each TAP
610 * state adjacent to the previous one. Start
613 collecting_path
= true;
621 if (read(xsvf_fd
, &uc
, 1) < 0) {
626 /* see page 22 of XSVF spec */
630 xendir
= TAP_IRPAUSE
;
632 LOG_ERROR("illegial XENDIR argument: 0x%02X", uc
);
637 LOG_DEBUG("XENDIR 0x%02X %s", uc
, tap_state_name(xendir
));
642 if (read(xsvf_fd
, &uc
, 1) < 0) {
647 /* see page 22 of XSVF spec */
651 xenddr
= TAP_DRPAUSE
;
653 LOG_ERROR("illegial XENDDR argument: 0x%02X", uc
);
658 LOG_DEBUG("XENDDR %02X %s", uc
, tap_state_name(xenddr
));
664 uint8_t short_buf
[2];
667 tap_state_t my_end_state
= xruntest
? TAP_IDLE
: xendir
;
669 if (opcode
== XSIR
) {
670 /* one byte bitcount */
671 if (read(xsvf_fd
, short_buf
, 1) < 0) {
675 bitcount
= short_buf
[0];
676 LOG_DEBUG("XSIR %d", bitcount
);
678 if (read(xsvf_fd
, short_buf
, 2) < 0) {
682 bitcount
= be_to_h_u16(short_buf
);
683 LOG_DEBUG("XSIR2 %d", bitcount
);
686 ir_buf
= malloc((bitcount
+ 7) / 8);
688 if (xsvf_read_buffer(bitcount
, xsvf_fd
, ir_buf
) != ERROR_OK
)
691 struct scan_field field
;
693 field
.num_bits
= bitcount
;
694 field
.out_value
= ir_buf
;
696 field
.in_value
= NULL
;
699 jtag_add_plain_ir_scan(field
.num_bits
,
700 field
.out_value
, field
.in_value
, my_end_state
);
702 jtag_add_ir_scan(tap
, &field
, my_end_state
);
705 if (runtest_requires_tck
)
706 jtag_add_clocks(xruntest
);
708 jtag_add_sleep(xruntest
);
711 /* Note that an -irmask of non-zero in your config file
712 * can cause this to fail. Setting -irmask to zero cand work
713 * around the problem.
716 /* LOG_DEBUG("FLUSHING QUEUE"); */
717 result
= jtag_execute_queue();
718 if (result
!= ERROR_OK
)
727 unsigned int ndx
= 0;
731 if (read(xsvf_fd
, &uc
, 1) < 0) {
736 if (ndx
< sizeof(comment
)-1)
741 comment
[sizeof(comment
)-1] = 0; /* regardless, terminate */
743 LOG_USER("# %s", comment
);
749 /* expected in stream:
750 XWAIT <uint8_t wait_state> <uint8_t end_state> <uint32_t usecs>
755 uint8_t delay_buf
[4];
757 tap_state_t wait_state
;
758 tap_state_t end_state
;
761 if (read(xsvf_fd
, &wait_local
, 1) < 0
762 || read(xsvf_fd
, &end
, 1) < 0
763 || read(xsvf_fd
, delay_buf
, 4) < 0) {
768 wait_state
= xsvf_to_tap(wait_local
);
769 end_state
= xsvf_to_tap(end
);
770 delay
= be_to_h_u32(delay_buf
);
772 LOG_DEBUG("XWAIT %s %s usecs:%d", tap_state_name(
773 wait_state
), tap_state_name(end_state
), delay
);
775 if (runtest_requires_tck
&& wait_state
== TAP_IDLE
)
776 jtag_add_runtest(delay
, end_state
);
778 /* FIXME handle statemove errors ... */
779 result
= svf_add_statemove(wait_state
);
780 if (result
!= ERROR_OK
)
782 jtag_add_sleep(delay
);
783 result
= svf_add_statemove(end_state
);
784 if (result
!= ERROR_OK
)
792 /* expected in stream:
793 * XWAITSTATE <uint8_t wait_state> <uint8_t end_state> <uint32_t clock_count>
797 uint8_t clock_buf
[4];
798 uint8_t usecs_buf
[4];
801 tap_state_t wait_state
;
802 tap_state_t end_state
;
806 if (read(xsvf_fd
, &wait_local
, 1) < 0
807 || read(xsvf_fd
, &end
, 1) < 0
808 || read(xsvf_fd
, clock_buf
, 4) < 0
809 || read(xsvf_fd
, usecs_buf
, 4) < 0) {
814 wait_state
= xsvf_to_tap(wait_local
);
815 end_state
= xsvf_to_tap(end
);
817 clock_count
= be_to_h_u32(clock_buf
);
818 usecs
= be_to_h_u32(usecs_buf
);
820 LOG_DEBUG("XWAITSTATE %s %s clocks:%i usecs:%i",
821 tap_state_name(wait_state
),
822 tap_state_name(end_state
),
825 /* the following states are 'stable', meaning that they have a transition
826 * in the state diagram back to themselves. This is necessary because we will
827 * be issuing a number of clocks in this state. This set of allowed states is also
828 * determined by the SVF RUNTEST command's allowed states.
830 if (!svf_tap_state_is_stable(wait_state
)) {
831 LOG_ERROR("illegal XWAITSTATE wait_state: \"%s\"",
832 tap_state_name(wait_state
));
834 /* REVISIT "break" so we won't run? */
837 /* FIXME handle statemove errors ... */
838 result
= svf_add_statemove(wait_state
);
839 if (result
!= ERROR_OK
)
842 jtag_add_clocks(clock_count
);
843 jtag_add_sleep(usecs
);
845 result
= svf_add_statemove(end_state
);
846 if (result
!= ERROR_OK
)
853 /* expected in stream:
854 * LCOUNT <uint32_t loop_count>
856 uint8_t count_buf
[4];
858 if (read(xsvf_fd
, count_buf
, 4) < 0) {
863 loop_count
= be_to_h_u32(count_buf
);
864 LOG_DEBUG("LCOUNT %d", loop_count
);
870 /* expected in stream:
871 * LDELAY <uint8_t wait_state> <uint32_t clock_count> <uint32_t usecs_to_sleep>
874 uint8_t clock_buf
[4];
875 uint8_t usecs_buf
[4];
877 if (read(xsvf_fd
, &state
, 1) < 0
878 || read(xsvf_fd
, clock_buf
, 4) < 0
879 || read(xsvf_fd
, usecs_buf
, 4) < 0) {
884 /* NOTE: loop_state must be stable! */
885 loop_state
= xsvf_to_tap(state
);
886 loop_clocks
= be_to_h_u32(clock_buf
);
887 loop_usecs
= be_to_h_u32(usecs_buf
);
889 LOG_DEBUG("LDELAY %s clocks:%d usecs:%d", tap_state_name(
890 loop_state
), loop_clocks
, loop_usecs
);
894 /* LSDR is more like XSDRTDO than it is like XSDR. It uses LDELAY which
895 * comes with clocks !AND! sleep requirements.
899 int limit
= loop_count
;
905 if (xsvf_read_buffer(xsdrsize
, xsvf_fd
, dr_out_buf
) != ERROR_OK
906 || xsvf_read_buffer(xsdrsize
, xsvf_fd
, dr_in_buf
) != ERROR_OK
) {
914 for (attempt
= 0; attempt
< limit
; ++attempt
) {
915 struct scan_field field
;
917 result
= svf_add_statemove(loop_state
);
918 if (result
!= ERROR_OK
) {
922 jtag_add_clocks(loop_clocks
);
923 jtag_add_sleep(loop_usecs
);
925 field
.num_bits
= xsdrsize
;
926 field
.out_value
= dr_out_buf
;
927 field
.in_value
= calloc(DIV_ROUND_UP(field
.num_bits
, 8), 1);
929 if (attempt
> 0 && verbose
)
930 LOG_USER("LSDR retry %d", attempt
);
933 jtag_add_plain_dr_scan(field
.num_bits
,
938 jtag_add_dr_scan(tap
, 1, &field
, TAP_DRPAUSE
);
940 jtag_check_value_mask(&field
, dr_in_buf
, dr_in_mask
);
942 free(field
.in_value
);
945 /* LOG_DEBUG("FLUSHING QUEUE"); */
946 result
= jtag_execute_queue();
947 if (result
== ERROR_OK
) {
954 LOG_USER("LSDR mismatch");
965 if (read(xsvf_fd
, &trst_mode
, 1) < 0) {
972 jtag_add_reset(1, 0);
976 jtag_add_reset(0, 0);
981 LOG_ERROR("XTRST mode argument (0x%02X) out of range", trst_mode
);
988 LOG_ERROR("unknown xsvf command (0x%02X)", uc
);
992 if (do_abort
|| unsupported
|| tdo_mismatch
) {
993 LOG_DEBUG("xsvf failed, setting taps to reasonable state");
995 /* upon error, return the TAPs to a reasonable state */
996 result
= svf_add_statemove(TAP_IDLE
);
997 if (result
!= ERROR_OK
)
999 result
= jtag_execute_queue();
1000 if (result
!= ERROR_OK
)
1008 "TDO mismatch, somewhere near offset %lu in xsvf file, aborting",
1015 off_t offset
= lseek(xsvf_fd
, 0, SEEK_CUR
) - 1;
1017 "unsupported xsvf command (0x%02X) at offset %jd, aborting",
1018 uc
, (intmax_t)offset
);
1023 command_print(CMD
, "premature end of xsvf file detected, aborting");
1033 command_print(CMD
, "XSVF file programmed successfully");
1038 static const struct command_registration xsvf_command_handlers
[] = {
1041 .handler
= handle_xsvf_command
,
1042 .mode
= COMMAND_EXEC
,
1043 .help
= "Runs a XSVF file. If 'virt2' is given, xruntest "
1044 "counts are interpreted as TCK cycles rather than "
1045 "as microseconds. Without the 'quiet' option, all "
1046 "comments, retries, and mismatches will be reported.",
1047 .usage
= "(tapname|'plain') filename ['virt2'] ['quiet']",
1049 COMMAND_REGISTRATION_DONE
1052 int xsvf_register_commands(struct command_context
*cmd_ctx
)
1054 return register_commands(cmd_ctx
, NULL
, xsvf_command_handlers
);
1059 PSUEDO-Code from Xilinx Appnote XAPP067.pdf :
1061 the following pseudo code clarifies the intent of the xrepeat support.The
1062 flow given is for the entire processing of an SVF file, not an XSVF file.
1063 No idea if this is just for the XC9500/XL/XV devices or all Xilinx parts.
1065 "Pseudo-Code Algorithm for SVF-Based ISP"
1067 1. Go to Test-Logic-Reset state
1068 2. Go to Run-Test Idle state
1071 4. if SIR record then
1072 go to Shift-IR state
1075 5. else if SDR record then
1076 set <repeat count> to 0
1077 store <TDI value> as <current TDI value>
1078 store <TDO value> as <current TDO value>
1079 6. go to Shift-DR state
1080 scan in <current TDI value>
1081 if < current TDO value > is specified then
1082 if < current TDO value > does not equal <actual TDO value> then
1083 if < repeat count > > 32 then
1085 go to Run-Test Idle state
1094 increment <repeat count> by 1
1095 pause <current pause time> microseconds
1099 go to Run-Test Idle state
1102 else if RUNTEST record then
1103 pause tester for < TCK value > microseconds
1104 store <TCK value> as <current pause time>
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)