jtag: linuxgpiod: drop extra parenthesis
[openocd.git] / src / target / embeddedice.c
1 /***************************************************************************
2 * Copyright (C) 2005 by Dominic Rath *
3 * Dominic.Rath@gmx.de *
4 * *
5 * Copyright (C) 2007-2010 Øyvind Harboe *
6 * oyvind.harboe@zylin.com *
7 * *
8 * Copyright (C) 2008 by Spencer Oliver *
9 * spen@spen-soft.co.uk *
10 * *
11 * This program is free software; you can redistribute it and/or modify *
12 * it under the terms of the GNU General Public License as published by *
13 * the Free Software Foundation; either version 2 of the License, or *
14 * (at your option) any later version. *
15 * *
16 * This program is distributed in the hope that it will be useful, *
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
19 * GNU General Public License for more details. *
20 * *
21 * You should have received a copy of the GNU General Public License *
22 * along with this program. If not, see <http://www.gnu.org/licenses/>. *
23 ***************************************************************************/
24
25 #ifdef HAVE_CONFIG_H
26 #include "config.h"
27 #endif
28
29 #include "embeddedice.h"
30 #include "register.h"
31 #include <helper/time_support.h>
32
33 /**
34 * @file
35 *
36 * This provides lowlevel glue to the EmbeddedICE (or EmbeddedICE-RT)
37 * module found on scan chain 2 in ARM7, ARM9, and some other families
38 * of ARM cores. The module is called "EmbeddedICE-RT" if it has
39 * monitor mode support.
40 *
41 * EmbeddedICE provides basic watchpoint/breakpoint hardware and a Debug
42 * Communications Channel (DCC) used to read or write 32-bit words to
43 * OpenOCD-aware code running on the target CPU.
44 * Newer modules also include vector catch hardware. Some versions
45 * support hardware single-stepping, "monitor mode" debug (which is not
46 * currently supported by OpenOCD), or extended reporting on why the
47 * core entered debug mode.
48 */
49
50 static int embeddedice_set_reg_w_exec(struct reg *reg, uint8_t *buf);
51
52 /*
53 * From: ARM9E-S TRM, DDI 0165, table C-4 (and similar, for other cores)
54 */
55 static const struct {
56 const char *name;
57 unsigned short addr;
58 unsigned short width;
59 } eice_regs[] = {
60 [EICE_DBG_CTRL] = {
61 .name = "debug_ctrl",
62 .addr = 0,
63 /* width is assigned based on EICE version */
64 },
65 [EICE_DBG_STAT] = {
66 .name = "debug_status",
67 .addr = 1,
68 /* width is assigned based on EICE version */
69 },
70 [EICE_COMMS_CTRL] = {
71 .name = "comms_ctrl",
72 .addr = 4,
73 .width = 6,
74 },
75 [EICE_COMMS_DATA] = {
76 .name = "comms_data",
77 .addr = 5,
78 .width = 32,
79 },
80 [EICE_W0_ADDR_VALUE] = {
81 .name = "watch_0_addr_value",
82 .addr = 8,
83 .width = 32,
84 },
85 [EICE_W0_ADDR_MASK] = {
86 .name = "watch_0_addr_mask",
87 .addr = 9,
88 .width = 32,
89 },
90 [EICE_W0_DATA_VALUE] = {
91 .name = "watch_0_data_value",
92 .addr = 10,
93 .width = 32,
94 },
95 [EICE_W0_DATA_MASK] = {
96 .name = "watch_0_data_mask",
97 .addr = 11,
98 .width = 32,
99 },
100 [EICE_W0_CONTROL_VALUE] = {
101 .name = "watch_0_control_value",
102 .addr = 12,
103 .width = 9,
104 },
105 [EICE_W0_CONTROL_MASK] = {
106 .name = "watch_0_control_mask",
107 .addr = 13,
108 .width = 8,
109 },
110 [EICE_W1_ADDR_VALUE] = {
111 .name = "watch_1_addr_value",
112 .addr = 16,
113 .width = 32,
114 },
115 [EICE_W1_ADDR_MASK] = {
116 .name = "watch_1_addr_mask",
117 .addr = 17,
118 .width = 32,
119 },
120 [EICE_W1_DATA_VALUE] = {
121 .name = "watch_1_data_value",
122 .addr = 18,
123 .width = 32,
124 },
125 [EICE_W1_DATA_MASK] = {
126 .name = "watch_1_data_mask",
127 .addr = 19,
128 .width = 32,
129 },
130 [EICE_W1_CONTROL_VALUE] = {
131 .name = "watch_1_control_value",
132 .addr = 20,
133 .width = 9,
134 },
135 [EICE_W1_CONTROL_MASK] = {
136 .name = "watch_1_control_mask",
137 .addr = 21,
138 .width = 8,
139 },
140 /* vector_catch isn't always present */
141 [EICE_VEC_CATCH] = {
142 .name = "vector_catch",
143 .addr = 2,
144 .width = 8,
145 },
146 };
147
148 static int embeddedice_get_reg(struct reg *reg)
149 {
150 int retval = embeddedice_read_reg(reg);
151 if (retval != ERROR_OK) {
152 LOG_ERROR("error queueing EmbeddedICE register read");
153 return retval;
154 }
155
156 retval = jtag_execute_queue();
157 if (retval != ERROR_OK)
158 LOG_ERROR("EmbeddedICE register read failed");
159
160 return retval;
161 }
162
163 static const struct reg_arch_type eice_reg_type = {
164 .get = embeddedice_get_reg,
165 .set = embeddedice_set_reg_w_exec,
166 };
167
168 /**
169 * Probe EmbeddedICE module and set up local records of its registers.
170 * Different versions of the modules have different capabilities, such as
171 * hardware support for vector_catch, single stepping, and monitor mode.
172 */
173 struct reg_cache *embeddedice_build_reg_cache(struct target *target,
174 struct arm7_9_common *arm7_9)
175 {
176 int retval;
177 struct reg_cache *reg_cache = malloc(sizeof(struct reg_cache));
178 struct reg *reg_list = NULL;
179 struct embeddedice_reg *arch_info = NULL;
180 struct arm_jtag *jtag_info = &arm7_9->jtag_info;
181 int num_regs = ARRAY_SIZE(eice_regs);
182 int i;
183 int eice_version = 0;
184
185 /* vector_catch isn't always present */
186 if (!arm7_9->has_vector_catch)
187 num_regs--;
188
189 /* the actual registers are kept in two arrays */
190 reg_list = calloc(num_regs, sizeof(struct reg));
191 arch_info = calloc(num_regs, sizeof(struct embeddedice_reg));
192
193 /* fill in values for the reg cache */
194 reg_cache->name = "EmbeddedICE registers";
195 reg_cache->next = NULL;
196 reg_cache->reg_list = reg_list;
197 reg_cache->num_regs = num_regs;
198
199 /* FIXME the second watchpoint unit on Feroceon and Dragonite
200 * seems not to work ... we should have a way to not set up
201 * its four registers here!
202 */
203
204 /* set up registers */
205 for (i = 0; i < num_regs; i++) {
206 reg_list[i].name = eice_regs[i].name;
207 reg_list[i].size = eice_regs[i].width;
208 reg_list[i].dirty = false;
209 reg_list[i].valid = false;
210 reg_list[i].value = calloc(1, 4);
211 reg_list[i].arch_info = &arch_info[i];
212 reg_list[i].type = &eice_reg_type;
213 arch_info[i].addr = eice_regs[i].addr;
214 arch_info[i].jtag_info = jtag_info;
215 }
216
217 /* identify EmbeddedICE version by reading DCC control register */
218 embeddedice_read_reg(&reg_list[EICE_COMMS_CTRL]);
219 retval = jtag_execute_queue();
220 if (retval != ERROR_OK) {
221 for (i = 0; i < num_regs; i++)
222 free(reg_list[i].value);
223 free(reg_list);
224 free(reg_cache);
225 free(arch_info);
226 return NULL;
227 }
228
229 eice_version = buf_get_u32(reg_list[EICE_COMMS_CTRL].value, 28, 4);
230 LOG_INFO("Embedded ICE version %d", eice_version);
231
232 switch (eice_version) {
233 case 1:
234 /* ARM7TDMI r3, ARM7TDMI-S r3
235 *
236 * REVISIT docs say ARM7TDMI-S r4 uses version 1 but
237 * that it has 6-bit CTRL and 5-bit STAT... doc bug?
238 * ARM7TDMI r4 docs say EICE v4.
239 */
240 reg_list[EICE_DBG_CTRL].size = 3;
241 reg_list[EICE_DBG_STAT].size = 5;
242 break;
243 case 2:
244 /* ARM9TDMI */
245 reg_list[EICE_DBG_CTRL].size = 4;
246 reg_list[EICE_DBG_STAT].size = 5;
247 arm7_9->has_single_step = 1;
248 break;
249 case 3:
250 LOG_ERROR("EmbeddedICE v%d handling might be broken",
251 eice_version);
252 reg_list[EICE_DBG_CTRL].size = 6;
253 reg_list[EICE_DBG_STAT].size = 5;
254 arm7_9->has_single_step = 1;
255 arm7_9->has_monitor_mode = 1;
256 break;
257 case 4:
258 /* ARM7TDMI r4 */
259 reg_list[EICE_DBG_CTRL].size = 6;
260 reg_list[EICE_DBG_STAT].size = 5;
261 arm7_9->has_monitor_mode = 1;
262 break;
263 case 5:
264 /* ARM9E-S rev 1 */
265 reg_list[EICE_DBG_CTRL].size = 6;
266 reg_list[EICE_DBG_STAT].size = 5;
267 arm7_9->has_single_step = 1;
268 arm7_9->has_monitor_mode = 1;
269 break;
270 case 6:
271 /* ARM7EJ-S, ARM9E-S rev 2, ARM9EJ-S */
272 reg_list[EICE_DBG_CTRL].size = 6;
273 reg_list[EICE_DBG_STAT].size = 10;
274 /* DBG_STAT has MOE bits */
275 arm7_9->has_monitor_mode = 1;
276 break;
277 case 7:
278 LOG_ERROR("EmbeddedICE v%d handling might be broken",
279 eice_version);
280 reg_list[EICE_DBG_CTRL].size = 6;
281 reg_list[EICE_DBG_STAT].size = 5;
282 arm7_9->has_monitor_mode = 1;
283 break;
284 default:
285 /*
286 * The Feroceon implementation has the version number
287 * in some unusual bits. Let feroceon.c validate it
288 * and do the appropriate setup itself.
289 */
290 if (strcmp(target_type_name(target), "feroceon") == 0 ||
291 strcmp(target_type_name(target), "dragonite") == 0)
292 break;
293 LOG_ERROR("unknown EmbeddedICE version "
294 "(comms ctrl: 0x%8.8" PRIx32 ")",
295 buf_get_u32(reg_list[EICE_COMMS_CTRL].value, 0, 32));
296 }
297
298 /* On Feroceon and Dragonite the second unit is seemingly missing. */
299 LOG_INFO("%s: hardware has %d breakpoint/watchpoint unit%s",
300 target_name(target), arm7_9->wp_available_max,
301 (arm7_9->wp_available_max != 1) ? "s" : "");
302
303 return reg_cache;
304 }
305
306 /**
307 * Free all memory allocated for EmbeddedICE register cache
308 */
309 void embeddedice_free_reg_cache(struct reg_cache *reg_cache)
310 {
311 if (!reg_cache)
312 return;
313
314 for (unsigned int i = 0; i < reg_cache->num_regs; i++)
315 free(reg_cache->reg_list[i].value);
316
317 free(reg_cache->reg_list[0].arch_info);
318 free(reg_cache->reg_list);
319 free(reg_cache);
320 }
321
322 /**
323 * Initialize EmbeddedICE module, if needed.
324 */
325 int embeddedice_setup(struct target *target)
326 {
327 int retval;
328 struct arm7_9_common *arm7_9 = target_to_arm7_9(target);
329
330 /* Explicitly disable monitor mode. For now we only support halting
331 * debug ... we don't know how to talk with a resident debug monitor
332 * that manages break requests. ARM's "Angel Debug Monitor" is one
333 * common example of such code.
334 */
335 if (arm7_9->has_monitor_mode) {
336 struct reg *dbg_ctrl = &arm7_9->eice_cache->reg_list[EICE_DBG_CTRL];
337
338 embeddedice_read_reg(dbg_ctrl);
339 retval = jtag_execute_queue();
340 if (retval != ERROR_OK)
341 return retval;
342 buf_set_u32(dbg_ctrl->value, 4, 1, 0);
343 embeddedice_set_reg_w_exec(dbg_ctrl, dbg_ctrl->value);
344 }
345 return jtag_execute_queue();
346 }
347
348 /**
349 * Queue a read for an EmbeddedICE register into the register cache,
350 * optionally checking the value read.
351 * Note that at this level, all registers are 32 bits wide.
352 */
353 int embeddedice_read_reg_w_check(struct reg *reg,
354 uint8_t *check_value, uint8_t *check_mask)
355 {
356 struct embeddedice_reg *ice_reg = reg->arch_info;
357 uint8_t reg_addr = ice_reg->addr & 0x1f;
358 struct scan_field fields[3];
359 uint8_t field1_out[1];
360 uint8_t field2_out[1];
361 int retval;
362
363 retval = arm_jtag_scann(ice_reg->jtag_info, 0x2, TAP_IDLE);
364 if (retval != ERROR_OK)
365 return retval;
366
367 retval = arm_jtag_set_instr(ice_reg->jtag_info->tap,
368 ice_reg->jtag_info->intest_instr, NULL, TAP_IDLE);
369 if (retval != ERROR_OK)
370 return retval;
371
372 /* bits 31:0 -- data (ignored here) */
373 fields[0].num_bits = 32;
374 fields[0].out_value = reg->value;
375 fields[0].in_value = NULL;
376 fields[0].check_value = NULL;
377 fields[0].check_mask = NULL;
378
379 /* bits 36:32 -- register */
380 fields[1].num_bits = 5;
381 fields[1].out_value = field1_out;
382 field1_out[0] = reg_addr;
383 fields[1].in_value = NULL;
384 fields[1].check_value = NULL;
385 fields[1].check_mask = NULL;
386
387 /* bit 37 -- 0/read */
388 fields[2].num_bits = 1;
389 fields[2].out_value = field2_out;
390 field2_out[0] = 0;
391 fields[2].in_value = NULL;
392 fields[2].check_value = NULL;
393 fields[2].check_mask = NULL;
394
395 /* traverse Update-DR, setting address for the next read */
396 jtag_add_dr_scan(ice_reg->jtag_info->tap, 3, fields, TAP_IDLE);
397
398 /* bits 31:0 -- the data we're reading (and maybe checking) */
399 fields[0].in_value = reg->value;
400 fields[0].check_value = check_value;
401 fields[0].check_mask = check_mask;
402
403 /* when reading the DCC data register, leaving the address field set to
404 * EICE_COMMS_DATA would read the register twice
405 * reading the control register is safe
406 */
407 field1_out[0] = eice_regs[EICE_COMMS_CTRL].addr;
408
409 /* traverse Update-DR, reading but with no other side effects */
410 jtag_add_dr_scan_check(ice_reg->jtag_info->tap, 3, fields, TAP_IDLE);
411
412 return ERROR_OK;
413 }
414
415 /**
416 * Receive a block of size 32-bit words from the DCC.
417 * We assume the target is always going to be fast enough (relative to
418 * the JTAG clock) that the debugger won't need to poll the handshake
419 * bit. The JTAG clock is usually at least six times slower than the
420 * functional clock, so the 50+ JTAG clocks needed to receive the word
421 * allow hundreds of instruction cycles (per word) in the target.
422 */
423 int embeddedice_receive(struct arm_jtag *jtag_info, uint32_t *data, uint32_t size)
424 {
425 struct scan_field fields[3];
426 uint8_t field1_out[1];
427 uint8_t field2_out[1];
428 int retval;
429
430 retval = arm_jtag_scann(jtag_info, 0x2, TAP_IDLE);
431 if (retval != ERROR_OK)
432 return retval;
433 retval = arm_jtag_set_instr(jtag_info->tap, jtag_info->intest_instr, NULL, TAP_IDLE);
434 if (retval != ERROR_OK)
435 return retval;
436
437 fields[0].num_bits = 32;
438 fields[0].out_value = NULL;
439 fields[0].in_value = NULL;
440
441 fields[1].num_bits = 5;
442 fields[1].out_value = field1_out;
443 field1_out[0] = eice_regs[EICE_COMMS_DATA].addr;
444 fields[1].in_value = NULL;
445
446 fields[2].num_bits = 1;
447 fields[2].out_value = field2_out;
448 field2_out[0] = 0;
449 fields[2].in_value = NULL;
450
451 jtag_add_dr_scan(jtag_info->tap, 3, fields, TAP_IDLE);
452
453 while (size > 0) {
454 /* when reading the last item, set the register address to the DCC control reg,
455 * to avoid reading additional data from the DCC data reg
456 */
457 if (size == 1)
458 field1_out[0] = eice_regs[EICE_COMMS_CTRL].addr;
459
460 fields[0].in_value = (uint8_t *)data;
461 jtag_add_dr_scan(jtag_info->tap, 3, fields, TAP_IDLE);
462 jtag_add_callback(arm_le_to_h_u32, (jtag_callback_data_t)data);
463
464 data++;
465 size--;
466 }
467
468 return jtag_execute_queue();
469 }
470
471 /**
472 * Queue a read for an EmbeddedICE register into the register cache,
473 * not checking the value read.
474 */
475 int embeddedice_read_reg(struct reg *reg)
476 {
477 return embeddedice_read_reg_w_check(reg, NULL, NULL);
478 }
479
480 /**
481 * Queue a write for an EmbeddedICE register, updating the register cache.
482 * Uses embeddedice_write_reg().
483 */
484 void embeddedice_set_reg(struct reg *reg, uint32_t value)
485 {
486 embeddedice_write_reg(reg, value);
487
488 buf_set_u32(reg->value, 0, reg->size, value);
489 reg->valid = true;
490 reg->dirty = false;
491
492 }
493
494 /**
495 * Write an EmbeddedICE register, updating the register cache.
496 * Uses embeddedice_set_reg(); not queued.
497 */
498 static int embeddedice_set_reg_w_exec(struct reg *reg, uint8_t *buf)
499 {
500 int retval;
501
502 embeddedice_set_reg(reg, buf_get_u32(buf, 0, reg->size));
503 retval = jtag_execute_queue();
504 if (retval != ERROR_OK)
505 LOG_ERROR("register write failed");
506 return retval;
507 }
508
509 /**
510 * Queue a write for an EmbeddedICE register, bypassing the register cache.
511 */
512 void embeddedice_write_reg(struct reg *reg, uint32_t value)
513 {
514 struct embeddedice_reg *ice_reg = reg->arch_info;
515
516 LOG_DEBUG("%i: 0x%8.8" PRIx32 "", ice_reg->addr, value);
517
518 arm_jtag_scann(ice_reg->jtag_info, 0x2, TAP_IDLE);
519
520 arm_jtag_set_instr(ice_reg->jtag_info->tap, ice_reg->jtag_info->intest_instr, NULL, TAP_IDLE);
521
522 uint8_t reg_addr = ice_reg->addr & 0x1f;
523 embeddedice_write_reg_inner(ice_reg->jtag_info->tap, reg_addr, value);
524 }
525
526 /**
527 * Queue a write for an EmbeddedICE register, using cached value.
528 * Uses embeddedice_write_reg().
529 */
530 void embeddedice_store_reg(struct reg *reg)
531 {
532 embeddedice_write_reg(reg, buf_get_u32(reg->value, 0, reg->size));
533 }
534
535 /**
536 * Send a block of size 32-bit words to the DCC.
537 * We assume the target is always going to be fast enough (relative to
538 * the JTAG clock) that the debugger won't need to poll the handshake
539 * bit. The JTAG clock is usually at least six times slower than the
540 * functional clock, so the 50+ JTAG clocks needed to receive the word
541 * allow hundreds of instruction cycles (per word) in the target.
542 */
543 int embeddedice_send(struct arm_jtag *jtag_info, uint32_t *data, uint32_t size)
544 {
545 struct scan_field fields[3];
546 uint8_t field0_out[4];
547 uint8_t field1_out[1];
548 uint8_t field2_out[1];
549 int retval;
550
551 retval = arm_jtag_scann(jtag_info, 0x2, TAP_IDLE);
552 if (retval != ERROR_OK)
553 return retval;
554 retval = arm_jtag_set_instr(jtag_info->tap, jtag_info->intest_instr, NULL, TAP_IDLE);
555 if (retval != ERROR_OK)
556 return retval;
557
558 fields[0].num_bits = 32;
559 fields[0].out_value = field0_out;
560 fields[0].in_value = NULL;
561
562 fields[1].num_bits = 5;
563 fields[1].out_value = field1_out;
564 field1_out[0] = eice_regs[EICE_COMMS_DATA].addr;
565 fields[1].in_value = NULL;
566
567 fields[2].num_bits = 1;
568 fields[2].out_value = field2_out;
569 field2_out[0] = 1;
570
571 fields[2].in_value = NULL;
572
573 while (size > 0) {
574 buf_set_u32(field0_out, 0, 32, *data);
575 jtag_add_dr_scan(jtag_info->tap, 3, fields, TAP_IDLE);
576
577 data++;
578 size--;
579 }
580
581 /* call to jtag_execute_queue() intentionally omitted */
582 return ERROR_OK;
583 }
584
585 /**
586 * Poll DCC control register until read or write handshake completes.
587 */
588 int embeddedice_handshake(struct arm_jtag *jtag_info, int hsbit, uint32_t timeout)
589 {
590 struct scan_field fields[3];
591 uint8_t field0_in[4];
592 uint8_t field1_out[1];
593 uint8_t field2_out[1];
594 int retval;
595 uint32_t hsact;
596 struct timeval now;
597 struct timeval timeout_end;
598
599 if (hsbit == EICE_COMM_CTRL_WBIT)
600 hsact = 1;
601 else if (hsbit == EICE_COMM_CTRL_RBIT)
602 hsact = 0;
603 else {
604 LOG_ERROR("Invalid arguments");
605 return ERROR_COMMAND_SYNTAX_ERROR;
606 }
607
608 retval = arm_jtag_scann(jtag_info, 0x2, TAP_IDLE);
609 if (retval != ERROR_OK)
610 return retval;
611 retval = arm_jtag_set_instr(jtag_info->tap, jtag_info->intest_instr, NULL, TAP_IDLE);
612 if (retval != ERROR_OK)
613 return retval;
614
615 fields[0].num_bits = 32;
616 fields[0].out_value = NULL;
617 fields[0].in_value = field0_in;
618
619 fields[1].num_bits = 5;
620 fields[1].out_value = field1_out;
621 field1_out[0] = eice_regs[EICE_COMMS_DATA].addr;
622 fields[1].in_value = NULL;
623
624 fields[2].num_bits = 1;
625 fields[2].out_value = field2_out;
626 field2_out[0] = 0;
627 fields[2].in_value = NULL;
628
629 jtag_add_dr_scan(jtag_info->tap, 3, fields, TAP_IDLE);
630 gettimeofday(&timeout_end, NULL);
631 timeval_add_time(&timeout_end, 0, timeout * 1000);
632 do {
633 jtag_add_dr_scan(jtag_info->tap, 3, fields, TAP_IDLE);
634 retval = jtag_execute_queue();
635 if (retval != ERROR_OK)
636 return retval;
637
638 if (buf_get_u32(field0_in, hsbit, 1) == hsact)
639 return ERROR_OK;
640
641 gettimeofday(&now, NULL);
642 } while (timeval_compare(&now, &timeout_end) <= 0);
643
644 LOG_ERROR("embeddedice handshake timeout");
645 return ERROR_TARGET_TIMEOUT;
646 }
647
648 /**
649 * This is an inner loop of the open loop DCC write of data to target
650 */
651 void embeddedice_write_dcc(struct jtag_tap *tap,
652 int reg_addr, const uint8_t *buffer, int little, int count)
653 {
654 int i;
655
656 for (i = 0; i < count; i++) {
657 embeddedice_write_reg_inner(tap, reg_addr,
658 fast_target_buffer_get_u32(buffer, little));
659 buffer += 4;
660 }
661 }

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)