1 /***************************************************************************
2 * Copyright (C) 2005 by Dominic Rath *
3 * Dominic.Rath@gmx.de *
5 * Copyright (C) 2009 by Øyvind Harboe *
6 * oyvind.harboe@zylin.com *
8 * This program is free software; you can redistribute it and/or modify *
9 * it under the terms of the GNU General Public License as published by *
10 * the Free Software Foundation; either version 2 of the License, or *
11 * (at your option) any later version. *
13 * This program is distributed in the hope that it will be useful, *
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
16 * GNU General Public License for more details. *
18 * You should have received a copy of the GNU General Public License *
19 * along with this program; if not, write to the *
20 * Free Software Foundation, Inc., *
21 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
22 ***************************************************************************/
28 #include "time_support.h"
29 #include "target_type.h"
33 #define _DEBUG_INSTRUCTION_EXECUTION_
37 int arm720t_register_commands(struct command_context_s
*cmd_ctx
);
39 int arm720t_handle_cp15_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
41 /* forward declarations */
42 int arm720t_target_create(struct target_s
*target
,Jim_Interp
*interp
);
43 int arm720t_init_target(struct command_context_s
*cmd_ctx
, struct target_s
*target
);
44 int arm720t_arch_state(struct target_s
*target
);
45 int arm720t_read_memory(struct target_s
*target
, uint32_t address
, uint32_t size
, uint32_t count
, uint8_t *buffer
);
46 int arm720t_write_memory(struct target_s
*target
, uint32_t address
, uint32_t size
, uint32_t count
, uint8_t *buffer
);
47 int arm720t_read_phys_memory(struct target_s
*target
, uint32_t address
, uint32_t size
, uint32_t count
, uint8_t *buffer
);
48 int arm720t_write_phys_memory(struct target_s
*target
, uint32_t address
, uint32_t size
, uint32_t count
, uint8_t *buffer
);
49 int arm720t_soft_reset_halt(struct target_s
*target
);
51 static int arm720t_mrc(target_t
*target
, int cpnum
, uint32_t op1
, uint32_t op2
, uint32_t CRn
, uint32_t CRm
, uint32_t *value
);
52 static int arm720t_mcr(target_t
*target
, int cpnum
, uint32_t op1
, uint32_t op2
, uint32_t CRn
, uint32_t CRm
, uint32_t value
);
54 target_type_t arm720t_target
=
59 .arch_state
= arm720t_arch_state
,
62 .resume
= arm7_9_resume
,
65 .assert_reset
= arm7_9_assert_reset
,
66 .deassert_reset
= arm7_9_deassert_reset
,
67 .soft_reset_halt
= arm720t_soft_reset_halt
,
69 .get_gdb_reg_list
= armv4_5_get_gdb_reg_list
,
71 .read_memory
= arm720t_read_memory
,
72 .write_memory
= arm720t_write_memory
,
73 .read_phys_memory
= arm720t_read_phys_memory
,
74 .write_phys_memory
= arm720t_write_phys_memory
,
75 .bulk_write_memory
= arm7_9_bulk_write_memory
,
76 .checksum_memory
= arm7_9_checksum_memory
,
77 .blank_check_memory
= arm7_9_blank_check_memory
,
79 .run_algorithm
= armv4_5_run_algorithm
,
81 .add_breakpoint
= arm7_9_add_breakpoint
,
82 .remove_breakpoint
= arm7_9_remove_breakpoint
,
83 .add_watchpoint
= arm7_9_add_watchpoint
,
84 .remove_watchpoint
= arm7_9_remove_watchpoint
,
86 .register_commands
= arm720t_register_commands
,
87 .target_create
= arm720t_target_create
,
88 .init_target
= arm720t_init_target
,
89 .examine
= arm7tdmi_examine
,
95 int arm720t_scan_cp15(target_t
*target
, uint32_t out
, uint32_t *in
, int instruction
, int clock
)
97 int retval
= ERROR_OK
;
98 armv4_5_common_t
*armv4_5
= target
->arch_info
;
99 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
100 arm_jtag_t
*jtag_info
= &arm7_9
->jtag_info
;
101 scan_field_t fields
[2];
103 uint8_t instruction_buf
= instruction
;
105 buf_set_u32(out_buf
, 0, 32, flip_u32(out
, 32));
107 jtag_set_end_state(TAP_DRPAUSE
);
108 if ((retval
= arm_jtag_scann(jtag_info
, 0xf)) != ERROR_OK
)
112 if ((retval
= arm_jtag_set_instr(jtag_info
, jtag_info
->intest_instr
, NULL
)) != ERROR_OK
)
117 fields
[0].tap
= jtag_info
->tap
;
118 fields
[0].num_bits
= 1;
119 fields
[0].out_value
= &instruction_buf
;
120 fields
[0].in_value
= NULL
;
122 fields
[1].tap
= jtag_info
->tap
;
123 fields
[1].num_bits
= 32;
124 fields
[1].out_value
= out_buf
;
125 fields
[1].in_value
= NULL
;
129 fields
[1].in_value
= (uint8_t *)in
;
130 jtag_add_dr_scan(2, fields
, jtag_get_end_state());
131 jtag_add_callback(arm7flip32
, (jtag_callback_data_t
)in
);
134 jtag_add_dr_scan(2, fields
, jtag_get_end_state());
138 jtag_add_runtest(0, jtag_get_end_state());
140 #ifdef _DEBUG_INSTRUCTION_EXECUTION_
141 if ((retval
= jtag_execute_queue()) != ERROR_OK
)
147 LOG_DEBUG("out: %8.8x, in: %8.8x, instruction: %i, clock: %i", out
, *in
, instruction
, clock
);
149 LOG_DEBUG("out: %8.8x, instruction: %i, clock: %i", out
, instruction
, clock
);
151 LOG_DEBUG("out: %8.8" PRIx32
", instruction: %i, clock: %i", out
, instruction
, clock
);
157 int arm720t_read_cp15(target_t
*target
, uint32_t opcode
, uint32_t *value
)
159 /* fetch CP15 opcode */
160 arm720t_scan_cp15(target
, opcode
, NULL
, 1, 1);
162 arm720t_scan_cp15(target
, ARMV4_5_NOP
, NULL
, 1, 1);
163 /* "EXECUTE" stage (1) */
164 arm720t_scan_cp15(target
, ARMV4_5_NOP
, NULL
, 1, 0);
165 arm720t_scan_cp15(target
, 0x0, NULL
, 0, 1);
166 /* "EXECUTE" stage (2) */
167 arm720t_scan_cp15(target
, 0x0, NULL
, 0, 1);
168 /* "EXECUTE" stage (3), CDATA is read */
169 arm720t_scan_cp15(target
, ARMV4_5_NOP
, value
, 1, 1);
174 int arm720t_write_cp15(target_t
*target
, uint32_t opcode
, uint32_t value
)
176 /* fetch CP15 opcode */
177 arm720t_scan_cp15(target
, opcode
, NULL
, 1, 1);
179 arm720t_scan_cp15(target
, ARMV4_5_NOP
, NULL
, 1, 1);
180 /* "EXECUTE" stage (1) */
181 arm720t_scan_cp15(target
, ARMV4_5_NOP
, NULL
, 1, 0);
182 arm720t_scan_cp15(target
, 0x0, NULL
, 0, 1);
183 /* "EXECUTE" stage (2) */
184 arm720t_scan_cp15(target
, value
, NULL
, 0, 1);
185 arm720t_scan_cp15(target
, ARMV4_5_NOP
, NULL
, 1, 1);
190 uint32_t arm720t_get_ttb(target_t
*target
)
194 arm720t_read_cp15(target
, 0xee120f10, &ttb
);
195 jtag_execute_queue();
202 void arm720t_disable_mmu_caches(target_t
*target
, int mmu
, int d_u_cache
, int i_cache
)
204 uint32_t cp15_control
;
206 /* read cp15 control register */
207 arm720t_read_cp15(target
, 0xee110f10, &cp15_control
);
208 jtag_execute_queue();
211 cp15_control
&= ~0x1U
;
213 if (d_u_cache
|| i_cache
)
214 cp15_control
&= ~0x4U
;
216 arm720t_write_cp15(target
, 0xee010f10, cp15_control
);
219 void arm720t_enable_mmu_caches(target_t
*target
, int mmu
, int d_u_cache
, int i_cache
)
221 uint32_t cp15_control
;
223 /* read cp15 control register */
224 arm720t_read_cp15(target
, 0xee110f10, &cp15_control
);
225 jtag_execute_queue();
228 cp15_control
|= 0x1U
;
230 if (d_u_cache
|| i_cache
)
231 cp15_control
|= 0x4U
;
233 arm720t_write_cp15(target
, 0xee010f10, cp15_control
);
236 void arm720t_post_debug_entry(target_t
*target
)
238 armv4_5_common_t
*armv4_5
= target
->arch_info
;
239 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
240 arm7tdmi_common_t
*arm7tdmi
= arm7_9
->arch_info
;
241 arm720t_common_t
*arm720t
= arm7tdmi
->arch_info
;
243 /* examine cp15 control reg */
244 arm720t_read_cp15(target
, 0xee110f10, &arm720t
->cp15_control_reg
);
245 jtag_execute_queue();
246 LOG_DEBUG("cp15_control_reg: %8.8" PRIx32
"", arm720t
->cp15_control_reg
);
248 arm720t
->armv4_5_mmu
.mmu_enabled
= (arm720t
->cp15_control_reg
& 0x1U
) ? 1 : 0;
249 arm720t
->armv4_5_mmu
.armv4_5_cache
.d_u_cache_enabled
= (arm720t
->cp15_control_reg
& 0x4U
) ? 1 : 0;
250 arm720t
->armv4_5_mmu
.armv4_5_cache
.i_cache_enabled
= 0;
252 /* save i/d fault status and address register */
253 arm720t_read_cp15(target
, 0xee150f10, &arm720t
->fsr_reg
);
254 arm720t_read_cp15(target
, 0xee160f10, &arm720t
->far_reg
);
255 jtag_execute_queue();
258 void arm720t_pre_restore_context(target_t
*target
)
260 armv4_5_common_t
*armv4_5
= target
->arch_info
;
261 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
262 arm7tdmi_common_t
*arm7tdmi
= arm7_9
->arch_info
;
263 arm720t_common_t
*arm720t
= arm7tdmi
->arch_info
;
265 /* restore i/d fault status and address register */
266 arm720t_write_cp15(target
, 0xee050f10, arm720t
->fsr_reg
);
267 arm720t_write_cp15(target
, 0xee060f10, arm720t
->far_reg
);
270 int arm720t_get_arch_pointers(target_t
*target
, armv4_5_common_t
**armv4_5_p
, arm7_9_common_t
**arm7_9_p
, arm7tdmi_common_t
**arm7tdmi_p
, arm720t_common_t
**arm720t_p
)
272 armv4_5_common_t
*armv4_5
= target
->arch_info
;
273 arm7_9_common_t
*arm7_9
;
274 arm7tdmi_common_t
*arm7tdmi
;
275 arm720t_common_t
*arm720t
;
277 if (armv4_5
->common_magic
!= ARMV4_5_COMMON_MAGIC
)
282 arm7_9
= armv4_5
->arch_info
;
283 if (arm7_9
->common_magic
!= ARM7_9_COMMON_MAGIC
)
288 arm7tdmi
= arm7_9
->arch_info
;
289 if (arm7tdmi
->common_magic
!= ARM7TDMI_COMMON_MAGIC
)
294 arm720t
= arm7tdmi
->arch_info
;
295 if (arm720t
->common_magic
!= ARM720T_COMMON_MAGIC
)
300 *armv4_5_p
= armv4_5
;
302 *arm7tdmi_p
= arm7tdmi
;
303 *arm720t_p
= arm720t
;
308 int arm720t_arch_state(struct target_s
*target
)
310 armv4_5_common_t
*armv4_5
= target
->arch_info
;
311 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
312 arm7tdmi_common_t
*arm7tdmi
= arm7_9
->arch_info
;
313 arm720t_common_t
*arm720t
= arm7tdmi
->arch_info
;
317 "disabled", "enabled"
320 if (armv4_5
->common_magic
!= ARMV4_5_COMMON_MAGIC
)
322 LOG_ERROR("BUG: called for a non-ARMv4/5 target");
326 LOG_USER("target halted in %s state due to %s, current mode: %s\n"
327 "cpsr: 0x%8.8" PRIx32
" pc: 0x%8.8" PRIx32
"\n"
328 "MMU: %s, Cache: %s",
329 armv4_5_state_strings
[armv4_5
->core_state
],
330 Jim_Nvp_value2name_simple(nvp_target_debug_reason
, target
->debug_reason
)->name
,
331 armv4_5_mode_strings
[armv4_5_mode_to_number(armv4_5
->core_mode
)],
332 buf_get_u32(armv4_5
->core_cache
->reg_list
[ARMV4_5_CPSR
].value
, 0, 32),
333 buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32),
334 state
[arm720t
->armv4_5_mmu
.mmu_enabled
],
335 state
[arm720t
->armv4_5_mmu
.armv4_5_cache
.d_u_cache_enabled
]);
340 int arm720t_read_memory(struct target_s
*target
, uint32_t address
, uint32_t size
, uint32_t count
, uint8_t *buffer
)
343 armv4_5_common_t
*armv4_5
= target
->arch_info
;
344 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
345 arm7tdmi_common_t
*arm7tdmi
= arm7_9
->arch_info
;
346 arm720t_common_t
*arm720t
= arm7tdmi
->arch_info
;
348 /* disable cache, but leave MMU enabled */
349 if (arm720t
->armv4_5_mmu
.armv4_5_cache
.d_u_cache_enabled
)
350 arm720t_disable_mmu_caches(target
, 0, 1, 0);
352 retval
= arm7_9_read_memory(target
, address
, size
, count
, buffer
);
354 if (arm720t
->armv4_5_mmu
.armv4_5_cache
.d_u_cache_enabled
)
355 arm720t_enable_mmu_caches(target
, 0, 1, 0);
360 int arm720t_write_memory(struct target_s
*target
, uint32_t address
, uint32_t size
, uint32_t count
, uint8_t *buffer
)
364 if ((retval
= arm7_9_write_memory(target
, address
, size
, count
, buffer
)) != ERROR_OK
)
371 int arm720t_read_phys_memory(struct target_s
*target
, uint32_t address
, uint32_t size
, uint32_t count
, uint8_t *buffer
)
373 armv4_5_common_t
*armv4_5
= target
->arch_info
;
374 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
375 arm7tdmi_common_t
*arm7tdmi
= arm7_9
->arch_info
;
376 arm720t_common_t
*arm720t
= arm7tdmi
->arch_info
;
378 return armv4_5_mmu_read_physical(target
, &arm720t
->armv4_5_mmu
, address
, size
, count
, buffer
);
381 int arm720t_write_phys_memory(struct target_s
*target
, uint32_t address
, uint32_t size
, uint32_t count
, uint8_t *buffer
)
383 armv4_5_common_t
*armv4_5
= target
->arch_info
;
384 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
385 arm7tdmi_common_t
*arm7tdmi
= arm7_9
->arch_info
;
386 arm720t_common_t
*arm720t
= arm7tdmi
->arch_info
;
388 return armv4_5_mmu_write_physical(target
, &arm720t
->armv4_5_mmu
, address
, size
, count
, buffer
);
392 int arm720t_soft_reset_halt(struct target_s
*target
)
394 int retval
= ERROR_OK
;
395 armv4_5_common_t
*armv4_5
= target
->arch_info
;
396 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
397 arm7tdmi_common_t
*arm7tdmi
= arm7_9
->arch_info
;
398 arm720t_common_t
*arm720t
= arm7tdmi
->arch_info
;
399 reg_t
*dbg_stat
= &arm7_9
->eice_cache
->reg_list
[EICE_DBG_STAT
];
401 if ((retval
= target_halt(target
)) != ERROR_OK
)
406 long long then
= timeval_ms();
408 while (!(timeout
= ((timeval_ms()-then
) > 1000)))
410 if (buf_get_u32(dbg_stat
->value
, EICE_DBG_STATUS_DBGACK
, 1) == 0)
412 embeddedice_read_reg(dbg_stat
);
413 if ((retval
= jtag_execute_queue()) != ERROR_OK
)
421 if (debug_level
>= 3)
431 LOG_ERROR("Failed to halt CPU after 1 sec");
432 return ERROR_TARGET_TIMEOUT
;
435 target
->state
= TARGET_HALTED
;
437 /* SVC, ARM state, IRQ and FIQ disabled */
438 buf_set_u32(armv4_5
->core_cache
->reg_list
[ARMV4_5_CPSR
].value
, 0, 8, 0xd3);
439 armv4_5
->core_cache
->reg_list
[ARMV4_5_CPSR
].dirty
= 1;
440 armv4_5
->core_cache
->reg_list
[ARMV4_5_CPSR
].valid
= 1;
442 /* start fetching from 0x0 */
443 buf_set_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32, 0x0);
444 armv4_5
->core_cache
->reg_list
[15].dirty
= 1;
445 armv4_5
->core_cache
->reg_list
[15].valid
= 1;
447 armv4_5
->core_mode
= ARMV4_5_MODE_SVC
;
448 armv4_5
->core_state
= ARMV4_5_STATE_ARM
;
450 arm720t_disable_mmu_caches(target
, 1, 1, 1);
451 arm720t
->armv4_5_mmu
.mmu_enabled
= 0;
452 arm720t
->armv4_5_mmu
.armv4_5_cache
.d_u_cache_enabled
= 0;
453 arm720t
->armv4_5_mmu
.armv4_5_cache
.i_cache_enabled
= 0;
455 if ((retval
= target_call_event_callbacks(target
, TARGET_EVENT_HALTED
)) != ERROR_OK
)
463 int arm720t_init_target(struct command_context_s
*cmd_ctx
, struct target_s
*target
)
465 arm7tdmi_init_target(cmd_ctx
, target
);
471 int arm720t_init_arch_info(target_t
*target
, arm720t_common_t
*arm720t
, jtag_tap_t
*tap
)
473 arm7tdmi_common_t
*arm7tdmi
= &arm720t
->arm7tdmi_common
;
474 arm7_9_common_t
*arm7_9
= &arm7tdmi
->arm7_9_common
;
476 arm7tdmi_init_arch_info(target
, arm7tdmi
, tap
);
478 arm7tdmi
->arch_info
= arm720t
;
479 arm720t
->common_magic
= ARM720T_COMMON_MAGIC
;
481 arm7_9
->post_debug_entry
= arm720t_post_debug_entry
;
482 arm7_9
->pre_restore_context
= arm720t_pre_restore_context
;
484 arm720t
->armv4_5_mmu
.armv4_5_cache
.ctype
= -1;
485 arm720t
->armv4_5_mmu
.get_ttb
= arm720t_get_ttb
;
486 arm720t
->armv4_5_mmu
.read_memory
= arm7_9_read_memory
;
487 arm720t
->armv4_5_mmu
.write_memory
= arm7_9_write_memory
;
488 arm720t
->armv4_5_mmu
.disable_mmu_caches
= arm720t_disable_mmu_caches
;
489 arm720t
->armv4_5_mmu
.enable_mmu_caches
= arm720t_enable_mmu_caches
;
490 arm720t
->armv4_5_mmu
.has_tiny_pages
= 0;
491 arm720t
->armv4_5_mmu
.mmu_enabled
= 0;
496 int arm720t_target_create(struct target_s
*target
, Jim_Interp
*interp
)
498 arm720t_common_t
*arm720t
= calloc(1,sizeof(arm720t_common_t
));
500 arm720t_init_arch_info(target
, arm720t
, target
->tap
);
505 int arm720t_register_commands(struct command_context_s
*cmd_ctx
)
508 command_t
*arm720t_cmd
;
511 retval
= arm7tdmi_register_commands(cmd_ctx
);
513 arm720t_cmd
= register_command(cmd_ctx
, NULL
, "arm720t", NULL
, COMMAND_ANY
, "arm720t specific commands");
515 register_command(cmd_ctx
, arm720t_cmd
, "cp15", arm720t_handle_cp15_command
, COMMAND_EXEC
, "display/modify cp15 register <opcode> [value]");
520 int arm720t_handle_cp15_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
523 target_t
*target
= get_current_target(cmd_ctx
);
524 armv4_5_common_t
*armv4_5
;
525 arm7_9_common_t
*arm7_9
;
526 arm7tdmi_common_t
*arm7tdmi
;
527 arm720t_common_t
*arm720t
;
528 arm_jtag_t
*jtag_info
;
530 if (arm720t_get_arch_pointers(target
, &armv4_5
, &arm7_9
, &arm7tdmi
, &arm720t
) != ERROR_OK
)
532 command_print(cmd_ctx
, "current target isn't an ARM720t target");
536 jtag_info
= &arm7_9
->jtag_info
;
538 if (target
->state
!= TARGET_HALTED
)
540 command_print(cmd_ctx
, "target must be stopped for \"%s\" command", cmd
);
544 /* one or more argument, access a single register (write if second argument is given */
548 COMMAND_PARSE_NUMBER(u32
, args
[0], opcode
);
553 if ((retval
= arm720t_read_cp15(target
, opcode
, &value
)) != ERROR_OK
)
555 command_print(cmd_ctx
, "couldn't access cp15 with opcode 0x%8.8" PRIx32
"", opcode
);
559 if ((retval
= jtag_execute_queue()) != ERROR_OK
)
564 command_print(cmd_ctx
, "0x%8.8" PRIx32
": 0x%8.8" PRIx32
"", opcode
, value
);
569 COMMAND_PARSE_NUMBER(u32
, args
[1], value
);
571 if ((retval
= arm720t_write_cp15(target
, opcode
, value
)) != ERROR_OK
)
573 command_print(cmd_ctx
, "couldn't access cp15 with opcode 0x%8.8" PRIx32
"", opcode
);
576 command_print(cmd_ctx
, "0x%8.8" PRIx32
": 0x%8.8" PRIx32
"", opcode
, value
);
584 static int arm720t_mrc(target_t
*target
, int cpnum
, uint32_t op1
, uint32_t op2
, uint32_t CRn
, uint32_t CRm
, uint32_t *value
)
588 LOG_ERROR("Only cp15 is supported");
592 return arm720t_read_cp15(target
, mrc_opcode(cpnum
, op1
, op2
, CRn
, CRm
), value
);
596 static int arm720t_mcr(target_t
*target
, int cpnum
, uint32_t op1
, uint32_t op2
, uint32_t CRn
, uint32_t CRm
, uint32_t value
)
600 LOG_ERROR("Only cp15 is supported");
604 return arm720t_write_cp15(target
, mrc_opcode(cpnum
, op1
, op2
, CRn
, CRm
), value
);
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)