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

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)