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

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)