2a96833dae931db100c005165c0ea90ddabd53f2
[openocd.git] / src / target / mips_m4k.c
1 /***************************************************************************
2 * Copyright (C) 2008 by Spencer Oliver *
3 * spen@spen-soft.co.uk *
4 * *
5 * Copyright (C) 2008 by David T.L. Wong *
6 * *
7 * This program is free software; you can redistribute it and/or modify *
8 * it under the terms of the GNU General Public License as published by *
9 * the Free Software Foundation; either version 2 of the License, or *
10 * (at your option) any later version. *
11 * *
12 * This program is distributed in the hope that it will be useful, *
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
15 * GNU General Public License for more details. *
16 * *
17 * You should have received a copy of the GNU General Public License *
18 * along with this program; if not, write to the *
19 * Free Software Foundation, Inc., *
20 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
21 ***************************************************************************/
22 #ifdef HAVE_CONFIG_H
23 #include "config.h"
24 #endif
25
26 #include "mips32.h"
27 #include "mips_m4k.h"
28 #include "mips32_dmaacc.h"
29 #include "jtag.h"
30 #include "log.h"
31
32 #include <stdlib.h>
33 #include <string.h>
34
35 /* cli handling */
36
37 /* forward declarations */
38 int mips_m4k_poll(target_t *target);
39 int mips_m4k_halt(struct target_s *target);
40 int mips_m4k_soft_reset_halt(struct target_s *target);
41 int mips_m4k_resume(struct target_s *target, int current, u32 address, int handle_breakpoints, int debug_execution);
42 int mips_m4k_step(struct target_s *target, int current, u32 address, int handle_breakpoints);
43 int mips_m4k_read_memory(struct target_s *target, u32 address, u32 size, u32 count, u8 *buffer);
44 int mips_m4k_write_memory(struct target_s *target, u32 address, u32 size, u32 count, u8 *buffer);
45 int mips_m4k_register_commands(struct command_context_s *cmd_ctx);
46 int mips_m4k_init_target(struct command_context_s *cmd_ctx, struct target_s *target);
47 int mips_m4k_quit(void);
48 int mips_m4k_target_create(struct target_s *target, Jim_Interp *interp);
49
50 int mips_m4k_examine(struct target_s *target);
51 int mips_m4k_assert_reset(target_t *target);
52 int mips_m4k_deassert_reset(target_t *target);
53
54 target_type_t mips_m4k_target =
55 {
56 .name = "mips_m4k",
57
58 .poll = mips_m4k_poll,
59 .arch_state = mips32_arch_state,
60
61 .target_request_data = NULL,
62
63 .halt = mips_m4k_halt,
64 .resume = mips_m4k_resume,
65 .step = mips_m4k_step,
66
67 .assert_reset = mips_m4k_assert_reset,
68 .deassert_reset = mips_m4k_deassert_reset,
69 .soft_reset_halt = mips_m4k_soft_reset_halt,
70
71 .get_gdb_reg_list = mips32_get_gdb_reg_list,
72
73 .read_memory = mips_m4k_read_memory,
74 .write_memory = mips_m4k_write_memory,
75 .bulk_write_memory = mips_m4k_bulk_write_memory,
76 .checksum_memory = NULL,
77 .blank_check_memory = NULL,
78
79 .run_algorithm = mips32_run_algorithm,
80
81 .add_breakpoint = mips_m4k_add_breakpoint,
82 .remove_breakpoint = mips_m4k_remove_breakpoint,
83 .add_watchpoint = mips_m4k_add_watchpoint,
84 .remove_watchpoint = mips_m4k_remove_watchpoint,
85
86 .register_commands = mips_m4k_register_commands,
87 .target_create = mips_m4k_target_create,
88 .init_target = mips_m4k_init_target,
89 .examine = mips_m4k_examine,
90 .quit = mips_m4k_quit
91 };
92
93 int mips_m4k_debug_entry(target_t *target)
94 {
95 u32 debug_reg;
96 mips32_common_t *mips32 = target->arch_info;
97 mips_ejtag_t *ejtag_info = &mips32->ejtag_info;
98
99 /* read debug register */
100 mips_ejtag_read_debug(ejtag_info, &debug_reg);
101
102 if ((target->debug_reason != DBG_REASON_DBGRQ)
103 && (target->debug_reason != DBG_REASON_SINGLESTEP))
104 {
105 // if (cortex_m3->nvic_dfsr & DFSR_BKPT)
106 // {
107 // target->debug_reason = DBG_REASON_BREAKPOINT;
108 // if (cortex_m3->nvic_dfsr & DFSR_DWTTRAP)
109 // target->debug_reason = DBG_REASON_WPTANDBKPT;
110 // }
111 // else if (cortex_m3->nvic_dfsr & DFSR_DWTTRAP)
112 // target->debug_reason = DBG_REASON_WATCHPOINT;
113 }
114
115 if (debug_reg & EJTAG_DEBUG_DSS)
116 {
117 /* stopped due to single step - clear step bit */
118 mips_ejtag_config_step(ejtag_info, 0);
119 }
120
121 mips32_save_context(target);
122
123 LOG_DEBUG("entered debug state at PC 0x%x, target->state: %s",
124 *(u32*)(mips32->core_cache->reg_list[MIPS32_PC].value),
125 Jim_Nvp_value2name_simple( nvp_target_state, target->state )->name);
126
127 return ERROR_OK;
128 }
129
130 int mips_m4k_poll(target_t *target)
131 {
132 int retval;
133 mips32_common_t *mips32 = target->arch_info;
134 mips_ejtag_t *ejtag_info = &mips32->ejtag_info;
135 u32 ejtag_ctrl = ejtag_info->ejtag_ctrl;
136
137 /* read ejtag control reg */
138 jtag_add_end_state(TAP_RTI);
139 mips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL, NULL);
140 mips_ejtag_drscan_32(ejtag_info, &ejtag_ctrl);
141
142 if (ejtag_ctrl & EJTAG_CTRL_BRKST)
143 {
144 if ((target->state == TARGET_RUNNING) || (target->state == TARGET_RESET))
145 {
146 jtag_add_end_state(TAP_RTI);
147 mips_ejtag_set_instr(ejtag_info, EJTAG_INST_NORMALBOOT, NULL);
148
149 target->state = TARGET_HALTED;
150
151 if ((retval = mips_m4k_debug_entry(target)) != ERROR_OK)
152 return retval;
153
154 target_call_event_callbacks(target, TARGET_EVENT_HALTED);
155 }
156 else if (target->state == TARGET_DEBUG_RUNNING)
157 {
158 target->state = TARGET_HALTED;
159
160 if ((retval = mips_m4k_debug_entry(target)) != ERROR_OK)
161 return retval;
162
163 target_call_event_callbacks(target, TARGET_EVENT_DEBUG_HALTED);
164 }
165 }
166 else
167 {
168 target->state = TARGET_RUNNING;
169 }
170
171 if (ejtag_ctrl & EJTAG_CTRL_ROCC)
172 {
173 /* we have detected a reset, clear flag
174 * otherwise ejtag will not work */
175 jtag_add_end_state(TAP_RTI);
176 ejtag_ctrl = ejtag_info->ejtag_ctrl & ~EJTAG_CTRL_ROCC;
177
178 mips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL, NULL);
179 mips_ejtag_drscan_32(ejtag_info, &ejtag_ctrl);
180 LOG_DEBUG("Reset Detected");
181 }
182
183 // LOG_DEBUG("ctrl=0x%08X", ejtag_ctrl);
184
185 return ERROR_OK;
186 }
187
188 int mips_m4k_halt(struct target_s *target)
189 {
190 mips32_common_t *mips32 = target->arch_info;
191 mips_ejtag_t *ejtag_info = &mips32->ejtag_info;
192
193 LOG_DEBUG("target->state: %s",
194 Jim_Nvp_value2name_simple( nvp_target_state, target->state )->name);
195
196 if (target->state == TARGET_HALTED)
197 {
198 LOG_DEBUG("target was already halted");
199 return ERROR_OK;
200 }
201
202 if (target->state == TARGET_UNKNOWN)
203 {
204 LOG_WARNING("target was in unknown state when halt was requested");
205 }
206
207 if (target->state == TARGET_RESET)
208 {
209 if ((jtag_reset_config & RESET_SRST_PULLS_TRST) && jtag_srst)
210 {
211 LOG_ERROR("can't request a halt while in reset if nSRST pulls nTRST");
212 return ERROR_TARGET_FAILURE;
213 }
214 else
215 {
216 /* we came here in a reset_halt or reset_init sequence
217 * debug entry was already prepared in mips32_prepare_reset_halt()
218 */
219 target->debug_reason = DBG_REASON_DBGRQ;
220
221 return ERROR_OK;
222 }
223 }
224
225 /* break processor */
226 mips_ejtag_enter_debug(ejtag_info);
227
228 target->debug_reason = DBG_REASON_DBGRQ;
229
230 return ERROR_OK;
231 }
232
233 int mips_m4k_assert_reset(target_t *target)
234 {
235 mips32_common_t *mips32 = target->arch_info;
236 mips_ejtag_t *ejtag_info = &mips32->ejtag_info;
237 mips_m4k_common_t *mips_m4k = mips32->arch_info;
238
239 LOG_DEBUG("target->state: %s",
240 Jim_Nvp_value2name_simple( nvp_target_state, target->state )->name);
241
242 if (!(jtag_reset_config & RESET_HAS_SRST))
243 {
244 LOG_ERROR("Can't assert SRST");
245 return ERROR_FAIL;
246 }
247
248 if (target->reset_halt)
249 {
250 /* use hardware to catch reset */
251 jtag_add_end_state(TAP_RTI);
252 mips_ejtag_set_instr(ejtag_info, EJTAG_INST_EJTAGBOOT, NULL);
253 }
254 else
255 {
256 jtag_add_end_state(TAP_RTI);
257 mips_ejtag_set_instr(ejtag_info, EJTAG_INST_NORMALBOOT, NULL);
258 }
259
260 if (strcmp(mips_m4k->variant, "ejtag_srst") == 0)
261 {
262 u32 ejtag_ctrl = ejtag_info->ejtag_ctrl | EJTAG_CTRL_PRRST | EJTAG_CTRL_PERRST;
263 LOG_DEBUG("Using EJTAG reset (PRRST) to reset processor...");
264 mips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL, NULL);
265 mips_ejtag_drscan_32(ejtag_info, &ejtag_ctrl);
266 }
267 else
268 {
269 /* here we should issue a srst only, but we may have to assert trst as well */
270 if (jtag_reset_config & RESET_SRST_PULLS_TRST)
271 {
272 jtag_add_reset(1, 1);
273 }
274 else
275 {
276 jtag_add_reset(0, 1);
277 }
278 }
279
280 target->state = TARGET_RESET;
281 jtag_add_sleep(50000);
282
283 mips32_invalidate_core_regs(target);
284
285 if (target->reset_halt)
286 {
287 int retval;
288 if ((retval = target_halt(target))!=ERROR_OK)
289 return retval;
290 }
291
292
293 return ERROR_OK;
294 }
295
296 int mips_m4k_deassert_reset(target_t *target)
297 {
298 LOG_DEBUG("target->state: %s",
299 Jim_Nvp_value2name_simple( nvp_target_state, target->state )->name);
300
301 /* deassert reset lines */
302 jtag_add_reset(0, 0);
303
304 return ERROR_OK;
305 }
306
307 int mips_m4k_soft_reset_halt(struct target_s *target)
308 {
309 /* TODO */
310 return ERROR_OK;
311 }
312
313 int mips_m4k_resume(struct target_s *target, int current, u32 address, int handle_breakpoints, int debug_execution)
314 {
315 mips32_common_t *mips32 = target->arch_info;
316 mips_ejtag_t *ejtag_info = &mips32->ejtag_info;
317 breakpoint_t *breakpoint = NULL;
318 u32 resume_pc;
319
320 if (target->state != TARGET_HALTED)
321 {
322 LOG_WARNING("target not halted");
323 return ERROR_TARGET_NOT_HALTED;
324 }
325
326 if (!debug_execution)
327 {
328 target_free_all_working_areas(target);
329 mips_m4k_enable_breakpoints(target);
330 mips_m4k_enable_watchpoints(target);
331 }
332
333 /* current = 1: continue on current pc, otherwise continue at <address> */
334 if (!current)
335 {
336 buf_set_u32(mips32->core_cache->reg_list[MIPS32_PC].value, 0, 32, address);
337 mips32->core_cache->reg_list[MIPS32_PC].dirty = 1;
338 mips32->core_cache->reg_list[MIPS32_PC].valid = 1;
339 }
340
341 resume_pc = buf_get_u32(mips32->core_cache->reg_list[MIPS32_PC].value, 0, 32);
342
343 mips32_restore_context(target);
344
345 /* the front-end may request us not to handle breakpoints */
346 if (handle_breakpoints)
347 {
348 /* Single step past breakpoint at current address */
349 if ((breakpoint = breakpoint_find(target, resume_pc)))
350 {
351 LOG_DEBUG("unset breakpoint at 0x%8.8x", breakpoint->address);
352 mips_m4k_unset_breakpoint(target, breakpoint);
353 //mips_m4k_single_step_core(target);
354 mips_m4k_set_breakpoint(target, breakpoint);
355 }
356 }
357
358 /* exit debug mode - enable interrupts if required */
359 mips_ejtag_exit_debug(ejtag_info, !debug_execution);
360
361 /* registers are now invalid */
362 mips32_invalidate_core_regs(target);
363
364 if (!debug_execution)
365 {
366 target->state = TARGET_RUNNING;
367 target_call_event_callbacks(target, TARGET_EVENT_RESUMED);
368 LOG_DEBUG("target resumed at 0x%x", resume_pc);
369 }
370 else
371 {
372 target->state = TARGET_DEBUG_RUNNING;
373 target_call_event_callbacks(target, TARGET_EVENT_DEBUG_RESUMED);
374 LOG_DEBUG("target debug resumed at 0x%x", resume_pc);
375 }
376
377 return ERROR_OK;
378 }
379
380 int mips_m4k_step(struct target_s *target, int current, u32 address, int handle_breakpoints)
381 {
382 /* get pointers to arch-specific information */
383 mips32_common_t *mips32 = target->arch_info;
384 mips_ejtag_t *ejtag_info = &mips32->ejtag_info;
385 breakpoint_t *breakpoint = NULL;
386
387 if (target->state != TARGET_HALTED)
388 {
389 LOG_WARNING("target not halted");
390 return ERROR_TARGET_NOT_HALTED;
391 }
392
393 /* current = 1: continue on current pc, otherwise continue at <address> */
394 if (!current)
395 buf_set_u32(mips32->core_cache->reg_list[MIPS32_PC].value, 0, 32, address);
396
397 /* the front-end may request us not to handle breakpoints */
398 if (handle_breakpoints)
399 if ((breakpoint = breakpoint_find(target, buf_get_u32(mips32->core_cache->reg_list[MIPS32_PC].value, 0, 32))))
400 mips_m4k_unset_breakpoint(target, breakpoint);
401
402 /* restore context */
403 mips32_restore_context(target);
404
405 /* configure single step mode */
406 mips_ejtag_config_step(ejtag_info, 1);
407
408 target->debug_reason = DBG_REASON_SINGLESTEP;
409
410 target_call_event_callbacks(target, TARGET_EVENT_RESUMED);
411
412 /* exit debug mode */
413 mips_ejtag_exit_debug(ejtag_info, 1);
414
415 /* registers are now invalid */
416 mips32_invalidate_core_regs(target);
417
418 if (breakpoint)
419 mips_m4k_set_breakpoint(target, breakpoint);
420
421 LOG_DEBUG("target stepped ");
422
423 mips_m4k_debug_entry(target);
424 target_call_event_callbacks(target, TARGET_EVENT_HALTED);
425
426 return ERROR_OK;
427 }
428
429 void mips_m4k_enable_breakpoints(struct target_s *target)
430 {
431 breakpoint_t *breakpoint = target->breakpoints;
432
433 /* set any pending breakpoints */
434 while (breakpoint)
435 {
436 if (breakpoint->set == 0)
437 mips_m4k_set_breakpoint(target, breakpoint);
438 breakpoint = breakpoint->next;
439 }
440 }
441
442 int mips_m4k_set_breakpoint(struct target_s *target, breakpoint_t *breakpoint)
443 {
444 /* TODO */
445 return ERROR_OK;
446 }
447
448 int mips_m4k_unset_breakpoint(struct target_s *target, breakpoint_t *breakpoint)
449 {
450 /* TODO */
451 return ERROR_OK;
452 }
453
454 int mips_m4k_add_breakpoint(struct target_s *target, breakpoint_t *breakpoint)
455 {
456 /* TODO */
457 return ERROR_OK;
458 }
459
460 int mips_m4k_remove_breakpoint(struct target_s *target, breakpoint_t *breakpoint)
461 {
462 /* TODO */
463 return ERROR_OK;
464 }
465
466 int mips_m4k_set_watchpoint(struct target_s *target, watchpoint_t *watchpoint)
467 {
468 /* TODO */
469 return ERROR_OK;
470 }
471
472 int mips_m4k_unset_watchpoint(struct target_s *target, watchpoint_t *watchpoint)
473 {
474 /* TODO */
475 return ERROR_OK;
476 }
477
478 int mips_m4k_add_watchpoint(struct target_s *target, watchpoint_t *watchpoint)
479 {
480 /* TODO */
481 return ERROR_OK;
482 }
483
484 int mips_m4k_remove_watchpoint(struct target_s *target, watchpoint_t *watchpoint)
485 {
486 /* TODO */
487 return ERROR_OK;
488 }
489
490 void mips_m4k_enable_watchpoints(struct target_s *target)
491 {
492 watchpoint_t *watchpoint = target->watchpoints;
493
494 /* set any pending watchpoints */
495 while (watchpoint)
496 {
497 if (watchpoint->set == 0)
498 mips_m4k_set_watchpoint(target, watchpoint);
499 watchpoint = watchpoint->next;
500 }
501 }
502
503 int mips_m4k_read_memory(struct target_s *target, u32 address, u32 size, u32 count, u8 *buffer)
504 {
505 mips32_common_t *mips32 = target->arch_info;
506 mips_ejtag_t *ejtag_info = &mips32->ejtag_info;
507
508 LOG_DEBUG("address: 0x%8.8x, size: 0x%8.8x, count: 0x%8.8x", address, size, count);
509
510 if (target->state != TARGET_HALTED)
511 {
512 LOG_WARNING("target not halted");
513 return ERROR_TARGET_NOT_HALTED;
514 }
515
516 /* sanitize arguments */
517 if (((size != 4) && (size != 2) && (size != 1)) || (count == 0) || !(buffer))
518 return ERROR_INVALID_ARGUMENTS;
519
520 if (((size == 4) && (address & 0x3u)) || ((size == 2) && (address & 0x1u)))
521 return ERROR_TARGET_UNALIGNED_ACCESS;
522
523 switch (size)
524 {
525 case 4:
526 case 2:
527 case 1:
528 /* if noDMA off, use DMAACC mode for memory read */
529 if(ejtag_info->impcode & EJTAG_IMP_NODMA)
530 return mips32_pracc_read_mem(ejtag_info, address, size, count, (void *)buffer);
531 else
532 return mips32_dmaacc_read_mem(ejtag_info, address, size, count, (void *)buffer);
533 default:
534 LOG_ERROR("BUG: we shouldn't get here");
535 exit(-1);
536 break;
537 }
538
539 return ERROR_OK;
540 }
541
542 int mips_m4k_write_memory(struct target_s *target, u32 address, u32 size, u32 count, u8 *buffer)
543 {
544 mips32_common_t *mips32 = target->arch_info;
545 mips_ejtag_t *ejtag_info = &mips32->ejtag_info;
546
547 LOG_DEBUG("address: 0x%8.8x, size: 0x%8.8x, count: 0x%8.8x", address, size, count);
548
549 if (target->state != TARGET_HALTED)
550 {
551 LOG_WARNING("target not halted");
552 return ERROR_TARGET_NOT_HALTED;
553 }
554
555 /* sanitize arguments */
556 if (((size != 4) && (size != 2) && (size != 1)) || (count == 0) || !(buffer))
557 return ERROR_INVALID_ARGUMENTS;
558
559 if (((size == 4) && (address & 0x3u)) || ((size == 2) && (address & 0x1u)))
560 return ERROR_TARGET_UNALIGNED_ACCESS;
561
562 switch (size)
563 {
564 case 4:
565 case 2:
566 case 1:
567 /* if noDMA off, use DMAACC mode for memory write */
568 if(ejtag_info->impcode & EJTAG_IMP_NODMA)
569 mips32_pracc_write_mem(ejtag_info, address, size, count, (void *)buffer);
570 else
571 mips32_dmaacc_write_mem(ejtag_info, address, size, count, (void *)buffer);
572 break;
573 default:
574 LOG_ERROR("BUG: we shouldn't get here");
575 exit(-1);
576 break;
577 }
578
579 return ERROR_OK;
580 }
581
582 int mips_m4k_register_commands(struct command_context_s *cmd_ctx)
583 {
584 int retval;
585
586 retval = mips32_register_commands(cmd_ctx);
587 return retval;
588 }
589
590 int mips_m4k_init_target(struct command_context_s *cmd_ctx, struct target_s *target)
591 {
592 mips32_build_reg_cache(target);
593
594 return ERROR_OK;
595 }
596
597 int mips_m4k_quit(void)
598 {
599 return ERROR_OK;
600 }
601
602 int mips_m4k_init_arch_info(target_t *target, mips_m4k_common_t *mips_m4k, int chain_pos, const char *variant)
603 {
604 mips32_common_t *mips32 = &mips_m4k->mips32_common;
605
606 if (variant)
607 {
608 mips_m4k->variant = strdup(variant);
609 }
610 else
611 {
612 mips_m4k->variant = strdup("");
613 }
614
615 mips_m4k->common_magic = MIPSM4K_COMMON_MAGIC;
616
617 /* initialize mips4k specific info */
618 mips32_init_arch_info(target, mips32, chain_pos, variant);
619 mips32->arch_info = mips_m4k;
620
621 return ERROR_OK;
622 }
623
624 int mips_m4k_target_create(struct target_s *target, Jim_Interp *interp)
625 {
626 mips_m4k_common_t *mips_m4k = calloc(1,sizeof(mips_m4k_common_t));
627
628 mips_m4k_init_arch_info(target, mips_m4k, target->chain_position, target->variant);
629
630 return ERROR_OK;
631 }
632
633 int mips_m4k_examine(struct target_s *target)
634 {
635 int retval;
636 mips32_common_t *mips32 = target->arch_info;
637 mips_ejtag_t *ejtag_info = &mips32->ejtag_info;
638 u32 idcode = 0;
639
640 target->type->examined = 1;
641
642 mips_ejtag_get_idcode(ejtag_info, &idcode, NULL);
643
644 if (((idcode >> 1) & 0x7FF) == 0x29)
645 {
646 /* we are using a pic32mx so select ejtag port
647 * as it is not selected by default */
648 mips_ejtag_set_instr(ejtag_info, 0x05, NULL);
649 LOG_DEBUG("PIC32MX Detected - using EJTAG Interface");
650 }
651
652 /* init rest of ejtag interface */
653 if ((retval = mips_ejtag_init(ejtag_info)) != ERROR_OK)
654 return retval;
655
656 return ERROR_OK;
657 }
658
659 int mips_m4k_bulk_write_memory(target_t *target, u32 address, u32 count, u8 *buffer)
660 {
661 return mips_m4k_write_memory(target, address, 4, count, buffer);
662 }

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)