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