1 /***************************************************************************
2 * Copyright (C) 2005 by Dominic Rath *
3 * Dominic.Rath@gmx.de *
5 * Copyright (C) 2008 by Spencer Oliver *
6 * spen@spen-soft.co.uk *
8 * Copyright (C) 2008 by Hongtao Zheng *
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. *
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. *
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 ***************************************************************************/
32 #include "arm7_9_common.h"
36 #include "embeddedice.h"
47 #define _DEBUG_INSTRUCTION_EXECUTION_
51 int handle_arm9tdmi_catch_vectors_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
53 /* forward declarations */
54 int arm9tdmi_target_create( struct target_s
*target
, Jim_Interp
*interp
);
56 int arm9tdmi_quit(void);
58 target_type_t arm9tdmi_target
=
63 .arch_state
= armv4_5_arch_state
,
65 .target_request_data
= arm7_9_target_request_data
,
68 .resume
= arm7_9_resume
,
71 .assert_reset
= arm7_9_assert_reset
,
72 .deassert_reset
= arm7_9_deassert_reset
,
73 .soft_reset_halt
= arm7_9_soft_reset_halt
,
75 .get_gdb_reg_list
= armv4_5_get_gdb_reg_list
,
77 .read_memory
= arm7_9_read_memory
,
78 .write_memory
= arm7_9_write_memory
,
79 .bulk_write_memory
= arm7_9_bulk_write_memory
,
80 .checksum_memory
= arm7_9_checksum_memory
,
81 .blank_check_memory
= arm7_9_blank_check_memory
,
83 .run_algorithm
= armv4_5_run_algorithm
,
85 .add_breakpoint
= arm7_9_add_breakpoint
,
86 .remove_breakpoint
= arm7_9_remove_breakpoint
,
87 .add_watchpoint
= arm7_9_add_watchpoint
,
88 .remove_watchpoint
= arm7_9_remove_watchpoint
,
90 .register_commands
= arm9tdmi_register_commands
,
91 .target_create
= arm9tdmi_target_create
,
92 .init_target
= arm9tdmi_init_target
,
93 .examine
= arm9tdmi_examine
,
97 arm9tdmi_vector_t arm9tdmi_vectors
[] =
99 {"reset", ARM9TDMI_RESET_VECTOR
},
100 {"undef", ARM9TDMI_UNDEF_VECTOR
},
101 {"swi", ARM9TDMI_SWI_VECTOR
},
102 {"pabt", ARM9TDMI_PABT_VECTOR
},
103 {"dabt", ARM9TDMI_DABT_VECTOR
},
104 {"reserved", ARM9TDMI_RESERVED_VECTOR
},
105 {"irq", ARM9TDMI_IRQ_VECTOR
},
106 {"fiq", ARM9TDMI_FIQ_VECTOR
},
110 int arm9tdmi_examine_debug_reason(target_t
*target
)
112 int retval
= ERROR_OK
;
113 /* get pointers to arch-specific information */
114 armv4_5_common_t
*armv4_5
= target
->arch_info
;
115 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
117 /* only check the debug reason if we don't know it already */
118 if ((target
->debug_reason
!= DBG_REASON_DBGRQ
)
119 && (target
->debug_reason
!= DBG_REASON_SINGLESTEP
))
121 scan_field_t fields
[3];
123 u8 instructionbus
[4];
126 jtag_add_end_state(TAP_DRPAUSE
);
128 fields
[0].tap
= arm7_9
->jtag_info
.tap
;
129 fields
[0].num_bits
= 32;
130 fields
[0].out_value
= NULL
;
131 fields
[0].out_mask
= NULL
;
132 fields
[0].in_value
= databus
;
133 fields
[0].in_check_value
= NULL
;
134 fields
[0].in_check_mask
= NULL
;
135 fields
[0].in_handler
= NULL
;
136 fields
[0].in_handler_priv
= NULL
;
138 fields
[1].tap
= arm7_9
->jtag_info
.tap
;
139 fields
[1].num_bits
= 3;
140 fields
[1].out_value
= NULL
;
141 fields
[1].out_mask
= NULL
;
142 fields
[1].in_value
= &debug_reason
;
143 fields
[1].in_check_value
= NULL
;
144 fields
[1].in_check_mask
= NULL
;
145 fields
[1].in_handler
= NULL
;
146 fields
[1].in_handler_priv
= NULL
;
148 fields
[2].tap
= arm7_9
->jtag_info
.tap
;
149 fields
[2].num_bits
= 32;
150 fields
[2].out_value
= NULL
;
151 fields
[2].out_mask
= NULL
;
152 fields
[2].in_value
= instructionbus
;
153 fields
[2].in_check_value
= NULL
;
154 fields
[2].in_check_mask
= NULL
;
155 fields
[2].in_handler
= NULL
;
156 fields
[2].in_handler_priv
= NULL
;
158 if((retval
= arm_jtag_scann(&arm7_9
->jtag_info
, 0x1)) != ERROR_OK
)
162 arm_jtag_set_instr(&arm7_9
->jtag_info
, arm7_9
->jtag_info
.intest_instr
, NULL
);
164 jtag_add_dr_scan(3, fields
, TAP_DRPAUSE
);
165 if((retval
= jtag_execute_queue()) != ERROR_OK
)
170 fields
[0].in_value
= NULL
;
171 fields
[0].out_value
= databus
;
172 fields
[1].in_value
= NULL
;
173 fields
[1].out_value
= &debug_reason
;
174 fields
[2].in_value
= NULL
;
175 fields
[2].out_value
= instructionbus
;
177 jtag_add_dr_scan(3, fields
, TAP_DRPAUSE
);
179 if (debug_reason
& 0x4)
180 if (debug_reason
& 0x2)
181 target
->debug_reason
= DBG_REASON_WPTANDBKPT
;
183 target
->debug_reason
= DBG_REASON_WATCHPOINT
;
185 target
->debug_reason
= DBG_REASON_BREAKPOINT
;
191 /* put an instruction in the ARM9TDMI pipeline or write the data bus, and optionally read data */
192 int arm9tdmi_clock_out(arm_jtag_t
*jtag_info
, u32 instr
, u32 out
, u32
*in
, int sysspeed
)
194 int retval
= ERROR_OK
;
195 scan_field_t fields
[3];
198 u8 sysspeed_buf
= 0x0;
201 buf_set_u32(out_buf
, 0, 32, out
);
203 buf_set_u32(instr_buf
, 0, 32, flip_u32(instr
, 32));
206 buf_set_u32(&sysspeed_buf
, 2, 1, 1);
208 jtag_add_end_state(TAP_DRPAUSE
);
209 if((retval
= arm_jtag_scann(jtag_info
, 0x1)) != ERROR_OK
)
214 arm_jtag_set_instr(jtag_info
, jtag_info
->intest_instr
, NULL
);
216 fields
[0].tap
= jtag_info
->tap
;
217 fields
[0].num_bits
= 32;
218 fields
[0].out_value
= out_buf
;
219 fields
[0].out_mask
= NULL
;
220 fields
[0].in_value
= NULL
;
223 fields
[0].in_handler
= arm_jtag_buf_to_u32
; /* deprecated! invoke this from user code! */
224 fields
[0].in_handler_priv
= in
;
228 fields
[0].in_handler
= NULL
;
229 fields
[0].in_handler_priv
= NULL
;
231 fields
[0].in_check_value
= NULL
;
232 fields
[0].in_check_mask
= NULL
;
234 fields
[1].tap
= jtag_info
->tap
;
235 fields
[1].num_bits
= 3;
236 fields
[1].out_value
= &sysspeed_buf
;
237 fields
[1].out_mask
= NULL
;
238 fields
[1].in_value
= NULL
;
239 fields
[1].in_check_value
= NULL
;
240 fields
[1].in_check_mask
= NULL
;
241 fields
[1].in_handler
= NULL
;
242 fields
[1].in_handler_priv
= NULL
;
244 fields
[2].tap
= jtag_info
->tap
;
245 fields
[2].num_bits
= 32;
246 fields
[2].out_value
= instr_buf
;
247 fields
[2].out_mask
= NULL
;
248 fields
[2].in_value
= NULL
;
249 fields
[2].in_check_value
= NULL
;
250 fields
[2].in_check_mask
= NULL
;
251 fields
[2].in_handler
= NULL
;
252 fields
[2].in_handler_priv
= NULL
;
254 jtag_add_dr_scan(3, fields
, TAP_INVALID
);
256 jtag_add_runtest(0, TAP_INVALID
);
258 #ifdef _DEBUG_INSTRUCTION_EXECUTION_
260 if((retval
= jtag_execute_queue()) != ERROR_OK
)
267 LOG_DEBUG("instr: 0x%8.8x, out: 0x%8.8x, in: 0x%8.8x", instr
, out
, *in
);
270 LOG_DEBUG("instr: 0x%8.8x, out: 0x%8.8x", instr
, out
);
277 /* just read data (instruction and data-out = don't care) */
278 int arm9tdmi_clock_data_in(arm_jtag_t
*jtag_info
, u32
*in
)
280 int retval
= ERROR_OK
;;
281 scan_field_t fields
[3];
283 jtag_add_end_state(TAP_DRPAUSE
);
284 if((retval
= arm_jtag_scann(jtag_info
, 0x1)) != ERROR_OK
)
289 arm_jtag_set_instr(jtag_info
, jtag_info
->intest_instr
, NULL
);
291 fields
[0].tap
= jtag_info
->tap
;
292 fields
[0].num_bits
= 32;
293 fields
[0].out_value
= NULL
;
294 fields
[0].out_mask
= NULL
;
295 fields
[0].in_value
= NULL
;
296 fields
[0].in_handler
= arm_jtag_buf_to_u32
; /* deprecated! invoke this from user code! */
297 fields
[0].in_handler_priv
= in
;
298 fields
[0].in_check_value
= NULL
;
299 fields
[0].in_check_mask
= NULL
;
301 fields
[1].tap
= jtag_info
->tap
;
302 fields
[1].num_bits
= 3;
303 fields
[1].out_value
= NULL
;
304 fields
[1].out_mask
= NULL
;
305 fields
[1].in_value
= NULL
;
306 fields
[1].in_handler
= NULL
;
307 fields
[1].in_handler_priv
= NULL
;
308 fields
[1].in_check_value
= NULL
;
309 fields
[1].in_check_mask
= NULL
;
311 fields
[2].tap
= jtag_info
->tap
;
312 fields
[2].num_bits
= 32;
313 fields
[2].out_value
= NULL
;
314 fields
[2].out_mask
= NULL
;
315 fields
[2].in_value
= NULL
;
316 fields
[2].in_check_value
= NULL
;
317 fields
[2].in_check_mask
= NULL
;
318 fields
[2].in_handler
= NULL
;
319 fields
[2].in_handler_priv
= NULL
;
321 jtag_add_dr_scan(3, fields
, TAP_INVALID
);
323 jtag_add_runtest(0, TAP_INVALID
);
325 #ifdef _DEBUG_INSTRUCTION_EXECUTION_
327 if((retval
= jtag_execute_queue()) != ERROR_OK
)
334 LOG_DEBUG("in: 0x%8.8x", *in
);
338 LOG_ERROR("BUG: called with in == NULL");
346 /* clock the target, and read the databus
347 * the *in pointer points to a buffer where elements of 'size' bytes
348 * are stored in big (be==1) or little (be==0) endianness
350 int arm9tdmi_clock_data_in_endianness(arm_jtag_t
*jtag_info
, void *in
, int size
, int be
)
352 int retval
= ERROR_OK
;
353 scan_field_t fields
[3];
355 jtag_add_end_state(TAP_DRPAUSE
);
356 if((retval
= arm_jtag_scann(jtag_info
, 0x1)) != ERROR_OK
)
361 arm_jtag_set_instr(jtag_info
, jtag_info
->intest_instr
, NULL
);
363 fields
[0].tap
= jtag_info
->tap
;
364 fields
[0].num_bits
= 32;
365 fields
[0].out_value
= NULL
;
366 fields
[0].out_mask
= NULL
;
367 fields
[0].in_value
= NULL
;
371 fields
[0].in_handler
= (be
) ? arm_jtag_buf_to_be32
: arm_jtag_buf_to_le32
; /* deprecated! invoke this from user code! */
374 fields
[0].in_handler
= (be
) ? arm_jtag_buf_to_be16
: arm_jtag_buf_to_le16
; /* deprecated! invoke this from user code! */
377 fields
[0].in_handler
= arm_jtag_buf_to_8
; /* deprecated! invoke this from user code! */
380 fields
[0].in_handler_priv
= in
;
381 fields
[0].in_check_value
= NULL
;
382 fields
[0].in_check_mask
= NULL
;
384 fields
[1].tap
= jtag_info
->tap
;
385 fields
[1].num_bits
= 3;
386 fields
[1].out_value
= NULL
;
387 fields
[1].out_mask
= NULL
;
388 fields
[1].in_value
= NULL
;
389 fields
[1].in_handler
= NULL
;
390 fields
[1].in_handler_priv
= NULL
;
391 fields
[1].in_check_value
= NULL
;
392 fields
[1].in_check_mask
= NULL
;
394 fields
[2].tap
= jtag_info
->tap
;
395 fields
[2].num_bits
= 32;
396 fields
[2].out_value
= NULL
;
397 fields
[2].out_mask
= NULL
;
398 fields
[2].in_value
= NULL
;
399 fields
[2].in_check_value
= NULL
;
400 fields
[2].in_check_mask
= NULL
;
401 fields
[2].in_handler
= NULL
;
402 fields
[2].in_handler_priv
= NULL
;
404 jtag_add_dr_scan(3, fields
, TAP_INVALID
);
406 jtag_add_runtest(0, TAP_INVALID
);
408 #ifdef _DEBUG_INSTRUCTION_EXECUTION_
410 if((retval
= jtag_execute_queue()) != ERROR_OK
)
417 LOG_DEBUG("in: 0x%8.8x", *(u32
*)in
);
421 LOG_ERROR("BUG: called with in == NULL");
429 void arm9tdmi_change_to_arm(target_t
*target
, u32
*r0
, u32
*pc
)
431 int retval
= ERROR_OK
;
432 /* get pointers to arch-specific information */
433 armv4_5_common_t
*armv4_5
= target
->arch_info
;
434 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
435 arm_jtag_t
*jtag_info
= &arm7_9
->jtag_info
;
437 /* save r0 before using it and put system in ARM state
438 * to allow common handling of ARM and THUMB debugging */
440 /* fetch STR r0, [r0] */
441 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_STR(0, 0), 0, NULL
, 0);
442 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, 0, NULL
, 0);
443 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, 0, NULL
, 0);
444 /* STR r0, [r0] in Memory */
445 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, 0, r0
, 0);
447 /* MOV r0, r15 fetched, STR in Decode */
448 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_MOV(0, 15), 0, NULL
, 0);
449 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, 0, NULL
, 0);
450 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_STR(0, 0), 0, NULL
, 0);
451 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, 0, NULL
, 0);
452 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, 0, NULL
, 0);
453 /* nothing fetched, STR r0, [r0] in Memory */
454 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, 0, pc
, 0);
456 /* use pc-relative LDR to clear r0[1:0] (for switch to ARM mode) */
457 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_LDR_PCREL(0), 0, NULL
, 0);
459 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, 0, NULL
, 0);
461 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, 0, NULL
, 0);
462 /* LDR in Memory (to account for interlock) */
463 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, 0, NULL
, 0);
466 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_BX(0), 0, NULL
, 0);
467 /* NOP fetched, BX in Decode, MOV in Execute */
468 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, 0, NULL
, 0);
469 /* NOP fetched, BX in Execute (1) */
470 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, 0, NULL
, 0);
472 if((retval
= jtag_execute_queue()) != ERROR_OK
)
477 /* fix program counter:
478 * MOV r0, r15 was the 5th instruction (+8)
479 * reading PC in Thumb state gives address of instruction + 4
484 void arm9tdmi_read_core_regs(target_t
*target
, u32 mask
, u32
* core_regs
[16])
487 /* get pointers to arch-specific information */
488 armv4_5_common_t
*armv4_5
= target
->arch_info
;
489 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
490 arm_jtag_t
*jtag_info
= &arm7_9
->jtag_info
;
492 /* STMIA r0-15, [r0] at debug speed
493 * register values will start to appear on 4th DCLK
495 arm9tdmi_clock_out(jtag_info
, ARMV4_5_STMIA(0, mask
& 0xffff, 0, 0), 0, NULL
, 0);
497 /* fetch NOP, STM in DECODE stage */
498 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
499 /* fetch NOP, STM in EXECUTE stage (1st cycle) */
500 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
502 for (i
= 0; i
<= 15; i
++)
505 /* nothing fetched, STM in MEMORY (i'th cycle) */
506 arm9tdmi_clock_data_in(jtag_info
, core_regs
[i
]);
510 void arm9tdmi_read_core_regs_target_buffer(target_t
*target
, u32 mask
, void* buffer
, int size
)
513 /* get pointers to arch-specific information */
514 armv4_5_common_t
*armv4_5
= target
->arch_info
;
515 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
516 arm_jtag_t
*jtag_info
= &arm7_9
->jtag_info
;
517 int be
= (target
->endianness
== TARGET_BIG_ENDIAN
) ? 1 : 0;
518 u32
*buf_u32
= buffer
;
519 u16
*buf_u16
= buffer
;
522 /* STMIA r0-15, [r0] at debug speed
523 * register values will start to appear on 4th DCLK
525 arm9tdmi_clock_out(jtag_info
, ARMV4_5_STMIA(0, mask
& 0xffff, 0, 0), 0, NULL
, 0);
527 /* fetch NOP, STM in DECODE stage */
528 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
529 /* fetch NOP, STM in EXECUTE stage (1st cycle) */
530 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
532 for (i
= 0; i
<= 15; i
++)
535 /* nothing fetched, STM in MEMORY (i'th cycle) */
539 arm9tdmi_clock_data_in_endianness(jtag_info
, buf_u32
++, 4, be
);
542 arm9tdmi_clock_data_in_endianness(jtag_info
, buf_u16
++, 2, be
);
545 arm9tdmi_clock_data_in_endianness(jtag_info
, buf_u8
++, 1, be
);
551 void arm9tdmi_read_xpsr(target_t
*target
, u32
*xpsr
, int spsr
)
553 /* get pointers to arch-specific information */
554 armv4_5_common_t
*armv4_5
= target
->arch_info
;
555 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
556 arm_jtag_t
*jtag_info
= &arm7_9
->jtag_info
;
559 arm9tdmi_clock_out(jtag_info
, ARMV4_5_MRS(0, spsr
& 1), 0, NULL
, 0);
560 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
561 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
562 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
563 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
566 arm9tdmi_clock_out(jtag_info
, ARMV4_5_STR(0, 15), 0, NULL
, 0);
567 /* fetch NOP, STR in DECODE stage */
568 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
569 /* fetch NOP, STR in EXECUTE stage (1st cycle) */
570 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
571 /* nothing fetched, STR in MEMORY */
572 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, xpsr
, 0);
575 void arm9tdmi_write_xpsr(target_t
*target
, u32 xpsr
, int spsr
)
577 /* get pointers to arch-specific information */
578 armv4_5_common_t
*armv4_5
= target
->arch_info
;
579 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
580 arm_jtag_t
*jtag_info
= &arm7_9
->jtag_info
;
582 LOG_DEBUG("xpsr: %8.8x, spsr: %i", xpsr
, spsr
);
585 arm9tdmi_clock_out(jtag_info
, ARMV4_5_MSR_IM(xpsr
& 0xff, 0, 1, spsr
), 0, NULL
, 0);
586 /* MSR2 fetched, MSR1 in DECODE */
587 arm9tdmi_clock_out(jtag_info
, ARMV4_5_MSR_IM((xpsr
& 0xff00) >> 8, 0xc, 2, spsr
), 0, NULL
, 0);
588 /* MSR3 fetched, MSR1 in EXECUTE (1), MSR2 in DECODE */
589 arm9tdmi_clock_out(jtag_info
, ARMV4_5_MSR_IM((xpsr
& 0xff0000) >> 16, 0x8, 4, spsr
), 0, NULL
, 0);
590 /* nothing fetched, MSR1 in EXECUTE (2) */
591 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
592 /* nothing fetched, MSR1 in EXECUTE (3) */
593 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
594 /* MSR4 fetched, MSR2 in EXECUTE (1), MSR3 in DECODE */
595 arm9tdmi_clock_out(jtag_info
, ARMV4_5_MSR_IM((xpsr
& 0xff000000) >> 24, 0x4, 8, spsr
), 0, NULL
, 0);
596 /* nothing fetched, MSR2 in EXECUTE (2) */
597 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
598 /* nothing fetched, MSR2 in EXECUTE (3) */
599 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
600 /* NOP fetched, MSR3 in EXECUTE (1), MSR4 in DECODE */
601 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
602 /* nothing fetched, MSR3 in EXECUTE (2) */
603 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
604 /* nothing fetched, MSR3 in EXECUTE (3) */
605 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
606 /* NOP fetched, MSR4 in EXECUTE (1) */
607 /* last MSR writes flags, which takes only one cycle */
608 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
611 void arm9tdmi_write_xpsr_im8(target_t
*target
, u8 xpsr_im
, int rot
, int spsr
)
613 /* get pointers to arch-specific information */
614 armv4_5_common_t
*armv4_5
= target
->arch_info
;
615 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
616 arm_jtag_t
*jtag_info
= &arm7_9
->jtag_info
;
618 LOG_DEBUG("xpsr_im: %2.2x, rot: %i, spsr: %i", xpsr_im
, rot
, spsr
);
621 arm9tdmi_clock_out(jtag_info
, ARMV4_5_MSR_IM(xpsr_im
, rot
, 1, spsr
), 0, NULL
, 0);
622 /* NOP fetched, MSR in DECODE */
623 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
624 /* NOP fetched, MSR in EXECUTE (1) */
625 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
627 /* rot == 4 writes flags, which takes only one cycle */
630 /* nothing fetched, MSR in EXECUTE (2) */
631 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
632 /* nothing fetched, MSR in EXECUTE (3) */
633 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
637 void arm9tdmi_write_core_regs(target_t
*target
, u32 mask
, u32 core_regs
[16])
640 /* get pointers to arch-specific information */
641 armv4_5_common_t
*armv4_5
= target
->arch_info
;
642 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
643 arm_jtag_t
*jtag_info
= &arm7_9
->jtag_info
;
645 /* LDMIA r0-15, [r0] at debug speed
646 * register values will start to appear on 4th DCLK
648 arm9tdmi_clock_out(jtag_info
, ARMV4_5_LDMIA(0, mask
& 0xffff, 0, 0), 0, NULL
, 0);
650 /* fetch NOP, LDM in DECODE stage */
651 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
652 /* fetch NOP, LDM in EXECUTE stage (1st cycle) */
653 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
655 for (i
= 0; i
<= 15; i
++)
658 /* nothing fetched, LDM still in EXECUTE (1+i cycle) */
659 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, core_regs
[i
], NULL
, 0);
661 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
664 void arm9tdmi_load_word_regs(target_t
*target
, u32 mask
)
666 /* get pointers to arch-specific information */
667 armv4_5_common_t
*armv4_5
= target
->arch_info
;
668 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
669 arm_jtag_t
*jtag_info
= &arm7_9
->jtag_info
;
671 /* put system-speed load-multiple into the pipeline */
672 arm9tdmi_clock_out(jtag_info
, ARMV4_5_LDMIA(0, mask
& 0xffff, 0, 1), 0, NULL
, 0);
673 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 1);
676 void arm9tdmi_load_hword_reg(target_t
*target
, int num
)
678 /* get pointers to arch-specific information */
679 armv4_5_common_t
*armv4_5
= target
->arch_info
;
680 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
681 arm_jtag_t
*jtag_info
= &arm7_9
->jtag_info
;
683 /* put system-speed load half-word into the pipeline */
684 arm9tdmi_clock_out(jtag_info
, ARMV4_5_LDRH_IP(num
, 0), 0, NULL
, 0);
685 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 1);
688 void arm9tdmi_load_byte_reg(target_t
*target
, int num
)
690 /* get pointers to arch-specific information */
691 armv4_5_common_t
*armv4_5
= target
->arch_info
;
692 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
693 arm_jtag_t
*jtag_info
= &arm7_9
->jtag_info
;
695 /* put system-speed load byte into the pipeline */
696 arm9tdmi_clock_out(jtag_info
, ARMV4_5_LDRB_IP(num
, 0), 0, NULL
, 0);
697 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 1);
700 void arm9tdmi_store_word_regs(target_t
*target
, u32 mask
)
702 /* get pointers to arch-specific information */
703 armv4_5_common_t
*armv4_5
= target
->arch_info
;
704 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
705 arm_jtag_t
*jtag_info
= &arm7_9
->jtag_info
;
707 /* put system-speed store-multiple into the pipeline */
708 arm9tdmi_clock_out(jtag_info
, ARMV4_5_STMIA(0, mask
, 0, 1), 0, NULL
, 0);
709 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 1);
712 void arm9tdmi_store_hword_reg(target_t
*target
, int num
)
714 /* get pointers to arch-specific information */
715 armv4_5_common_t
*armv4_5
= target
->arch_info
;
716 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
717 arm_jtag_t
*jtag_info
= &arm7_9
->jtag_info
;
719 /* put system-speed store half-word into the pipeline */
720 arm9tdmi_clock_out(jtag_info
, ARMV4_5_STRH_IP(num
, 0), 0, NULL
, 0);
721 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 1);
724 void arm9tdmi_store_byte_reg(target_t
*target
, int num
)
726 /* get pointers to arch-specific information */
727 armv4_5_common_t
*armv4_5
= target
->arch_info
;
728 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
729 arm_jtag_t
*jtag_info
= &arm7_9
->jtag_info
;
731 /* put system-speed store byte into the pipeline */
732 arm9tdmi_clock_out(jtag_info
, ARMV4_5_STRB_IP(num
, 0), 0, NULL
, 0);
733 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 1);
736 void arm9tdmi_write_pc(target_t
*target
, u32 pc
)
738 /* get pointers to arch-specific information */
739 armv4_5_common_t
*armv4_5
= target
->arch_info
;
740 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
741 arm_jtag_t
*jtag_info
= &arm7_9
->jtag_info
;
743 /* LDMIA r0-15, [r0] at debug speed
744 * register values will start to appear on 4th DCLK
746 arm9tdmi_clock_out(jtag_info
, ARMV4_5_LDMIA(0, 0x8000, 0, 0), 0, NULL
, 0);
748 /* fetch NOP, LDM in DECODE stage */
749 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
750 /* fetch NOP, LDM in EXECUTE stage (1st cycle) */
751 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
752 /* nothing fetched, LDM in EXECUTE stage (2nd cycle) (output data) */
753 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, pc
, NULL
, 0);
754 /* nothing fetched, LDM in EXECUTE stage (3rd cycle) */
755 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
756 /* fetch NOP, LDM in EXECUTE stage (4th cycle) */
757 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
758 /* fetch NOP, LDM in EXECUTE stage (5th cycle) */
759 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
762 void arm9tdmi_branch_resume(target_t
*target
)
764 /* get pointers to arch-specific information */
765 armv4_5_common_t
*armv4_5
= target
->arch_info
;
766 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
767 arm_jtag_t
*jtag_info
= &arm7_9
->jtag_info
;
769 arm9tdmi_clock_out(jtag_info
, ARMV4_5_B(0xfffffc, 0), 0, NULL
, 0);
770 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 1);
773 void arm9tdmi_branch_resume_thumb(target_t
*target
)
777 /* get pointers to arch-specific information */
778 armv4_5_common_t
*armv4_5
= target
->arch_info
;
779 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
780 arm_jtag_t
*jtag_info
= &arm7_9
->jtag_info
;
781 reg_t
*dbg_stat
= &arm7_9
->eice_cache
->reg_list
[EICE_DBG_STAT
];
783 /* LDMIA r0-15, [r0] at debug speed
784 * register values will start to appear on 4th DCLK
786 arm9tdmi_clock_out(jtag_info
, ARMV4_5_LDMIA(0, 0x1, 0, 0), 0, NULL
, 0);
788 /* fetch NOP, LDM in DECODE stage */
789 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
790 /* fetch NOP, LDM in EXECUTE stage (1st cycle) */
791 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
792 /* nothing fetched, LDM in EXECUTE stage (2nd cycle) */
793 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32) | 1, NULL
, 0);
794 /* nothing fetched, LDM in EXECUTE stage (3rd cycle) */
795 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
797 /* Branch and eXchange */
798 arm9tdmi_clock_out(jtag_info
, ARMV4_5_BX(0), 0, NULL
, 0);
800 embeddedice_read_reg(dbg_stat
);
802 /* fetch NOP, BX in DECODE stage */
803 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
805 embeddedice_read_reg(dbg_stat
);
807 /* fetch NOP, BX in EXECUTE stage (1st cycle) */
808 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
810 /* target is now in Thumb state */
811 embeddedice_read_reg(dbg_stat
);
813 /* load r0 value, MOV_IM in Decode*/
814 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_LDR_PCREL(0), 0, NULL
, 0);
815 /* fetch NOP, LDR in Decode, MOV_IM in Execute */
816 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, 0, NULL
, 0);
817 /* fetch NOP, LDR in Execute */
818 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, 0, NULL
, 0);
819 /* nothing fetched, LDR in EXECUTE stage (2nd cycle) */
820 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, buf_get_u32(armv4_5
->core_cache
->reg_list
[0].value
, 0, 32), NULL
, 0);
821 /* nothing fetched, LDR in EXECUTE stage (3rd cycle) */
822 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, 0, NULL
, 0);
824 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, 0, NULL
, 0);
825 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, 0, NULL
, 0);
827 embeddedice_read_reg(dbg_stat
);
829 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_B(0x7f7), 0, NULL
, 1);
830 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, 0, NULL
, 0);
833 void arm9tdmi_enable_single_step(target_t
*target
, u32 next_pc
)
835 /* get pointers to arch-specific information */
836 armv4_5_common_t
*armv4_5
= target
->arch_info
;
837 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
839 if (arm7_9
->has_single_step
)
841 buf_set_u32(arm7_9
->eice_cache
->reg_list
[EICE_DBG_CTRL
].value
, 3, 1, 1);
842 embeddedice_store_reg(&arm7_9
->eice_cache
->reg_list
[EICE_DBG_CTRL
]);
846 arm7_9_enable_eice_step(target
, next_pc
);
850 void arm9tdmi_disable_single_step(target_t
*target
)
852 /* get pointers to arch-specific information */
853 armv4_5_common_t
*armv4_5
= target
->arch_info
;
854 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
856 if (arm7_9
->has_single_step
)
858 buf_set_u32(arm7_9
->eice_cache
->reg_list
[EICE_DBG_CTRL
].value
, 3, 1, 0);
859 embeddedice_store_reg(&arm7_9
->eice_cache
->reg_list
[EICE_DBG_CTRL
]);
863 arm7_9_disable_eice_step(target
);
867 void arm9tdmi_build_reg_cache(target_t
*target
)
869 reg_cache_t
**cache_p
= register_get_last_cache_p(&target
->reg_cache
);
870 /* get pointers to arch-specific information */
871 armv4_5_common_t
*armv4_5
= target
->arch_info
;
873 (*cache_p
) = armv4_5_build_reg_cache(target
, armv4_5
);
874 armv4_5
->core_cache
= (*cache_p
);
877 int arm9tdmi_examine(struct target_s
*target
)
879 /* get pointers to arch-specific information */
881 armv4_5_common_t
*armv4_5
= target
->arch_info
;
882 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
883 if (!target
->type
->examined
)
885 reg_cache_t
**cache_p
= register_get_last_cache_p(&target
->reg_cache
);
887 /* one extra register (vector catch) */
888 t
=embeddedice_build_reg_cache(target
, arm7_9
);
892 arm7_9
->eice_cache
= (*cache_p
);
896 arm_jtag_t
*jtag_info
= &arm7_9
->jtag_info
;
897 (*cache_p
)->next
= etm_build_reg_cache(target
, jtag_info
, arm7_9
->etm_ctx
);
898 arm7_9
->etm_ctx
->reg_cache
= (*cache_p
)->next
;
900 target
->type
->examined
= 1;
902 if ((retval
=embeddedice_setup(target
))!=ERROR_OK
)
904 if ((retval
=arm7_9_setup(target
))!=ERROR_OK
)
908 if ((retval
=etm_setup(target
))!=ERROR_OK
)
914 int arm9tdmi_init_target(struct command_context_s
*cmd_ctx
, struct target_s
*target
)
917 arm9tdmi_build_reg_cache(target
);
922 int arm9tdmi_quit(void)
927 int arm9tdmi_init_arch_info(target_t
*target
, arm9tdmi_common_t
*arm9tdmi
, jtag_tap_t
*tap
)
929 armv4_5_common_t
*armv4_5
;
930 arm7_9_common_t
*arm7_9
;
932 arm7_9
= &arm9tdmi
->arm7_9_common
;
933 armv4_5
= &arm7_9
->armv4_5_common
;
935 /* prepare JTAG information for the new target */
936 arm7_9
->jtag_info
.tap
= tap
;
937 arm7_9
->jtag_info
.scann_size
= 5;
939 /* register arch-specific functions */
940 arm7_9
->examine_debug_reason
= arm9tdmi_examine_debug_reason
;
941 arm7_9
->change_to_arm
= arm9tdmi_change_to_arm
;
942 arm7_9
->read_core_regs
= arm9tdmi_read_core_regs
;
943 arm7_9
->read_core_regs_target_buffer
= arm9tdmi_read_core_regs_target_buffer
;
944 arm7_9
->read_xpsr
= arm9tdmi_read_xpsr
;
946 arm7_9
->write_xpsr
= arm9tdmi_write_xpsr
;
947 arm7_9
->write_xpsr_im8
= arm9tdmi_write_xpsr_im8
;
948 arm7_9
->write_core_regs
= arm9tdmi_write_core_regs
;
950 arm7_9
->load_word_regs
= arm9tdmi_load_word_regs
;
951 arm7_9
->load_hword_reg
= arm9tdmi_load_hword_reg
;
952 arm7_9
->load_byte_reg
= arm9tdmi_load_byte_reg
;
954 arm7_9
->store_word_regs
= arm9tdmi_store_word_regs
;
955 arm7_9
->store_hword_reg
= arm9tdmi_store_hword_reg
;
956 arm7_9
->store_byte_reg
= arm9tdmi_store_byte_reg
;
958 arm7_9
->write_pc
= arm9tdmi_write_pc
;
959 arm7_9
->branch_resume
= arm9tdmi_branch_resume
;
960 arm7_9
->branch_resume_thumb
= arm9tdmi_branch_resume_thumb
;
962 arm7_9
->enable_single_step
= arm9tdmi_enable_single_step
;
963 arm7_9
->disable_single_step
= arm9tdmi_disable_single_step
;
965 arm7_9
->pre_debug_entry
= NULL
;
966 arm7_9
->post_debug_entry
= NULL
;
968 arm7_9
->pre_restore_context
= NULL
;
969 arm7_9
->post_restore_context
= NULL
;
971 /* initialize arch-specific breakpoint handling */
972 arm7_9
->arm_bkpt
= 0xdeeedeee;
973 arm7_9
->thumb_bkpt
= 0xdeee;
975 arm7_9
->dbgreq_adjust_pc
= 3;
976 arm7_9
->arch_info
= arm9tdmi
;
978 arm9tdmi
->common_magic
= ARM9TDMI_COMMON_MAGIC
;
979 arm9tdmi
->arch_info
= NULL
;
981 arm7_9_init_arch_info(target
, arm7_9
);
983 /* override use of DBGRQ, this is safe on ARM9TDMI */
984 arm7_9
->use_dbgrq
= 1;
986 /* all ARM9s have the vector catch register */
987 arm7_9
->has_vector_catch
= 1;
992 int arm9tdmi_get_arch_pointers(target_t
*target
, armv4_5_common_t
**armv4_5_p
, arm7_9_common_t
**arm7_9_p
, arm9tdmi_common_t
**arm9tdmi_p
)
994 armv4_5_common_t
*armv4_5
= target
->arch_info
;
995 arm7_9_common_t
*arm7_9
;
996 arm9tdmi_common_t
*arm9tdmi
;
998 if (armv4_5
->common_magic
!= ARMV4_5_COMMON_MAGIC
)
1003 arm7_9
= armv4_5
->arch_info
;
1004 if (arm7_9
->common_magic
!= ARM7_9_COMMON_MAGIC
)
1009 arm9tdmi
= arm7_9
->arch_info
;
1010 if (arm9tdmi
->common_magic
!= ARM9TDMI_COMMON_MAGIC
)
1015 *armv4_5_p
= armv4_5
;
1017 *arm9tdmi_p
= arm9tdmi
;
1022 int arm9tdmi_target_create(struct target_s
*target
, Jim_Interp
*interp
)
1024 arm9tdmi_common_t
*arm9tdmi
= calloc(1,sizeof(arm9tdmi_common_t
));
1026 arm9tdmi_init_arch_info(target
, arm9tdmi
, target
->tap
);
1031 int arm9tdmi_register_commands(struct command_context_s
*cmd_ctx
)
1034 command_t
*arm9tdmi_cmd
;
1036 retval
= arm7_9_register_commands(cmd_ctx
);
1037 arm9tdmi_cmd
= register_command(cmd_ctx
, NULL
, "arm9tdmi", NULL
, COMMAND_ANY
, "arm9tdmi specific commands");
1038 register_command(cmd_ctx
, arm9tdmi_cmd
, "vector_catch", handle_arm9tdmi_catch_vectors_command
, COMMAND_EXEC
, "catch arm920t vectors ['all'|'none'|'<vec1 vec2 ...>']");
1043 int handle_arm9tdmi_catch_vectors_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1045 target_t
*target
= get_current_target(cmd_ctx
);
1046 armv4_5_common_t
*armv4_5
;
1047 arm7_9_common_t
*arm7_9
;
1048 arm9tdmi_common_t
*arm9tdmi
;
1049 reg_t
*vector_catch
;
1050 u32 vector_catch_value
;
1053 if (arm9tdmi_get_arch_pointers(target
, &armv4_5
, &arm7_9
, &arm9tdmi
) != ERROR_OK
)
1055 command_print(cmd_ctx
, "current target isn't an ARM9TDMI based target");
1059 vector_catch
= &arm7_9
->eice_cache
->reg_list
[EICE_VEC_CATCH
];
1061 /* read the vector catch register if necessary */
1062 if (!vector_catch
->valid
)
1063 embeddedice_read_reg(vector_catch
);
1065 /* get the current setting */
1066 vector_catch_value
= buf_get_u32(vector_catch
->value
, 0, 32);
1070 vector_catch_value
= 0x0;
1071 if (strcmp(args
[0], "all") == 0)
1073 vector_catch_value
= 0xdf;
1075 else if (strcmp(args
[0], "none") == 0)
1081 for (i
= 0; i
< argc
; i
++)
1083 /* go through list of vectors */
1084 for(j
= 0; arm9tdmi_vectors
[j
].name
; j
++)
1086 if (strcmp(args
[i
], arm9tdmi_vectors
[j
].name
) == 0)
1088 vector_catch_value
|= arm9tdmi_vectors
[j
].value
;
1093 /* complain if vector wasn't found */
1094 if (!arm9tdmi_vectors
[j
].name
)
1096 command_print(cmd_ctx
, "vector '%s' not found, leaving current setting unchanged", args
[i
]);
1098 /* reread current setting */
1099 vector_catch_value
= buf_get_u32(vector_catch
->value
, 0, 32);
1106 /* store new settings */
1107 buf_set_u32(vector_catch
->value
, 0, 32, vector_catch_value
);
1108 embeddedice_store_reg(vector_catch
);
1111 /* output current settings (skip RESERVED vector) */
1112 for (i
= 0; i
< 8; i
++)
1116 command_print(cmd_ctx
, "%s: %s", arm9tdmi_vectors
[i
].name
,
1117 (vector_catch_value
& (1 << i
)) ? "catch" : "don't catch");
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)