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

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)