stlink: add STLINK_F_HAS_JTAG_SET_FREQ
[openocd.git] / src / jtag / drivers / bitbang.c
1 /***************************************************************************
2 * Copyright (C) 2005 by Dominic Rath *
3 * Dominic.Rath@gmx.de *
4 * *
5 * Copyright (C) 2007,2008 Øyvind Harboe *
6 * oyvind.harboe@zylin.com *
7 * *
8 * This program is free software; you can redistribute it and/or modify *
9 * it under the terms of the GNU General Public License as published by *
10 * the Free Software Foundation; either version 2 of the License, or *
11 * (at your option) any later version. *
12 * *
13 * This program is distributed in the hope that it will be useful, *
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
16 * GNU General Public License for more details. *
17 * *
18 * You should have received a copy of the GNU General Public License *
19 * along with this program. If not, see <http://www.gnu.org/licenses/>. *
20 ***************************************************************************/
21
22 /* 2014-12: Addition of the SWD protocol support is based on the initial work
23 * by Paul Fertser and modifications by Jean-Christian de Rivaz. */
24
25 #ifdef HAVE_CONFIG_H
26 #include "config.h"
27 #endif
28
29 #include "bitbang.h"
30 #include <jtag/interface.h>
31 #include <jtag/commands.h>
32
33 /* YUK! - but this is currently a global.... */
34 extern struct jtag_interface *jtag_interface;
35
36 /**
37 * Function bitbang_stableclocks
38 * issues a number of clock cycles while staying in a stable state.
39 * Because the TMS value required to stay in the RESET state is a 1, whereas
40 * the TMS value required to stay in any of the other stable states is a 0,
41 * this function checks the current stable state to decide on the value of TMS
42 * to use.
43 */
44 static int bitbang_stableclocks(int num_cycles);
45
46 static void bitbang_swd_write_reg(uint8_t cmd, uint32_t value, uint32_t ap_delay_clk);
47
48 struct bitbang_interface *bitbang_interface;
49
50 /* DANGER!!!! clock absolutely *MUST* be 0 in idle or reset won't work!
51 *
52 * Set this to 1 and str912 reset halt will fail.
53 *
54 * If someone can submit a patch with an explanation it will be greatly
55 * appreciated, but as far as I can tell (ØH) DCLK is generated upon
56 * clk = 0 in TAP_IDLE. Good luck deducing that from the ARM documentation!
57 * The ARM documentation uses the term "DCLK is asserted while in the TAP_IDLE
58 * state". With hardware there is no such thing as *while* in a state. There
59 * are only edges. So clk => 0 is in fact a very subtle state transition that
60 * happens *while* in the TAP_IDLE state. "#&¤"#¤&"#&"#&
61 *
62 * For "reset halt" the last thing that happens before srst is asserted
63 * is that the breakpoint is set up. If DCLK is not wiggled one last
64 * time before the reset, then the breakpoint is not set up and
65 * "reset halt" will fail to halt.
66 *
67 */
68 #define CLOCK_IDLE() 0
69
70 /* The bitbang driver leaves the TCK 0 when in idle */
71 static void bitbang_end_state(tap_state_t state)
72 {
73 assert(tap_is_state_stable(state));
74 tap_set_end_state(state);
75 }
76
77 static int bitbang_state_move(int skip)
78 {
79 int i = 0, tms = 0;
80 uint8_t tms_scan = tap_get_tms_path(tap_get_state(), tap_get_end_state());
81 int tms_count = tap_get_tms_path_len(tap_get_state(), tap_get_end_state());
82
83 for (i = skip; i < tms_count; i++) {
84 tms = (tms_scan >> i) & 1;
85 if (bitbang_interface->write(0, tms, 0) != ERROR_OK)
86 return ERROR_FAIL;
87 if (bitbang_interface->write(1, tms, 0) != ERROR_OK)
88 return ERROR_FAIL;
89 }
90 if (bitbang_interface->write(CLOCK_IDLE(), tms, 0) != ERROR_OK)
91 return ERROR_FAIL;
92
93 tap_set_state(tap_get_end_state());
94 return ERROR_OK;
95 }
96
97 /**
98 * Clock a bunch of TMS (or SWDIO) transitions, to change the JTAG
99 * (or SWD) state machine.
100 */
101 static int bitbang_execute_tms(struct jtag_command *cmd)
102 {
103 unsigned num_bits = cmd->cmd.tms->num_bits;
104 const uint8_t *bits = cmd->cmd.tms->bits;
105
106 DEBUG_JTAG_IO("TMS: %d bits", num_bits);
107
108 int tms = 0;
109 for (unsigned i = 0; i < num_bits; i++) {
110 tms = ((bits[i/8] >> (i % 8)) & 1);
111 if (bitbang_interface->write(0, tms, 0) != ERROR_OK)
112 return ERROR_FAIL;
113 if (bitbang_interface->write(1, tms, 0) != ERROR_OK)
114 return ERROR_FAIL;
115 }
116 if (bitbang_interface->write(CLOCK_IDLE(), tms, 0) != ERROR_OK)
117 return ERROR_FAIL;
118
119 return ERROR_OK;
120 }
121
122 static int bitbang_path_move(struct pathmove_command *cmd)
123 {
124 int num_states = cmd->num_states;
125 int state_count;
126 int tms = 0;
127
128 state_count = 0;
129 while (num_states) {
130 if (tap_state_transition(tap_get_state(), false) == cmd->path[state_count])
131 tms = 0;
132 else if (tap_state_transition(tap_get_state(), true) == cmd->path[state_count])
133 tms = 1;
134 else {
135 LOG_ERROR("BUG: %s -> %s isn't a valid TAP transition",
136 tap_state_name(tap_get_state()),
137 tap_state_name(cmd->path[state_count]));
138 exit(-1);
139 }
140
141 if (bitbang_interface->write(0, tms, 0) != ERROR_OK)
142 return ERROR_FAIL;
143 if (bitbang_interface->write(1, tms, 0) != ERROR_OK)
144 return ERROR_FAIL;
145
146 tap_set_state(cmd->path[state_count]);
147 state_count++;
148 num_states--;
149 }
150
151 if (bitbang_interface->write(CLOCK_IDLE(), tms, 0) != ERROR_OK)
152 return ERROR_FAIL;
153
154 tap_set_end_state(tap_get_state());
155 return ERROR_OK;
156 }
157
158 static int bitbang_runtest(int num_cycles)
159 {
160 int i;
161
162 tap_state_t saved_end_state = tap_get_end_state();
163
164 /* only do a state_move when we're not already in IDLE */
165 if (tap_get_state() != TAP_IDLE) {
166 bitbang_end_state(TAP_IDLE);
167 if (bitbang_state_move(0) != ERROR_OK)
168 return ERROR_FAIL;
169 }
170
171 /* execute num_cycles */
172 for (i = 0; i < num_cycles; i++) {
173 if (bitbang_interface->write(0, 0, 0) != ERROR_OK)
174 return ERROR_FAIL;
175 if (bitbang_interface->write(1, 0, 0) != ERROR_OK)
176 return ERROR_FAIL;
177 }
178 if (bitbang_interface->write(CLOCK_IDLE(), 0, 0) != ERROR_OK)
179 return ERROR_FAIL;
180
181 /* finish in end_state */
182 bitbang_end_state(saved_end_state);
183 if (tap_get_state() != tap_get_end_state())
184 if (bitbang_state_move(0) != ERROR_OK)
185 return ERROR_FAIL;
186
187 return ERROR_OK;
188 }
189
190 static int bitbang_stableclocks(int num_cycles)
191 {
192 int tms = (tap_get_state() == TAP_RESET ? 1 : 0);
193 int i;
194
195 /* send num_cycles clocks onto the cable */
196 for (i = 0; i < num_cycles; i++) {
197 if (bitbang_interface->write(1, tms, 0) != ERROR_OK)
198 return ERROR_FAIL;
199 if (bitbang_interface->write(0, tms, 0) != ERROR_OK)
200 return ERROR_FAIL;
201 }
202
203 return ERROR_OK;
204 }
205
206 static int bitbang_scan(bool ir_scan, enum scan_type type, uint8_t *buffer,
207 unsigned scan_size)
208 {
209 tap_state_t saved_end_state = tap_get_end_state();
210 unsigned bit_cnt;
211
212 if (!((!ir_scan &&
213 (tap_get_state() == TAP_DRSHIFT)) ||
214 (ir_scan && (tap_get_state() == TAP_IRSHIFT)))) {
215 if (ir_scan)
216 bitbang_end_state(TAP_IRSHIFT);
217 else
218 bitbang_end_state(TAP_DRSHIFT);
219
220 if (bitbang_state_move(0) != ERROR_OK)
221 return ERROR_FAIL;
222 bitbang_end_state(saved_end_state);
223 }
224
225 size_t buffered = 0;
226 for (bit_cnt = 0; bit_cnt < scan_size; bit_cnt++) {
227 int tms = (bit_cnt == scan_size-1) ? 1 : 0;
228 int tdi;
229 int bytec = bit_cnt/8;
230 int bcval = 1 << (bit_cnt % 8);
231
232 /* if we're just reading the scan, but don't care about the output
233 * default to outputting 'low', this also makes valgrind traces more readable,
234 * as it removes the dependency on an uninitialised value
235 */
236 tdi = 0;
237 if ((type != SCAN_IN) && (buffer[bytec] & bcval))
238 tdi = 1;
239
240 if (bitbang_interface->write(0, tms, tdi) != ERROR_OK)
241 return ERROR_FAIL;
242
243 if (type != SCAN_OUT) {
244 if (bitbang_interface->buf_size) {
245 if (bitbang_interface->sample() != ERROR_OK)
246 return ERROR_FAIL;
247 buffered++;
248 } else {
249 switch (bitbang_interface->read()) {
250 case BB_LOW:
251 buffer[bytec] &= ~bcval;
252 break;
253 case BB_HIGH:
254 buffer[bytec] |= bcval;
255 break;
256 default:
257 return ERROR_FAIL;
258 }
259 }
260 }
261
262 if (bitbang_interface->write(1, tms, tdi) != ERROR_OK)
263 return ERROR_FAIL;
264
265 if (type != SCAN_OUT && bitbang_interface->buf_size &&
266 (buffered == bitbang_interface->buf_size ||
267 bit_cnt == scan_size - 1)) {
268 for (unsigned i = bit_cnt + 1 - buffered; i <= bit_cnt; i++) {
269 switch (bitbang_interface->read_sample()) {
270 case BB_LOW:
271 buffer[i/8] &= ~(1 << (i % 8));
272 break;
273 case BB_HIGH:
274 buffer[i/8] |= 1 << (i % 8);
275 break;
276 default:
277 return ERROR_FAIL;
278 }
279 }
280 buffered = 0;
281 }
282 }
283
284 if (tap_get_state() != tap_get_end_state()) {
285 /* we *KNOW* the above loop transitioned out of
286 * the shift state, so we skip the first state
287 * and move directly to the end state.
288 */
289 if (bitbang_state_move(1) != ERROR_OK)
290 return ERROR_FAIL;
291 }
292 return ERROR_OK;
293 }
294
295 int bitbang_execute_queue(void)
296 {
297 struct jtag_command *cmd = jtag_command_queue; /* currently processed command */
298 int scan_size;
299 enum scan_type type;
300 uint8_t *buffer;
301 int retval;
302
303 if (!bitbang_interface) {
304 LOG_ERROR("BUG: Bitbang interface called, but not yet initialized");
305 exit(-1);
306 }
307
308 /* return ERROR_OK, unless a jtag_read_buffer returns a failed check
309 * that wasn't handled by a caller-provided error handler
310 */
311 retval = ERROR_OK;
312
313 if (bitbang_interface->blink) {
314 if (bitbang_interface->blink(1) != ERROR_OK)
315 return ERROR_FAIL;
316 }
317
318 while (cmd) {
319 switch (cmd->type) {
320 case JTAG_RESET:
321 #ifdef _DEBUG_JTAG_IO_
322 LOG_DEBUG("reset trst: %i srst %i",
323 cmd->cmd.reset->trst,
324 cmd->cmd.reset->srst);
325 #endif
326 if ((cmd->cmd.reset->trst == 1) ||
327 (cmd->cmd.reset->srst && (jtag_get_reset_config() & RESET_SRST_PULLS_TRST)))
328 tap_set_state(TAP_RESET);
329 if (bitbang_interface->reset(cmd->cmd.reset->trst,
330 cmd->cmd.reset->srst) != ERROR_OK)
331 return ERROR_FAIL;
332 break;
333 case JTAG_RUNTEST:
334 #ifdef _DEBUG_JTAG_IO_
335 LOG_DEBUG("runtest %i cycles, end in %s",
336 cmd->cmd.runtest->num_cycles,
337 tap_state_name(cmd->cmd.runtest->end_state));
338 #endif
339 bitbang_end_state(cmd->cmd.runtest->end_state);
340 if (bitbang_runtest(cmd->cmd.runtest->num_cycles) != ERROR_OK)
341 return ERROR_FAIL;
342 break;
343
344 case JTAG_STABLECLOCKS:
345 /* this is only allowed while in a stable state. A check for a stable
346 * state was done in jtag_add_clocks()
347 */
348 if (bitbang_stableclocks(cmd->cmd.stableclocks->num_cycles) != ERROR_OK)
349 return ERROR_FAIL;
350 break;
351
352 case JTAG_TLR_RESET:
353 #ifdef _DEBUG_JTAG_IO_
354 LOG_DEBUG("statemove end in %s",
355 tap_state_name(cmd->cmd.statemove->end_state));
356 #endif
357 bitbang_end_state(cmd->cmd.statemove->end_state);
358 if (bitbang_state_move(0) != ERROR_OK)
359 return ERROR_FAIL;
360 break;
361 case JTAG_PATHMOVE:
362 #ifdef _DEBUG_JTAG_IO_
363 LOG_DEBUG("pathmove: %i states, end in %s",
364 cmd->cmd.pathmove->num_states,
365 tap_state_name(cmd->cmd.pathmove->path[cmd->cmd.pathmove->num_states - 1]));
366 #endif
367 if (bitbang_path_move(cmd->cmd.pathmove) != ERROR_OK)
368 return ERROR_FAIL;
369 break;
370 case JTAG_SCAN:
371 bitbang_end_state(cmd->cmd.scan->end_state);
372 scan_size = jtag_build_buffer(cmd->cmd.scan, &buffer);
373 #ifdef _DEBUG_JTAG_IO_
374 LOG_DEBUG("%s scan %d bits; end in %s",
375 (cmd->cmd.scan->ir_scan) ? "IR" : "DR",
376 scan_size,
377 tap_state_name(cmd->cmd.scan->end_state));
378 #endif
379 type = jtag_scan_type(cmd->cmd.scan);
380 if (bitbang_scan(cmd->cmd.scan->ir_scan, type, buffer,
381 scan_size) != ERROR_OK)
382 return ERROR_FAIL;
383 if (jtag_read_buffer(buffer, cmd->cmd.scan) != ERROR_OK)
384 retval = ERROR_JTAG_QUEUE_FAILED;
385 if (buffer)
386 free(buffer);
387 break;
388 case JTAG_SLEEP:
389 #ifdef _DEBUG_JTAG_IO_
390 LOG_DEBUG("sleep %" PRIi32, cmd->cmd.sleep->us);
391 #endif
392 jtag_sleep(cmd->cmd.sleep->us);
393 break;
394 case JTAG_TMS:
395 retval = bitbang_execute_tms(cmd);
396 break;
397 default:
398 LOG_ERROR("BUG: unknown JTAG command type encountered");
399 exit(-1);
400 }
401 cmd = cmd->next;
402 }
403 if (bitbang_interface->blink) {
404 if (bitbang_interface->blink(0) != ERROR_OK)
405 return ERROR_FAIL;
406 }
407
408 return retval;
409 }
410
411
412 bool swd_mode;
413 static int queued_retval;
414
415 static int bitbang_swd_init(void)
416 {
417 LOG_DEBUG("bitbang_swd_init");
418 swd_mode = true;
419 return ERROR_OK;
420 }
421
422 static void bitbang_exchange(bool rnw, uint8_t buf[], unsigned int offset, unsigned int bit_cnt)
423 {
424 LOG_DEBUG("bitbang_exchange");
425 int tdi;
426
427 for (unsigned int i = offset; i < bit_cnt + offset; i++) {
428 int bytec = i/8;
429 int bcval = 1 << (i % 8);
430 tdi = !rnw && (buf[bytec] & bcval);
431
432 bitbang_interface->write(0, 0, tdi);
433
434 if (rnw && buf) {
435 if (bitbang_interface->swdio_read())
436 buf[bytec] |= bcval;
437 else
438 buf[bytec] &= ~bcval;
439 }
440
441 bitbang_interface->write(1, 0, tdi);
442 }
443 }
444
445 int bitbang_swd_switch_seq(enum swd_special_seq seq)
446 {
447 LOG_DEBUG("bitbang_swd_switch_seq");
448
449 switch (seq) {
450 case LINE_RESET:
451 LOG_DEBUG("SWD line reset");
452 bitbang_exchange(false, (uint8_t *)swd_seq_line_reset, 0, swd_seq_line_reset_len);
453 break;
454 case JTAG_TO_SWD:
455 LOG_DEBUG("JTAG-to-SWD");
456 bitbang_exchange(false, (uint8_t *)swd_seq_jtag_to_swd, 0, swd_seq_jtag_to_swd_len);
457 break;
458 case SWD_TO_JTAG:
459 LOG_DEBUG("SWD-to-JTAG");
460 bitbang_exchange(false, (uint8_t *)swd_seq_swd_to_jtag, 0, swd_seq_swd_to_jtag_len);
461 break;
462 default:
463 LOG_ERROR("Sequence %d not supported", seq);
464 return ERROR_FAIL;
465 }
466
467 return ERROR_OK;
468 }
469
470 void bitbang_switch_to_swd(void)
471 {
472 LOG_DEBUG("bitbang_switch_to_swd");
473 bitbang_exchange(false, (uint8_t *)swd_seq_jtag_to_swd, 0, swd_seq_jtag_to_swd_len);
474 }
475
476 static void swd_clear_sticky_errors(void)
477 {
478 bitbang_swd_write_reg(swd_cmd(false, false, DP_ABORT),
479 STKCMPCLR | STKERRCLR | WDERRCLR | ORUNERRCLR, 0);
480 }
481
482 static void bitbang_swd_read_reg(uint8_t cmd, uint32_t *value, uint32_t ap_delay_clk)
483 {
484 LOG_DEBUG("bitbang_swd_read_reg");
485 assert(cmd & SWD_CMD_RnW);
486
487 if (queued_retval != ERROR_OK) {
488 LOG_DEBUG("Skip bitbang_swd_read_reg because queued_retval=%d", queued_retval);
489 return;
490 }
491
492 for (;;) {
493 uint8_t trn_ack_data_parity_trn[DIV_ROUND_UP(4 + 3 + 32 + 1 + 4, 8)];
494
495 cmd |= SWD_CMD_START | (1 << 7);
496 bitbang_exchange(false, &cmd, 0, 8);
497
498 bitbang_interface->swdio_drive(false);
499 bitbang_exchange(true, trn_ack_data_parity_trn, 0, 1 + 3 + 32 + 1 + 1);
500 bitbang_interface->swdio_drive(true);
501
502 int ack = buf_get_u32(trn_ack_data_parity_trn, 1, 3);
503 uint32_t data = buf_get_u32(trn_ack_data_parity_trn, 1 + 3, 32);
504 int parity = buf_get_u32(trn_ack_data_parity_trn, 1 + 3 + 32, 1);
505
506 LOG_DEBUG("%s %s %s reg %X = %08"PRIx32,
507 ack == SWD_ACK_OK ? "OK" : ack == SWD_ACK_WAIT ? "WAIT" : ack == SWD_ACK_FAULT ? "FAULT" : "JUNK",
508 cmd & SWD_CMD_APnDP ? "AP" : "DP",
509 cmd & SWD_CMD_RnW ? "read" : "write",
510 (cmd & SWD_CMD_A32) >> 1,
511 data);
512
513 switch (ack) {
514 case SWD_ACK_OK:
515 if (parity != parity_u32(data)) {
516 LOG_DEBUG("Wrong parity detected");
517 queued_retval = ERROR_FAIL;
518 return;
519 }
520 if (value)
521 *value = data;
522 if (cmd & SWD_CMD_APnDP)
523 bitbang_exchange(true, NULL, 0, ap_delay_clk);
524 return;
525 case SWD_ACK_WAIT:
526 LOG_DEBUG("SWD_ACK_WAIT");
527 swd_clear_sticky_errors();
528 break;
529 case SWD_ACK_FAULT:
530 LOG_DEBUG("SWD_ACK_FAULT");
531 queued_retval = ack;
532 return;
533 default:
534 LOG_DEBUG("No valid acknowledge: ack=%d", ack);
535 queued_retval = ack;
536 return;
537 }
538 }
539 }
540
541 static void bitbang_swd_write_reg(uint8_t cmd, uint32_t value, uint32_t ap_delay_clk)
542 {
543 LOG_DEBUG("bitbang_swd_write_reg");
544 assert(!(cmd & SWD_CMD_RnW));
545
546 if (queued_retval != ERROR_OK) {
547 LOG_DEBUG("Skip bitbang_swd_write_reg because queued_retval=%d", queued_retval);
548 return;
549 }
550
551 for (;;) {
552 uint8_t trn_ack_data_parity_trn[DIV_ROUND_UP(4 + 3 + 32 + 1 + 4, 8)];
553 buf_set_u32(trn_ack_data_parity_trn, 1 + 3 + 1, 32, value);
554 buf_set_u32(trn_ack_data_parity_trn, 1 + 3 + 1 + 32, 1, parity_u32(value));
555
556 cmd |= SWD_CMD_START | (1 << 7);
557 bitbang_exchange(false, &cmd, 0, 8);
558
559 bitbang_interface->swdio_drive(false);
560 bitbang_exchange(true, trn_ack_data_parity_trn, 0, 1 + 3 + 1);
561 bitbang_interface->swdio_drive(true);
562 bitbang_exchange(false, trn_ack_data_parity_trn, 1 + 3 + 1, 32 + 1);
563
564 int ack = buf_get_u32(trn_ack_data_parity_trn, 1, 3);
565 LOG_DEBUG("%s %s %s reg %X = %08"PRIx32,
566 ack == SWD_ACK_OK ? "OK" : ack == SWD_ACK_WAIT ? "WAIT" : ack == SWD_ACK_FAULT ? "FAULT" : "JUNK",
567 cmd & SWD_CMD_APnDP ? "AP" : "DP",
568 cmd & SWD_CMD_RnW ? "read" : "write",
569 (cmd & SWD_CMD_A32) >> 1,
570 buf_get_u32(trn_ack_data_parity_trn, 1 + 3 + 1, 32));
571
572 switch (ack) {
573 case SWD_ACK_OK:
574 if (cmd & SWD_CMD_APnDP)
575 bitbang_exchange(true, NULL, 0, ap_delay_clk);
576 return;
577 case SWD_ACK_WAIT:
578 LOG_DEBUG("SWD_ACK_WAIT");
579 swd_clear_sticky_errors();
580 break;
581 case SWD_ACK_FAULT:
582 LOG_DEBUG("SWD_ACK_FAULT");
583 queued_retval = ack;
584 return;
585 default:
586 LOG_DEBUG("No valid acknowledge: ack=%d", ack);
587 queued_retval = ack;
588 return;
589 }
590 }
591 }
592
593 static int bitbang_swd_run_queue(void)
594 {
595 LOG_DEBUG("bitbang_swd_run_queue");
596 /* A transaction must be followed by another transaction or at least 8 idle cycles to
597 * ensure that data is clocked through the AP. */
598 bitbang_exchange(true, NULL, 0, 8);
599
600 int retval = queued_retval;
601 queued_retval = ERROR_OK;
602 LOG_DEBUG("SWD queue return value: %02x", retval);
603 return retval;
604 }
605
606 const struct swd_driver bitbang_swd = {
607 .init = bitbang_swd_init,
608 .switch_seq = bitbang_swd_switch_seq,
609 .read_reg = bitbang_swd_read_reg,
610 .write_reg = bitbang_swd_write_reg,
611 .run = bitbang_swd_run_queue,
612 };

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)