more error handling
[openocd.git] / src / target / arm11.c
1 /***************************************************************************
2 * Copyright (C) 2008 digenius technology GmbH. *
3 * *
4 * Copyright (C) 2008 Oyvind Harboe oyvind.harboe@zylin.com *
5 * *
6 * Copyright (C) 2008 Georg Acher <acher@in.tum.de> *
7 * *
8 * This program is free software; you can redistribute it and/or modify *
9 * it under the terms of the GNU General Public License as published by *
10 * the Free Software Foundation; either version 2 of the License, or *
11 * (at your option) any later version. *
12 * *
13 * This program is distributed in the hope that it will be useful, *
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
16 * GNU General Public License for more details. *
17 * *
18 * You should have received a copy of the GNU General Public License *
19 * along with this program; if not, write to the *
20 * Free Software Foundation, Inc., *
21 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
22 ***************************************************************************/
23
24 #ifdef HAVE_CONFIG_H
25 #include "config.h"
26 #endif
27
28 #include "arm11.h"
29 #include "jtag.h"
30 #include "log.h"
31
32 #include <stdlib.h>
33 #include <string.h>
34
35 #if 0
36 #define _DEBUG_INSTRUCTION_EXECUTION_
37 #endif
38
39 #if 0
40 #define FNC_INFO LOG_DEBUG("-")
41 #else
42 #define FNC_INFO
43 #endif
44
45 #if 1
46 #define FNC_INFO_NOTIMPLEMENTED do { LOG_DEBUG("NOT IMPLEMENTED"); /*exit(-1);*/ } while (0)
47 #else
48 #define FNC_INFO_NOTIMPLEMENTED
49 #endif
50
51 static int arm11_on_enter_debug_state(arm11_common_t * arm11);
52
53 bool arm11_config_memwrite_burst = true;
54 bool arm11_config_memwrite_error_fatal = true;
55 u32 arm11_vcr = 0;
56 bool arm11_config_memrw_no_increment = false;
57 bool arm11_config_step_irq_enable = false;
58
59 #define ARM11_HANDLER(x) \
60 .x = arm11_##x
61
62 target_type_t arm11_target =
63 {
64 .name = "arm11",
65
66 ARM11_HANDLER(poll),
67 ARM11_HANDLER(arch_state),
68
69 ARM11_HANDLER(target_request_data),
70
71 ARM11_HANDLER(halt),
72 ARM11_HANDLER(resume),
73 ARM11_HANDLER(step),
74
75 ARM11_HANDLER(assert_reset),
76 ARM11_HANDLER(deassert_reset),
77 ARM11_HANDLER(soft_reset_halt),
78
79 ARM11_HANDLER(get_gdb_reg_list),
80
81 ARM11_HANDLER(read_memory),
82 ARM11_HANDLER(write_memory),
83
84 ARM11_HANDLER(bulk_write_memory),
85
86 ARM11_HANDLER(checksum_memory),
87
88 ARM11_HANDLER(add_breakpoint),
89 ARM11_HANDLER(remove_breakpoint),
90 ARM11_HANDLER(add_watchpoint),
91 ARM11_HANDLER(remove_watchpoint),
92
93 ARM11_HANDLER(run_algorithm),
94
95 ARM11_HANDLER(register_commands),
96 ARM11_HANDLER(target_create),
97 ARM11_HANDLER(init_target),
98 ARM11_HANDLER(examine),
99 ARM11_HANDLER(quit),
100 };
101
102 int arm11_regs_arch_type = -1;
103
104
105 enum arm11_regtype
106 {
107 ARM11_REGISTER_CORE,
108 ARM11_REGISTER_CPSR,
109
110 ARM11_REGISTER_FX,
111 ARM11_REGISTER_FPS,
112
113 ARM11_REGISTER_FIQ,
114 ARM11_REGISTER_SVC,
115 ARM11_REGISTER_ABT,
116 ARM11_REGISTER_IRQ,
117 ARM11_REGISTER_UND,
118 ARM11_REGISTER_MON,
119
120 ARM11_REGISTER_SPSR_FIQ,
121 ARM11_REGISTER_SPSR_SVC,
122 ARM11_REGISTER_SPSR_ABT,
123 ARM11_REGISTER_SPSR_IRQ,
124 ARM11_REGISTER_SPSR_UND,
125 ARM11_REGISTER_SPSR_MON,
126
127 /* debug regs */
128 ARM11_REGISTER_DSCR,
129 ARM11_REGISTER_WDTR,
130 ARM11_REGISTER_RDTR,
131 };
132
133
134 typedef struct arm11_reg_defs_s
135 {
136 char * name;
137 u32 num;
138 int gdb_num;
139 enum arm11_regtype type;
140 } arm11_reg_defs_t;
141
142 /* update arm11_regcache_ids when changing this */
143 static const arm11_reg_defs_t arm11_reg_defs[] =
144 {
145 {"r0", 0, 0, ARM11_REGISTER_CORE},
146 {"r1", 1, 1, ARM11_REGISTER_CORE},
147 {"r2", 2, 2, ARM11_REGISTER_CORE},
148 {"r3", 3, 3, ARM11_REGISTER_CORE},
149 {"r4", 4, 4, ARM11_REGISTER_CORE},
150 {"r5", 5, 5, ARM11_REGISTER_CORE},
151 {"r6", 6, 6, ARM11_REGISTER_CORE},
152 {"r7", 7, 7, ARM11_REGISTER_CORE},
153 {"r8", 8, 8, ARM11_REGISTER_CORE},
154 {"r9", 9, 9, ARM11_REGISTER_CORE},
155 {"r10", 10, 10, ARM11_REGISTER_CORE},
156 {"r11", 11, 11, ARM11_REGISTER_CORE},
157 {"r12", 12, 12, ARM11_REGISTER_CORE},
158 {"sp", 13, 13, ARM11_REGISTER_CORE},
159 {"lr", 14, 14, ARM11_REGISTER_CORE},
160 {"pc", 15, 15, ARM11_REGISTER_CORE},
161
162 #if ARM11_REGCACHE_FREGS
163 {"f0", 0, 16, ARM11_REGISTER_FX},
164 {"f1", 1, 17, ARM11_REGISTER_FX},
165 {"f2", 2, 18, ARM11_REGISTER_FX},
166 {"f3", 3, 19, ARM11_REGISTER_FX},
167 {"f4", 4, 20, ARM11_REGISTER_FX},
168 {"f5", 5, 21, ARM11_REGISTER_FX},
169 {"f6", 6, 22, ARM11_REGISTER_FX},
170 {"f7", 7, 23, ARM11_REGISTER_FX},
171 {"fps", 0, 24, ARM11_REGISTER_FPS},
172 #endif
173
174 {"cpsr", 0, 25, ARM11_REGISTER_CPSR},
175
176 #if ARM11_REGCACHE_MODEREGS
177 {"r8_fiq", 8, -1, ARM11_REGISTER_FIQ},
178 {"r9_fiq", 9, -1, ARM11_REGISTER_FIQ},
179 {"r10_fiq", 10, -1, ARM11_REGISTER_FIQ},
180 {"r11_fiq", 11, -1, ARM11_REGISTER_FIQ},
181 {"r12_fiq", 12, -1, ARM11_REGISTER_FIQ},
182 {"r13_fiq", 13, -1, ARM11_REGISTER_FIQ},
183 {"r14_fiq", 14, -1, ARM11_REGISTER_FIQ},
184 {"spsr_fiq", 0, -1, ARM11_REGISTER_SPSR_FIQ},
185
186 {"r13_svc", 13, -1, ARM11_REGISTER_SVC},
187 {"r14_svc", 14, -1, ARM11_REGISTER_SVC},
188 {"spsr_svc", 0, -1, ARM11_REGISTER_SPSR_SVC},
189
190 {"r13_abt", 13, -1, ARM11_REGISTER_ABT},
191 {"r14_abt", 14, -1, ARM11_REGISTER_ABT},
192 {"spsr_abt", 0, -1, ARM11_REGISTER_SPSR_ABT},
193
194 {"r13_irq", 13, -1, ARM11_REGISTER_IRQ},
195 {"r14_irq", 14, -1, ARM11_REGISTER_IRQ},
196 {"spsr_irq", 0, -1, ARM11_REGISTER_SPSR_IRQ},
197
198 {"r13_und", 13, -1, ARM11_REGISTER_UND},
199 {"r14_und", 14, -1, ARM11_REGISTER_UND},
200 {"spsr_und", 0, -1, ARM11_REGISTER_SPSR_UND},
201
202 /* ARM1176 only */
203 {"r13_mon", 13, -1, ARM11_REGISTER_MON},
204 {"r14_mon", 14, -1, ARM11_REGISTER_MON},
205 {"spsr_mon", 0, -1, ARM11_REGISTER_SPSR_MON},
206 #endif
207
208 /* Debug Registers */
209 {"dscr", 0, -1, ARM11_REGISTER_DSCR},
210 {"wdtr", 0, -1, ARM11_REGISTER_WDTR},
211 {"rdtr", 0, -1, ARM11_REGISTER_RDTR},
212 };
213
214 enum arm11_regcache_ids
215 {
216 ARM11_RC_R0,
217 ARM11_RC_RX = ARM11_RC_R0,
218
219 ARM11_RC_R1,
220 ARM11_RC_R2,
221 ARM11_RC_R3,
222 ARM11_RC_R4,
223 ARM11_RC_R5,
224 ARM11_RC_R6,
225 ARM11_RC_R7,
226 ARM11_RC_R8,
227 ARM11_RC_R9,
228 ARM11_RC_R10,
229 ARM11_RC_R11,
230 ARM11_RC_R12,
231 ARM11_RC_R13,
232 ARM11_RC_SP = ARM11_RC_R13,
233 ARM11_RC_R14,
234 ARM11_RC_LR = ARM11_RC_R14,
235 ARM11_RC_R15,
236 ARM11_RC_PC = ARM11_RC_R15,
237
238 #if ARM11_REGCACHE_FREGS
239 ARM11_RC_F0,
240 ARM11_RC_FX = ARM11_RC_F0,
241 ARM11_RC_F1,
242 ARM11_RC_F2,
243 ARM11_RC_F3,
244 ARM11_RC_F4,
245 ARM11_RC_F5,
246 ARM11_RC_F6,
247 ARM11_RC_F7,
248 ARM11_RC_FPS,
249 #endif
250
251 ARM11_RC_CPSR,
252
253 #if ARM11_REGCACHE_MODEREGS
254 ARM11_RC_R8_FIQ,
255 ARM11_RC_R9_FIQ,
256 ARM11_RC_R10_FIQ,
257 ARM11_RC_R11_FIQ,
258 ARM11_RC_R12_FIQ,
259 ARM11_RC_R13_FIQ,
260 ARM11_RC_R14_FIQ,
261 ARM11_RC_SPSR_FIQ,
262
263 ARM11_RC_R13_SVC,
264 ARM11_RC_R14_SVC,
265 ARM11_RC_SPSR_SVC,
266
267 ARM11_RC_R13_ABT,
268 ARM11_RC_R14_ABT,
269 ARM11_RC_SPSR_ABT,
270
271 ARM11_RC_R13_IRQ,
272 ARM11_RC_R14_IRQ,
273 ARM11_RC_SPSR_IRQ,
274
275 ARM11_RC_R13_UND,
276 ARM11_RC_R14_UND,
277 ARM11_RC_SPSR_UND,
278
279 ARM11_RC_R13_MON,
280 ARM11_RC_R14_MON,
281 ARM11_RC_SPSR_MON,
282 #endif
283
284 ARM11_RC_DSCR,
285 ARM11_RC_WDTR,
286 ARM11_RC_RDTR,
287
288 ARM11_RC_MAX,
289 };
290
291 #define ARM11_GDB_REGISTER_COUNT 26
292
293 u8 arm11_gdb_dummy_fp_value[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
294
295 reg_t arm11_gdb_dummy_fp_reg =
296 {
297 "GDB dummy floating-point register", arm11_gdb_dummy_fp_value, 0, 1, 96, NULL, 0, NULL, 0
298 };
299
300 u8 arm11_gdb_dummy_fps_value[] = {0, 0, 0, 0};
301
302 reg_t arm11_gdb_dummy_fps_reg =
303 {
304 "GDB dummy floating-point status register", arm11_gdb_dummy_fps_value, 0, 1, 32, NULL, 0, NULL, 0
305 };
306
307
308
309 /** Check and if necessary take control of the system
310 *
311 * \param arm11 Target state variable.
312 * \param dscr If the current DSCR content is
313 * available a pointer to a word holding the
314 * DSCR can be passed. Otherwise use NULL.
315 */
316 int arm11_check_init(arm11_common_t * arm11, u32 * dscr)
317 {
318 FNC_INFO;
319 int retval;
320
321 u32 dscr_local_tmp_copy;
322
323 if (!dscr)
324 {
325 dscr = &dscr_local_tmp_copy;
326 if ((retval=arm11_read_DSCR(arm11, dscr))!=ERROR_OK)
327 return retval;
328 }
329
330 if (!(*dscr & ARM11_DSCR_MODE_SELECT))
331 {
332 LOG_DEBUG("Bringing target into debug mode");
333
334 *dscr |= ARM11_DSCR_MODE_SELECT; /* Halt debug-mode */
335 arm11_write_DSCR(arm11, *dscr);
336
337 /* add further reset initialization here */
338
339 arm11->simulate_reset_on_next_halt = true;
340
341 if (*dscr & ARM11_DSCR_CORE_HALTED)
342 {
343 /** \todo TODO: this needs further scrutiny because
344 * arm11_on_enter_debug_state() never gets properly called
345 */
346
347 arm11->target->state = TARGET_HALTED;
348 arm11->target->debug_reason = arm11_get_DSCR_debug_reason(*dscr);
349 }
350 else
351 {
352 arm11->target->state = TARGET_RUNNING;
353 arm11->target->debug_reason = DBG_REASON_NOTHALTED;
354 }
355
356 arm11_sc7_clear_vbw(arm11);
357 }
358
359 return ERROR_OK;
360 }
361
362
363
364 #define R(x) \
365 (arm11->reg_values[ARM11_RC_##x])
366
367 /** Save processor state.
368 *
369 * This is called when the HALT instruction has succeeded
370 * or on other occasions that stop the processor.
371 *
372 */
373 static int arm11_on_enter_debug_state(arm11_common_t * arm11)
374 {
375 FNC_INFO;
376
377 {size_t i;
378 for(i = 0; i < asizeof(arm11->reg_values); i++)
379 {
380 arm11->reg_list[i].valid = 1;
381 arm11->reg_list[i].dirty = 0;
382 }}
383
384 /* Save DSCR */
385 int retval;
386 if ((retval=arm11_read_DSCR(arm11, &R(DSCR)))!=ERROR_OK)
387 return retval;
388
389 /* Save wDTR */
390
391 if (R(DSCR) & ARM11_DSCR_WDTR_FULL)
392 {
393 arm11_add_debug_SCAN_N(arm11, 0x05, ARM11_TAP_DEFAULT);
394
395 arm11_add_IR(arm11, ARM11_INTEST, ARM11_TAP_DEFAULT);
396
397 scan_field_t chain5_fields[3];
398
399 arm11_setup_field(arm11, 32, NULL, &R(WDTR), chain5_fields + 0);
400 arm11_setup_field(arm11, 1, NULL, NULL, chain5_fields + 1);
401 arm11_setup_field(arm11, 1, NULL, NULL, chain5_fields + 2);
402
403 arm11_add_dr_scan_vc(asizeof(chain5_fields), chain5_fields, TAP_DRPAUSE);
404 }
405 else
406 {
407 arm11->reg_list[ARM11_RC_WDTR].valid = 0;
408 }
409
410
411 /* DSCR: set ARM11_DSCR_EXECUTE_ARM_INSTRUCTION_ENABLE */
412 /* ARM1176 spec says this is needed only for wDTR/rDTR's "ITR mode", but not to issue ITRs
413 ARM1136 seems to require this to issue ITR's as well */
414
415 u32 new_dscr = R(DSCR) | ARM11_DSCR_EXECUTE_ARM_INSTRUCTION_ENABLE;
416
417 /* this executes JTAG queue: */
418
419 arm11_write_DSCR(arm11, new_dscr);
420
421
422 /* From the spec:
423 Before executing any instruction in debug state you have to drain the write buffer.
424 This ensures that no imprecise Data Aborts can return at a later point:*/
425
426 /** \todo TODO: Test drain write buffer. */
427
428 #if 0
429 while (1)
430 {
431 /* MRC p14,0,R0,c5,c10,0 */
432 // arm11_run_instr_no_data1(arm11, /*0xee150e1a*/0xe320f000);
433
434 /* mcr 15, 0, r0, cr7, cr10, {4} */
435 arm11_run_instr_no_data1(arm11, 0xee070f9a);
436
437 u32 dscr = arm11_read_DSCR(arm11);
438
439 LOG_DEBUG("DRAIN, DSCR %08x", dscr);
440
441 if (dscr & ARM11_DSCR_STICKY_IMPRECISE_DATA_ABORT)
442 {
443 arm11_run_instr_no_data1(arm11, 0xe320f000);
444
445 dscr = arm11_read_DSCR(arm11);
446
447 LOG_DEBUG("DRAIN, DSCR %08x (DONE)", dscr);
448
449 break;
450 }
451 }
452 #endif
453
454 arm11_run_instr_data_prepare(arm11);
455
456 /* save r0 - r14 */
457
458 /** \todo TODO: handle other mode registers */
459
460 {size_t i;
461 for (i = 0; i < 15; i++)
462 {
463 /* MCR p14,0,R?,c0,c5,0 */
464 arm11_run_instr_data_from_core(arm11, 0xEE000E15 | (i << 12), &R(RX + i), 1);
465 }}
466
467 /* save rDTR */
468
469 /* check rDTRfull in DSCR */
470
471 if (R(DSCR) & ARM11_DSCR_RDTR_FULL)
472 {
473 /* MRC p14,0,R0,c0,c5,0 (move rDTR -> r0 (-> wDTR -> local var)) */
474 arm11_run_instr_data_from_core_via_r0(arm11, 0xEE100E15, &R(RDTR));
475 }
476 else
477 {
478 arm11->reg_list[ARM11_RC_RDTR].valid = 0;
479 }
480
481 /* save CPSR */
482
483 /* MRS r0,CPSR (move CPSR -> r0 (-> wDTR -> local var)) */
484 arm11_run_instr_data_from_core_via_r0(arm11, 0xE10F0000, &R(CPSR));
485
486 /* save PC */
487
488 /* MOV R0,PC (move PC -> r0 (-> wDTR -> local var)) */
489 arm11_run_instr_data_from_core_via_r0(arm11, 0xE1A0000F, &R(PC));
490
491 /* adjust PC depending on ARM state */
492
493 if (R(CPSR) & ARM11_CPSR_J) /* Java state */
494 {
495 arm11->reg_values[ARM11_RC_PC] -= 0;
496 }
497 else if (R(CPSR) & ARM11_CPSR_T) /* Thumb state */
498 {
499 arm11->reg_values[ARM11_RC_PC] -= 4;
500 }
501 else /* ARM state */
502 {
503 arm11->reg_values[ARM11_RC_PC] -= 8;
504 }
505
506 if (arm11->simulate_reset_on_next_halt)
507 {
508 arm11->simulate_reset_on_next_halt = false;
509
510 LOG_DEBUG("Reset c1 Control Register");
511
512 /* Write 0 (reset value) to Control register 0 to disable MMU/Cache etc. */
513
514 /* MCR p15,0,R0,c1,c0,0 */
515 arm11_run_instr_data_to_core_via_r0(arm11, 0xee010f10, 0);
516
517 }
518
519 arm11_run_instr_data_finish(arm11);
520
521 arm11_dump_reg_changes(arm11);
522
523 return ERROR_OK;
524 }
525
526 void arm11_dump_reg_changes(arm11_common_t * arm11)
527 {
528 {size_t i;
529 for(i = 0; i < ARM11_REGCACHE_COUNT; i++)
530 {
531 if (!arm11->reg_list[i].valid)
532 {
533 if (arm11->reg_history[i].valid)
534 LOG_INFO("%8s INVALID (%08x)", arm11_reg_defs[i].name, arm11->reg_history[i].value);
535 }
536 else
537 {
538 if (arm11->reg_history[i].valid)
539 {
540 if (arm11->reg_history[i].value != arm11->reg_values[i])
541 LOG_INFO("%8s %08x (%08x)", arm11_reg_defs[i].name, arm11->reg_values[i], arm11->reg_history[i].value);
542 }
543 else
544 {
545 LOG_INFO("%8s %08x (INVALID)", arm11_reg_defs[i].name, arm11->reg_values[i]);
546 }
547 }
548 }}
549 }
550
551 /** Restore processor state
552 *
553 * This is called in preparation for the RESTART function.
554 *
555 */
556 int arm11_leave_debug_state(arm11_common_t * arm11)
557 {
558 FNC_INFO;
559
560 arm11_run_instr_data_prepare(arm11);
561
562 /** \todo TODO: handle other mode registers */
563
564 /* restore R1 - R14 */
565 {size_t i;
566 for (i = 1; i < 15; i++)
567 {
568 if (!arm11->reg_list[ARM11_RC_RX + i].dirty)
569 continue;
570
571 /* MRC p14,0,r?,c0,c5,0 */
572 arm11_run_instr_data_to_core1(arm11, 0xee100e15 | (i << 12), R(RX + i));
573
574 // LOG_DEBUG("RESTORE R" ZU " %08x", i, R(RX + i));
575 }}
576
577 arm11_run_instr_data_finish(arm11);
578
579 /* spec says clear wDTR and rDTR; we assume they are clear as
580 otherwise our programming would be sloppy */
581 {
582 u32 DSCR;
583 int retval;
584 if ((retval=arm11_read_DSCR(arm11, &DSCR))!=ERROR_OK)
585 {
586 return retval;
587 }
588
589 if (DSCR & (ARM11_DSCR_RDTR_FULL | ARM11_DSCR_WDTR_FULL))
590 {
591 LOG_ERROR("wDTR/rDTR inconsistent (DSCR %08x)", DSCR);
592 }
593 }
594
595 arm11_run_instr_data_prepare(arm11);
596
597 /* restore original wDTR */
598
599 if ((R(DSCR) & ARM11_DSCR_WDTR_FULL) || arm11->reg_list[ARM11_RC_WDTR].dirty)
600 {
601 /* MCR p14,0,R0,c0,c5,0 */
602 arm11_run_instr_data_to_core_via_r0(arm11, 0xee000e15, R(WDTR));
603 }
604
605 /* restore CPSR */
606
607 /* MSR CPSR,R0*/
608 arm11_run_instr_data_to_core_via_r0(arm11, 0xe129f000, R(CPSR));
609
610 /* restore PC */
611
612 /* MOV PC,R0 */
613 arm11_run_instr_data_to_core_via_r0(arm11, 0xe1a0f000, R(PC));
614
615 /* restore R0 */
616
617 /* MRC p14,0,r0,c0,c5,0 */
618 arm11_run_instr_data_to_core1(arm11, 0xee100e15, R(R0));
619
620 arm11_run_instr_data_finish(arm11);
621
622 /* restore DSCR */
623
624 arm11_write_DSCR(arm11, R(DSCR));
625
626 /* restore rDTR */
627
628 if (R(DSCR) & ARM11_DSCR_RDTR_FULL || arm11->reg_list[ARM11_RC_RDTR].dirty)
629 {
630 arm11_add_debug_SCAN_N(arm11, 0x05, ARM11_TAP_DEFAULT);
631
632 arm11_add_IR(arm11, ARM11_EXTEST, ARM11_TAP_DEFAULT);
633
634 scan_field_t chain5_fields[3];
635
636 u8 Ready = 0; /* ignored */
637 u8 Valid = 0; /* ignored */
638
639 arm11_setup_field(arm11, 32, &R(RDTR), NULL, chain5_fields + 0);
640 arm11_setup_field(arm11, 1, &Ready, NULL, chain5_fields + 1);
641 arm11_setup_field(arm11, 1, &Valid, NULL, chain5_fields + 2);
642
643 arm11_add_dr_scan_vc(asizeof(chain5_fields), chain5_fields, TAP_DRPAUSE);
644 }
645
646 arm11_record_register_history(arm11);
647
648 return ERROR_OK;
649 }
650
651 void arm11_record_register_history(arm11_common_t * arm11)
652 {
653 {size_t i;
654 for(i = 0; i < ARM11_REGCACHE_COUNT; i++)
655 {
656 arm11->reg_history[i].value = arm11->reg_values[i];
657 arm11->reg_history[i].valid = arm11->reg_list[i].valid;
658
659 arm11->reg_list[i].valid = 0;
660 arm11->reg_list[i].dirty = 0;
661 }}
662 }
663
664
665 /* poll current target status */
666 int arm11_poll(struct target_s *target)
667 {
668 FNC_INFO;
669
670 arm11_common_t * arm11 = target->arch_info;
671
672 if (arm11->trst_active)
673 return ERROR_OK;
674
675 u32 dscr;
676 int retval;
677 if ((retval=arm11_read_DSCR(arm11, &dscr))!=ERROR_OK)
678 return retval;
679
680 LOG_DEBUG("DSCR %08x", dscr);
681
682 if ((retval=arm11_check_init(arm11, &dscr))!=ERROR_OK)
683 return retval;
684
685 if (dscr & ARM11_DSCR_CORE_HALTED)
686 {
687 if (target->state != TARGET_HALTED)
688 {
689 enum target_state old_state = target->state;
690
691 LOG_DEBUG("enter TARGET_HALTED");
692 target->state = TARGET_HALTED;
693 target->debug_reason = arm11_get_DSCR_debug_reason(dscr);
694 arm11_on_enter_debug_state(arm11);
695
696 target_call_event_callbacks(target,
697 old_state == TARGET_DEBUG_RUNNING ? TARGET_EVENT_DEBUG_HALTED : TARGET_EVENT_HALTED);
698 }
699 }
700 else
701 {
702 if (target->state != TARGET_RUNNING && target->state != TARGET_DEBUG_RUNNING)
703 {
704 LOG_DEBUG("enter TARGET_RUNNING");
705 target->state = TARGET_RUNNING;
706 target->debug_reason = DBG_REASON_NOTHALTED;
707 }
708 }
709
710 return ERROR_OK;
711 }
712 /* architecture specific status reply */
713 int arm11_arch_state(struct target_s *target)
714 {
715 FNC_INFO_NOTIMPLEMENTED;
716
717 return ERROR_OK;
718 }
719
720 /* target request support */
721 int arm11_target_request_data(struct target_s *target, u32 size, u8 *buffer)
722 {
723 FNC_INFO_NOTIMPLEMENTED;
724
725 return ERROR_OK;
726 }
727
728 /* target execution control */
729 int arm11_halt(struct target_s *target)
730 {
731 int retval = ERROR_OK;
732
733 FNC_INFO;
734
735 arm11_common_t * arm11 = target->arch_info;
736
737 LOG_DEBUG("target->state: %s",
738 Jim_Nvp_value2name_simple( nvp_target_state, target->state )->name );
739
740 if (target->state == TARGET_UNKNOWN)
741 {
742 arm11->simulate_reset_on_next_halt = true;
743 }
744
745 if (target->state == TARGET_HALTED)
746 {
747 LOG_DEBUG("target was already halted");
748 return ERROR_OK;
749 }
750
751 if (arm11->trst_active)
752 {
753 arm11->halt_requested = true;
754 return ERROR_OK;
755 }
756
757 arm11_add_IR(arm11, ARM11_HALT, TAP_IDLE);
758
759 if((retval = jtag_execute_queue()) != ERROR_OK)
760 {
761 return retval;
762 }
763
764 u32 dscr;
765
766 while (1)
767 {
768 int retval;
769 retval = arm11_read_DSCR(arm11, &dscr);
770 if (retval!=ERROR_OK)
771 return retval;
772
773 if (dscr & ARM11_DSCR_CORE_HALTED)
774 break;
775 }
776
777 arm11_on_enter_debug_state(arm11);
778
779 enum target_state old_state = target->state;
780
781 target->state = TARGET_HALTED;
782 target->debug_reason = arm11_get_DSCR_debug_reason(dscr);
783
784 if((retval = target_call_event_callbacks(target,
785 old_state == TARGET_DEBUG_RUNNING ? TARGET_EVENT_DEBUG_HALTED : TARGET_EVENT_HALTED)) != ERROR_OK)
786 {
787 return retval;
788 }
789
790 return ERROR_OK;
791 }
792
793 int arm11_resume(struct target_s *target, int current, u32 address, int handle_breakpoints, int debug_execution)
794 {
795 int retval = ERROR_OK;
796
797 FNC_INFO;
798
799 // LOG_DEBUG("current %d address %08x handle_breakpoints %d debug_execution %d",
800 // current, address, handle_breakpoints, debug_execution);
801
802 arm11_common_t * arm11 = target->arch_info;
803
804 LOG_DEBUG("target->state: %s",
805 Jim_Nvp_value2name_simple( nvp_target_state, target->state )->name );
806
807
808 if (target->state != TARGET_HALTED)
809 {
810 LOG_ERROR("Target not halted");
811 return ERROR_TARGET_NOT_HALTED;
812 }
813
814 if (!current)
815 R(PC) = address;
816
817 LOG_INFO("RESUME PC %08x%s", R(PC), !current ? "!" : "");
818
819 /* clear breakpoints/watchpoints and VCR*/
820 arm11_sc7_clear_vbw(arm11);
821
822 /* Set up breakpoints */
823 if (!debug_execution)
824 {
825 /* check if one matches PC and step over it if necessary */
826
827 breakpoint_t * bp;
828
829 for (bp = target->breakpoints; bp; bp = bp->next)
830 {
831 if (bp->address == R(PC))
832 {
833 LOG_DEBUG("must step over %08x", bp->address);
834 arm11_step(target, 1, 0, 0);
835 break;
836 }
837 }
838
839 /* set all breakpoints */
840
841 size_t brp_num = 0;
842
843 for (bp = target->breakpoints; bp; bp = bp->next)
844 {
845 arm11_sc7_action_t brp[2];
846
847 brp[0].write = 1;
848 brp[0].address = ARM11_SC7_BVR0 + brp_num;
849 brp[0].value = bp->address;
850 brp[1].write = 1;
851 brp[1].address = ARM11_SC7_BCR0 + brp_num;
852 brp[1].value = 0x1 | (3 << 1) | (0x0F << 5) | (0 << 14) | (0 << 16) | (0 << 20) | (0 << 21);
853
854 arm11_sc7_run(arm11, brp, asizeof(brp));
855
856 LOG_DEBUG("Add BP " ZU " at %08x", brp_num, bp->address);
857
858 brp_num++;
859 }
860
861 arm11_sc7_set_vcr(arm11, arm11_vcr);
862 }
863
864 arm11_leave_debug_state(arm11);
865
866 arm11_add_IR(arm11, ARM11_RESTART, TAP_IDLE);
867
868 if((retval = jtag_execute_queue()) != ERROR_OK)
869 {
870 return retval;
871 }
872
873 while (1)
874 {
875 u32 dscr;
876 retval = arm11_read_DSCR(arm11, &dscr);
877 if (retval!=ERROR_OK)
878 return retval;
879
880 LOG_DEBUG("DSCR %08x", dscr);
881
882 if (dscr & ARM11_DSCR_CORE_RESTARTED)
883 break;
884 }
885
886 if (!debug_execution)
887 {
888 target->state = TARGET_RUNNING;
889 target->debug_reason = DBG_REASON_NOTHALTED;
890
891 if((retval = target_call_event_callbacks(target, TARGET_EVENT_RESUMED)) != ERROR_OK)
892 {
893 return retval;
894 }
895 }
896 else
897 {
898 target->state = TARGET_DEBUG_RUNNING;
899 target->debug_reason = DBG_REASON_NOTHALTED;
900 if((retval = target_call_event_callbacks(target, TARGET_EVENT_RESUMED)) != ERROR_OK)
901 {
902 return retval;
903 }
904 }
905
906 return ERROR_OK;
907 }
908
909 int arm11_step(struct target_s *target, int current, u32 address, int handle_breakpoints)
910 {
911 int retval = ERROR_OK;
912
913 FNC_INFO;
914
915 LOG_DEBUG("target->state: %s",
916 Jim_Nvp_value2name_simple( nvp_target_state, target->state )->name );
917
918 if (target->state != TARGET_HALTED)
919 {
920 LOG_WARNING("target was not halted");
921 return ERROR_TARGET_NOT_HALTED;
922 }
923
924 arm11_common_t * arm11 = target->arch_info;
925
926 if (!current)
927 R(PC) = address;
928
929 LOG_INFO("STEP PC %08x%s", R(PC), !current ? "!" : "");
930
931 /** \todo TODO: Thumb not supported here */
932
933 u32 next_instruction;
934
935 if ((arm11_read_memory_word(arm11, R(PC), &next_instruction))!=ERROR_OK)
936 return retval;
937
938 /* skip over BKPT */
939 if ((next_instruction & 0xFFF00070) == 0xe1200070)
940 {
941 R(PC) += 4;
942 arm11->reg_list[ARM11_RC_PC].valid = 1;
943 arm11->reg_list[ARM11_RC_PC].dirty = 0;
944 LOG_INFO("Skipping BKPT");
945 }
946 /* skip over Wait for interrupt / Standby */
947 /* mcr 15, 0, r?, cr7, cr0, {4} */
948 else if ((next_instruction & 0xFFFF0FFF) == 0xee070f90)
949 {
950 R(PC) += 4;
951 arm11->reg_list[ARM11_RC_PC].valid = 1;
952 arm11->reg_list[ARM11_RC_PC].dirty = 0;
953 LOG_INFO("Skipping WFI");
954 }
955 /* ignore B to self */
956 else if ((next_instruction & 0xFEFFFFFF) == 0xeafffffe)
957 {
958 LOG_INFO("Not stepping jump to self");
959 }
960 else
961 {
962 /** \todo TODO: check if break-/watchpoints make any sense at all in combination
963 * with this. */
964
965 /** \todo TODO: check if disabling IRQs might be a good idea here. Alternatively
966 * the VCR might be something worth looking into. */
967
968
969 /* Set up breakpoint for stepping */
970
971 arm11_sc7_action_t brp[2];
972
973 brp[0].write = 1;
974 brp[0].address = ARM11_SC7_BVR0;
975 brp[0].value = R(PC);
976 brp[1].write = 1;
977 brp[1].address = ARM11_SC7_BCR0;
978 brp[1].value = 0x1 | (3 << 1) | (0x0F << 5) | (0 << 14) | (0 << 16) | (0 << 20) | (2 << 21);
979
980 if ((retval=arm11_sc7_run(arm11, brp, asizeof(brp)))!=ERROR_OK)
981 return retval;
982
983 /* resume */
984
985
986 if (arm11_config_step_irq_enable)
987 R(DSCR) &= ~ARM11_DSCR_INTERRUPTS_DISABLE; /* should be redundant */
988 else
989 R(DSCR) |= ARM11_DSCR_INTERRUPTS_DISABLE;
990
991
992 if ((retval=arm11_leave_debug_state(arm11))!=ERROR_OK)
993 return retval;
994
995 arm11_add_IR(arm11, ARM11_RESTART, TAP_IDLE);
996
997 if((retval = jtag_execute_queue()) != ERROR_OK)
998 {
999 return retval;
1000 }
1001
1002 /** \todo TODO: add a timeout */
1003
1004 /* wait for halt */
1005
1006 while (1)
1007 {
1008 u32 dscr;
1009 retval = arm11_read_DSCR(arm11, &dscr);
1010 if (retval!=ERROR_OK)
1011 return retval;
1012
1013 LOG_DEBUG("DSCR %08x", dscr);
1014
1015 if ((dscr & (ARM11_DSCR_CORE_RESTARTED | ARM11_DSCR_CORE_HALTED)) ==
1016 (ARM11_DSCR_CORE_RESTARTED | ARM11_DSCR_CORE_HALTED))
1017 break;
1018 }
1019
1020 /* clear breakpoint */
1021 arm11_sc7_clear_vbw(arm11);
1022
1023 /* save state */
1024 if((retval = arm11_on_enter_debug_state(arm11))!=ERROR_OK)
1025 return retval;
1026
1027 /* restore default state */
1028 R(DSCR) &= ~ARM11_DSCR_INTERRUPTS_DISABLE;
1029
1030 }
1031
1032 // target->state = TARGET_HALTED;
1033 target->debug_reason = DBG_REASON_SINGLESTEP;
1034
1035 if((retval = target_call_event_callbacks(target, TARGET_EVENT_HALTED)) != ERROR_OK)
1036 {
1037 return retval;
1038 }
1039
1040 return ERROR_OK;
1041 }
1042
1043 /* target reset control */
1044 int arm11_assert_reset(struct target_s *target)
1045 {
1046 FNC_INFO;
1047
1048 #if 0
1049 /* assert reset lines */
1050 /* resets only the DBGTAP, not the ARM */
1051
1052 jtag_add_reset(1, 0);
1053 jtag_add_sleep(5000);
1054
1055 arm11_common_t * arm11 = target->arch_info;
1056 arm11->trst_active = true;
1057 #endif
1058
1059 if (target->reset_halt)
1060 {
1061 int retval;
1062 if ((retval = target_halt(target))!=ERROR_OK)
1063 return retval;
1064 }
1065
1066 return ERROR_OK;
1067 }
1068
1069 int arm11_deassert_reset(struct target_s *target)
1070 {
1071 FNC_INFO;
1072
1073 #if 0
1074 LOG_DEBUG("target->state: %s",
1075 Jim_Nvp_value2name_simple( nvp_target_state, target->state )->name );
1076
1077
1078 /* deassert reset lines */
1079 jtag_add_reset(0, 0);
1080
1081 arm11_common_t * arm11 = target->arch_info;
1082 arm11->trst_active = false;
1083
1084 if (arm11->halt_requested)
1085 return arm11_halt(target);
1086 #endif
1087
1088 return ERROR_OK;
1089 }
1090
1091 int arm11_soft_reset_halt(struct target_s *target)
1092 {
1093 FNC_INFO_NOTIMPLEMENTED;
1094
1095 return ERROR_OK;
1096 }
1097
1098 /* target register access for gdb */
1099 int arm11_get_gdb_reg_list(struct target_s *target, struct reg_s **reg_list[], int *reg_list_size)
1100 {
1101 FNC_INFO;
1102
1103 arm11_common_t * arm11 = target->arch_info;
1104
1105 *reg_list_size = ARM11_GDB_REGISTER_COUNT;
1106 *reg_list = malloc(sizeof(reg_t*) * ARM11_GDB_REGISTER_COUNT);
1107
1108 {size_t i;
1109 for (i = 16; i < 24; i++)
1110 {
1111 (*reg_list)[i] = &arm11_gdb_dummy_fp_reg;
1112 }}
1113
1114 (*reg_list)[24] = &arm11_gdb_dummy_fps_reg;
1115
1116 {size_t i;
1117 for (i = 0; i < ARM11_REGCACHE_COUNT; i++)
1118 {
1119 if (arm11_reg_defs[i].gdb_num == -1)
1120 continue;
1121
1122 (*reg_list)[arm11_reg_defs[i].gdb_num] = arm11->reg_list + i;
1123 }}
1124
1125 return ERROR_OK;
1126 }
1127
1128 /* target memory access
1129 * size: 1 = byte (8bit), 2 = half-word (16bit), 4 = word (32bit)
1130 * count: number of items of <size>
1131 */
1132 int arm11_read_memory(struct target_s *target, u32 address, u32 size, u32 count, u8 *buffer)
1133 {
1134 /** \todo TODO: check if buffer cast to u32* and u16* might cause alignment problems */
1135
1136 FNC_INFO;
1137
1138 if (target->state != TARGET_HALTED)
1139 {
1140 LOG_WARNING("target was not halted");
1141 return ERROR_TARGET_NOT_HALTED;
1142 }
1143
1144 LOG_DEBUG("ADDR %08x SIZE %08x COUNT %08x", address, size, count);
1145
1146 arm11_common_t * arm11 = target->arch_info;
1147
1148 arm11_run_instr_data_prepare(arm11);
1149
1150 /* MRC p14,0,r0,c0,c5,0 */
1151 arm11_run_instr_data_to_core1(arm11, 0xee100e15, address);
1152
1153 switch (size)
1154 {
1155 case 1:
1156 /** \todo TODO: check if dirty is the right choice to force a rewrite on arm11_resume() */
1157 arm11->reg_list[ARM11_RC_R1].dirty = 1;
1158
1159 {size_t i;
1160 for (i = 0; i < count; i++)
1161 {
1162 /* ldrb r1, [r0], #1 */
1163 /* ldrb r1, [r0] */
1164 arm11_run_instr_no_data1(arm11,
1165 !arm11_config_memrw_no_increment ? 0xe4d01001 : 0xe5d01000);
1166
1167 u32 res;
1168 /* MCR p14,0,R1,c0,c5,0 */
1169 arm11_run_instr_data_from_core(arm11, 0xEE001E15, &res, 1);
1170
1171 *buffer++ = res;
1172 }}
1173
1174 break;
1175
1176 case 2:
1177 {
1178 arm11->reg_list[ARM11_RC_R1].dirty = 1;
1179
1180 u16 * buf16 = (u16*)buffer;
1181
1182 {size_t i;
1183 for (i = 0; i < count; i++)
1184 {
1185 /* ldrh r1, [r0], #2 */
1186 arm11_run_instr_no_data1(arm11,
1187 !arm11_config_memrw_no_increment ? 0xe0d010b2 : 0xe1d010b0);
1188
1189 u32 res;
1190
1191 /* MCR p14,0,R1,c0,c5,0 */
1192 arm11_run_instr_data_from_core(arm11, 0xEE001E15, &res, 1);
1193
1194 *buf16++ = res;
1195 }}
1196
1197 break;
1198 }
1199
1200 case 4:
1201
1202 /* LDC p14,c5,[R0],#4 */
1203 /* LDC p14,c5,[R0] */
1204 arm11_run_instr_data_from_core(arm11,
1205 (!arm11_config_memrw_no_increment ? 0xecb05e01 : 0xed905e00),
1206 (u32 *)buffer, count);
1207 break;
1208 }
1209
1210 arm11_run_instr_data_finish(arm11);
1211
1212 return ERROR_OK;
1213 }
1214
1215 int arm11_write_memory(struct target_s *target, u32 address, u32 size, u32 count, u8 *buffer)
1216 {
1217 FNC_INFO;
1218
1219 if (target->state != TARGET_HALTED)
1220 {
1221 LOG_WARNING("target was not halted");
1222 return ERROR_TARGET_NOT_HALTED;
1223 }
1224
1225 LOG_DEBUG("ADDR %08x SIZE %08x COUNT %08x", address, size, count);
1226
1227 arm11_common_t * arm11 = target->arch_info;
1228
1229 arm11_run_instr_data_prepare(arm11);
1230
1231 /* MRC p14,0,r0,c0,c5,0 */
1232 arm11_run_instr_data_to_core1(arm11, 0xee100e15, address);
1233
1234 switch (size)
1235 {
1236 case 1:
1237 {
1238 arm11->reg_list[ARM11_RC_R1].dirty = 1;
1239
1240 {size_t i;
1241 for (i = 0; i < count; i++)
1242 {
1243 /* MRC p14,0,r1,c0,c5,0 */
1244 arm11_run_instr_data_to_core1(arm11, 0xee101e15, *buffer++);
1245
1246 /* strb r1, [r0], #1 */
1247 /* strb r1, [r0] */
1248 arm11_run_instr_no_data1(arm11,
1249 !arm11_config_memrw_no_increment ? 0xe4c01001 : 0xe5c01000);
1250 }}
1251
1252 break;
1253 }
1254
1255 case 2:
1256 {
1257 arm11->reg_list[ARM11_RC_R1].dirty = 1;
1258
1259 u16 * buf16 = (u16*)buffer;
1260
1261 {size_t i;
1262 for (i = 0; i < count; i++)
1263 {
1264 /* MRC p14,0,r1,c0,c5,0 */
1265 arm11_run_instr_data_to_core1(arm11, 0xee101e15, *buf16++);
1266
1267 /* strh r1, [r0], #2 */
1268 /* strh r1, [r0] */
1269 arm11_run_instr_no_data1(arm11,
1270 !arm11_config_memrw_no_increment ? 0xe0c010b2 : 0xe1c010b0);
1271 }}
1272
1273 break;
1274 }
1275
1276 case 4:
1277 /** \todo TODO: check if buffer cast to u32* might cause alignment problems */
1278
1279 if (!arm11_config_memwrite_burst)
1280 {
1281 /* STC p14,c5,[R0],#4 */
1282 /* STC p14,c5,[R0]*/
1283 arm11_run_instr_data_to_core(arm11,
1284 (!arm11_config_memrw_no_increment ? 0xeca05e01 : 0xed805e00),
1285 (u32 *)buffer, count);
1286 }
1287 else
1288 {
1289 /* STC p14,c5,[R0],#4 */
1290 /* STC p14,c5,[R0]*/
1291 arm11_run_instr_data_to_core_noack(arm11,
1292 (!arm11_config_memrw_no_increment ? 0xeca05e01 : 0xed805e00),
1293 (u32 *)buffer, count);
1294 }
1295
1296 break;
1297 }
1298
1299 #if 1
1300 /* r0 verification */
1301 if (!arm11_config_memrw_no_increment)
1302 {
1303 u32 r0;
1304
1305 /* MCR p14,0,R0,c0,c5,0 */
1306 arm11_run_instr_data_from_core(arm11, 0xEE000E15, &r0, 1);
1307
1308 if (address + size * count != r0)
1309 {
1310 LOG_ERROR("Data transfer failed. (%d)", (r0 - address) - size * count);
1311
1312 if (arm11_config_memwrite_burst)
1313 LOG_ERROR("use 'arm11 memwrite burst disable' to disable fast burst mode");
1314
1315 if (arm11_config_memwrite_error_fatal)
1316 return ERROR_FAIL;
1317 }
1318 }
1319 #endif
1320
1321 arm11_run_instr_data_finish(arm11);
1322
1323 return ERROR_OK;
1324 }
1325
1326
1327 /* write target memory in multiples of 4 byte, optimized for writing large quantities of data */
1328 int arm11_bulk_write_memory(struct target_s *target, u32 address, u32 count, u8 *buffer)
1329 {
1330 FNC_INFO;
1331
1332 if (target->state != TARGET_HALTED)
1333 {
1334 LOG_WARNING("target was not halted");
1335 return ERROR_TARGET_NOT_HALTED;
1336 }
1337
1338 return arm11_write_memory(target, address, 4, count, buffer);
1339 }
1340
1341 int arm11_checksum_memory(struct target_s *target, u32 address, u32 count, u32* checksum)
1342 {
1343 FNC_INFO_NOTIMPLEMENTED;
1344
1345 return ERROR_OK;
1346 }
1347
1348 /* target break-/watchpoint control
1349 * rw: 0 = write, 1 = read, 2 = access
1350 */
1351 int arm11_add_breakpoint(struct target_s *target, breakpoint_t *breakpoint)
1352 {
1353 FNC_INFO;
1354
1355 arm11_common_t * arm11 = target->arch_info;
1356
1357 #if 0
1358 if (breakpoint->type == BKPT_SOFT)
1359 {
1360 LOG_INFO("sw breakpoint requested, but software breakpoints not enabled");
1361 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
1362 }
1363 #endif
1364
1365 if (!arm11->free_brps)
1366 {
1367 LOG_INFO("no breakpoint unit available for hardware breakpoint");
1368 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
1369 }
1370
1371 if (breakpoint->length != 4)
1372 {
1373 LOG_INFO("only breakpoints of four bytes length supported");
1374 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
1375 }
1376
1377 arm11->free_brps--;
1378
1379 return ERROR_OK;
1380 }
1381
1382 int arm11_remove_breakpoint(struct target_s *target, breakpoint_t *breakpoint)
1383 {
1384 FNC_INFO;
1385
1386 arm11_common_t * arm11 = target->arch_info;
1387
1388 arm11->free_brps++;
1389
1390 return ERROR_OK;
1391 }
1392
1393 int arm11_add_watchpoint(struct target_s *target, watchpoint_t *watchpoint)
1394 {
1395 FNC_INFO_NOTIMPLEMENTED;
1396
1397 return ERROR_OK;
1398 }
1399
1400 int arm11_remove_watchpoint(struct target_s *target, watchpoint_t *watchpoint)
1401 {
1402 FNC_INFO_NOTIMPLEMENTED;
1403
1404 return ERROR_OK;
1405 }
1406
1407 // HACKHACKHACK - FIXME mode/state
1408 /* target algorithm support */
1409 int arm11_run_algorithm(struct target_s *target, int num_mem_params, mem_param_t *mem_params,
1410 int num_reg_params, reg_param_t *reg_params, u32 entry_point, u32 exit_point,
1411 int timeout_ms, void *arch_info)
1412 {
1413 arm11_common_t *arm11 = target->arch_info;
1414 armv4_5_algorithm_t *arm11_algorithm_info = arch_info;
1415 // enum armv4_5_state core_state = arm11->core_state;
1416 // enum armv4_5_mode core_mode = arm11->core_mode;
1417 u32 context[16];
1418 u32 cpsr;
1419 int exit_breakpoint_size = 0;
1420 int i;
1421 int retval = ERROR_OK;
1422 LOG_DEBUG("Running algorithm");
1423
1424 if (arm11_algorithm_info->common_magic != ARMV4_5_COMMON_MAGIC)
1425 {
1426 LOG_ERROR("current target isn't an ARMV4/5 target");
1427 return ERROR_TARGET_INVALID;
1428 }
1429
1430 if (target->state != TARGET_HALTED)
1431 {
1432 LOG_WARNING("target not halted");
1433 return ERROR_TARGET_NOT_HALTED;
1434 }
1435
1436 // FIXME
1437 // if (armv4_5_mode_to_number(arm11->core_mode)==-1)
1438 // return ERROR_FAIL;
1439
1440 // Save regs
1441 for (i = 0; i < 16; i++)
1442 {
1443 context[i] = buf_get_u32((u8*)(&arm11->reg_values[i]),0,32);
1444 LOG_DEBUG("Save %i: 0x%x",i,context[i]);
1445 }
1446
1447 cpsr = buf_get_u32((u8*)(arm11->reg_values+ARM11_RC_CPSR),0,32);
1448 LOG_DEBUG("Save CPSR: 0x%x", cpsr);
1449
1450 for (i = 0; i < num_mem_params; i++)
1451 {
1452 target_write_buffer(target, mem_params[i].address, mem_params[i].size, mem_params[i].value);
1453 }
1454
1455 // Set register parameters
1456 for (i = 0; i < num_reg_params; i++)
1457 {
1458 reg_t *reg = register_get_by_name(arm11->core_cache, reg_params[i].reg_name, 0);
1459 if (!reg)
1460 {
1461 LOG_ERROR("BUG: register '%s' not found", reg_params[i].reg_name);
1462 exit(-1);
1463 }
1464
1465 if (reg->size != reg_params[i].size)
1466 {
1467 LOG_ERROR("BUG: register '%s' size doesn't match reg_params[i].size", reg_params[i].reg_name);
1468 exit(-1);
1469 }
1470 arm11_set_reg(reg,reg_params[i].value);
1471 // printf("%i: Set %s =%08x\n", i, reg_params[i].reg_name,val);
1472 }
1473
1474 exit_breakpoint_size = 4;
1475
1476 /* arm11->core_state = arm11_algorithm_info->core_state;
1477 if (arm11->core_state == ARMV4_5_STATE_ARM)
1478 exit_breakpoint_size = 4;
1479 else if (arm11->core_state == ARMV4_5_STATE_THUMB)
1480 exit_breakpoint_size = 2;
1481 else
1482 {
1483 LOG_ERROR("BUG: can't execute algorithms when not in ARM or Thumb state");
1484 exit(-1);
1485 }
1486 */
1487 if (arm11_algorithm_info->core_mode != ARMV4_5_MODE_ANY)
1488 {
1489 LOG_DEBUG("setting core_mode: 0x%2.2x", arm11_algorithm_info->core_mode);
1490 buf_set_u32(arm11->reg_list[ARM11_RC_CPSR].value, 0, 5, arm11_algorithm_info->core_mode);
1491 arm11->reg_list[ARM11_RC_CPSR].dirty = 1;
1492 arm11->reg_list[ARM11_RC_CPSR].valid = 1;
1493 }
1494
1495 if ((retval = breakpoint_add(target, exit_point, exit_breakpoint_size, BKPT_HARD)) != ERROR_OK)
1496 {
1497 LOG_ERROR("can't add breakpoint to finish algorithm execution");
1498 retval = ERROR_TARGET_FAILURE;
1499 goto restore;
1500 }
1501
1502 // no debug, otherwise breakpoint is not set
1503 if((retval = target_resume(target, 0, entry_point, 1, 0)) != ERROR_OK)
1504 {
1505 return retval;
1506 }
1507
1508 if((retval = target_wait_state(target, TARGET_HALTED, timeout_ms)) != ERROR_OK)
1509 {
1510 return retval;
1511 }
1512
1513 if (target->state != TARGET_HALTED)
1514 {
1515 if ((retval=target_halt(target))!=ERROR_OK)
1516 return retval;
1517 if ((retval=target_wait_state(target, TARGET_HALTED, 500))!=ERROR_OK)
1518 {
1519 return retval;
1520 }
1521 retval = ERROR_TARGET_TIMEOUT;
1522 goto del_breakpoint;
1523 }
1524
1525 if (buf_get_u32(arm11->reg_list[15].value, 0, 32) != exit_point)
1526 {
1527 LOG_WARNING("target reentered debug state, but not at the desired exit point: 0x%4.4x",
1528 buf_get_u32(arm11->reg_list[15].value, 0, 32));
1529 retval = ERROR_TARGET_TIMEOUT;
1530 goto del_breakpoint;
1531 }
1532
1533 for (i = 0; i < num_mem_params; i++)
1534 {
1535 if (mem_params[i].direction != PARAM_OUT)
1536 target_read_buffer(target, mem_params[i].address, mem_params[i].size, mem_params[i].value);
1537 }
1538
1539 for (i = 0; i < num_reg_params; i++)
1540 {
1541 if (reg_params[i].direction != PARAM_OUT)
1542 {
1543 reg_t *reg = register_get_by_name(arm11->core_cache, reg_params[i].reg_name, 0);
1544 if (!reg)
1545 {
1546 LOG_ERROR("BUG: register '%s' not found", reg_params[i].reg_name);
1547 exit(-1);
1548 }
1549
1550 if (reg->size != reg_params[i].size)
1551 {
1552 LOG_ERROR("BUG: register '%s' size doesn't match reg_params[i].size", reg_params[i].reg_name);
1553 exit(-1);
1554 }
1555
1556 buf_set_u32(reg_params[i].value, 0, 32, buf_get_u32(reg->value, 0, 32));
1557 }
1558 }
1559
1560 del_breakpoint:
1561 breakpoint_remove(target, exit_point);
1562
1563 restore:
1564 // Restore context
1565 for (i = 0; i < 16; i++)
1566 {
1567 LOG_DEBUG("restoring register %s with value 0x%8.8x",
1568 arm11->reg_list[i].name, context[i]);
1569 arm11_set_reg(&arm11->reg_list[i], (u8*)&context[i]);
1570 }
1571 LOG_DEBUG("restoring CPSR with value 0x%8.8x", cpsr);
1572 arm11_set_reg(&arm11->reg_list[ARM11_RC_CPSR], (u8*)&cpsr);
1573
1574 // arm11->core_state = core_state;
1575 // arm11->core_mode = core_mode;
1576
1577 return retval;
1578 }
1579
1580 int arm11_target_create(struct target_s *target, Jim_Interp *interp)
1581 {
1582 int retval = ERROR_OK;
1583 FNC_INFO;
1584
1585 NEW(arm11_common_t, arm11, 1);
1586
1587 arm11->target = target;
1588
1589 /* prepare JTAG information for the new target */
1590 arm11->jtag_info.tap = target->tap;
1591 arm11->jtag_info.scann_size = 5;
1592
1593 if((retval = arm_jtag_setup_connection(&arm11->jtag_info)) != ERROR_OK)
1594 {
1595 return retval;
1596 }
1597
1598 if (target->tap==NULL)
1599 return ERROR_FAIL;
1600
1601 if (target->tap->ir_length != 5)
1602 {
1603 LOG_ERROR("'target arm11' expects IR LENGTH = 5");
1604 return ERROR_COMMAND_SYNTAX_ERROR;
1605 }
1606
1607 target->arch_info = arm11;
1608
1609 return ERROR_OK;
1610 }
1611
1612 int arm11_init_target(struct command_context_s *cmd_ctx, struct target_s *target)
1613 {
1614 /* Initialize anything we can set up without talking to the target */
1615 return arm11_build_reg_cache(target);
1616 }
1617
1618 /* talk to the target and set things up */
1619 int arm11_examine(struct target_s *target)
1620 {
1621 FNC_INFO;
1622 int retval;
1623
1624 arm11_common_t * arm11 = target->arch_info;
1625
1626 /* check IDCODE */
1627
1628 arm11_add_IR(arm11, ARM11_IDCODE, ARM11_TAP_DEFAULT);
1629
1630 scan_field_t idcode_field;
1631
1632 arm11_setup_field(arm11, 32, NULL, &arm11->device_id, &idcode_field);
1633
1634 arm11_add_dr_scan_vc(1, &idcode_field, TAP_DRPAUSE);
1635
1636 /* check DIDR */
1637
1638 arm11_add_debug_SCAN_N(arm11, 0x00, ARM11_TAP_DEFAULT);
1639
1640 arm11_add_IR(arm11, ARM11_INTEST, ARM11_TAP_DEFAULT);
1641
1642 scan_field_t chain0_fields[2];
1643
1644 arm11_setup_field(arm11, 32, NULL, &arm11->didr, chain0_fields + 0);
1645 arm11_setup_field(arm11, 8, NULL, &arm11->implementor, chain0_fields + 1);
1646
1647 arm11_add_dr_scan_vc(asizeof(chain0_fields), chain0_fields, TAP_IDLE);
1648
1649 if ((retval=jtag_execute_queue())!=ERROR_OK)
1650 return retval;
1651
1652
1653 switch (arm11->device_id & 0x0FFFF000)
1654 {
1655 case 0x07B36000: LOG_INFO("found ARM1136"); break;
1656 case 0x07B56000: LOG_INFO("found ARM1156"); break;
1657 case 0x07B76000: LOG_INFO("found ARM1176"); break;
1658 default:
1659 {
1660 LOG_ERROR("'target arm11' expects IDCODE 0x*7B*7****");
1661 return ERROR_FAIL;
1662 }
1663 }
1664
1665 arm11->debug_version = (arm11->didr >> 16) & 0x0F;
1666
1667 if (arm11->debug_version != ARM11_DEBUG_V6 &&
1668 arm11->debug_version != ARM11_DEBUG_V61)
1669 {
1670 LOG_ERROR("Only ARMv6 v6 and v6.1 architectures supported.");
1671 return ERROR_FAIL;
1672 }
1673
1674 arm11->brp = ((arm11->didr >> 24) & 0x0F) + 1;
1675 arm11->wrp = ((arm11->didr >> 28) & 0x0F) + 1;
1676
1677 /** \todo TODO: reserve one brp slot if we allow breakpoints during step */
1678 arm11->free_brps = arm11->brp;
1679 arm11->free_wrps = arm11->wrp;
1680
1681 LOG_DEBUG("IDCODE %08x IMPLEMENTOR %02x DIDR %08x",
1682 arm11->device_id,
1683 arm11->implementor,
1684 arm11->didr);
1685
1686 /* as a side-effect this reads DSCR and thus
1687 * clears the ARM11_DSCR_STICKY_PRECISE_DATA_ABORT / Sticky Precise Data Abort Flag
1688 * as suggested by the spec.
1689 */
1690
1691 arm11_check_init(arm11, NULL);
1692
1693 target->type->examined = 1;
1694
1695 return ERROR_OK;
1696 }
1697
1698 int arm11_quit(void)
1699 {
1700 FNC_INFO_NOTIMPLEMENTED;
1701
1702 return ERROR_OK;
1703 }
1704
1705 /** Load a register that is marked !valid in the register cache */
1706 int arm11_get_reg(reg_t *reg)
1707 {
1708 FNC_INFO;
1709
1710 target_t * target = ((arm11_reg_state_t *)reg->arch_info)->target;
1711
1712 if (target->state != TARGET_HALTED)
1713 {
1714 LOG_WARNING("target was not halted");
1715 return ERROR_TARGET_NOT_HALTED;
1716 }
1717
1718 /** \todo TODO: Check this. We assume that all registers are fetched at debug entry. */
1719
1720 #if 0
1721 arm11_common_t *arm11 = target->arch_info;
1722 const arm11_reg_defs_t * arm11_reg_info = arm11_reg_defs + ((arm11_reg_state_t *)reg->arch_info)->def_index;
1723 #endif
1724
1725 return ERROR_OK;
1726 }
1727
1728 /** Change a value in the register cache */
1729 int arm11_set_reg(reg_t *reg, u8 *buf)
1730 {
1731 FNC_INFO;
1732
1733 target_t * target = ((arm11_reg_state_t *)reg->arch_info)->target;
1734 arm11_common_t *arm11 = target->arch_info;
1735 // const arm11_reg_defs_t * arm11_reg_info = arm11_reg_defs + ((arm11_reg_state_t *)reg->arch_info)->def_index;
1736
1737 arm11->reg_values[((arm11_reg_state_t *)reg->arch_info)->def_index] = buf_get_u32(buf, 0, 32);
1738 reg->valid = 1;
1739 reg->dirty = 1;
1740
1741 return ERROR_OK;
1742 }
1743
1744 int arm11_build_reg_cache(target_t *target)
1745 {
1746 arm11_common_t *arm11 = target->arch_info;
1747
1748 NEW(reg_cache_t, cache, 1);
1749 NEW(reg_t, reg_list, ARM11_REGCACHE_COUNT);
1750 NEW(arm11_reg_state_t, arm11_reg_states, ARM11_REGCACHE_COUNT);
1751
1752 if (arm11_regs_arch_type == -1)
1753 arm11_regs_arch_type = register_reg_arch_type(arm11_get_reg, arm11_set_reg);
1754
1755 register_init_dummy(&arm11_gdb_dummy_fp_reg);
1756 register_init_dummy(&arm11_gdb_dummy_fps_reg);
1757
1758 arm11->reg_list = reg_list;
1759
1760 /* Build the process context cache */
1761 cache->name = "arm11 registers";
1762 cache->next = NULL;
1763 cache->reg_list = reg_list;
1764 cache->num_regs = ARM11_REGCACHE_COUNT;
1765
1766 reg_cache_t **cache_p = register_get_last_cache_p(&target->reg_cache);
1767 (*cache_p) = cache;
1768
1769 arm11->core_cache = cache;
1770 // armv7m->process_context = cache;
1771
1772 size_t i;
1773
1774 /* Not very elegant assertion */
1775 if (ARM11_REGCACHE_COUNT != asizeof(arm11->reg_values) ||
1776 ARM11_REGCACHE_COUNT != asizeof(arm11_reg_defs) ||
1777 ARM11_REGCACHE_COUNT != ARM11_RC_MAX)
1778 {
1779 LOG_ERROR("BUG: arm11->reg_values inconsistent (%d " ZU " " ZU " %d)", ARM11_REGCACHE_COUNT, asizeof(arm11->reg_values), asizeof(arm11_reg_defs), ARM11_RC_MAX);
1780 exit(-1);
1781 }
1782
1783 for (i = 0; i < ARM11_REGCACHE_COUNT; i++)
1784 {
1785 reg_t * r = reg_list + i;
1786 const arm11_reg_defs_t * rd = arm11_reg_defs + i;
1787 arm11_reg_state_t * rs = arm11_reg_states + i;
1788
1789 r->name = rd->name;
1790 r->size = 32;
1791 r->value = (u8 *)(arm11->reg_values + i);
1792 r->dirty = 0;
1793 r->valid = 0;
1794 r->bitfield_desc = NULL;
1795 r->num_bitfields = 0;
1796 r->arch_type = arm11_regs_arch_type;
1797 r->arch_info = rs;
1798
1799 rs->def_index = i;
1800 rs->target = target;
1801 }
1802
1803 return ERROR_OK;
1804 }
1805
1806 int arm11_handle_bool(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, bool * var, char * name)
1807 {
1808 if (argc == 0)
1809 {
1810 LOG_INFO("%s is %s.", name, *var ? "enabled" : "disabled");
1811 return ERROR_OK;
1812 }
1813
1814 if (argc != 1)
1815 return ERROR_COMMAND_SYNTAX_ERROR;
1816
1817 switch (args[0][0])
1818 {
1819 case '0': /* 0 */
1820 case 'f': /* false */
1821 case 'F':
1822 case 'd': /* disable */
1823 case 'D':
1824 *var = false;
1825 break;
1826
1827 case '1': /* 1 */
1828 case 't': /* true */
1829 case 'T':
1830 case 'e': /* enable */
1831 case 'E':
1832 *var = true;
1833 break;
1834 }
1835
1836 LOG_INFO("%s %s.", *var ? "Enabled" : "Disabled", name);
1837
1838 return ERROR_OK;
1839 }
1840
1841 #define BOOL_WRAPPER(name, print_name) \
1842 int arm11_handle_bool_##name(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc) \
1843 { \
1844 return arm11_handle_bool(cmd_ctx, cmd, args, argc, &arm11_config_##name, print_name); \
1845 }
1846
1847 #define RC_TOP(name, descr, more) \
1848 { \
1849 command_t * new_cmd = register_command(cmd_ctx, top_cmd, name, NULL, COMMAND_ANY, descr); \
1850 command_t * top_cmd = new_cmd; \
1851 more \
1852 }
1853
1854 #define RC_FINAL(name, descr, handler) \
1855 register_command(cmd_ctx, top_cmd, name, handler, COMMAND_ANY, descr);
1856
1857 #define RC_FINAL_BOOL(name, descr, var) \
1858 register_command(cmd_ctx, top_cmd, name, arm11_handle_bool_##var, COMMAND_ANY, descr);
1859
1860 BOOL_WRAPPER(memwrite_burst, "memory write burst mode")
1861 BOOL_WRAPPER(memwrite_error_fatal, "fatal error mode for memory writes")
1862 BOOL_WRAPPER(memrw_no_increment, "\"no increment\" mode for memory transfers")
1863 BOOL_WRAPPER(step_irq_enable, "IRQs while stepping")
1864
1865 int arm11_handle_vcr(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
1866 {
1867 if (argc == 1)
1868 {
1869 arm11_vcr = strtoul(args[0], NULL, 0);
1870 }
1871 else if (argc != 0)
1872 {
1873 return ERROR_COMMAND_SYNTAX_ERROR;
1874 }
1875
1876 LOG_INFO("VCR 0x%08X", arm11_vcr);
1877 return ERROR_OK;
1878 }
1879
1880 const u32 arm11_coproc_instruction_limits[] =
1881 {
1882 15, /* coprocessor */
1883 7, /* opcode 1 */
1884 15, /* CRn */
1885 15, /* CRm */
1886 7, /* opcode 2 */
1887 0xFFFFFFFF, /* value */
1888 };
1889
1890 const char arm11_mrc_syntax[] = "Syntax: mrc <jtag_target> <coprocessor> <opcode 1> <CRn> <CRm> <opcode 2>. All parameters are numbers only.";
1891 const char arm11_mcr_syntax[] = "Syntax: mcr <jtag_target> <coprocessor> <opcode 1> <CRn> <CRm> <opcode 2> <32bit value to write>. All parameters are numbers only.";
1892
1893 arm11_common_t * arm11_find_target(const char * arg)
1894 {
1895 jtag_tap_t * tap;
1896 target_t * t;
1897
1898 tap = jtag_TapByString(arg);
1899
1900 if (!tap)
1901 return 0;
1902
1903 for (t = all_targets; t; t = t->next)
1904 {
1905 if (t->tap != tap)
1906 continue;
1907
1908 /* if (t->type == arm11_target) */
1909 if (0 == strcmp(t->type->name, "arm11"))
1910 return t->arch_info;
1911 }
1912
1913 return 0;
1914 }
1915
1916 int arm11_handle_mrc_mcr(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, bool read)
1917 {
1918 if (argc != (read ? 6 : 7))
1919 {
1920 LOG_ERROR("Invalid number of arguments. %s", read ? arm11_mrc_syntax : arm11_mcr_syntax);
1921 return -1;
1922 }
1923
1924 arm11_common_t * arm11 = arm11_find_target(args[0]);
1925
1926 if (!arm11)
1927 {
1928 LOG_ERROR("Parameter 1 is not a the JTAG chain position of an ARM11 device. %s",
1929 read ? arm11_mrc_syntax : arm11_mcr_syntax);
1930
1931 return -1;
1932 }
1933
1934 if (arm11->target->state != TARGET_HALTED)
1935 {
1936 LOG_WARNING("target was not halted");
1937 return ERROR_TARGET_NOT_HALTED;
1938 }
1939
1940 u32 values[6];
1941
1942 {size_t i;
1943 for (i = 0; i < (read ? 5 : 6); i++)
1944 {
1945 values[i] = strtoul(args[i + 1], NULL, 0);
1946
1947 if (values[i] > arm11_coproc_instruction_limits[i])
1948 {
1949 LOG_ERROR("Parameter %ld out of bounds (%d max). %s",
1950 (long)(i + 2), arm11_coproc_instruction_limits[i],
1951 read ? arm11_mrc_syntax : arm11_mcr_syntax);
1952 return -1;
1953 }
1954 }}
1955
1956 u32 instr = 0xEE000010 |
1957 (values[0] << 8) |
1958 (values[1] << 21) |
1959 (values[2] << 16) |
1960 (values[3] << 0) |
1961 (values[4] << 5);
1962
1963 if (read)
1964 instr |= 0x00100000;
1965
1966 arm11_run_instr_data_prepare(arm11);
1967
1968 if (read)
1969 {
1970 u32 result;
1971 arm11_run_instr_data_from_core_via_r0(arm11, instr, &result);
1972
1973 LOG_INFO("MRC p%d, %d, R0, c%d, c%d, %d = 0x%08x (%d)",
1974 values[0], values[1], values[2], values[3], values[4], result, result);
1975 }
1976 else
1977 {
1978 arm11_run_instr_data_to_core_via_r0(arm11, instr, values[5]);
1979
1980 LOG_INFO("MRC p%d, %d, R0 (#0x%08x), c%d, c%d, %d",
1981 values[0], values[1],
1982 values[5],
1983 values[2], values[3], values[4]);
1984 }
1985
1986 arm11_run_instr_data_finish(arm11);
1987
1988
1989 return ERROR_OK;
1990 }
1991
1992 int arm11_handle_mrc(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
1993 {
1994 return arm11_handle_mrc_mcr(cmd_ctx, cmd, args, argc, true);
1995 }
1996
1997 int arm11_handle_mcr(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
1998 {
1999 return arm11_handle_mrc_mcr(cmd_ctx, cmd, args, argc, false);
2000 }
2001
2002 int arm11_register_commands(struct command_context_s *cmd_ctx)
2003 {
2004 FNC_INFO;
2005
2006 command_t * top_cmd = NULL;
2007
2008 RC_TOP( "arm11", "arm11 specific commands",
2009
2010 RC_TOP( "memwrite", "Control memory write transfer mode",
2011
2012 RC_FINAL_BOOL( "burst", "Enable/Disable non-standard but fast burst mode (default: enabled)",
2013 memwrite_burst)
2014
2015 RC_FINAL_BOOL( "error_fatal", "Terminate program if transfer error was found (default: enabled)",
2016 memwrite_error_fatal)
2017 )
2018
2019 RC_FINAL_BOOL( "no_increment", "Don't increment address on multi-read/-write (default: disabled)",
2020 memrw_no_increment)
2021
2022 RC_FINAL_BOOL( "step_irq_enable", "Enable interrupts while stepping (default: disabled)",
2023 step_irq_enable)
2024
2025 RC_FINAL( "vcr", "Control (Interrupt) Vector Catch Register",
2026 arm11_handle_vcr)
2027
2028 RC_FINAL( "mrc", "Read Coprocessor register",
2029 arm11_handle_mrc)
2030
2031 RC_FINAL( "mcr", "Write Coprocessor register",
2032 arm11_handle_mcr)
2033 )
2034
2035 return ERROR_OK;
2036 }

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)