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_quit(void);
45 int arm720t_arch_state(struct target_s
*target
);
46 int arm720t_read_memory(struct target_s
*target
, uint32_t address
, uint32_t size
, uint32_t count
, uint8_t *buffer
);
47 int arm720t_write_memory(struct target_s
*target
, uint32_t address
, uint32_t size
, uint32_t count
, uint8_t *buffer
);
48 int arm720t_read_phys_memory(struct target_s
*target
, uint32_t address
, uint32_t size
, uint32_t count
, uint8_t *buffer
);
49 int arm720t_write_phys_memory(struct target_s
*target
, uint32_t address
, uint32_t size
, uint32_t count
, uint8_t *buffer
);
50 int arm720t_soft_reset_halt(struct target_s
*target
);
52 static int arm720t_mrc(target_t
*target
, int cpnum
, uint32_t op1
, uint32_t op2
, uint32_t CRn
, uint32_t CRm
, uint32_t *value
);
53 static int arm720t_mcr(target_t
*target
, int cpnum
, uint32_t op1
, uint32_t op2
, uint32_t CRn
, uint32_t CRm
, uint32_t value
);
55 target_type_t arm720t_target
=
60 .arch_state
= arm720t_arch_state
,
63 .resume
= arm7_9_resume
,
66 .assert_reset
= arm7_9_assert_reset
,
67 .deassert_reset
= arm7_9_deassert_reset
,
68 .soft_reset_halt
= arm720t_soft_reset_halt
,
70 .get_gdb_reg_list
= armv4_5_get_gdb_reg_list
,
72 .read_memory
= arm720t_read_memory
,
73 .write_memory
= arm720t_write_memory
,
74 .read_phys_memory
= arm720t_read_phys_memory
,
75 .write_phys_memory
= arm720t_write_phys_memory
,
76 .bulk_write_memory
= arm7_9_bulk_write_memory
,
77 .checksum_memory
= arm7_9_checksum_memory
,
78 .blank_check_memory
= arm7_9_blank_check_memory
,
80 .run_algorithm
= armv4_5_run_algorithm
,
82 .add_breakpoint
= arm7_9_add_breakpoint
,
83 .remove_breakpoint
= arm7_9_remove_breakpoint
,
84 .add_watchpoint
= arm7_9_add_watchpoint
,
85 .remove_watchpoint
= arm7_9_remove_watchpoint
,
87 .register_commands
= arm720t_register_commands
,
88 .target_create
= arm720t_target_create
,
89 .init_target
= arm720t_init_target
,
90 .examine
= arm7tdmi_examine
,
97 int arm720t_scan_cp15(target_t
*target
, uint32_t out
, uint32_t *in
, int instruction
, int clock
)
99 int retval
= ERROR_OK
;
100 armv4_5_common_t
*armv4_5
= target
->arch_info
;
101 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
102 arm_jtag_t
*jtag_info
= &arm7_9
->jtag_info
;
103 scan_field_t fields
[2];
105 uint8_t instruction_buf
= instruction
;
107 buf_set_u32(out_buf
, 0, 32, flip_u32(out
, 32));
109 jtag_set_end_state(TAP_DRPAUSE
);
110 if ((retval
= arm_jtag_scann(jtag_info
, 0xf)) != ERROR_OK
)
114 if ((retval
= arm_jtag_set_instr(jtag_info
, jtag_info
->intest_instr
, NULL
)) != ERROR_OK
)
119 fields
[0].tap
= jtag_info
->tap
;
120 fields
[0].num_bits
= 1;
121 fields
[0].out_value
= &instruction_buf
;
122 fields
[0].in_value
= NULL
;
124 fields
[1].tap
= jtag_info
->tap
;
125 fields
[1].num_bits
= 32;
126 fields
[1].out_value
= out_buf
;
127 fields
[1].in_value
= NULL
;
131 fields
[1].in_value
= (uint8_t *)in
;
132 jtag_add_dr_scan(2, fields
, jtag_get_end_state());
133 jtag_add_callback(arm7flip32
, (jtag_callback_data_t
)in
);
136 jtag_add_dr_scan(2, fields
, jtag_get_end_state());
140 jtag_add_runtest(0, jtag_get_end_state());
142 #ifdef _DEBUG_INSTRUCTION_EXECUTION_
143 if ((retval
= jtag_execute_queue()) != ERROR_OK
)
149 LOG_DEBUG("out: %8.8x, in: %8.8x, instruction: %i, clock: %i", out
, *in
, instruction
, clock
);
151 LOG_DEBUG("out: %8.8x, instruction: %i, clock: %i", out
, instruction
, clock
);
153 LOG_DEBUG("out: %8.8" PRIx32
", instruction: %i, clock: %i", out
, instruction
, clock
);
159 int arm720t_read_cp15(target_t
*target
, uint32_t opcode
, uint32_t *value
)
161 /* fetch CP15 opcode */
162 arm720t_scan_cp15(target
, opcode
, NULL
, 1, 1);
164 arm720t_scan_cp15(target
, ARMV4_5_NOP
, NULL
, 1, 1);
165 /* "EXECUTE" stage (1) */
166 arm720t_scan_cp15(target
, ARMV4_5_NOP
, NULL
, 1, 0);
167 arm720t_scan_cp15(target
, 0x0, NULL
, 0, 1);
168 /* "EXECUTE" stage (2) */
169 arm720t_scan_cp15(target
, 0x0, NULL
, 0, 1);
170 /* "EXECUTE" stage (3), CDATA is read */
171 arm720t_scan_cp15(target
, ARMV4_5_NOP
, value
, 1, 1);
176 int arm720t_write_cp15(target_t
*target
, uint32_t opcode
, uint32_t value
)
178 /* fetch CP15 opcode */
179 arm720t_scan_cp15(target
, opcode
, NULL
, 1, 1);
181 arm720t_scan_cp15(target
, ARMV4_5_NOP
, NULL
, 1, 1);
182 /* "EXECUTE" stage (1) */
183 arm720t_scan_cp15(target
, ARMV4_5_NOP
, NULL
, 1, 0);
184 arm720t_scan_cp15(target
, 0x0, NULL
, 0, 1);
185 /* "EXECUTE" stage (2) */
186 arm720t_scan_cp15(target
, value
, NULL
, 0, 1);
187 arm720t_scan_cp15(target
, ARMV4_5_NOP
, NULL
, 1, 1);
192 uint32_t arm720t_get_ttb(target_t
*target
)
196 arm720t_read_cp15(target
, 0xee120f10, &ttb
);
197 jtag_execute_queue();
204 void arm720t_disable_mmu_caches(target_t
*target
, int mmu
, int d_u_cache
, int i_cache
)
206 uint32_t cp15_control
;
208 /* read cp15 control register */
209 arm720t_read_cp15(target
, 0xee110f10, &cp15_control
);
210 jtag_execute_queue();
213 cp15_control
&= ~0x1U
;
215 if (d_u_cache
|| i_cache
)
216 cp15_control
&= ~0x4U
;
218 arm720t_write_cp15(target
, 0xee010f10, cp15_control
);
221 void arm720t_enable_mmu_caches(target_t
*target
, int mmu
, int d_u_cache
, int i_cache
)
223 uint32_t cp15_control
;
225 /* read cp15 control register */
226 arm720t_read_cp15(target
, 0xee110f10, &cp15_control
);
227 jtag_execute_queue();
230 cp15_control
|= 0x1U
;
232 if (d_u_cache
|| i_cache
)
233 cp15_control
|= 0x4U
;
235 arm720t_write_cp15(target
, 0xee010f10, cp15_control
);
238 void arm720t_post_debug_entry(target_t
*target
)
240 armv4_5_common_t
*armv4_5
= target
->arch_info
;
241 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
242 arm7tdmi_common_t
*arm7tdmi
= arm7_9
->arch_info
;
243 arm720t_common_t
*arm720t
= arm7tdmi
->arch_info
;
245 /* examine cp15 control reg */
246 arm720t_read_cp15(target
, 0xee110f10, &arm720t
->cp15_control_reg
);
247 jtag_execute_queue();
248 LOG_DEBUG("cp15_control_reg: %8.8" PRIx32
"", arm720t
->cp15_control_reg
);
250 arm720t
->armv4_5_mmu
.mmu_enabled
= (arm720t
->cp15_control_reg
& 0x1U
) ? 1 : 0;
251 arm720t
->armv4_5_mmu
.armv4_5_cache
.d_u_cache_enabled
= (arm720t
->cp15_control_reg
& 0x4U
) ? 1 : 0;
252 arm720t
->armv4_5_mmu
.armv4_5_cache
.i_cache_enabled
= 0;
254 /* save i/d fault status and address register */
255 arm720t_read_cp15(target
, 0xee150f10, &arm720t
->fsr_reg
);
256 arm720t_read_cp15(target
, 0xee160f10, &arm720t
->far_reg
);
257 jtag_execute_queue();
260 void arm720t_pre_restore_context(target_t
*target
)
262 armv4_5_common_t
*armv4_5
= target
->arch_info
;
263 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
264 arm7tdmi_common_t
*arm7tdmi
= arm7_9
->arch_info
;
265 arm720t_common_t
*arm720t
= arm7tdmi
->arch_info
;
267 /* restore i/d fault status and address register */
268 arm720t_write_cp15(target
, 0xee050f10, arm720t
->fsr_reg
);
269 arm720t_write_cp15(target
, 0xee060f10, arm720t
->far_reg
);
272 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
)
274 armv4_5_common_t
*armv4_5
= target
->arch_info
;
275 arm7_9_common_t
*arm7_9
;
276 arm7tdmi_common_t
*arm7tdmi
;
277 arm720t_common_t
*arm720t
;
279 if (armv4_5
->common_magic
!= ARMV4_5_COMMON_MAGIC
)
284 arm7_9
= armv4_5
->arch_info
;
285 if (arm7_9
->common_magic
!= ARM7_9_COMMON_MAGIC
)
290 arm7tdmi
= arm7_9
->arch_info
;
291 if (arm7tdmi
->common_magic
!= ARM7TDMI_COMMON_MAGIC
)
296 arm720t
= arm7tdmi
->arch_info
;
297 if (arm720t
->common_magic
!= ARM720T_COMMON_MAGIC
)
302 *armv4_5_p
= armv4_5
;
304 *arm7tdmi_p
= arm7tdmi
;
305 *arm720t_p
= arm720t
;
310 int arm720t_arch_state(struct target_s
*target
)
312 armv4_5_common_t
*armv4_5
= target
->arch_info
;
313 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
314 arm7tdmi_common_t
*arm7tdmi
= arm7_9
->arch_info
;
315 arm720t_common_t
*arm720t
= arm7tdmi
->arch_info
;
319 "disabled", "enabled"
322 if (armv4_5
->common_magic
!= ARMV4_5_COMMON_MAGIC
)
324 LOG_ERROR("BUG: called for a non-ARMv4/5 target");
328 LOG_USER("target halted in %s state due to %s, current mode: %s\n"
329 "cpsr: 0x%8.8" PRIx32
" pc: 0x%8.8" PRIx32
"\n"
330 "MMU: %s, Cache: %s",
331 armv4_5_state_strings
[armv4_5
->core_state
],
332 Jim_Nvp_value2name_simple(nvp_target_debug_reason
, target
->debug_reason
)->name
,
333 armv4_5_mode_strings
[armv4_5_mode_to_number(armv4_5
->core_mode
)],
334 buf_get_u32(armv4_5
->core_cache
->reg_list
[ARMV4_5_CPSR
].value
, 0, 32),
335 buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32),
336 state
[arm720t
->armv4_5_mmu
.mmu_enabled
],
337 state
[arm720t
->armv4_5_mmu
.armv4_5_cache
.d_u_cache_enabled
]);
342 int arm720t_read_memory(struct target_s
*target
, uint32_t address
, uint32_t size
, uint32_t count
, uint8_t *buffer
)
345 armv4_5_common_t
*armv4_5
= target
->arch_info
;
346 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
347 arm7tdmi_common_t
*arm7tdmi
= arm7_9
->arch_info
;
348 arm720t_common_t
*arm720t
= arm7tdmi
->arch_info
;
350 /* disable cache, but leave MMU enabled */
351 if (arm720t
->armv4_5_mmu
.armv4_5_cache
.d_u_cache_enabled
)
352 arm720t_disable_mmu_caches(target
, 0, 1, 0);
354 retval
= arm7_9_read_memory(target
, address
, size
, count
, buffer
);
356 if (arm720t
->armv4_5_mmu
.armv4_5_cache
.d_u_cache_enabled
)
357 arm720t_enable_mmu_caches(target
, 0, 1, 0);
362 int arm720t_write_memory(struct target_s
*target
, uint32_t address
, uint32_t size
, uint32_t count
, uint8_t *buffer
)
366 if ((retval
= arm7_9_write_memory(target
, address
, size
, count
, buffer
)) != ERROR_OK
)
373 int arm720t_read_phys_memory(struct target_s
*target
, uint32_t address
, uint32_t size
, uint32_t count
, uint8_t *buffer
)
375 armv4_5_common_t
*armv4_5
= target
->arch_info
;
376 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
377 arm7tdmi_common_t
*arm7tdmi
= arm7_9
->arch_info
;
378 arm720t_common_t
*arm720t
= arm7tdmi
->arch_info
;
380 return armv4_5_mmu_read_physical(target
, &arm720t
->armv4_5_mmu
, address
, size
, count
, buffer
);
383 int arm720t_write_phys_memory(struct target_s
*target
, uint32_t address
, uint32_t size
, uint32_t count
, uint8_t *buffer
)
385 armv4_5_common_t
*armv4_5
= target
->arch_info
;
386 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
387 arm7tdmi_common_t
*arm7tdmi
= arm7_9
->arch_info
;
388 arm720t_common_t
*arm720t
= arm7tdmi
->arch_info
;
390 return armv4_5_mmu_write_physical(target
, &arm720t
->armv4_5_mmu
, address
, size
, count
, buffer
);
394 int arm720t_soft_reset_halt(struct target_s
*target
)
396 int retval
= ERROR_OK
;
397 armv4_5_common_t
*armv4_5
= target
->arch_info
;
398 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
399 arm7tdmi_common_t
*arm7tdmi
= arm7_9
->arch_info
;
400 arm720t_common_t
*arm720t
= arm7tdmi
->arch_info
;
401 reg_t
*dbg_stat
= &arm7_9
->eice_cache
->reg_list
[EICE_DBG_STAT
];
403 if ((retval
= target_halt(target
)) != ERROR_OK
)
408 long long then
= timeval_ms();
410 while (!(timeout
= ((timeval_ms()-then
) > 1000)))
412 if (buf_get_u32(dbg_stat
->value
, EICE_DBG_STATUS_DBGACK
, 1) == 0)
414 embeddedice_read_reg(dbg_stat
);
415 if ((retval
= jtag_execute_queue()) != ERROR_OK
)
423 if (debug_level
>= 3)
433 LOG_ERROR("Failed to halt CPU after 1 sec");
434 return ERROR_TARGET_TIMEOUT
;
437 target
->state
= TARGET_HALTED
;
439 /* SVC, ARM state, IRQ and FIQ disabled */
440 buf_set_u32(armv4_5
->core_cache
->reg_list
[ARMV4_5_CPSR
].value
, 0, 8, 0xd3);
441 armv4_5
->core_cache
->reg_list
[ARMV4_5_CPSR
].dirty
= 1;
442 armv4_5
->core_cache
->reg_list
[ARMV4_5_CPSR
].valid
= 1;
444 /* start fetching from 0x0 */
445 buf_set_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32, 0x0);
446 armv4_5
->core_cache
->reg_list
[15].dirty
= 1;
447 armv4_5
->core_cache
->reg_list
[15].valid
= 1;
449 armv4_5
->core_mode
= ARMV4_5_MODE_SVC
;
450 armv4_5
->core_state
= ARMV4_5_STATE_ARM
;
452 arm720t_disable_mmu_caches(target
, 1, 1, 1);
453 arm720t
->armv4_5_mmu
.mmu_enabled
= 0;
454 arm720t
->armv4_5_mmu
.armv4_5_cache
.d_u_cache_enabled
= 0;
455 arm720t
->armv4_5_mmu
.armv4_5_cache
.i_cache_enabled
= 0;
457 if ((retval
= target_call_event_callbacks(target
, TARGET_EVENT_HALTED
)) != ERROR_OK
)
465 int arm720t_init_target(struct command_context_s
*cmd_ctx
, struct target_s
*target
)
467 arm7tdmi_init_target(cmd_ctx
, target
);
472 int arm720t_quit(void)
477 int arm720t_init_arch_info(target_t
*target
, arm720t_common_t
*arm720t
, jtag_tap_t
*tap
)
479 arm7tdmi_common_t
*arm7tdmi
= &arm720t
->arm7tdmi_common
;
480 arm7_9_common_t
*arm7_9
= &arm7tdmi
->arm7_9_common
;
482 arm7tdmi_init_arch_info(target
, arm7tdmi
, tap
);
484 arm7tdmi
->arch_info
= arm720t
;
485 arm720t
->common_magic
= ARM720T_COMMON_MAGIC
;
487 arm7_9
->post_debug_entry
= arm720t_post_debug_entry
;
488 arm7_9
->pre_restore_context
= arm720t_pre_restore_context
;
490 arm720t
->armv4_5_mmu
.armv4_5_cache
.ctype
= -1;
491 arm720t
->armv4_5_mmu
.get_ttb
= arm720t_get_ttb
;
492 arm720t
->armv4_5_mmu
.read_memory
= arm7_9_read_memory
;
493 arm720t
->armv4_5_mmu
.write_memory
= arm7_9_write_memory
;
494 arm720t
->armv4_5_mmu
.disable_mmu_caches
= arm720t_disable_mmu_caches
;
495 arm720t
->armv4_5_mmu
.enable_mmu_caches
= arm720t_enable_mmu_caches
;
496 arm720t
->armv4_5_mmu
.has_tiny_pages
= 0;
497 arm720t
->armv4_5_mmu
.mmu_enabled
= 0;
502 int arm720t_target_create(struct target_s
*target
, Jim_Interp
*interp
)
504 arm720t_common_t
*arm720t
= calloc(1,sizeof(arm720t_common_t
));
506 arm720t_init_arch_info(target
, arm720t
, target
->tap
);
511 int arm720t_register_commands(struct command_context_s
*cmd_ctx
)
514 command_t
*arm720t_cmd
;
517 retval
= arm7tdmi_register_commands(cmd_ctx
);
519 arm720t_cmd
= register_command(cmd_ctx
, NULL
, "arm720t", NULL
, COMMAND_ANY
, "arm720t specific commands");
521 register_command(cmd_ctx
, arm720t_cmd
, "cp15", arm720t_handle_cp15_command
, COMMAND_EXEC
, "display/modify cp15 register <opcode> [value]");
526 int arm720t_handle_cp15_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
529 target_t
*target
= get_current_target(cmd_ctx
);
530 armv4_5_common_t
*armv4_5
;
531 arm7_9_common_t
*arm7_9
;
532 arm7tdmi_common_t
*arm7tdmi
;
533 arm720t_common_t
*arm720t
;
534 arm_jtag_t
*jtag_info
;
536 if (arm720t_get_arch_pointers(target
, &armv4_5
, &arm7_9
, &arm7tdmi
, &arm720t
) != ERROR_OK
)
538 command_print(cmd_ctx
, "current target isn't an ARM720t target");
542 jtag_info
= &arm7_9
->jtag_info
;
544 if (target
->state
!= TARGET_HALTED
)
546 command_print(cmd_ctx
, "target must be stopped for \"%s\" command", cmd
);
550 /* one or more argument, access a single register (write if second argument is given */
553 uint32_t opcode
= strtoul(args
[0], NULL
, 0);
558 if ((retval
= arm720t_read_cp15(target
, opcode
, &value
)) != ERROR_OK
)
560 command_print(cmd_ctx
, "couldn't access cp15 with opcode 0x%8.8" PRIx32
"", opcode
);
564 if ((retval
= jtag_execute_queue()) != ERROR_OK
)
569 command_print(cmd_ctx
, "0x%8.8" PRIx32
": 0x%8.8" PRIx32
"", opcode
, value
);
573 uint32_t value
= strtoul(args
[1], NULL
, 0);
574 if ((retval
= arm720t_write_cp15(target
, opcode
, value
)) != ERROR_OK
)
576 command_print(cmd_ctx
, "couldn't access cp15 with opcode 0x%8.8" PRIx32
"", opcode
);
579 command_print(cmd_ctx
, "0x%8.8" PRIx32
": 0x%8.8" PRIx32
"", opcode
, value
);
587 static int arm720t_mrc(target_t
*target
, int cpnum
, uint32_t op1
, uint32_t op2
, uint32_t CRn
, uint32_t CRm
, uint32_t *value
)
591 LOG_ERROR("Only cp15 is supported");
595 return arm720t_read_cp15(target
, mrc_opcode(cpnum
, op1
, op2
, CRn
, CRm
), value
);
599 static int arm720t_mcr(target_t
*target
, int cpnum
, uint32_t op1
, uint32_t op2
, uint32_t CRn
, uint32_t CRm
, uint32_t value
)
603 LOG_ERROR("Only cp15 is supported");
607 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)