- correct the register hi/lo read - wrong way round
[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 /* clear this bit before handling polling
143 * as after reset registers will read zero */
144 if (ejtag_ctrl & EJTAG_CTRL_ROCC)
145 {
146 /* we have detected a reset, clear flag
147 * otherwise ejtag will not work */
148 jtag_add_end_state(TAP_RTI);
149 ejtag_ctrl = ejtag_info->ejtag_ctrl & ~EJTAG_CTRL_ROCC;
150
151 mips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL, NULL);
152 mips_ejtag_drscan_32(ejtag_info, &ejtag_ctrl);
153 LOG_DEBUG("Reset Detected");
154 }
155
156 /* check for processor halted */
157 if (ejtag_ctrl & EJTAG_CTRL_BRKST)
158 {
159 if ((target->state == TARGET_RUNNING) || (target->state == TARGET_RESET))
160 {
161 jtag_add_end_state(TAP_RTI);
162 mips_ejtag_set_instr(ejtag_info, EJTAG_INST_NORMALBOOT, NULL);
163
164 target->state = TARGET_HALTED;
165
166 if ((retval = mips_m4k_debug_entry(target)) != ERROR_OK)
167 return retval;
168
169 target_call_event_callbacks(target, TARGET_EVENT_HALTED);
170 }
171 else if (target->state == TARGET_DEBUG_RUNNING)
172 {
173 target->state = TARGET_HALTED;
174
175 if ((retval = mips_m4k_debug_entry(target)) != ERROR_OK)
176 return retval;
177
178 target_call_event_callbacks(target, TARGET_EVENT_DEBUG_HALTED);
179 }
180 }
181 else
182 {
183 target->state = TARGET_RUNNING;
184 }
185
186 // LOG_DEBUG("ctrl=0x%08X", ejtag_ctrl);
187
188 return ERROR_OK;
189 }
190
191 int mips_m4k_halt(struct target_s *target)
192 {
193 mips32_common_t *mips32 = target->arch_info;
194 mips_ejtag_t *ejtag_info = &mips32->ejtag_info;
195
196 LOG_DEBUG("target->state: %s",
197 Jim_Nvp_value2name_simple( nvp_target_state, target->state )->name);
198
199 if (target->state == TARGET_HALTED)
200 {
201 LOG_DEBUG("target was already halted");
202 return ERROR_OK;
203 }
204
205 if (target->state == TARGET_UNKNOWN)
206 {
207 LOG_WARNING("target was in unknown state when halt was requested");
208 }
209
210 if (target->state == TARGET_RESET)
211 {
212 if ((jtag_reset_config & RESET_SRST_PULLS_TRST) && jtag_srst)
213 {
214 LOG_ERROR("can't request a halt while in reset if nSRST pulls nTRST");
215 return ERROR_TARGET_FAILURE;
216 }
217 else
218 {
219 /* we came here in a reset_halt or reset_init sequence
220 * debug entry was already prepared in mips32_prepare_reset_halt()
221 */
222 target->debug_reason = DBG_REASON_DBGRQ;
223
224 return ERROR_OK;
225 }
226 }
227
228 /* break processor */
229 mips_ejtag_enter_debug(ejtag_info);
230
231 target->debug_reason = DBG_REASON_DBGRQ;
232
233 return ERROR_OK;
234 }
235
236 int mips_m4k_assert_reset(target_t *target)
237 {
238 mips32_common_t *mips32 = target->arch_info;
239 mips_ejtag_t *ejtag_info = &mips32->ejtag_info;
240 mips_m4k_common_t *mips_m4k = mips32->arch_info;
241
242 LOG_DEBUG("target->state: %s",
243 Jim_Nvp_value2name_simple( nvp_target_state, target->state )->name);
244
245 if (!(jtag_reset_config & RESET_HAS_SRST))
246 {
247 LOG_ERROR("Can't assert SRST");
248 return ERROR_FAIL;
249 }
250
251 if (target->reset_halt)
252 {
253 /* use hardware to catch reset */
254 jtag_add_end_state(TAP_RTI);
255 mips_ejtag_set_instr(ejtag_info, EJTAG_INST_EJTAGBOOT, NULL);
256 }
257 else
258 {
259 jtag_add_end_state(TAP_RTI);
260 mips_ejtag_set_instr(ejtag_info, EJTAG_INST_NORMALBOOT, NULL);
261 }
262
263 if (strcmp(mips_m4k->variant, "ejtag_srst") == 0)
264 {
265 u32 ejtag_ctrl = ejtag_info->ejtag_ctrl | EJTAG_CTRL_PRRST | EJTAG_CTRL_PERRST;
266 LOG_DEBUG("Using EJTAG reset (PRRST) to reset processor...");
267 mips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL, NULL);
268 mips_ejtag_drscan_32(ejtag_info, &ejtag_ctrl);
269 }
270 else
271 {
272 /* here we should issue a srst only, but we may have to assert trst as well */
273 if (jtag_reset_config & RESET_SRST_PULLS_TRST)
274 {
275 jtag_add_reset(1, 1);
276 }
277 else
278 {
279 jtag_add_reset(0, 1);
280 }
281 }
282
283 target->state = TARGET_RESET;
284 jtag_add_sleep(50000);
285
286 mips32_invalidate_core_regs(target);
287
288 if (target->reset_halt)
289 {
290 int retval;
291 if ((retval = target_halt(target))!=ERROR_OK)
292 return retval;
293 }
294
295 return ERROR_OK;
296 }
297
298 int mips_m4k_deassert_reset(target_t *target)
299 {
300 LOG_DEBUG("target->state: %s",
301 Jim_Nvp_value2name_simple( nvp_target_state, target->state )->name);
302
303 /* deassert reset lines */
304 jtag_add_reset(0, 0);
305
306 return ERROR_OK;
307 }
308
309 int mips_m4k_soft_reset_halt(struct target_s *target)
310 {
311 /* TODO */
312 return ERROR_OK;
313 }
314
315 int mips_m4k_resume(struct target_s *target, int current, u32 address, int handle_breakpoints, int debug_execution)
316 {
317 mips32_common_t *mips32 = target->arch_info;
318 mips_ejtag_t *ejtag_info = &mips32->ejtag_info;
319 breakpoint_t *breakpoint = NULL;
320 u32 resume_pc;
321
322 if (target->state != TARGET_HALTED)
323 {
324 LOG_WARNING("target not halted");
325 return ERROR_TARGET_NOT_HALTED;
326 }
327
328 if (!debug_execution)
329 {
330 target_free_all_working_areas(target);
331 mips_m4k_enable_breakpoints(target);
332 mips_m4k_enable_watchpoints(target);
333 }
334
335 /* current = 1: continue on current pc, otherwise continue at <address> */
336 if (!current)
337 {
338 buf_set_u32(mips32->core_cache->reg_list[MIPS32_PC].value, 0, 32, address);
339 mips32->core_cache->reg_list[MIPS32_PC].dirty = 1;
340 mips32->core_cache->reg_list[MIPS32_PC].valid = 1;
341 }
342
343 resume_pc = buf_get_u32(mips32->core_cache->reg_list[MIPS32_PC].value, 0, 32);
344
345 mips32_restore_context(target);
346
347 /* the front-end may request us not to handle breakpoints */
348 if (handle_breakpoints)
349 {
350 /* Single step past breakpoint at current address */
351 if ((breakpoint = breakpoint_find(target, resume_pc)))
352 {
353 LOG_DEBUG("unset breakpoint at 0x%8.8x", breakpoint->address);
354 mips_m4k_unset_breakpoint(target, breakpoint);
355 //mips_m4k_single_step_core(target);
356 mips_m4k_set_breakpoint(target, breakpoint);
357 }
358 }
359
360 /* exit debug mode - enable interrupts if required */
361 mips_ejtag_exit_debug(ejtag_info, !debug_execution);
362
363 /* registers are now invalid */
364 mips32_invalidate_core_regs(target);
365
366 if (!debug_execution)
367 {
368 target->state = TARGET_RUNNING;
369 target_call_event_callbacks(target, TARGET_EVENT_RESUMED);
370 LOG_DEBUG("target resumed at 0x%x", resume_pc);
371 }
372 else
373 {
374 target->state = TARGET_DEBUG_RUNNING;
375 target_call_event_callbacks(target, TARGET_EVENT_DEBUG_RESUMED);
376 LOG_DEBUG("target debug resumed at 0x%x", resume_pc);
377 }
378
379 return ERROR_OK;
380 }
381
382 int mips_m4k_step(struct target_s *target, int current, u32 address, int handle_breakpoints)
383 {
384 /* get pointers to arch-specific information */
385 mips32_common_t *mips32 = target->arch_info;
386 mips_ejtag_t *ejtag_info = &mips32->ejtag_info;
387 breakpoint_t *breakpoint = NULL;
388
389 if (target->state != TARGET_HALTED)
390 {
391 LOG_WARNING("target not halted");
392 return ERROR_TARGET_NOT_HALTED;
393 }
394
395 /* current = 1: continue on current pc, otherwise continue at <address> */
396 if (!current)
397 buf_set_u32(mips32->core_cache->reg_list[MIPS32_PC].value, 0, 32, address);
398
399 /* the front-end may request us not to handle breakpoints */
400 if (handle_breakpoints)
401 if ((breakpoint = breakpoint_find(target, buf_get_u32(mips32->core_cache->reg_list[MIPS32_PC].value, 0, 32))))
402 mips_m4k_unset_breakpoint(target, breakpoint);
403
404 /* restore context */
405 mips32_restore_context(target);
406
407 /* configure single step mode */
408 mips_ejtag_config_step(ejtag_info, 1);
409
410 target->debug_reason = DBG_REASON_SINGLESTEP;
411
412 target_call_event_callbacks(target, TARGET_EVENT_RESUMED);
413
414 /* exit debug mode */
415 mips_ejtag_exit_debug(ejtag_info, 1);
416
417 /* registers are now invalid */
418 mips32_invalidate_core_regs(target);
419
420 if (breakpoint)
421 mips_m4k_set_breakpoint(target, breakpoint);
422
423 LOG_DEBUG("target stepped ");
424
425 mips_m4k_debug_entry(target);
426 target_call_event_callbacks(target, TARGET_EVENT_HALTED);
427
428 return ERROR_OK;
429 }
430
431 void mips_m4k_enable_breakpoints(struct target_s *target)
432 {
433 breakpoint_t *breakpoint = target->breakpoints;
434
435 /* set any pending breakpoints */
436 while (breakpoint)
437 {
438 if (breakpoint->set == 0)
439 mips_m4k_set_breakpoint(target, breakpoint);
440 breakpoint = breakpoint->next;
441 }
442 }
443
444 int mips_m4k_set_breakpoint(struct target_s *target, breakpoint_t *breakpoint)
445 {
446 /* TODO */
447 return ERROR_OK;
448 }
449
450 int mips_m4k_unset_breakpoint(struct target_s *target, breakpoint_t *breakpoint)
451 {
452 /* TODO */
453 return ERROR_OK;
454 }
455
456 int mips_m4k_add_breakpoint(struct target_s *target, breakpoint_t *breakpoint)
457 {
458 /* TODO */
459 return ERROR_OK;
460 }
461
462 int mips_m4k_remove_breakpoint(struct target_s *target, breakpoint_t *breakpoint)
463 {
464 /* TODO */
465 return ERROR_OK;
466 }
467
468 int mips_m4k_set_watchpoint(struct target_s *target, watchpoint_t *watchpoint)
469 {
470 /* TODO */
471 return ERROR_OK;
472 }
473
474 int mips_m4k_unset_watchpoint(struct target_s *target, watchpoint_t *watchpoint)
475 {
476 /* TODO */
477 return ERROR_OK;
478 }
479
480 int mips_m4k_add_watchpoint(struct target_s *target, watchpoint_t *watchpoint)
481 {
482 /* TODO */
483 return ERROR_OK;
484 }
485
486 int mips_m4k_remove_watchpoint(struct target_s *target, watchpoint_t *watchpoint)
487 {
488 /* TODO */
489 return ERROR_OK;
490 }
491
492 void mips_m4k_enable_watchpoints(struct target_s *target)
493 {
494 watchpoint_t *watchpoint = target->watchpoints;
495
496 /* set any pending watchpoints */
497 while (watchpoint)
498 {
499 if (watchpoint->set == 0)
500 mips_m4k_set_watchpoint(target, watchpoint);
501 watchpoint = watchpoint->next;
502 }
503 }
504
505 int mips_m4k_read_memory(struct target_s *target, u32 address, u32 size, u32 count, u8 *buffer)
506 {
507 mips32_common_t *mips32 = target->arch_info;
508 mips_ejtag_t *ejtag_info = &mips32->ejtag_info;
509
510 LOG_DEBUG("address: 0x%8.8x, size: 0x%8.8x, count: 0x%8.8x", address, size, count);
511
512 if (target->state != TARGET_HALTED)
513 {
514 LOG_WARNING("target not halted");
515 return ERROR_TARGET_NOT_HALTED;
516 }
517
518 /* sanitize arguments */
519 if (((size != 4) && (size != 2) && (size != 1)) || (count == 0) || !(buffer))
520 return ERROR_INVALID_ARGUMENTS;
521
522 if (((size == 4) && (address & 0x3u)) || ((size == 2) && (address & 0x1u)))
523 return ERROR_TARGET_UNALIGNED_ACCESS;
524
525 switch (size)
526 {
527 case 4:
528 case 2:
529 case 1:
530 /* if noDMA off, use DMAACC mode for memory read */
531 if(ejtag_info->impcode & EJTAG_IMP_NODMA)
532 return mips32_pracc_read_mem(ejtag_info, address, size, count, (void *)buffer);
533 else
534 return mips32_dmaacc_read_mem(ejtag_info, address, size, count, (void *)buffer);
535 default:
536 LOG_ERROR("BUG: we shouldn't get here");
537 exit(-1);
538 break;
539 }
540
541 return ERROR_OK;
542 }
543
544 int mips_m4k_write_memory(struct target_s *target, u32 address, u32 size, u32 count, u8 *buffer)
545 {
546 mips32_common_t *mips32 = target->arch_info;
547 mips_ejtag_t *ejtag_info = &mips32->ejtag_info;
548
549 LOG_DEBUG("address: 0x%8.8x, size: 0x%8.8x, count: 0x%8.8x", address, size, count);
550
551 if (target->state != TARGET_HALTED)
552 {
553 LOG_WARNING("target not halted");
554 return ERROR_TARGET_NOT_HALTED;
555 }
556
557 /* sanitize arguments */
558 if (((size != 4) && (size != 2) && (size != 1)) || (count == 0) || !(buffer))
559 return ERROR_INVALID_ARGUMENTS;
560
561 if (((size == 4) && (address & 0x3u)) || ((size == 2) && (address & 0x1u)))
562 return ERROR_TARGET_UNALIGNED_ACCESS;
563
564 switch (size)
565 {
566 case 4:
567 case 2:
568 case 1:
569 /* if noDMA off, use DMAACC mode for memory write */
570 if(ejtag_info->impcode & EJTAG_IMP_NODMA)
571 mips32_pracc_write_mem(ejtag_info, address, size, count, (void *)buffer);
572 else
573 mips32_dmaacc_write_mem(ejtag_info, address, size, count, (void *)buffer);
574 break;
575 default:
576 LOG_ERROR("BUG: we shouldn't get here");
577 exit(-1);
578 break;
579 }
580
581 return ERROR_OK;
582 }
583
584 int mips_m4k_register_commands(struct command_context_s *cmd_ctx)
585 {
586 int retval;
587
588 retval = mips32_register_commands(cmd_ctx);
589 return retval;
590 }
591
592 int mips_m4k_init_target(struct command_context_s *cmd_ctx, struct target_s *target)
593 {
594 mips32_build_reg_cache(target);
595
596 return ERROR_OK;
597 }
598
599 int mips_m4k_quit(void)
600 {
601 return ERROR_OK;
602 }
603
604 int mips_m4k_init_arch_info(target_t *target, mips_m4k_common_t *mips_m4k, int chain_pos, const char *variant)
605 {
606 mips32_common_t *mips32 = &mips_m4k->mips32_common;
607
608 if (variant)
609 {
610 mips_m4k->variant = strdup(variant);
611 }
612 else
613 {
614 mips_m4k->variant = strdup("");
615 }
616
617 mips_m4k->common_magic = MIPSM4K_COMMON_MAGIC;
618
619 /* initialize mips4k specific info */
620 mips32_init_arch_info(target, mips32, chain_pos, variant);
621 mips32->arch_info = mips_m4k;
622
623 return ERROR_OK;
624 }
625
626 int mips_m4k_target_create(struct target_s *target, Jim_Interp *interp)
627 {
628 mips_m4k_common_t *mips_m4k = calloc(1,sizeof(mips_m4k_common_t));
629
630 mips_m4k_init_arch_info(target, mips_m4k, target->chain_position, target->variant);
631
632 return ERROR_OK;
633 }
634
635 int mips_m4k_examine(struct target_s *target)
636 {
637 int retval;
638 mips32_common_t *mips32 = target->arch_info;
639 mips_ejtag_t *ejtag_info = &mips32->ejtag_info;
640 u32 idcode = 0;
641
642 target->type->examined = 1;
643
644 mips_ejtag_get_idcode(ejtag_info, &idcode, NULL);
645
646 if (((idcode >> 1) & 0x7FF) == 0x29)
647 {
648 /* we are using a pic32mx so select ejtag port
649 * as it is not selected by default */
650 mips_ejtag_set_instr(ejtag_info, 0x05, NULL);
651 LOG_DEBUG("PIC32MX Detected - using EJTAG Interface");
652 }
653
654 /* init rest of ejtag interface */
655 if ((retval = mips_ejtag_init(ejtag_info)) != ERROR_OK)
656 return retval;
657
658 return ERROR_OK;
659 }
660
661 int mips_m4k_bulk_write_memory(target_t *target, u32 address, u32 count, u8 *buffer)
662 {
663 return mips_m4k_write_memory(target, address, 4, count, buffer);
664 }

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)