more in_handler typo fixes
[openocd.git] / src / target / arm9tdmi.c
1 /***************************************************************************
2 * Copyright (C) 2005 by Dominic Rath *
3 * Dominic.Rath@gmx.de *
4 * *
5 * Copyright (C) 2008 by Spencer Oliver *
6 * spen@spen-soft.co.uk *
7 * *
8 * Copyright (C) 2008 by Hongtao Zheng *
9 * hontor@126.com *
10 * *
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. *
15 * *
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. *
20 * *
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 ***************************************************************************/
26 #ifdef HAVE_CONFIG_H
27 #include "config.h"
28 #endif
29
30 #include "arm9tdmi.h"
31
32 #include "arm7_9_common.h"
33 #include "register.h"
34 #include "target.h"
35 #include "armv4_5.h"
36 #include "embeddedice.h"
37 #include "etm.h"
38 #include "etb.h"
39 #include "log.h"
40 #include "jtag.h"
41 #include "arm_jtag.h"
42
43 #include <stdlib.h>
44 #include <string.h>
45
46 #if 0
47 #define _DEBUG_INSTRUCTION_EXECUTION_
48 #endif
49
50 /* cli handling */
51 int handle_arm9tdmi_catch_vectors_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
52
53 /* forward declarations */
54 int arm9tdmi_target_create( struct target_s *target, Jim_Interp *interp );
55
56 int arm9tdmi_quit(void);
57
58 target_type_t arm9tdmi_target =
59 {
60 .name = "arm9tdmi",
61
62 .poll = arm7_9_poll,
63 .arch_state = armv4_5_arch_state,
64
65 .target_request_data = arm7_9_target_request_data,
66
67 .halt = arm7_9_halt,
68 .resume = arm7_9_resume,
69 .step = arm7_9_step,
70
71 .assert_reset = arm7_9_assert_reset,
72 .deassert_reset = arm7_9_deassert_reset,
73 .soft_reset_halt = arm7_9_soft_reset_halt,
74
75 .get_gdb_reg_list = armv4_5_get_gdb_reg_list,
76
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,
82
83 .run_algorithm = armv4_5_run_algorithm,
84
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,
89
90 .register_commands = arm9tdmi_register_commands,
91 .target_create = arm9tdmi_target_create,
92 .init_target = arm9tdmi_init_target,
93 .examine = arm9tdmi_examine,
94 .quit = arm9tdmi_quit
95 };
96
97 arm9tdmi_vector_t arm9tdmi_vectors[] =
98 {
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},
107 {0, 0},
108 };
109
110 int arm9tdmi_examine_debug_reason(target_t *target)
111 {
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;
116
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))
120 {
121 scan_field_t fields[3];
122 u8 databus[4];
123 u8 instructionbus[4];
124 u8 debug_reason;
125
126 jtag_add_end_state(TAP_DRPAUSE);
127
128 fields[0].tap = arm7_9->jtag_info.tap;
129 fields[0].num_bits = 32;
130 fields[0].out_value = NULL;
131
132 fields[0].in_value = databus;
133
134
135 fields[0].in_handler = NULL;
136
137
138 fields[1].tap = arm7_9->jtag_info.tap;
139 fields[1].num_bits = 3;
140 fields[1].out_value = NULL;
141
142 fields[1].in_value = &debug_reason;
143
144
145 fields[1].in_handler = NULL;
146
147
148 fields[2].tap = arm7_9->jtag_info.tap;
149 fields[2].num_bits = 32;
150 fields[2].out_value = NULL;
151
152 fields[2].in_value = instructionbus;
153
154
155 fields[2].in_handler = NULL;
156
157
158 if((retval = arm_jtag_scann(&arm7_9->jtag_info, 0x1)) != ERROR_OK)
159 {
160 return retval;
161 }
162 arm_jtag_set_instr(&arm7_9->jtag_info, arm7_9->jtag_info.intest_instr, NULL);
163
164 jtag_add_dr_scan(3, fields, TAP_DRPAUSE);
165 if((retval = jtag_execute_queue()) != ERROR_OK)
166 {
167 return retval;
168 }
169
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;
176
177 jtag_add_dr_scan(3, fields, TAP_DRPAUSE);
178
179 if (debug_reason & 0x4)
180 if (debug_reason & 0x2)
181 target->debug_reason = DBG_REASON_WPTANDBKPT;
182 else
183 target->debug_reason = DBG_REASON_WATCHPOINT;
184 else
185 target->debug_reason = DBG_REASON_BREAKPOINT;
186 }
187
188 return ERROR_OK;
189 }
190
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)
193 {
194 int retval = ERROR_OK;
195 scan_field_t fields[3];
196 u8 out_buf[4];
197 u8 instr_buf[4];
198 u8 sysspeed_buf = 0x0;
199
200 /* prepare buffer */
201 buf_set_u32(out_buf, 0, 32, out);
202
203 buf_set_u32(instr_buf, 0, 32, flip_u32(instr, 32));
204
205 if (sysspeed)
206 buf_set_u32(&sysspeed_buf, 2, 1, 1);
207
208 jtag_add_end_state(TAP_DRPAUSE);
209 if((retval = arm_jtag_scann(jtag_info, 0x1)) != ERROR_OK)
210 {
211 return retval;
212 }
213
214 arm_jtag_set_instr(jtag_info, jtag_info->intest_instr, NULL);
215
216 fields[0].tap = jtag_info->tap;
217 fields[0].num_bits = 32;
218 fields[0].out_value = out_buf;
219 fields[0].in_value = NULL;
220 fields[0].in_handler = NULL;
221
222 fields[1].tap = jtag_info->tap;
223 fields[1].num_bits = 3;
224 fields[1].out_value = &sysspeed_buf;
225 fields[1].in_value = NULL;
226 fields[1].in_handler = NULL;
227
228
229 fields[2].tap = jtag_info->tap;
230 fields[2].num_bits = 32;
231 fields[2].out_value = instr_buf;
232 fields[2].in_value = NULL;
233 fields[2].in_handler = NULL;
234
235 if (in)
236 {
237 u8 tmp[4];
238 fields[0].in_value=tmp;
239 jtag_add_dr_scan_now(3, fields, TAP_INVALID);
240
241 *in=le_to_h_u32(tmp);
242 }
243 else
244 {
245 jtag_add_dr_scan(3, fields, TAP_INVALID);
246 }
247
248 jtag_add_runtest(0, TAP_INVALID);
249
250 #ifdef _DEBUG_INSTRUCTION_EXECUTION_
251 {
252 if((retval = jtag_execute_queue()) != ERROR_OK)
253 {
254 return retval;
255 }
256
257 if (in)
258 {
259 LOG_DEBUG("instr: 0x%8.8x, out: 0x%8.8x, in: 0x%8.8x", instr, out, *in);
260 }
261 else
262 LOG_DEBUG("instr: 0x%8.8x, out: 0x%8.8x", instr, out);
263 }
264 #endif
265
266 return ERROR_OK;
267 }
268
269 /* just read data (instruction and data-out = don't care) */
270 int arm9tdmi_clock_data_in(arm_jtag_t *jtag_info, u32 *in)
271 {
272 int retval = ERROR_OK;;
273 scan_field_t fields[3];
274
275 jtag_add_end_state(TAP_DRPAUSE);
276 if((retval = arm_jtag_scann(jtag_info, 0x1)) != ERROR_OK)
277 {
278 return retval;
279 }
280
281 arm_jtag_set_instr(jtag_info, jtag_info->intest_instr, NULL);
282
283 fields[0].tap = jtag_info->tap;
284 fields[0].num_bits = 32;
285 fields[0].out_value = NULL;
286 u8 tmp[4];
287 fields[0].in_value = tmp;
288 fields[0].in_handler = NULL;
289
290 fields[1].tap = jtag_info->tap;
291 fields[1].num_bits = 3;
292 fields[1].out_value = NULL;
293 fields[1].in_value = NULL;
294 fields[1].in_handler = NULL;
295
296 fields[2].tap = jtag_info->tap;
297 fields[2].num_bits = 32;
298 fields[2].out_value = NULL;
299 fields[2].in_value = NULL;
300 fields[2].in_handler = NULL;
301
302 jtag_add_dr_scan_now(3, fields, TAP_INVALID);
303
304 *in=le_to_h_u32(tmp);
305
306 jtag_add_runtest(0, TAP_INVALID);
307
308 #ifdef _DEBUG_INSTRUCTION_EXECUTION_
309 {
310 if((retval = jtag_execute_queue()) != ERROR_OK)
311 {
312 return retval;
313 }
314
315 if (in)
316 {
317 LOG_DEBUG("in: 0x%8.8x", *in);
318 }
319 else
320 {
321 LOG_ERROR("BUG: called with in == NULL");
322 }
323 }
324 #endif
325
326 return ERROR_OK;
327 }
328
329 extern void arm_endianness(u8 *tmp, void *in, int size, int be, int flip);
330
331 /* clock the target, and read the databus
332 * the *in pointer points to a buffer where elements of 'size' bytes
333 * are stored in big (be==1) or little (be==0) endianness
334 */
335 int arm9tdmi_clock_data_in_endianness(arm_jtag_t *jtag_info, void *in, int size, int be)
336 {
337 int retval = ERROR_OK;
338 scan_field_t fields[3];
339
340 jtag_add_end_state(TAP_DRPAUSE);
341 if((retval = arm_jtag_scann(jtag_info, 0x1)) != ERROR_OK)
342 {
343 return retval;
344 }
345
346 arm_jtag_set_instr(jtag_info, jtag_info->intest_instr, NULL);
347
348 fields[0].tap = jtag_info->tap;
349 fields[0].num_bits = 32;
350 fields[0].out_value = NULL;
351 u8 tmp[4];
352 fields[0].in_value = tmp;
353 fields[0].in_handler = NULL;
354
355 fields[1].tap = jtag_info->tap;
356 fields[1].num_bits = 3;
357 fields[1].out_value = NULL;
358 fields[1].in_value = NULL;
359 fields[1].in_handler = NULL;
360
361 fields[2].tap = jtag_info->tap;
362 fields[2].num_bits = 32;
363 fields[2].out_value = NULL;
364 fields[2].in_value = NULL;
365 fields[2].in_handler = NULL;
366
367 jtag_add_dr_scan_now(3, fields, TAP_INVALID);
368
369 arm_endianness(tmp, in, size, be, 0);
370
371
372 jtag_add_runtest(0, TAP_INVALID);
373
374 #ifdef _DEBUG_INSTRUCTION_EXECUTION_
375 {
376 if((retval = jtag_execute_queue()) != ERROR_OK)
377 {
378 return retval;
379 }
380
381 if (in)
382 {
383 LOG_DEBUG("in: 0x%8.8x", *(u32*)in);
384 }
385 else
386 {
387 LOG_ERROR("BUG: called with in == NULL");
388 }
389 }
390 #endif
391
392 return ERROR_OK;
393 }
394
395 void arm9tdmi_change_to_arm(target_t *target, u32 *r0, u32 *pc)
396 {
397 int retval = ERROR_OK;
398 /* get pointers to arch-specific information */
399 armv4_5_common_t *armv4_5 = target->arch_info;
400 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
401 arm_jtag_t *jtag_info = &arm7_9->jtag_info;
402
403 /* save r0 before using it and put system in ARM state
404 * to allow common handling of ARM and THUMB debugging */
405
406 /* fetch STR r0, [r0] */
407 arm9tdmi_clock_out(jtag_info, ARMV4_5_T_STR(0, 0), 0, NULL, 0);
408 arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0);
409 arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0);
410 /* STR r0, [r0] in Memory */
411 arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, r0, 0);
412
413 /* MOV r0, r15 fetched, STR in Decode */
414 arm9tdmi_clock_out(jtag_info, ARMV4_5_T_MOV(0, 15), 0, NULL, 0);
415 arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0);
416 arm9tdmi_clock_out(jtag_info, ARMV4_5_T_STR(0, 0), 0, NULL, 0);
417 arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0);
418 arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0);
419 /* nothing fetched, STR r0, [r0] in Memory */
420 arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, pc, 0);
421
422 /* use pc-relative LDR to clear r0[1:0] (for switch to ARM mode) */
423 arm9tdmi_clock_out(jtag_info, ARMV4_5_T_LDR_PCREL(0), 0, NULL, 0);
424 /* LDR in Decode */
425 arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0);
426 /* LDR in Execute */
427 arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0);
428 /* LDR in Memory (to account for interlock) */
429 arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0);
430
431 /* fetch BX */
432 arm9tdmi_clock_out(jtag_info, ARMV4_5_T_BX(0), 0, NULL, 0);
433 /* NOP fetched, BX in Decode, MOV in Execute */
434 arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0);
435 /* NOP fetched, BX in Execute (1) */
436 arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0);
437
438 if((retval = jtag_execute_queue()) != ERROR_OK)
439 {
440 return;
441 }
442
443 /* fix program counter:
444 * MOV r0, r15 was the 5th instruction (+8)
445 * reading PC in Thumb state gives address of instruction + 4
446 */
447 *pc -= 0xc;
448 }
449
450 void arm9tdmi_read_core_regs(target_t *target, u32 mask, u32* core_regs[16])
451 {
452 int i;
453 /* get pointers to arch-specific information */
454 armv4_5_common_t *armv4_5 = target->arch_info;
455 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
456 arm_jtag_t *jtag_info = &arm7_9->jtag_info;
457
458 /* STMIA r0-15, [r0] at debug speed
459 * register values will start to appear on 4th DCLK
460 */
461 arm9tdmi_clock_out(jtag_info, ARMV4_5_STMIA(0, mask & 0xffff, 0, 0), 0, NULL, 0);
462
463 /* fetch NOP, STM in DECODE stage */
464 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
465 /* fetch NOP, STM in EXECUTE stage (1st cycle) */
466 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
467
468 for (i = 0; i <= 15; i++)
469 {
470 if (mask & (1 << i))
471 /* nothing fetched, STM in MEMORY (i'th cycle) */
472 arm9tdmi_clock_data_in(jtag_info, core_regs[i]);
473 }
474 }
475
476 void arm9tdmi_read_core_regs_target_buffer(target_t *target, u32 mask, void* buffer, int size)
477 {
478 int i;
479 /* get pointers to arch-specific information */
480 armv4_5_common_t *armv4_5 = target->arch_info;
481 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
482 arm_jtag_t *jtag_info = &arm7_9->jtag_info;
483 int be = (target->endianness == TARGET_BIG_ENDIAN) ? 1 : 0;
484 u32 *buf_u32 = buffer;
485 u16 *buf_u16 = buffer;
486 u8 *buf_u8 = buffer;
487
488 /* STMIA r0-15, [r0] at debug speed
489 * register values will start to appear on 4th DCLK
490 */
491 arm9tdmi_clock_out(jtag_info, ARMV4_5_STMIA(0, mask & 0xffff, 0, 0), 0, NULL, 0);
492
493 /* fetch NOP, STM in DECODE stage */
494 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
495 /* fetch NOP, STM in EXECUTE stage (1st cycle) */
496 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
497
498 for (i = 0; i <= 15; i++)
499 {
500 if (mask & (1 << i))
501 /* nothing fetched, STM in MEMORY (i'th cycle) */
502 switch (size)
503 {
504 case 4:
505 arm9tdmi_clock_data_in_endianness(jtag_info, buf_u32++, 4, be);
506 break;
507 case 2:
508 arm9tdmi_clock_data_in_endianness(jtag_info, buf_u16++, 2, be);
509 break;
510 case 1:
511 arm9tdmi_clock_data_in_endianness(jtag_info, buf_u8++, 1, be);
512 break;
513 }
514 }
515 }
516
517 void arm9tdmi_read_xpsr(target_t *target, u32 *xpsr, int spsr)
518 {
519 /* get pointers to arch-specific information */
520 armv4_5_common_t *armv4_5 = target->arch_info;
521 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
522 arm_jtag_t *jtag_info = &arm7_9->jtag_info;
523
524 /* MRS r0, cpsr */
525 arm9tdmi_clock_out(jtag_info, ARMV4_5_MRS(0, spsr & 1), 0, NULL, 0);
526 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
527 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
528 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
529 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
530
531 /* STR r0, [r15] */
532 arm9tdmi_clock_out(jtag_info, ARMV4_5_STR(0, 15), 0, NULL, 0);
533 /* fetch NOP, STR in DECODE stage */
534 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
535 /* fetch NOP, STR in EXECUTE stage (1st cycle) */
536 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
537 /* nothing fetched, STR in MEMORY */
538 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, xpsr, 0);
539 }
540
541 void arm9tdmi_write_xpsr(target_t *target, u32 xpsr, int spsr)
542 {
543 /* get pointers to arch-specific information */
544 armv4_5_common_t *armv4_5 = target->arch_info;
545 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
546 arm_jtag_t *jtag_info = &arm7_9->jtag_info;
547
548 LOG_DEBUG("xpsr: %8.8x, spsr: %i", xpsr, spsr);
549
550 /* MSR1 fetched */
551 arm9tdmi_clock_out(jtag_info, ARMV4_5_MSR_IM(xpsr & 0xff, 0, 1, spsr), 0, NULL, 0);
552 /* MSR2 fetched, MSR1 in DECODE */
553 arm9tdmi_clock_out(jtag_info, ARMV4_5_MSR_IM((xpsr & 0xff00) >> 8, 0xc, 2, spsr), 0, NULL, 0);
554 /* MSR3 fetched, MSR1 in EXECUTE (1), MSR2 in DECODE */
555 arm9tdmi_clock_out(jtag_info, ARMV4_5_MSR_IM((xpsr & 0xff0000) >> 16, 0x8, 4, spsr), 0, NULL, 0);
556 /* nothing fetched, MSR1 in EXECUTE (2) */
557 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
558 /* nothing fetched, MSR1 in EXECUTE (3) */
559 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
560 /* MSR4 fetched, MSR2 in EXECUTE (1), MSR3 in DECODE */
561 arm9tdmi_clock_out(jtag_info, ARMV4_5_MSR_IM((xpsr & 0xff000000) >> 24, 0x4, 8, spsr), 0, NULL, 0);
562 /* nothing fetched, MSR2 in EXECUTE (2) */
563 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
564 /* nothing fetched, MSR2 in EXECUTE (3) */
565 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
566 /* NOP fetched, MSR3 in EXECUTE (1), MSR4 in DECODE */
567 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
568 /* nothing fetched, MSR3 in EXECUTE (2) */
569 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
570 /* nothing fetched, MSR3 in EXECUTE (3) */
571 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
572 /* NOP fetched, MSR4 in EXECUTE (1) */
573 /* last MSR writes flags, which takes only one cycle */
574 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
575 }
576
577 void arm9tdmi_write_xpsr_im8(target_t *target, u8 xpsr_im, int rot, int spsr)
578 {
579 /* get pointers to arch-specific information */
580 armv4_5_common_t *armv4_5 = target->arch_info;
581 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
582 arm_jtag_t *jtag_info = &arm7_9->jtag_info;
583
584 LOG_DEBUG("xpsr_im: %2.2x, rot: %i, spsr: %i", xpsr_im, rot, spsr);
585
586 /* MSR fetched */
587 arm9tdmi_clock_out(jtag_info, ARMV4_5_MSR_IM(xpsr_im, rot, 1, spsr), 0, NULL, 0);
588 /* NOP fetched, MSR in DECODE */
589 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
590 /* NOP fetched, MSR in EXECUTE (1) */
591 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
592
593 /* rot == 4 writes flags, which takes only one cycle */
594 if (rot != 4)
595 {
596 /* nothing fetched, MSR in EXECUTE (2) */
597 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
598 /* nothing fetched, MSR in EXECUTE (3) */
599 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
600 }
601 }
602
603 void arm9tdmi_write_core_regs(target_t *target, u32 mask, u32 core_regs[16])
604 {
605 int i;
606 /* get pointers to arch-specific information */
607 armv4_5_common_t *armv4_5 = target->arch_info;
608 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
609 arm_jtag_t *jtag_info = &arm7_9->jtag_info;
610
611 /* LDMIA r0-15, [r0] at debug speed
612 * register values will start to appear on 4th DCLK
613 */
614 arm9tdmi_clock_out(jtag_info, ARMV4_5_LDMIA(0, mask & 0xffff, 0, 0), 0, NULL, 0);
615
616 /* fetch NOP, LDM in DECODE stage */
617 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
618 /* fetch NOP, LDM in EXECUTE stage (1st cycle) */
619 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
620
621 for (i = 0; i <= 15; i++)
622 {
623 if (mask & (1 << i))
624 /* nothing fetched, LDM still in EXECUTE (1+i cycle) */
625 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, core_regs[i], NULL, 0);
626 }
627 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
628 }
629
630 void arm9tdmi_load_word_regs(target_t *target, u32 mask)
631 {
632 /* get pointers to arch-specific information */
633 armv4_5_common_t *armv4_5 = target->arch_info;
634 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
635 arm_jtag_t *jtag_info = &arm7_9->jtag_info;
636
637 /* put system-speed load-multiple into the pipeline */
638 arm9tdmi_clock_out(jtag_info, ARMV4_5_LDMIA(0, mask & 0xffff, 0, 1), 0, NULL, 0);
639 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 1);
640 }
641
642 void arm9tdmi_load_hword_reg(target_t *target, int num)
643 {
644 /* get pointers to arch-specific information */
645 armv4_5_common_t *armv4_5 = target->arch_info;
646 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
647 arm_jtag_t *jtag_info = &arm7_9->jtag_info;
648
649 /* put system-speed load half-word into the pipeline */
650 arm9tdmi_clock_out(jtag_info, ARMV4_5_LDRH_IP(num, 0), 0, NULL, 0);
651 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 1);
652 }
653
654 void arm9tdmi_load_byte_reg(target_t *target, int num)
655 {
656 /* get pointers to arch-specific information */
657 armv4_5_common_t *armv4_5 = target->arch_info;
658 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
659 arm_jtag_t *jtag_info = &arm7_9->jtag_info;
660
661 /* put system-speed load byte into the pipeline */
662 arm9tdmi_clock_out(jtag_info, ARMV4_5_LDRB_IP(num, 0), 0, NULL, 0);
663 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 1);
664 }
665
666 void arm9tdmi_store_word_regs(target_t *target, u32 mask)
667 {
668 /* get pointers to arch-specific information */
669 armv4_5_common_t *armv4_5 = target->arch_info;
670 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
671 arm_jtag_t *jtag_info = &arm7_9->jtag_info;
672
673 /* put system-speed store-multiple into the pipeline */
674 arm9tdmi_clock_out(jtag_info, ARMV4_5_STMIA(0, mask, 0, 1), 0, NULL, 0);
675 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 1);
676 }
677
678 void arm9tdmi_store_hword_reg(target_t *target, int num)
679 {
680 /* get pointers to arch-specific information */
681 armv4_5_common_t *armv4_5 = target->arch_info;
682 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
683 arm_jtag_t *jtag_info = &arm7_9->jtag_info;
684
685 /* put system-speed store half-word into the pipeline */
686 arm9tdmi_clock_out(jtag_info, ARMV4_5_STRH_IP(num, 0), 0, NULL, 0);
687 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 1);
688 }
689
690 void arm9tdmi_store_byte_reg(target_t *target, int num)
691 {
692 /* get pointers to arch-specific information */
693 armv4_5_common_t *armv4_5 = target->arch_info;
694 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
695 arm_jtag_t *jtag_info = &arm7_9->jtag_info;
696
697 /* put system-speed store byte into the pipeline */
698 arm9tdmi_clock_out(jtag_info, ARMV4_5_STRB_IP(num, 0), 0, NULL, 0);
699 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 1);
700 }
701
702 void arm9tdmi_write_pc(target_t *target, u32 pc)
703 {
704 /* get pointers to arch-specific information */
705 armv4_5_common_t *armv4_5 = target->arch_info;
706 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
707 arm_jtag_t *jtag_info = &arm7_9->jtag_info;
708
709 /* LDMIA r0-15, [r0] at debug speed
710 * register values will start to appear on 4th DCLK
711 */
712 arm9tdmi_clock_out(jtag_info, ARMV4_5_LDMIA(0, 0x8000, 0, 0), 0, NULL, 0);
713
714 /* fetch NOP, LDM in DECODE stage */
715 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
716 /* fetch NOP, LDM in EXECUTE stage (1st cycle) */
717 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
718 /* nothing fetched, LDM in EXECUTE stage (2nd cycle) (output data) */
719 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, pc, NULL, 0);
720 /* nothing fetched, LDM in EXECUTE stage (3rd cycle) */
721 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
722 /* fetch NOP, LDM in EXECUTE stage (4th cycle) */
723 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
724 /* fetch NOP, LDM in EXECUTE stage (5th cycle) */
725 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
726 }
727
728 void arm9tdmi_branch_resume(target_t *target)
729 {
730 /* get pointers to arch-specific information */
731 armv4_5_common_t *armv4_5 = target->arch_info;
732 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
733 arm_jtag_t *jtag_info = &arm7_9->jtag_info;
734
735 arm9tdmi_clock_out(jtag_info, ARMV4_5_B(0xfffffc, 0), 0, NULL, 0);
736 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 1);
737 }
738
739 void arm9tdmi_branch_resume_thumb(target_t *target)
740 {
741 LOG_DEBUG("-");
742
743 /* get pointers to arch-specific information */
744 armv4_5_common_t *armv4_5 = target->arch_info;
745 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
746 arm_jtag_t *jtag_info = &arm7_9->jtag_info;
747 reg_t *dbg_stat = &arm7_9->eice_cache->reg_list[EICE_DBG_STAT];
748
749 /* LDMIA r0-15, [r0] at debug speed
750 * register values will start to appear on 4th DCLK
751 */
752 arm9tdmi_clock_out(jtag_info, ARMV4_5_LDMIA(0, 0x1, 0, 0), 0, NULL, 0);
753
754 /* fetch NOP, LDM in DECODE stage */
755 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
756 /* fetch NOP, LDM in EXECUTE stage (1st cycle) */
757 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
758 /* nothing fetched, LDM in EXECUTE stage (2nd cycle) */
759 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32) | 1, NULL, 0);
760 /* nothing fetched, LDM in EXECUTE stage (3rd cycle) */
761 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
762
763 /* Branch and eXchange */
764 arm9tdmi_clock_out(jtag_info, ARMV4_5_BX(0), 0, NULL, 0);
765
766 embeddedice_read_reg(dbg_stat);
767
768 /* fetch NOP, BX in DECODE stage */
769 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
770
771 embeddedice_read_reg(dbg_stat);
772
773 /* fetch NOP, BX in EXECUTE stage (1st cycle) */
774 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
775
776 /* target is now in Thumb state */
777 embeddedice_read_reg(dbg_stat);
778
779 /* load r0 value, MOV_IM in Decode*/
780 arm9tdmi_clock_out(jtag_info, ARMV4_5_T_LDR_PCREL(0), 0, NULL, 0);
781 /* fetch NOP, LDR in Decode, MOV_IM in Execute */
782 arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0);
783 /* fetch NOP, LDR in Execute */
784 arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0);
785 /* nothing fetched, LDR in EXECUTE stage (2nd cycle) */
786 arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, buf_get_u32(armv4_5->core_cache->reg_list[0].value, 0, 32), NULL, 0);
787 /* nothing fetched, LDR in EXECUTE stage (3rd cycle) */
788 arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0);
789
790 arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0);
791 arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0);
792
793 embeddedice_read_reg(dbg_stat);
794
795 arm9tdmi_clock_out(jtag_info, ARMV4_5_T_B(0x7f7), 0, NULL, 1);
796 arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0);
797 }
798
799 void arm9tdmi_enable_single_step(target_t *target, u32 next_pc)
800 {
801 /* get pointers to arch-specific information */
802 armv4_5_common_t *armv4_5 = target->arch_info;
803 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
804
805 if (arm7_9->has_single_step)
806 {
807 buf_set_u32(arm7_9->eice_cache->reg_list[EICE_DBG_CTRL].value, 3, 1, 1);
808 embeddedice_store_reg(&arm7_9->eice_cache->reg_list[EICE_DBG_CTRL]);
809 }
810 else
811 {
812 arm7_9_enable_eice_step(target, next_pc);
813 }
814 }
815
816 void arm9tdmi_disable_single_step(target_t *target)
817 {
818 /* get pointers to arch-specific information */
819 armv4_5_common_t *armv4_5 = target->arch_info;
820 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
821
822 if (arm7_9->has_single_step)
823 {
824 buf_set_u32(arm7_9->eice_cache->reg_list[EICE_DBG_CTRL].value, 3, 1, 0);
825 embeddedice_store_reg(&arm7_9->eice_cache->reg_list[EICE_DBG_CTRL]);
826 }
827 else
828 {
829 arm7_9_disable_eice_step(target);
830 }
831 }
832
833 void arm9tdmi_build_reg_cache(target_t *target)
834 {
835 reg_cache_t **cache_p = register_get_last_cache_p(&target->reg_cache);
836 /* get pointers to arch-specific information */
837 armv4_5_common_t *armv4_5 = target->arch_info;
838
839 (*cache_p) = armv4_5_build_reg_cache(target, armv4_5);
840 armv4_5->core_cache = (*cache_p);
841 }
842
843 int arm9tdmi_examine(struct target_s *target)
844 {
845 /* get pointers to arch-specific information */
846 int retval;
847 armv4_5_common_t *armv4_5 = target->arch_info;
848 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
849 if (!target->type->examined)
850 {
851 reg_cache_t **cache_p = register_get_last_cache_p(&target->reg_cache);
852 reg_cache_t *t;
853 /* one extra register (vector catch) */
854 t=embeddedice_build_reg_cache(target, arm7_9);
855 if (t==NULL)
856 return ERROR_FAIL;
857 (*cache_p) = t;
858 arm7_9->eice_cache = (*cache_p);
859
860 if (arm7_9->etm_ctx)
861 {
862 arm_jtag_t *jtag_info = &arm7_9->jtag_info;
863 (*cache_p)->next = etm_build_reg_cache(target, jtag_info, arm7_9->etm_ctx);
864 arm7_9->etm_ctx->reg_cache = (*cache_p)->next;
865 }
866 target->type->examined = 1;
867 }
868 if ((retval=embeddedice_setup(target))!=ERROR_OK)
869 return retval;
870 if ((retval=arm7_9_setup(target))!=ERROR_OK)
871 return retval;
872 if (arm7_9->etm_ctx)
873 {
874 if ((retval=etm_setup(target))!=ERROR_OK)
875 return retval;
876 }
877 return ERROR_OK;
878 }
879
880 int arm9tdmi_init_target(struct command_context_s *cmd_ctx, struct target_s *target)
881 {
882
883 arm9tdmi_build_reg_cache(target);
884
885 return ERROR_OK;
886 }
887
888 int arm9tdmi_quit(void)
889 {
890 return ERROR_OK;
891 }
892
893 int arm9tdmi_init_arch_info(target_t *target, arm9tdmi_common_t *arm9tdmi, jtag_tap_t *tap)
894 {
895 armv4_5_common_t *armv4_5;
896 arm7_9_common_t *arm7_9;
897
898 arm7_9 = &arm9tdmi->arm7_9_common;
899 armv4_5 = &arm7_9->armv4_5_common;
900
901 /* prepare JTAG information for the new target */
902 arm7_9->jtag_info.tap = tap;
903 arm7_9->jtag_info.scann_size = 5;
904
905 /* register arch-specific functions */
906 arm7_9->examine_debug_reason = arm9tdmi_examine_debug_reason;
907 arm7_9->change_to_arm = arm9tdmi_change_to_arm;
908 arm7_9->read_core_regs = arm9tdmi_read_core_regs;
909 arm7_9->read_core_regs_target_buffer = arm9tdmi_read_core_regs_target_buffer;
910 arm7_9->read_xpsr = arm9tdmi_read_xpsr;
911
912 arm7_9->write_xpsr = arm9tdmi_write_xpsr;
913 arm7_9->write_xpsr_im8 = arm9tdmi_write_xpsr_im8;
914 arm7_9->write_core_regs = arm9tdmi_write_core_regs;
915
916 arm7_9->load_word_regs = arm9tdmi_load_word_regs;
917 arm7_9->load_hword_reg = arm9tdmi_load_hword_reg;
918 arm7_9->load_byte_reg = arm9tdmi_load_byte_reg;
919
920 arm7_9->store_word_regs = arm9tdmi_store_word_regs;
921 arm7_9->store_hword_reg = arm9tdmi_store_hword_reg;
922 arm7_9->store_byte_reg = arm9tdmi_store_byte_reg;
923
924 arm7_9->write_pc = arm9tdmi_write_pc;
925 arm7_9->branch_resume = arm9tdmi_branch_resume;
926 arm7_9->branch_resume_thumb = arm9tdmi_branch_resume_thumb;
927
928 arm7_9->enable_single_step = arm9tdmi_enable_single_step;
929 arm7_9->disable_single_step = arm9tdmi_disable_single_step;
930
931 arm7_9->pre_debug_entry = NULL;
932 arm7_9->post_debug_entry = NULL;
933
934 arm7_9->pre_restore_context = NULL;
935 arm7_9->post_restore_context = NULL;
936
937 /* initialize arch-specific breakpoint handling */
938 arm7_9->arm_bkpt = 0xdeeedeee;
939 arm7_9->thumb_bkpt = 0xdeee;
940
941 arm7_9->dbgreq_adjust_pc = 3;
942 arm7_9->arch_info = arm9tdmi;
943
944 arm9tdmi->common_magic = ARM9TDMI_COMMON_MAGIC;
945 arm9tdmi->arch_info = NULL;
946
947 arm7_9_init_arch_info(target, arm7_9);
948
949 /* override use of DBGRQ, this is safe on ARM9TDMI */
950 arm7_9->use_dbgrq = 1;
951
952 /* all ARM9s have the vector catch register */
953 arm7_9->has_vector_catch = 1;
954
955 return ERROR_OK;
956 }
957
958 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)
959 {
960 armv4_5_common_t *armv4_5 = target->arch_info;
961 arm7_9_common_t *arm7_9;
962 arm9tdmi_common_t *arm9tdmi;
963
964 if (armv4_5->common_magic != ARMV4_5_COMMON_MAGIC)
965 {
966 return -1;
967 }
968
969 arm7_9 = armv4_5->arch_info;
970 if (arm7_9->common_magic != ARM7_9_COMMON_MAGIC)
971 {
972 return -1;
973 }
974
975 arm9tdmi = arm7_9->arch_info;
976 if (arm9tdmi->common_magic != ARM9TDMI_COMMON_MAGIC)
977 {
978 return -1;
979 }
980
981 *armv4_5_p = armv4_5;
982 *arm7_9_p = arm7_9;
983 *arm9tdmi_p = arm9tdmi;
984
985 return ERROR_OK;
986 }
987
988 int arm9tdmi_target_create(struct target_s *target, Jim_Interp *interp)
989 {
990 arm9tdmi_common_t *arm9tdmi = calloc(1,sizeof(arm9tdmi_common_t));
991
992 arm9tdmi_init_arch_info(target, arm9tdmi, target->tap);
993
994 return ERROR_OK;
995 }
996
997 int arm9tdmi_register_commands(struct command_context_s *cmd_ctx)
998 {
999 int retval;
1000 command_t *arm9tdmi_cmd;
1001
1002 retval = arm7_9_register_commands(cmd_ctx);
1003 arm9tdmi_cmd = register_command(cmd_ctx, NULL, "arm9tdmi", NULL, COMMAND_ANY, "arm9tdmi specific commands");
1004 register_command(cmd_ctx, arm9tdmi_cmd, "vector_catch", handle_arm9tdmi_catch_vectors_command, COMMAND_EXEC, "catch arm920t vectors ['all'|'none'|'<vec1 vec2 ...>']");
1005
1006 return retval;
1007 }
1008
1009 int handle_arm9tdmi_catch_vectors_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
1010 {
1011 target_t *target = get_current_target(cmd_ctx);
1012 armv4_5_common_t *armv4_5;
1013 arm7_9_common_t *arm7_9;
1014 arm9tdmi_common_t *arm9tdmi;
1015 reg_t *vector_catch;
1016 u32 vector_catch_value;
1017 int i, j;
1018
1019 if (arm9tdmi_get_arch_pointers(target, &armv4_5, &arm7_9, &arm9tdmi) != ERROR_OK)
1020 {
1021 command_print(cmd_ctx, "current target isn't an ARM9TDMI based target");
1022 return ERROR_OK;
1023 }
1024
1025 vector_catch = &arm7_9->eice_cache->reg_list[EICE_VEC_CATCH];
1026
1027 /* read the vector catch register if necessary */
1028 if (!vector_catch->valid)
1029 embeddedice_read_reg(vector_catch);
1030
1031 /* get the current setting */
1032 vector_catch_value = buf_get_u32(vector_catch->value, 0, 32);
1033
1034 if (argc > 0)
1035 {
1036 vector_catch_value = 0x0;
1037 if (strcmp(args[0], "all") == 0)
1038 {
1039 vector_catch_value = 0xdf;
1040 }
1041 else if (strcmp(args[0], "none") == 0)
1042 {
1043 /* do nothing */
1044 }
1045 else
1046 {
1047 for (i = 0; i < argc; i++)
1048 {
1049 /* go through list of vectors */
1050 for(j = 0; arm9tdmi_vectors[j].name; j++)
1051 {
1052 if (strcmp(args[i], arm9tdmi_vectors[j].name) == 0)
1053 {
1054 vector_catch_value |= arm9tdmi_vectors[j].value;
1055 break;
1056 }
1057 }
1058
1059 /* complain if vector wasn't found */
1060 if (!arm9tdmi_vectors[j].name)
1061 {
1062 command_print(cmd_ctx, "vector '%s' not found, leaving current setting unchanged", args[i]);
1063
1064 /* reread current setting */
1065 vector_catch_value = buf_get_u32(vector_catch->value, 0, 32);
1066
1067 break;
1068 }
1069 }
1070 }
1071
1072 /* store new settings */
1073 buf_set_u32(vector_catch->value, 0, 32, vector_catch_value);
1074 embeddedice_store_reg(vector_catch);
1075 }
1076
1077 /* output current settings (skip RESERVED vector) */
1078 for (i = 0; i < 8; i++)
1079 {
1080 if (i != 5)
1081 {
1082 command_print(cmd_ctx, "%s: %s", arm9tdmi_vectors[i].name,
1083 (vector_catch_value & (1 << i)) ? "catch" : "don't catch");
1084 }
1085 }
1086
1087 return ERROR_OK;
1088 }

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)