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

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)