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

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)