- convert all files to unix line-ending
[openocd.git] / src / target / arm11.c
1 /***************************************************************************
2 * Copyright (C) 2008 digenius technology GmbH. *
3 * *
4 * This program is free software; you can redistribute it and/or modify *
5 * it under the terms of the GNU General Public License as published by *
6 * the Free Software Foundation; either version 2 of the License, or *
7 * (at your option) any later version. *
8 * *
9 * This program is distributed in the hope that it will be useful, *
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
12 * GNU General Public License for more details. *
13 * *
14 * You should have received a copy of the GNU General Public License *
15 * along with this program; if not, write to the *
16 * Free Software Foundation, Inc., *
17 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
18 ***************************************************************************/
19
20 #ifdef HAVE_CONFIG_H
21 #include "config.h"
22 #endif
23
24 #include "arm11.h"
25 #include "jtag.h"
26 #include "log.h"
27
28 #include <stdlib.h>
29 #include <string.h>
30
31 #if 0
32 #define _DEBUG_INSTRUCTION_EXECUTION_
33 #endif
34
35
36 #if 0
37 #define FNC_INFO DEBUG("-")
38 #else
39 #define FNC_INFO
40 #endif
41
42 #if 1
43 #define FNC_INFO_NOTIMPLEMENTED do { DEBUG("NOT IMPLEMENTED"); /*exit(-1);*/ } while (0)
44 #else
45 #define FNC_INFO_NOTIMPLEMENTED
46 #endif
47
48 static void arm11_on_enter_debug_state(arm11_common_t * arm11);
49
50
51 #define ARM11_HANDLER(x) \
52 .x = arm11_##x
53
54 target_type_t arm11_target =
55 {
56 .name = "arm11",
57
58 ARM11_HANDLER(poll),
59 ARM11_HANDLER(arch_state),
60
61 ARM11_HANDLER(target_request_data),
62
63 ARM11_HANDLER(halt),
64 ARM11_HANDLER(resume),
65 ARM11_HANDLER(step),
66
67 ARM11_HANDLER(assert_reset),
68 ARM11_HANDLER(deassert_reset),
69 ARM11_HANDLER(soft_reset_halt),
70 ARM11_HANDLER(prepare_reset_halt),
71
72 ARM11_HANDLER(get_gdb_reg_list),
73
74 ARM11_HANDLER(read_memory),
75 ARM11_HANDLER(write_memory),
76
77 ARM11_HANDLER(bulk_write_memory),
78
79 ARM11_HANDLER(checksum_memory),
80
81 ARM11_HANDLER(add_breakpoint),
82 ARM11_HANDLER(remove_breakpoint),
83 ARM11_HANDLER(add_watchpoint),
84 ARM11_HANDLER(remove_watchpoint),
85
86 ARM11_HANDLER(run_algorithm),
87
88 ARM11_HANDLER(register_commands),
89 ARM11_HANDLER(target_command),
90 ARM11_HANDLER(init_target),
91 ARM11_HANDLER(quit),
92 };
93
94 int arm11_regs_arch_type = -1;
95
96
97 enum arm11_regtype
98 {
99 ARM11_REGISTER_CORE,
100 ARM11_REGISTER_CPSR,
101
102 ARM11_REGISTER_FX,
103 ARM11_REGISTER_FPS,
104
105 ARM11_REGISTER_FIQ,
106 ARM11_REGISTER_SVC,
107 ARM11_REGISTER_ABT,
108 ARM11_REGISTER_IRQ,
109 ARM11_REGISTER_UND,
110 ARM11_REGISTER_MON,
111
112 ARM11_REGISTER_SPSR_FIQ,
113 ARM11_REGISTER_SPSR_SVC,
114 ARM11_REGISTER_SPSR_ABT,
115 ARM11_REGISTER_SPSR_IRQ,
116 ARM11_REGISTER_SPSR_UND,
117 ARM11_REGISTER_SPSR_MON,
118
119 /* debug regs */
120 ARM11_REGISTER_DSCR,
121 ARM11_REGISTER_WDTR,
122 ARM11_REGISTER_RDTR,
123 };
124
125
126 typedef struct arm11_reg_defs_s
127 {
128 char * name;
129 u32 num;
130 int gdb_num;
131 enum arm11_regtype type;
132 } arm11_reg_defs_t;
133
134 /* update arm11_regcache_ids when changing this */
135 static const arm11_reg_defs_t arm11_reg_defs[] =
136 {
137 {"r0", 0, 0, ARM11_REGISTER_CORE},
138 {"r1", 1, 1, ARM11_REGISTER_CORE},
139 {"r2", 2, 2, ARM11_REGISTER_CORE},
140 {"r3", 3, 3, ARM11_REGISTER_CORE},
141 {"r4", 4, 4, ARM11_REGISTER_CORE},
142 {"r5", 5, 5, ARM11_REGISTER_CORE},
143 {"r6", 6, 6, ARM11_REGISTER_CORE},
144 {"r7", 7, 7, ARM11_REGISTER_CORE},
145 {"r8", 8, 8, ARM11_REGISTER_CORE},
146 {"r9", 9, 9, ARM11_REGISTER_CORE},
147 {"r10", 10, 10, ARM11_REGISTER_CORE},
148 {"r11", 11, 11, ARM11_REGISTER_CORE},
149 {"r12", 12, 12, ARM11_REGISTER_CORE},
150 {"sp", 13, 13, ARM11_REGISTER_CORE},
151 {"lr", 14, 14, ARM11_REGISTER_CORE},
152 {"pc", 15, 15, ARM11_REGISTER_CORE},
153
154 #if ARM11_REGCACHE_FREGS
155 {"f0", 0, 16, ARM11_REGISTER_FX},
156 {"f1", 1, 17, ARM11_REGISTER_FX},
157 {"f2", 2, 18, ARM11_REGISTER_FX},
158 {"f3", 3, 19, ARM11_REGISTER_FX},
159 {"f4", 4, 20, ARM11_REGISTER_FX},
160 {"f5", 5, 21, ARM11_REGISTER_FX},
161 {"f6", 6, 22, ARM11_REGISTER_FX},
162 {"f7", 7, 23, ARM11_REGISTER_FX},
163 {"fps", 0, 24, ARM11_REGISTER_FPS},
164 #endif
165
166 {"cpsr", 0, 25, ARM11_REGISTER_CPSR},
167
168 #if ARM11_REGCACHE_MODEREGS
169 {"r8_fiq", 8, -1, ARM11_REGISTER_FIQ},
170 {"r9_fiq", 9, -1, ARM11_REGISTER_FIQ},
171 {"r10_fiq", 10, -1, ARM11_REGISTER_FIQ},
172 {"r11_fiq", 11, -1, ARM11_REGISTER_FIQ},
173 {"r12_fiq", 12, -1, ARM11_REGISTER_FIQ},
174 {"r13_fiq", 13, -1, ARM11_REGISTER_FIQ},
175 {"r14_fiq", 14, -1, ARM11_REGISTER_FIQ},
176 {"spsr_fiq", 0, -1, ARM11_REGISTER_SPSR_FIQ},
177
178 {"r13_svc", 13, -1, ARM11_REGISTER_SVC},
179 {"r14_svc", 14, -1, ARM11_REGISTER_SVC},
180 {"spsr_svc", 0, -1, ARM11_REGISTER_SPSR_SVC},
181
182 {"r13_abt", 13, -1, ARM11_REGISTER_ABT},
183 {"r14_abt", 14, -1, ARM11_REGISTER_ABT},
184 {"spsr_abt", 0, -1, ARM11_REGISTER_SPSR_ABT},
185
186 {"r13_irq", 13, -1, ARM11_REGISTER_IRQ},
187 {"r14_irq", 14, -1, ARM11_REGISTER_IRQ},
188 {"spsr_irq", 0, -1, ARM11_REGISTER_SPSR_IRQ},
189
190 {"r13_und", 13, -1, ARM11_REGISTER_UND},
191 {"r14_und", 14, -1, ARM11_REGISTER_UND},
192 {"spsr_und", 0, -1, ARM11_REGISTER_SPSR_UND},
193
194 /* ARM1176 only */
195 {"r13_mon", 13, -1, ARM11_REGISTER_MON},
196 {"r14_mon", 14, -1, ARM11_REGISTER_MON},
197 {"spsr_mon", 0, -1, ARM11_REGISTER_SPSR_MON},
198 #endif
199
200 /* Debug Registers */
201 {"dscr", 0, -1, ARM11_REGISTER_DSCR},
202 {"wdtr", 0, -1, ARM11_REGISTER_WDTR},
203 {"rdtr", 0, -1, ARM11_REGISTER_RDTR},
204 };
205
206 enum arm11_regcache_ids
207 {
208 ARM11_RC_R0,
209 ARM11_RC_RX = ARM11_RC_R0,
210
211 ARM11_RC_R1,
212 ARM11_RC_R2,
213 ARM11_RC_R3,
214 ARM11_RC_R4,
215 ARM11_RC_R5,
216 ARM11_RC_R6,
217 ARM11_RC_R7,
218 ARM11_RC_R8,
219 ARM11_RC_R9,
220 ARM11_RC_R10,
221 ARM11_RC_R11,
222 ARM11_RC_R12,
223 ARM11_RC_R13,
224 ARM11_RC_SP = ARM11_RC_R13,
225 ARM11_RC_R14,
226 ARM11_RC_LR = ARM11_RC_R14,
227 ARM11_RC_R15,
228 ARM11_RC_PC = ARM11_RC_R15,
229
230 #if ARM11_REGCACHE_FREGS
231 ARM11_RC_F0,
232 ARM11_RC_FX = ARM11_RC_F0,
233 ARM11_RC_F1,
234 ARM11_RC_F2,
235 ARM11_RC_F3,
236 ARM11_RC_F4,
237 ARM11_RC_F5,
238 ARM11_RC_F6,
239 ARM11_RC_F7,
240 ARM11_RC_FPS,
241 #endif
242
243 ARM11_RC_CPSR,
244
245 #if ARM11_REGCACHE_MODEREGS
246 ARM11_RC_R8_FIQ,
247 ARM11_RC_R9_FIQ,
248 ARM11_RC_R10_FIQ,
249 ARM11_RC_R11_FIQ,
250 ARM11_RC_R12_FIQ,
251 ARM11_RC_R13_FIQ,
252 ARM11_RC_R14_FIQ,
253 ARM11_RC_SPSR_FIQ,
254
255 ARM11_RC_R13_SVC,
256 ARM11_RC_R14_SVC,
257 ARM11_RC_SPSR_SVC,
258
259 ARM11_RC_R13_ABT,
260 ARM11_RC_R14_ABT,
261 ARM11_RC_SPSR_ABT,
262
263 ARM11_RC_R13_IRQ,
264 ARM11_RC_R14_IRQ,
265 ARM11_RC_SPSR_IRQ,
266
267 ARM11_RC_R13_UND,
268 ARM11_RC_R14_UND,
269 ARM11_RC_SPSR_UND,
270
271 ARM11_RC_R13_MON,
272 ARM11_RC_R14_MON,
273 ARM11_RC_SPSR_MON,
274 #endif
275
276 ARM11_RC_DSCR,
277 ARM11_RC_WDTR,
278 ARM11_RC_RDTR,
279
280
281 ARM11_RC_MAX,
282 };
283
284 #define ARM11_GDB_REGISTER_COUNT 26
285
286 u8 arm11_gdb_dummy_fp_value[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
287
288 reg_t arm11_gdb_dummy_fp_reg =
289 {
290 "GDB dummy floating-point register", arm11_gdb_dummy_fp_value, 0, 1, 96, NULL, 0, NULL, 0
291 };
292
293 u8 arm11_gdb_dummy_fps_value[] = {0, 0, 0, 0};
294
295 reg_t arm11_gdb_dummy_fps_reg =
296 {
297 "GDB dummy floating-point status register", arm11_gdb_dummy_fps_value, 0, 1, 32, NULL, 0, NULL, 0
298 };
299
300
301
302 /** Check and if necessary take control of the system
303 *
304 * \param arm11 Target state variable.
305 * \param dscr If the current DSCR content is
306 * available a pointer to a word holding the
307 * DSCR can be passed. Otherwise use NULL.
308 */
309 void arm11_check_init(arm11_common_t * arm11, u32 * dscr)
310 {
311 FNC_INFO;
312
313 u32 dscr_local_tmp_copy;
314
315 if (!dscr)
316 {
317 dscr = &dscr_local_tmp_copy;
318 *dscr = arm11_read_DSCR(arm11);
319 }
320
321 if (!(*dscr & ARM11_DSCR_MODE_SELECT))
322 {
323 DEBUG("Bringing target into debug mode");
324
325 *dscr |= ARM11_DSCR_MODE_SELECT; /* Halt debug-mode */
326 arm11_write_DSCR(arm11, *dscr);
327
328 /* add further reset initialization here */
329
330 if (*dscr & ARM11_DSCR_CORE_HALTED)
331 {
332 arm11->target->state = TARGET_HALTED;
333 arm11->target->debug_reason = arm11_get_DSCR_debug_reason(*dscr);
334 }
335 else
336 {
337 arm11->target->state = TARGET_RUNNING;
338 arm11->target->debug_reason = DBG_REASON_NOTHALTED;
339 }
340
341 arm11_sc7_clear_bw(arm11);
342 }
343 }
344
345
346
347 #define R(x) \
348 (arm11->reg_values[ARM11_RC_##x])
349
350 /** Save processor state.
351 *
352 * This is called when the HALT instruction has succeeded
353 * or on other occasions that stop the processor.
354 *
355 */
356 static void arm11_on_enter_debug_state(arm11_common_t * arm11)
357 {
358 FNC_INFO;
359
360 {size_t i;
361 for(i = 0; i < asizeof(arm11->reg_values); i++)
362 {
363 arm11->reg_list[i].valid = 1;
364 arm11->reg_list[i].dirty = 0;
365 }}
366
367 /* Save DSCR */
368
369 R(DSCR) = arm11_read_DSCR(arm11);
370
371 /* Save wDTR */
372
373 if (R(DSCR) & ARM11_DSCR_WDTR_FULL)
374 {
375 arm11_add_debug_SCAN_N(arm11, 0x05, -1);
376
377 arm11_add_IR(arm11, ARM11_INTEST, -1);
378
379 scan_field_t chain5_fields[3];
380
381 arm11_setup_field(arm11, 32, NULL, &R(WDTR), chain5_fields + 0);
382 arm11_setup_field(arm11, 1, NULL, NULL, chain5_fields + 1);
383 arm11_setup_field(arm11, 1, NULL, NULL, chain5_fields + 2);
384
385 jtag_add_dr_scan_vc(asizeof(chain5_fields), chain5_fields, TAP_PD);
386 }
387 else
388 {
389 arm11->reg_list[ARM11_RC_WDTR].valid = 0;
390 }
391
392
393 /* DSCR: set ARM11_DSCR_EXECUTE_ARM_INSTRUCTION_ENABLE */
394 /* ARM1176 spec says this is needed only for wDTR/rDTR's "ITR mode", but not to issue ITRs
395 ARM1136 seems to require this to issue ITR's as well */
396
397 u32 new_dscr = R(DSCR) | ARM11_DSCR_EXECUTE_ARM_INSTRUCTION_ENABLE;
398
399 /* this executes JTAG queue: */
400
401 arm11_write_DSCR(arm11, new_dscr);
402
403 // jtag_execute_queue();
404
405
406
407 // DEBUG("SAVE DSCR %08x", R(DSCR));
408
409 // if (R(DSCR) & ARM11_DSCR_WDTR_FULL)
410 // DEBUG("SAVE wDTR %08x", R(WDTR));
411
412
413 /* From the spec:
414 Before executing any instruction in debug state you have to drain the write buffer.
415 This ensures that no imprecise Data Aborts can return at a later point:*/
416
417 /** \todo TODO: Test drain write buffer. */
418
419 #if 0
420 while (1)
421 {
422 /* MRC p14,0,R0,c5,c10,0 */
423 // arm11_run_instr_no_data1(arm11, /*0xee150e1a*/0xe320f000);
424
425 /* mcr 15, 0, r0, cr7, cr10, {4} */
426 arm11_run_instr_no_data1(arm11, 0xee070f9a);
427
428 u32 dscr = arm11_read_DSCR(arm11);
429
430 DEBUG("DRAIN, DSCR %08x", dscr);
431
432 if (dscr & ARM11_DSCR_STICKY_IMPRECISE_DATA_ABORT)
433 {
434 arm11_run_instr_no_data1(arm11, 0xe320f000);
435
436 dscr = arm11_read_DSCR(arm11);
437
438 DEBUG("DRAIN, DSCR %08x (DONE)", dscr);
439
440 break;
441 }
442 }
443 #endif
444
445
446 arm11_run_instr_data_prepare(arm11);
447
448 /* save r0 - r14 */
449
450
451 /** \todo TODO: handle other mode registers */
452
453 {size_t i;
454 for (i = 0; i < 15; i++)
455 {
456 /* MCR p14,0,R?,c0,c5,0 */
457 arm11_run_instr_data_from_core(arm11, 0xEE000E15 | (i << 12), &R(RX + i), 1);
458 }}
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 // DEBUG("SAVE PC %08x", R(PC));
501
502 arm11_run_instr_data_finish(arm11);
503
504
505 {size_t i;
506 for(i = 0; i < ARM11_REGCACHE_COUNT; i++)
507 {
508 if (!arm11->reg_list[i].valid)
509 {
510 if (arm11->reg_history[i].valid)
511 INFO("%8s INVALID (%08x)", arm11_reg_defs[i].name, arm11->reg_history[i].value);
512 }
513 else
514 {
515 if (arm11->reg_history[i].valid)
516 {
517 if (arm11->reg_history[i].value != arm11->reg_values[i])
518 INFO("%8s %08x (%08x)", arm11_reg_defs[i].name, arm11->reg_values[i], arm11->reg_history[i].value);
519 }
520 else
521 {
522 INFO("%8s %08x (INVALID)", arm11_reg_defs[i].name, arm11->reg_values[i]);
523 }
524 }
525 }}
526 }
527
528
529 /** Restore processor state
530 *
531 * This is called in preparation for the RESTART function.
532 *
533 */
534 void arm11_leave_debug_state(arm11_common_t * arm11)
535 {
536 FNC_INFO;
537
538 arm11_run_instr_data_prepare(arm11);
539
540 /** \todo TODO: handle other mode registers */
541
542 /* restore R1 - R14 */
543 {size_t i;
544 for (i = 1; i < 15; i++)
545 {
546 if (!arm11->reg_list[ARM11_RC_RX + i].dirty)
547 continue;
548
549 /* MRC p14,0,r?,c0,c5,0 */
550 arm11_run_instr_data_to_core1(arm11, 0xee100e15 | (i << 12), R(RX + i));
551
552 // DEBUG("RESTORE R%d %08x", i, R(RX + i));
553 }}
554
555 arm11_run_instr_data_finish(arm11);
556
557
558 /* spec says clear wDTR and rDTR; we assume they are clear as
559 otherwide out programming would be sloppy */
560
561 {
562 u32 DSCR = arm11_read_DSCR(arm11);
563
564 if (DSCR & (ARM11_DSCR_RDTR_FULL | ARM11_DSCR_WDTR_FULL))
565 {
566 ERROR("wDTR/rDTR inconsistent (DSCR %08x)", DSCR);
567 }
568 }
569
570 arm11_run_instr_data_prepare(arm11);
571
572 /* restore original wDTR */
573
574 if ((R(DSCR) & ARM11_DSCR_WDTR_FULL) || arm11->reg_list[ARM11_RC_WDTR].dirty)
575 {
576 /* MCR p14,0,R0,c0,c5,0 */
577 arm11_run_instr_data_to_core_via_r0(arm11, 0xee000e15, R(WDTR));
578 }
579
580 /* restore CPSR */
581
582 /* MSR CPSR,R0*/
583 arm11_run_instr_data_to_core_via_r0(arm11, 0xe129f000, R(CPSR));
584
585
586 /* restore PC */
587
588 /* MOV PC,R0 */
589 arm11_run_instr_data_to_core_via_r0(arm11, 0xe1a0f000, R(PC));
590
591
592 /* restore R0 */
593
594 /* MRC p14,0,r0,c0,c5,0 */
595 arm11_run_instr_data_to_core1(arm11, 0xee100e15, R(R0));
596
597 arm11_run_instr_data_finish(arm11);
598
599
600 /* restore DSCR */
601
602 arm11_write_DSCR(arm11, R(DSCR));
603
604
605 /* restore rDTR */
606
607 if (R(DSCR) & ARM11_DSCR_RDTR_FULL || arm11->reg_list[ARM11_RC_RDTR].dirty)
608 {
609 arm11_add_debug_SCAN_N(arm11, 0x05, -1);
610
611 arm11_add_IR(arm11, ARM11_EXTEST, -1);
612
613 scan_field_t chain5_fields[3];
614
615 u8 Ready = 0; /* ignored */
616 u8 Valid = 0; /* ignored */
617
618 arm11_setup_field(arm11, 32, &R(RDTR), NULL, chain5_fields + 0);
619 arm11_setup_field(arm11, 1, &Ready, NULL, chain5_fields + 1);
620 arm11_setup_field(arm11, 1, &Valid, NULL, chain5_fields + 2);
621
622 jtag_add_dr_scan_vc(asizeof(chain5_fields), chain5_fields, TAP_PD);
623 }
624
625
626 {size_t i;
627 for(i = 0; i < ARM11_REGCACHE_COUNT; i++)
628 {
629 arm11->reg_history[i].value = arm11->reg_values[i];
630 arm11->reg_history[i].valid = arm11->reg_list[i].valid;
631
632 arm11->reg_list[i].valid = 0;
633 arm11->reg_list[i].dirty = 0;
634 }}
635 }
636
637
638 /* poll current target status */
639 int arm11_poll(struct target_s *target)
640 {
641 FNC_INFO;
642
643 arm11_common_t * arm11 = target->arch_info;
644
645 if (arm11->trst_active)
646 return ERROR_OK;
647
648 u32 dscr = arm11_read_DSCR(arm11);
649
650 DEBUG("DSCR %08x", dscr);
651
652 arm11_check_init(arm11, &dscr);
653
654 if (dscr & ARM11_DSCR_CORE_HALTED)
655 {
656 // DEBUG("CH %d", target->state);
657
658 if (target->state != TARGET_HALTED)
659 {
660 DEBUG("enter TARGET_HALTED");
661 target->state = TARGET_HALTED;
662 target->debug_reason = arm11_get_DSCR_debug_reason(dscr);
663 arm11_on_enter_debug_state(arm11);
664 }
665 }
666 else
667 {
668 // DEBUG("CR %d", target->state);
669
670 if (target->state != TARGET_RUNNING)
671 {
672 DEBUG("enter TARGET_RUNNING");
673 target->state = TARGET_RUNNING;
674 target->debug_reason = DBG_REASON_NOTHALTED;
675 }
676 }
677
678 return ERROR_OK;
679 }
680 /* architecture specific status reply */
681 int arm11_arch_state(struct target_s *target)
682 {
683 FNC_INFO_NOTIMPLEMENTED;
684
685 return ERROR_OK;
686 }
687
688
689 /* target request support */
690 int arm11_target_request_data(struct target_s *target, u32 size, u8 *buffer)
691 {
692 FNC_INFO_NOTIMPLEMENTED;
693
694 return ERROR_OK;
695 }
696
697
698
699 /* target execution control */
700 int arm11_halt(struct target_s *target)
701 {
702 FNC_INFO;
703
704 arm11_common_t * arm11 = target->arch_info;
705
706 DEBUG("target->state: %s", target_state_strings[target->state]);
707
708 if (target->state == TARGET_HALTED)
709 {
710 WARNING("target was already halted");
711 return ERROR_TARGET_ALREADY_HALTED;
712 }
713
714 if (arm11->trst_active)
715 {
716 arm11->halt_requested = true;
717 return ERROR_OK;
718 }
719
720 arm11_add_IR(arm11, ARM11_HALT, TAP_RTI);
721
722 jtag_execute_queue();
723
724 u32 dscr;
725
726 while (1)
727 {
728 dscr = arm11_read_DSCR(arm11);
729
730 if (dscr & ARM11_DSCR_CORE_HALTED)
731 break;
732 }
733
734 arm11_on_enter_debug_state(arm11);
735
736 target->state = TARGET_HALTED;
737 target->debug_reason = arm11_get_DSCR_debug_reason(dscr);
738
739 return ERROR_OK;
740 }
741
742
743 int arm11_resume(struct target_s *target, int current, u32 address, int handle_breakpoints, int debug_execution)
744 {
745 FNC_INFO;
746
747 arm11_common_t * arm11 = target->arch_info;
748
749 DEBUG("target->state: %s", target_state_strings[target->state]);
750
751 if (target->state != TARGET_HALTED)
752 {
753 WARNING("target was not halted");
754 return ERROR_TARGET_NOT_HALTED;
755 }
756
757 if (!current)
758 R(PC) = address;
759
760 target->state = TARGET_RUNNING;
761 target->debug_reason = DBG_REASON_NOTHALTED;
762
763 arm11_leave_debug_state(arm11);
764
765 arm11_add_IR(arm11, ARM11_RESTART, TAP_RTI);
766
767 jtag_execute_queue();
768
769 while (1)
770 {
771 u32 dscr = arm11_read_DSCR(arm11);
772
773 DEBUG("DSCR %08x", dscr);
774
775 if (dscr & ARM11_DSCR_CORE_RESTARTED)
776 break;
777 }
778
779 DEBUG("RES %d", target->state);
780
781 return ERROR_OK;
782 }
783
784 int arm11_step(struct target_s *target, int current, u32 address, int handle_breakpoints)
785 {
786 FNC_INFO;
787
788 DEBUG("target->state: %s", target_state_strings[target->state]);
789
790 if (target->state != TARGET_HALTED)
791 {
792 WARNING("target was not halted");
793 return ERROR_TARGET_NOT_HALTED;
794 }
795
796 arm11_common_t * arm11 = target->arch_info;
797
798 /** \todo TODO: check if break-/watchpoints make any sense at all in combination
799 * with this. */
800
801 /** \todo TODO: check if disabling IRQs might be a good idea here. Alternatively
802 the VCR might be something worth looking into. */
803
804 /* Set up breakpoint for stepping */
805
806 arm11_sc7_action_t brp[2];
807
808 brp[0].write = 1;
809 brp[0].address = ARM11_SC7_BVR0;
810 brp[0].value = R(PC);
811 brp[1].write = 1;
812 brp[1].address = ARM11_SC7_BCR0;
813 brp[1].value = 0x1 | (3 << 1) | (0x0F << 5) | (0 << 14) | (0 << 16) | (0 << 20) | (2 << 21);
814
815 arm11_sc7_run(arm11, brp, asizeof(brp));
816
817 /* resume */
818
819 arm11_leave_debug_state(arm11);
820
821 arm11_add_IR(arm11, ARM11_RESTART, TAP_RTI);
822
823 jtag_execute_queue();
824
825 /** \todo TODO: add a timeout */
826
827 /* wait for halt */
828
829 while (1)
830 {
831 u32 dscr = arm11_read_DSCR(arm11);
832
833 DEBUG("DSCR %08x", dscr);
834
835 if ((dscr & (ARM11_DSCR_CORE_RESTARTED | ARM11_DSCR_CORE_HALTED)) ==
836 (ARM11_DSCR_CORE_RESTARTED | ARM11_DSCR_CORE_HALTED))
837 break;
838 }
839
840
841 /* clear breakpoint */
842
843 arm11_sc7_clear_bw(arm11);
844
845
846 /* save state */
847
848 arm11_on_enter_debug_state(arm11);
849
850 // target->state = TARGET_HALTED;
851 target->debug_reason = DBG_REASON_SINGLESTEP;
852
853 return ERROR_OK;
854 }
855
856
857 /* target reset control */
858 int arm11_assert_reset(struct target_s *target)
859 {
860 FNC_INFO;
861
862 #if 0
863 /* assert reset lines */
864 /* resets only the DBGTAP, not the ARM */
865
866 jtag_add_reset(1, 0);
867 jtag_add_sleep(5000);
868
869 arm11_common_t * arm11 = target->arch_info;
870 arm11->trst_active = true;
871 #endif
872
873 return ERROR_OK;
874 }
875
876 int arm11_deassert_reset(struct target_s *target)
877 {
878 FNC_INFO;
879
880 #if 0
881 DEBUG("target->state: %s", target_state_strings[target->state]);
882
883 /* deassert reset lines */
884 jtag_add_reset(0, 0);
885
886 arm11_common_t * arm11 = target->arch_info;
887 arm11->trst_active = false;
888
889 if (arm11->halt_requested)
890 return arm11_halt(target);
891 #endif
892
893 return ERROR_OK;
894 }
895
896 int arm11_soft_reset_halt(struct target_s *target)
897 {
898 FNC_INFO_NOTIMPLEMENTED;
899
900 return ERROR_OK;
901 }
902
903 int arm11_prepare_reset_halt(struct target_s *target)
904 {
905 FNC_INFO_NOTIMPLEMENTED;
906
907 return ERROR_OK;
908 }
909
910
911 /* target register access for gdb */
912 int arm11_get_gdb_reg_list(struct target_s *target, struct reg_s **reg_list[], int *reg_list_size)
913 {
914 FNC_INFO;
915
916 arm11_common_t * arm11 = target->arch_info;
917
918 if (target->state != TARGET_HALTED)
919 {
920 return ERROR_TARGET_NOT_HALTED;
921 }
922
923 *reg_list_size = ARM11_GDB_REGISTER_COUNT;
924 *reg_list = malloc(sizeof(reg_t*) * ARM11_GDB_REGISTER_COUNT);
925
926 {size_t i;
927 for (i = 16; i < 24; i++)
928 {
929 (*reg_list)[i] = &arm11_gdb_dummy_fp_reg;
930 }}
931
932 (*reg_list)[24] = &arm11_gdb_dummy_fps_reg;
933
934
935 {size_t i;
936 for (i = 0; i < ARM11_REGCACHE_COUNT; i++)
937 {
938 if (arm11_reg_defs[i].gdb_num == -1)
939 continue;
940
941 (*reg_list)[arm11_reg_defs[i].gdb_num] = arm11->reg_list + i;
942 }}
943
944 return ERROR_OK;
945 }
946
947
948 /* target memory access
949 * size: 1 = byte (8bit), 2 = half-word (16bit), 4 = word (32bit)
950 * count: number of items of <size>
951 */
952 int arm11_read_memory(struct target_s *target, u32 address, u32 size, u32 count, u8 *buffer)
953 {
954 /** \todo TODO: check if buffer cast to u32* and u16* might cause alignment problems */
955
956 FNC_INFO;
957
958 DEBUG("ADDR %08x SIZE %08x COUNT %08x", address, size, count);
959
960 arm11_common_t * arm11 = target->arch_info;
961
962 arm11_run_instr_data_prepare(arm11);
963
964 /* MRC p14,0,r0,c0,c5,0 */
965 arm11_run_instr_data_to_core1(arm11, 0xee100e15, address);
966
967 switch (size)
968 {
969 case 1:
970 /** \todo TODO: check if dirty is the right choice to force a rewrite on arm11_resume() */
971 arm11->reg_list[ARM11_RC_R1].dirty = 1;
972
973 while (count--)
974 {
975 /* ldrb r1, [r0], #1 */
976 arm11_run_instr_no_data1(arm11, 0xe4d01001);
977
978 u32 res;
979 /* MCR p14,0,R1,c0,c5,0 */
980 arm11_run_instr_data_from_core(arm11, 0xEE001E15, &res, 1);
981
982 *buffer++ = res;
983 }
984 break;
985
986 case 2:
987 {
988 arm11->reg_list[ARM11_RC_R1].dirty = 1;
989
990 u16 * buf16 = (u16*)buffer;
991
992 while (count--)
993 {
994 /* ldrh r1, [r0], #2 */
995 arm11_run_instr_no_data1(arm11, 0xe0d010b2);
996
997 u32 res;
998
999 /* MCR p14,0,R1,c0,c5,0 */
1000 arm11_run_instr_data_from_core(arm11, 0xEE001E15, &res, 1);
1001
1002 *buf16++ = res;
1003 }
1004 break;
1005 }
1006
1007 case 4:
1008
1009 /* LDC p14,c5,[R0],#4 */
1010 arm11_run_instr_data_from_core(arm11, 0xecb05e01, (u32 *)buffer, count);
1011 break;
1012 }
1013
1014 arm11_run_instr_data_finish(arm11);
1015
1016 return ERROR_OK;
1017 }
1018
1019 int arm11_write_memory(struct target_s *target, u32 address, u32 size, u32 count, u8 *buffer)
1020 {
1021 FNC_INFO;
1022
1023 DEBUG("ADDR %08x SIZE %08x COUNT %08x", address, size, count);
1024
1025 arm11_common_t * arm11 = target->arch_info;
1026
1027 arm11_run_instr_data_prepare(arm11);
1028
1029 /* MRC p14,0,r0,c0,c5,0 */
1030 arm11_run_instr_data_to_core1(arm11, 0xee100e15, address);
1031
1032 switch (size)
1033 {
1034 case 1:
1035 arm11->reg_list[ARM11_RC_R1].dirty = 1;
1036
1037 while (count--)
1038 {
1039 /* MRC p14,0,r1,c0,c5,0 */
1040 arm11_run_instr_data_to_core1(arm11, 0xee101e15, *buffer++);
1041
1042 /* strb r1, [r0], #1 */
1043 arm11_run_instr_no_data1(arm11, 0xe4c01001);
1044 }
1045 break;
1046
1047 case 2:
1048 {
1049 arm11->reg_list[ARM11_RC_R1].dirty = 1;
1050
1051 u16 * buf16 = (u16*)buffer;
1052
1053 while (count--)
1054 {
1055 /* MRC p14,0,r1,c0,c5,0 */
1056 arm11_run_instr_data_to_core1(arm11, 0xee101e15, *buf16++);
1057
1058 /* strh r1, [r0], #2 */
1059 arm11_run_instr_no_data1(arm11, 0xe0c010b2);
1060 }
1061 break;
1062 }
1063
1064 case 4:
1065 /** \todo TODO: check if buffer cast to u32* might cause alignment problems */
1066
1067 /* STC p14,c5,[R0],#4 */
1068 arm11_run_instr_data_to_core(arm11, 0xeca05e01, (u32 *)buffer, count);
1069 break;
1070 }
1071
1072 arm11_run_instr_data_finish(arm11);
1073
1074 return ERROR_OK;
1075 }
1076
1077
1078 /* write target memory in multiples of 4 byte, optimized for writing large quantities of data */
1079 int arm11_bulk_write_memory(struct target_s *target, u32 address, u32 count, u8 *buffer)
1080 {
1081 FNC_INFO;
1082
1083 return arm11_write_memory(target, address, 4, count, buffer);
1084 }
1085
1086
1087 int arm11_checksum_memory(struct target_s *target, u32 address, u32 count, u32* checksum)
1088 {
1089 FNC_INFO_NOTIMPLEMENTED;
1090
1091 return ERROR_OK;
1092 }
1093
1094
1095 /* target break-/watchpoint control
1096 * rw: 0 = write, 1 = read, 2 = access
1097 */
1098 int arm11_add_breakpoint(struct target_s *target, breakpoint_t *breakpoint)
1099 {
1100 FNC_INFO_NOTIMPLEMENTED;
1101
1102 return ERROR_OK;
1103 }
1104
1105 int arm11_remove_breakpoint(struct target_s *target, breakpoint_t *breakpoint)
1106 {
1107 FNC_INFO_NOTIMPLEMENTED;
1108
1109 return ERROR_OK;
1110 }
1111
1112 int arm11_add_watchpoint(struct target_s *target, watchpoint_t *watchpoint)
1113 {
1114 FNC_INFO_NOTIMPLEMENTED;
1115
1116 return ERROR_OK;
1117 }
1118
1119 int arm11_remove_watchpoint(struct target_s *target, watchpoint_t *watchpoint)
1120 {
1121 FNC_INFO_NOTIMPLEMENTED;
1122
1123 return ERROR_OK;
1124 }
1125
1126
1127 /* target algorithm support */
1128 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)
1129 {
1130 FNC_INFO_NOTIMPLEMENTED;
1131
1132 return ERROR_OK;
1133 }
1134
1135
1136 int arm11_register_commands(struct command_context_s *cmd_ctx)
1137 {
1138 FNC_INFO;
1139
1140 return ERROR_OK;
1141 }
1142
1143 int arm11_target_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct target_s *target)
1144 {
1145 FNC_INFO;
1146
1147 if (argc < 4)
1148 {
1149 ERROR("'target arm11' 4th argument <jtag chain pos>");
1150 exit(-1);
1151 }
1152
1153 int chain_pos = strtoul(args[3], NULL, 0);
1154
1155 NEW(arm11_common_t, arm11, 1);
1156
1157 arm11->target = target;
1158
1159 /* prepare JTAG information for the new target */
1160 arm11->jtag_info.chain_pos = chain_pos;
1161 arm11->jtag_info.scann_size = 5;
1162
1163 arm_jtag_setup_connection(&arm11->jtag_info);
1164
1165 jtag_device_t *device = jtag_get_device(chain_pos);
1166
1167 if (device->ir_length != 5)
1168 {
1169 ERROR("'target arm11' expects 'jtag_device 5 0x01 0x1F 0x1E'");
1170 exit(-1);
1171 }
1172
1173 target->arch_info = arm11;
1174
1175 return ERROR_OK;
1176 }
1177
1178 int arm11_init_target(struct command_context_s *cmd_ctx, struct target_s *target)
1179 {
1180 FNC_INFO;
1181
1182 arm11_common_t * arm11 = target->arch_info;
1183
1184 /* check IDCODE */
1185
1186 arm11_add_IR(arm11, ARM11_IDCODE, -1);
1187
1188 scan_field_t idcode_field;
1189
1190 arm11_setup_field(arm11, 32, NULL, &arm11->device_id, &idcode_field);
1191
1192 jtag_add_dr_scan_vc(1, &idcode_field, TAP_PD);
1193
1194 /* check DIDR */
1195
1196 arm11_add_debug_SCAN_N(arm11, 0x00, -1);
1197
1198 arm11_add_IR(arm11, ARM11_INTEST, -1);
1199
1200 scan_field_t chain0_fields[2];
1201
1202 arm11_setup_field(arm11, 32, NULL, &arm11->didr, chain0_fields + 0);
1203 arm11_setup_field(arm11, 8, NULL, &arm11->implementor, chain0_fields + 1);
1204
1205 jtag_add_dr_scan_vc(asizeof(chain0_fields), chain0_fields, TAP_RTI);
1206
1207 jtag_execute_queue();
1208
1209
1210 switch (arm11->device_id & 0x0FFFF000)
1211 {
1212 case 0x07B36000: INFO("found ARM1136"); break;
1213 case 0x07B56000: INFO("found ARM1156"); break;
1214 case 0x07B76000: INFO("found ARM1176"); break;
1215 default:
1216 {
1217 ERROR("'target arm11' expects IDCODE 0x*7B*7****");
1218 exit(-1);
1219 }
1220 }
1221
1222 arm11->brp = ((arm11->didr >> 24) & 0x0F) + 1;
1223 arm11->wrp = ((arm11->didr >> 28) & 0x0F) + 1;
1224
1225
1226 DEBUG("IDCODE %08x IMPLEMENTOR %02x DIDR %08x",
1227 arm11->device_id,
1228 arm11->implementor,
1229 arm11->didr);
1230
1231 arm11_build_reg_cache(target);
1232
1233
1234 /* as a side-effect this reads DSCR and thus
1235 * clears the ARM11_DSCR_STICKY_PRECISE_DATA_ABORT / Sticky Precise Data Abort Flag
1236 * as suggested by the spec.
1237 */
1238
1239 arm11_check_init(arm11, NULL);
1240
1241 return ERROR_OK;
1242 }
1243
1244 int arm11_quit(void)
1245 {
1246 FNC_INFO_NOTIMPLEMENTED;
1247
1248 return ERROR_OK;
1249 }
1250
1251 /** Load a register that is marked !valid in the register cache */
1252 int arm11_get_reg(reg_t *reg)
1253 {
1254 FNC_INFO;
1255
1256 target_t * target = ((arm11_reg_state_t *)reg->arch_info)->target;
1257
1258 if (target->state != TARGET_HALTED)
1259 {
1260 return ERROR_TARGET_NOT_HALTED;
1261 }
1262
1263 /** \todo TODO: Check this. We assume that all registers are fetched debug entry. */
1264
1265 #if 0
1266 arm11_common_t *arm11 = target->arch_info;
1267 const arm11_reg_defs_t * arm11_reg_info = arm11_reg_defs + ((arm11_reg_state_t *)reg->arch_info)->def_index;
1268 #endif
1269
1270 return ERROR_OK;
1271 }
1272
1273 /** Change a value in the register cache */
1274 int arm11_set_reg(reg_t *reg, u8 *buf)
1275 {
1276 FNC_INFO;
1277
1278 target_t * target = ((arm11_reg_state_t *)reg->arch_info)->target;
1279 arm11_common_t *arm11 = target->arch_info;
1280 // const arm11_reg_defs_t * arm11_reg_info = arm11_reg_defs + ((arm11_reg_state_t *)reg->arch_info)->def_index;
1281
1282 arm11->reg_values[((arm11_reg_state_t *)reg->arch_info)->def_index] = buf_get_u32(buf, 0, 32);
1283 reg->valid = 1;
1284 reg->dirty = 1;
1285
1286 return ERROR_OK;
1287 }
1288
1289
1290 void arm11_build_reg_cache(target_t *target)
1291 {
1292 arm11_common_t *arm11 = target->arch_info;
1293
1294 NEW(reg_cache_t, cache, 1);
1295 NEW(reg_t, reg_list, ARM11_REGCACHE_COUNT);
1296 NEW(arm11_reg_state_t, arm11_reg_states, ARM11_REGCACHE_COUNT);
1297
1298 if (arm11_regs_arch_type == -1)
1299 arm11_regs_arch_type = register_reg_arch_type(arm11_get_reg, arm11_set_reg);
1300
1301 arm11->reg_list = reg_list;
1302
1303 /* Build the process context cache */
1304 cache->name = "arm11 registers";
1305 cache->next = NULL;
1306 cache->reg_list = reg_list;
1307 cache->num_regs = ARM11_REGCACHE_COUNT;
1308
1309 reg_cache_t **cache_p = register_get_last_cache_p(&target->reg_cache);
1310 (*cache_p) = cache;
1311
1312 // armv7m->core_cache = cache;
1313 // armv7m->process_context = cache;
1314
1315 size_t i;
1316
1317 /* Not very elegant assertion */
1318 if (ARM11_REGCACHE_COUNT != asizeof(arm11->reg_values) ||
1319 ARM11_REGCACHE_COUNT != asizeof(arm11_reg_defs) ||
1320 ARM11_REGCACHE_COUNT != ARM11_RC_MAX)
1321 {
1322 ERROR("arm11->reg_values inconsistent (%d %d %d %d)", ARM11_REGCACHE_COUNT, asizeof(arm11->reg_values), asizeof(arm11_reg_defs), ARM11_RC_MAX);
1323 exit(-1);
1324 }
1325
1326 for (i = 0; i < ARM11_REGCACHE_COUNT; i++)
1327 {
1328 reg_t * r = reg_list + i;
1329 const arm11_reg_defs_t * rd = arm11_reg_defs + i;
1330 arm11_reg_state_t * rs = arm11_reg_states + i;
1331
1332 r->name = rd->name;
1333 r->size = 32;
1334 r->value = (u8 *)(arm11->reg_values + i);
1335 r->dirty = 0;
1336 r->valid = 0;
1337 r->bitfield_desc = NULL;
1338 r->num_bitfields = 0;
1339 r->arch_type = arm11_regs_arch_type;
1340 r->arch_info = rs;
1341
1342 rs->def_index = i;
1343 rs->target = target;
1344 }
1345 }
1346
1347 #if 0
1348 arm11_run_instr_data_prepare(arm11);
1349
1350 /* MRC p14,0,r0,c0,c5,0 */
1351 arm11_run_instr_data_to_core(arm11, 0xee100e15, 0xCA00003C);
1352 /* MRC p14,0,r1,c0,c5,0 */
1353 arm11_run_instr_data_to_core(arm11, 0xee101e15, 0xFFFFFFFF);
1354
1355 arm11_run_instr_data_finish(arm11);
1356 #endif
1357
1358

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)