add flush_count jtag queue profiling feature
[openocd.git] / src / jtag / zy1000.c
1 /***************************************************************************
2 * Copyright (C) 2007-2008 by Øyvind Harboe *
3 * *
4 * This program is free software; you can redistribute it and/or modify *
5 * it under the terms of the GNU General Public License as published by *
6 * the Free Software Foundation; either version 2 of the License, or *
7 * (at your option) any later version. *
8 * *
9 * This program is distributed in the hope that it will be useful, *
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
12 * GNU General Public License for more details. *
13 * *
14 * You should have received a copy of the GNU General Public License *
15 * along with this program; if not, write to the *
16 * Free Software Foundation, Inc., *
17 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
18 ***************************************************************************/
19 #ifdef HAVE_CONFIG_H
20 #include "config.h"
21 #endif
22
23
24 #include "log.h"
25 #include "jtag.h"
26 #include "bitbang.h"
27 #include "../target/embeddedice.h"
28
29
30 #include <cyg/hal/hal_io.h> // low level i/o
31 #include <cyg/hal/hal_diag.h>
32
33 #include <stdlib.h>
34
35 #define ZYLIN_VERSION "1.51"
36 #define ZYLIN_DATE __DATE__
37 #define ZYLIN_TIME __TIME__
38 #define ZYLIN_OPENOCD "$Revision$"
39 #define ZYLIN_OPENOCD_VERSION "Zylin JTAG ZY1000 " ZYLIN_VERSION " " ZYLIN_DATE " " ZYLIN_TIME
40 const char *zylin_config_dir="/config/settings";
41
42 /* low level command set
43 */
44 int zy1000_read(void);
45 static void zy1000_write(int tck, int tms, int tdi);
46 void zy1000_reset(int trst, int srst);
47
48
49 int zy1000_speed(int speed);
50 int zy1000_register_commands(struct command_context_s *cmd_ctx);
51 int zy1000_init(void);
52 int zy1000_quit(void);
53
54 /* interface commands */
55 int zy1000_handle_zy1000_port_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
56
57 static int zy1000_khz(int khz, int *jtag_speed)
58 {
59 if (khz==0)
60 {
61 *jtag_speed=0;
62 }
63 else
64 {
65 *jtag_speed=64000/khz;
66 }
67 return ERROR_OK;
68 }
69
70 static int zy1000_speed_div(int speed, int *khz)
71 {
72 if (speed==0)
73 {
74 *khz = 0;
75 }
76 else
77 {
78 *khz=64000/speed;
79 }
80
81 return ERROR_OK;
82 }
83
84 static bool readPowerDropout(void)
85 {
86 cyg_uint32 state;
87 // sample and clear power dropout
88 HAL_WRITE_UINT32(ZY1000_JTAG_BASE+0x10, 0x80);
89 HAL_READ_UINT32(ZY1000_JTAG_BASE+0x10, state);
90 bool powerDropout;
91 powerDropout = (state & 0x80) != 0;
92 return powerDropout;
93 }
94
95
96 static bool readSRST(void)
97 {
98 cyg_uint32 state;
99 // sample and clear SRST sensing
100 HAL_WRITE_UINT32(ZY1000_JTAG_BASE+0x10, 0x00000040);
101 HAL_READ_UINT32(ZY1000_JTAG_BASE+0x10, state);
102 bool srstAsserted;
103 srstAsserted = (state & 0x40) != 0;
104 return srstAsserted;
105 }
106
107 static int zy1000_srst_asserted(int *srst_asserted)
108 {
109 *srst_asserted=readSRST();
110 return ERROR_OK;
111 }
112
113 static int zy1000_power_dropout(int *dropout)
114 {
115 *dropout=readPowerDropout();
116 return ERROR_OK;
117 }
118
119
120 jtag_interface_t zy1000_interface =
121 {
122 .name = "ZY1000",
123 .execute_queue = bitbang_execute_queue,
124 .speed = zy1000_speed,
125 .register_commands = zy1000_register_commands,
126 .init = zy1000_init,
127 .quit = zy1000_quit,
128 .khz = zy1000_khz,
129 .speed_div = zy1000_speed_div,
130 .power_dropout = zy1000_power_dropout,
131 .srst_asserted = zy1000_srst_asserted,
132 };
133
134 bitbang_interface_t zy1000_bitbang =
135 {
136 .read = zy1000_read,
137 .write = zy1000_write,
138 .reset = zy1000_reset
139 };
140
141
142
143 static void zy1000_write(int tck, int tms, int tdi)
144 {
145
146 }
147
148 int zy1000_read(void)
149 {
150 return -1;
151 }
152
153 extern bool readSRST(void);
154
155 void zy1000_reset(int trst, int srst)
156 {
157 LOG_DEBUG("zy1000 trst=%d, srst=%d", trst, srst);
158 if(!srst)
159 {
160 ZY1000_POKE(ZY1000_JTAG_BASE+0x14, 0x00000001);
161 }
162 else
163 {
164 /* Danger!!! if clk!=0 when in
165 * idle in TAP_IDLE, reset halt on str912 will fail.
166 */
167 ZY1000_POKE(ZY1000_JTAG_BASE+0x10, 0x00000001);
168 }
169
170 if(!trst)
171 {
172 ZY1000_POKE(ZY1000_JTAG_BASE+0x14, 0x00000002);
173 }
174 else
175 {
176 /* assert reset */
177 ZY1000_POKE(ZY1000_JTAG_BASE+0x10, 0x00000002);
178 }
179
180 if (trst||(srst&&(jtag_reset_config & RESET_SRST_PULLS_TRST)))
181 {
182 waitIdle();
183 /* we're now in the RESET state until trst is deasserted */
184 ZY1000_POKE(ZY1000_JTAG_BASE+0x20, TAP_RESET);
185 } else
186 {
187 /* We'll get RCLK failure when we assert TRST, so clear any false positives here */
188 ZY1000_POKE(ZY1000_JTAG_BASE+0x14, 0x400);
189 }
190
191 /* wait for srst to float back up */
192 if (!srst)
193 {
194 int i;
195 for (i=0; i<1000; i++)
196 {
197 // We don't want to sense our own reset, so we clear here.
198 // There is of course a timing hole where we could loose
199 // a "real" reset.
200 if (!readSRST())
201 break;
202
203 /* wait 1ms */
204 alive_sleep(1);
205 }
206
207 if (i==1000)
208 {
209 LOG_USER("SRST didn't deassert after %dms", i);
210 } else if (i>1)
211 {
212 LOG_USER("SRST took %dms to deassert", i);
213 }
214 }
215 }
216
217 int zy1000_speed(int speed)
218 {
219 if(speed == 0)
220 {
221 /*0 means RCLK*/
222 speed = 0;
223 ZY1000_POKE(ZY1000_JTAG_BASE+0x10, 0x100);
224 LOG_DEBUG("jtag_speed using RCLK");
225 }
226 else
227 {
228 if(speed > 8190 || speed < 2)
229 {
230 LOG_USER("valid ZY1000 jtag_speed=[8190,2]. Divisor is 64MHz / even values between 8190-2, i.e. min 7814Hz, max 32MHz");
231 return ERROR_INVALID_ARGUMENTS;
232 }
233
234 LOG_USER("jtag_speed %d => JTAG clk=%f", speed, 64.0/(float)speed);
235 ZY1000_POKE(ZY1000_JTAG_BASE+0x14, 0x100);
236 ZY1000_POKE(ZY1000_JTAG_BASE+0x1c, speed&~1);
237 }
238 return ERROR_OK;
239 }
240
241 static bool savePower;
242
243
244 static void setPower(bool power)
245 {
246 savePower = power;
247 if (power)
248 {
249 HAL_WRITE_UINT32(ZY1000_JTAG_BASE+0x14, 0x8);
250 } else
251 {
252 HAL_WRITE_UINT32(ZY1000_JTAG_BASE+0x10, 0x8);
253 }
254 }
255
256 int handle_power_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
257 {
258 if (argc > 1)
259 {
260 return ERROR_INVALID_ARGUMENTS;
261 }
262
263 if (argc == 1)
264 {
265 if (strcmp(args[0], "on") == 0)
266 {
267 setPower(1);
268 }
269 else if (strcmp(args[0], "off") == 0)
270 {
271 setPower(0);
272 } else
273 {
274 command_print(cmd_ctx, "arg is \"on\" or \"off\"");
275 return ERROR_INVALID_ARGUMENTS;
276 }
277 }
278
279 command_print(cmd_ctx, "Target power %s", savePower ? "on" : "off");
280
281 return ERROR_OK;
282 }
283
284
285 /* Give TELNET a way to find out what version this is */
286 static int jim_zy1000_version(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
287 {
288 if ((argc < 1) || (argc > 2))
289 return JIM_ERR;
290 char buff[128];
291 const char *version_str=NULL;
292
293 if (argc == 1)
294 {
295 version_str=ZYLIN_OPENOCD_VERSION;
296 } else
297 {
298 const char *str = Jim_GetString(argv[1], NULL);
299 if (strcmp("openocd", str) == 0)
300 {
301 int revision;
302 revision = atol(ZYLIN_OPENOCD+strlen("XRevision: "));
303 sprintf(buff, "%d", revision);
304 version_str=buff;
305 }
306 else if (strcmp("zy1000", str) == 0)
307 {
308 version_str=ZYLIN_VERSION;
309 }
310 else if (strcmp("date", str) == 0)
311 {
312 version_str=ZYLIN_DATE;
313 }
314 else
315 {
316 return JIM_ERR;
317 }
318 }
319
320 Jim_SetResult(interp, Jim_NewStringObj(interp, version_str, -1));
321
322 return JIM_OK;
323 }
324
325
326 static int
327 zylinjtag_Jim_Command_powerstatus(Jim_Interp *interp,
328 int argc,
329 Jim_Obj * const *argv)
330 {
331 if (argc != 1)
332 {
333 Jim_WrongNumArgs(interp, 1, argv, "powerstatus");
334 return JIM_ERR;
335 }
336
337 cyg_uint32 status;
338 ZY1000_PEEK(ZY1000_JTAG_BASE+0x10, status);
339
340 Jim_SetResult(interp, Jim_NewIntObj(interp, (status&0x80)!=0));
341
342 return JIM_OK;
343 }
344
345 int zy1000_register_commands(struct command_context_s *cmd_ctx)
346 {
347 register_command(cmd_ctx, NULL, "power", handle_power_command, COMMAND_ANY,
348 "power <on/off> - turn power switch to target on/off. No arguments - print status.");
349
350 Jim_CreateCommand(interp, "zy1000_version", jim_zy1000_version, NULL, NULL);
351
352
353 Jim_CreateCommand(interp, "powerstatus", zylinjtag_Jim_Command_powerstatus, NULL, NULL);
354
355 return ERROR_OK;
356 }
357
358
359
360
361 int zy1000_init(void)
362 {
363 LOG_USER("%s", ZYLIN_OPENOCD_VERSION);
364
365 ZY1000_POKE(ZY1000_JTAG_BASE+0x10, 0x30); // Turn on LED1 & LED2
366
367 setPower(true); // on by default
368
369
370 /* deassert resets. Important to avoid infinite loop waiting for SRST to deassert */
371 zy1000_reset(0, 0);
372 zy1000_speed(jtag_speed);
373
374 bitbang_interface = &zy1000_bitbang;
375
376 return ERROR_OK;
377 }
378
379 int zy1000_quit(void)
380 {
381
382 return ERROR_OK;
383 }
384
385
386
387
388 int interface_jtag_execute_queue(void)
389 {
390 cyg_uint32 empty;
391
392 waitIdle();
393 ZY1000_PEEK(ZY1000_JTAG_BASE+0x10, empty);
394 /* clear JTAG error register */
395 ZY1000_POKE(ZY1000_JTAG_BASE+0x14, 0x400);
396
397 if ((empty&0x400)!=0)
398 {
399 LOG_WARNING("RCLK timeout");
400 /* the error is informative only as we don't want to break the firmware if there
401 * is a false positive.
402 */
403 // return ERROR_FAIL;
404 }
405 return ERROR_OK;
406 }
407
408
409
410
411
412 static cyg_uint32 getShiftValue(void)
413 {
414 cyg_uint32 value;
415 waitIdle();
416 ZY1000_PEEK(ZY1000_JTAG_BASE+0xc, value);
417 VERBOSE(LOG_INFO("getShiftValue %08x", value));
418 return value;
419 }
420 #if 0
421 static cyg_uint32 getShiftValueFlip(void)
422 {
423 cyg_uint32 value;
424 waitIdle();
425 ZY1000_PEEK(ZY1000_JTAG_BASE+0x18, value);
426 VERBOSE(LOG_INFO("getShiftValue %08x (flipped)", value));
427 return value;
428 }
429 #endif
430
431 #if 0
432 static void shiftValueInnerFlip(const tap_state_t state, const tap_state_t endState, int repeat, cyg_uint32 value)
433 {
434 VERBOSE(LOG_INFO("shiftValueInner %s %s %d %08x (flipped)", tap_state_name(state), tap_state_name(endState), repeat, value));
435 cyg_uint32 a,b;
436 a=state;
437 b=endState;
438 ZY1000_POKE(ZY1000_JTAG_BASE+0xc, value);
439 ZY1000_POKE(ZY1000_JTAG_BASE+0x8, (1<<15)|(repeat<<8)|(a<<4)|b);
440 VERBOSE(getShiftValueFlip());
441 }
442 #endif
443
444 extern int jtag_check_value(u8 *captured, void *priv);
445
446 static void gotoEndState(void)
447 {
448 setCurrentState(cmd_queue_end_state);
449 }
450
451 static __inline void scanFields(int num_fields, scan_field_t *fields, tap_state_t shiftState, int pause)
452 {
453 int i;
454 int j;
455 int k;
456
457 for (i = 0; i < num_fields; i++)
458 {
459 cyg_uint32 value;
460
461 static u8 *in_buff=NULL; /* pointer to buffer for scanned data */
462 static int in_buff_size=0;
463 u8 *inBuffer=NULL;
464
465
466 // figure out where to store the input data
467 int num_bits=fields[i].num_bits;
468 if (fields[i].in_value!=NULL)
469 {
470 inBuffer=fields[i].in_value;
471 }
472
473 // here we shuffle N bits out/in
474 j=0;
475 while (j<num_bits)
476 {
477 tap_state_t pause_state;
478 int l;
479 k=num_bits-j;
480 pause_state=(shiftState==TAP_DRSHIFT)?TAP_DRSHIFT:TAP_IRSHIFT;
481 if (k>32)
482 {
483 k=32;
484 /* we have more to shift out */
485 } else if (pause&&(i == num_fields-1))
486 {
487 /* this was the last to shift out this time */
488 pause_state=(shiftState==TAP_DRSHIFT)?TAP_DRPAUSE:TAP_IRPAUSE;
489 }
490
491 // we have (num_bits+7)/8 bytes of bits to toggle out.
492 // bits are pushed out LSB to MSB
493 value=0;
494 if (fields[i].out_value!=NULL)
495 {
496 for (l=0; l<k; l+=8)
497 {
498 value|=fields[i].out_value[(j+l)/8]<<l;
499 }
500 }
501 /* mask away unused bits for easier debugging */
502 value&=~(((u32)0xffffffff)<<k);
503
504 shiftValueInner(shiftState, pause_state, k, value);
505
506 if (inBuffer!=NULL)
507 {
508 // data in, LSB to MSB
509 value=getShiftValue();
510 // we're shifting in data to MSB, shift data to be aligned for returning the value
511 value >>= 32-k;
512
513 for (l=0; l<k; l+=8)
514 {
515 inBuffer[(j+l)/8]=(value>>l)&0xff;
516 }
517 }
518 j+=k;
519 }
520 }
521 }
522
523 int interface_jtag_add_end_state(tap_state_t state)
524 {
525 return ERROR_OK;
526 }
527
528
529 int interface_jtag_add_ir_scan(int num_fields, scan_field_t *fields, tap_state_t state)
530 {
531
532 int j;
533 int scan_size = 0;
534 jtag_tap_t *tap, *nextTap;
535 for(tap = jtag_NextEnabledTap(NULL); tap!= NULL; tap=nextTap)
536 {
537 nextTap=jtag_NextEnabledTap(tap);
538 int pause=(nextTap==NULL);
539
540 int found = 0;
541
542 scan_size = tap->ir_length;
543
544 /* search the list */
545 for (j=0; j < num_fields; j++)
546 {
547 if (tap == fields[j].tap)
548 {
549 found = 1;
550
551 scanFields(1, fields+j, TAP_IRSHIFT, pause);
552 /* update device information */
553 buf_cpy(fields[j].out_value, tap->cur_instr, scan_size);
554
555 tap->bypass = 0;
556 break;
557 }
558 }
559
560 if (!found)
561 {
562 /* if a device isn't listed, set it to BYPASS */
563 u8 ones[]={0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff};
564
565 scan_field_t tmp;
566 memset(&tmp, 0, sizeof(tmp));
567 tmp.out_value = ones;
568 tmp.num_bits = scan_size;
569 scanFields(1, &tmp, TAP_IRSHIFT, pause);
570 /* update device information */
571 buf_cpy(tmp.out_value, tap->cur_instr, scan_size);
572 tap->bypass = 1;
573 }
574 }
575 gotoEndState();
576
577 return ERROR_OK;
578 }
579
580
581
582
583
584 int interface_jtag_add_plain_ir_scan(int num_fields, scan_field_t *fields, tap_state_t state)
585 {
586 scanFields(num_fields, fields, TAP_IRSHIFT, 1);
587 gotoEndState();
588
589 return ERROR_OK;
590 }
591
592 /*extern jtag_command_t **jtag_get_last_command_p(void);*/
593
594 int interface_jtag_add_dr_scan(int num_fields, scan_field_t *fields, tap_state_t state)
595 {
596
597 int j;
598 jtag_tap_t *tap, *nextTap;
599 for(tap = jtag_NextEnabledTap(NULL); tap!= NULL; tap=nextTap)
600 {
601 nextTap=jtag_NextEnabledTap(tap);
602 int found=0;
603 int pause=(nextTap==NULL);
604
605 for (j=0; j < num_fields; j++)
606 {
607 if (tap == fields[j].tap)
608 {
609 found = 1;
610
611 scanFields(1, fields+j, TAP_DRSHIFT, pause);
612 }
613 }
614 if (!found)
615 {
616 scan_field_t tmp;
617 /* program the scan field to 1 bit length, and ignore it's value */
618 tmp.num_bits = 1;
619 tmp.out_value = NULL;
620 tmp.in_value = NULL;
621
622 scanFields(1, &tmp, TAP_DRSHIFT, pause);
623 }
624 else
625 {
626 }
627 }
628 gotoEndState();
629 return ERROR_OK;
630 }
631
632 int interface_jtag_add_plain_dr_scan(int num_fields, scan_field_t *fields, tap_state_t state)
633 {
634 scanFields(num_fields, fields, TAP_DRSHIFT, 1);
635 gotoEndState();
636 return ERROR_OK;
637 }
638
639
640 int interface_jtag_add_tlr()
641 {
642 setCurrentState(TAP_RESET);
643 return ERROR_OK;
644 }
645
646
647
648
649 extern int jtag_nsrst_delay;
650 extern int jtag_ntrst_delay;
651
652 int interface_jtag_add_reset(int req_trst, int req_srst)
653 {
654 zy1000_reset(req_trst, req_srst);
655 return ERROR_OK;
656 }
657
658 static int zy1000_jtag_add_clocks(int num_cycles, tap_state_t state, tap_state_t clockstate)
659 {
660 /* num_cycles can be 0 */
661 setCurrentState(clockstate);
662
663 /* execute num_cycles, 32 at the time. */
664 int i;
665 for (i=0; i<num_cycles; i+=32)
666 {
667 int num;
668 num=32;
669 if (num_cycles-i<num)
670 {
671 num=num_cycles-i;
672 }
673 shiftValueInner(clockstate, clockstate, num, 0);
674 }
675
676 #if !TEST_MANUAL()
677 /* finish in end_state */
678 setCurrentState(state);
679 #else
680 tap_state_t t=TAP_IDLE;
681 /* test manual drive code on any target */
682 int tms;
683 u8 tms_scan = tap_get_tms_path(t, state);
684
685 for (i = 0; i < 7; i++)
686 {
687 tms = (tms_scan >> i) & 1;
688 waitIdle();
689 ZY1000_POKE(ZY1000_JTAG_BASE+0x28, tms);
690 }
691 waitIdle();
692 ZY1000_POKE(ZY1000_JTAG_BASE+0x20, state);
693 #endif
694
695
696 return ERROR_OK;
697 }
698
699 int interface_jtag_add_runtest(int num_cycles, tap_state_t state)
700 {
701 return zy1000_jtag_add_clocks(num_cycles, state, TAP_IDLE);
702 }
703
704 int interface_jtag_add_clocks(int num_cycles)
705 {
706 return zy1000_jtag_add_clocks(num_cycles, cmd_queue_cur_state, cmd_queue_end_state);
707 }
708
709 int interface_jtag_add_sleep(u32 us)
710 {
711 jtag_sleep(us);
712 return ERROR_OK;
713 }
714
715 int interface_jtag_add_pathmove(int num_states, tap_state_t *path)
716 {
717 int state_count;
718 int tms = 0;
719
720 /*wait for the fifo to be empty*/
721 waitIdle();
722
723 state_count = 0;
724
725 tap_state_t cur_state=cmd_queue_cur_state;
726
727 while (num_states)
728 {
729 if (tap_state_transition(cur_state, false) == path[state_count])
730 {
731 tms = 0;
732 }
733 else if (tap_state_transition(cur_state, true) == path[state_count])
734 {
735 tms = 1;
736 }
737 else
738 {
739 LOG_ERROR("BUG: %s -> %s isn't a valid TAP transition", tap_state_name(cur_state), tap_state_name(path[state_count]));
740 exit(-1);
741 }
742
743 waitIdle();
744 ZY1000_POKE(ZY1000_JTAG_BASE+0x28, tms);
745
746 cur_state = path[state_count];
747 state_count++;
748 num_states--;
749 }
750
751 waitIdle();
752 ZY1000_POKE(ZY1000_JTAG_BASE+0x20, cur_state);
753 return ERROR_OK;
754 }
755
756
757
758 void embeddedice_write_dcc(jtag_tap_t *tap, int reg_addr, u8 *buffer, int little, int count)
759 {
760 // static int const reg_addr=0x5;
761 tap_state_t end_state=cmd_queue_end_state;
762 if (jtag_NextEnabledTap(jtag_NextEnabledTap(NULL))==NULL)
763 {
764 /* better performance via code duplication */
765 if (little)
766 {
767 int i;
768 for (i = 0; i < count; i++)
769 {
770 shiftValueInner(TAP_DRSHIFT, TAP_DRSHIFT, 32, fast_target_buffer_get_u32(buffer, 1));
771 shiftValueInner(TAP_DRSHIFT, end_state, 6, reg_addr|(1<<5));
772 buffer+=4;
773 }
774 } else
775 {
776 int i;
777 for (i = 0; i < count; i++)
778 {
779 shiftValueInner(TAP_DRSHIFT, TAP_DRSHIFT, 32, fast_target_buffer_get_u32(buffer, 0));
780 shiftValueInner(TAP_DRSHIFT, end_state, 6, reg_addr|(1<<5));
781 buffer+=4;
782 }
783 }
784 }
785 else
786 {
787 int i;
788 for (i = 0; i < count; i++)
789 {
790 embeddedice_write_reg_inner(tap, reg_addr, fast_target_buffer_get_u32(buffer, little));
791 buffer += 4;
792 }
793 }
794 }
795
796 int loadFile(const char *fileName, void **data, int *len);
797
798 /* boolean parameter stored on config */
799 int boolParam(char *var)
800 {
801 bool result = false;
802 char *name = alloc_printf("%s/%s", zylin_config_dir, var);
803 if (name == NULL)
804 return result;
805
806 void *data;
807 int len;
808 if (loadFile(name, &data, &len) == ERROR_OK)
809 {
810 if (len > 1)
811 len = 1;
812 result = strncmp((char *) data, "1", len) == 0;
813 free(data);
814 }
815 free(name);
816 return result;
817 }
818
819

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)