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

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)