1 /***************************************************************************
2 * Copyright (C) 2008 digenius technology GmbH. *
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. *
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. *
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 ***************************************************************************/
32 #define _DEBUG_INSTRUCTION_EXECUTION_
37 #define FNC_INFO DEBUG("-")
43 #define FNC_INFO_NOTIMPLEMENTED do { DEBUG("NOT IMPLEMENTED"); /*exit(-1);*/ } while (0)
45 #define FNC_INFO_NOTIMPLEMENTED
48 static void arm11_on_enter_debug_state(arm11_common_t
* arm11
);
51 #define ARM11_HANDLER(x) \
54 target_type_t arm11_target
=
59 ARM11_HANDLER(arch_state
),
61 ARM11_HANDLER(target_request_data
),
64 ARM11_HANDLER(resume
),
67 ARM11_HANDLER(assert_reset
),
68 ARM11_HANDLER(deassert_reset
),
69 ARM11_HANDLER(soft_reset_halt
),
70 ARM11_HANDLER(prepare_reset_halt
),
72 ARM11_HANDLER(get_gdb_reg_list
),
74 ARM11_HANDLER(read_memory
),
75 ARM11_HANDLER(write_memory
),
77 ARM11_HANDLER(bulk_write_memory
),
79 ARM11_HANDLER(checksum_memory
),
81 ARM11_HANDLER(add_breakpoint
),
82 ARM11_HANDLER(remove_breakpoint
),
83 ARM11_HANDLER(add_watchpoint
),
84 ARM11_HANDLER(remove_watchpoint
),
86 ARM11_HANDLER(run_algorithm
),
88 ARM11_HANDLER(register_commands
),
89 ARM11_HANDLER(target_command
),
90 ARM11_HANDLER(init_target
),
94 int arm11_regs_arch_type
= -1;
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
,
126 typedef struct arm11_reg_defs_s
131 enum arm11_regtype type
;
134 /* update arm11_regcache_ids when changing this */
135 static const arm11_reg_defs_t arm11_reg_defs
[] =
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
},
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
},
166 {"cpsr", 0, 25, ARM11_REGISTER_CPSR
},
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
},
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
},
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
},
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
},
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
},
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
},
200 /* Debug Registers */
201 {"dscr", 0, -1, ARM11_REGISTER_DSCR
},
202 {"wdtr", 0, -1, ARM11_REGISTER_WDTR
},
203 {"rdtr", 0, -1, ARM11_REGISTER_RDTR
},
206 enum arm11_regcache_ids
209 ARM11_RC_RX
= ARM11_RC_R0
,
224 ARM11_RC_SP
= ARM11_RC_R13
,
226 ARM11_RC_LR
= ARM11_RC_R14
,
228 ARM11_RC_PC
= ARM11_RC_R15
,
230 #if ARM11_REGCACHE_FREGS
232 ARM11_RC_FX
= ARM11_RC_F0
,
245 #if ARM11_REGCACHE_MODEREGS
284 #define ARM11_GDB_REGISTER_COUNT 26
286 u8 arm11_gdb_dummy_fp_value
[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
288 reg_t arm11_gdb_dummy_fp_reg
=
290 "GDB dummy floating-point register", arm11_gdb_dummy_fp_value
, 0, 1, 96, NULL
, 0, NULL
, 0
293 u8 arm11_gdb_dummy_fps_value
[] = {0, 0, 0, 0};
295 reg_t arm11_gdb_dummy_fps_reg
=
297 "GDB dummy floating-point status register", arm11_gdb_dummy_fps_value
, 0, 1, 32, NULL
, 0, NULL
, 0
302 /** Check and if necessary take control of the system
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.
309 void arm11_check_init(arm11_common_t
* arm11
, u32
* dscr
)
313 u32 dscr_local_tmp_copy
;
317 dscr
= &dscr_local_tmp_copy
;
318 *dscr
= arm11_read_DSCR(arm11
);
321 if (!(*dscr
& ARM11_DSCR_MODE_SELECT
))
323 DEBUG("Bringing target into debug mode");
325 *dscr
|= ARM11_DSCR_MODE_SELECT
; /* Halt debug-mode */
326 arm11_write_DSCR(arm11
, *dscr
);
328 /* add further reset initialization here */
330 if (*dscr
& ARM11_DSCR_CORE_HALTED
)
332 arm11
->target
->state
= TARGET_HALTED
;
333 arm11
->target
->debug_reason
= arm11_get_DSCR_debug_reason(*dscr
);
337 arm11
->target
->state
= TARGET_RUNNING
;
338 arm11
->target
->debug_reason
= DBG_REASON_NOTHALTED
;
341 arm11_sc7_clear_bw(arm11
);
348 (arm11->reg_values[ARM11_RC_##x])
350 /** Save processor state.
352 * This is called when the HALT instruction has succeeded
353 * or on other occasions that stop the processor.
356 static void arm11_on_enter_debug_state(arm11_common_t
* arm11
)
361 for(i
= 0; i
< asizeof(arm11
->reg_values
); i
++)
363 arm11
->reg_list
[i
].valid
= 1;
364 arm11
->reg_list
[i
].dirty
= 0;
369 R(DSCR
) = arm11_read_DSCR(arm11
);
373 if (R(DSCR
) & ARM11_DSCR_WDTR_FULL
)
375 arm11_add_debug_SCAN_N(arm11
, 0x05, -1);
377 arm11_add_IR(arm11
, ARM11_INTEST
, -1);
379 scan_field_t chain5_fields
[3];
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);
385 jtag_add_dr_scan_vc(asizeof(chain5_fields
), chain5_fields
, TAP_PD
);
389 arm11
->reg_list
[ARM11_RC_WDTR
].valid
= 0;
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 */
397 u32 new_dscr
= R(DSCR
) | ARM11_DSCR_EXECUTE_ARM_INSTRUCTION_ENABLE
;
399 /* this executes JTAG queue: */
401 arm11_write_DSCR(arm11
, new_dscr
);
403 // jtag_execute_queue();
407 // DEBUG("SAVE DSCR %08x", R(DSCR));
409 // if (R(DSCR) & ARM11_DSCR_WDTR_FULL)
410 // DEBUG("SAVE wDTR %08x", R(WDTR));
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:*/
417 /** \todo TODO: Test drain write buffer. */
422 /* MRC p14,0,R0,c5,c10,0 */
423 // arm11_run_instr_no_data1(arm11, /*0xee150e1a*/0xe320f000);
425 /* mcr 15, 0, r0, cr7, cr10, {4} */
426 arm11_run_instr_no_data1(arm11
, 0xee070f9a);
428 u32 dscr
= arm11_read_DSCR(arm11
);
430 DEBUG("DRAIN, DSCR %08x", dscr
);
432 if (dscr
& ARM11_DSCR_STICKY_IMPRECISE_DATA_ABORT
)
434 arm11_run_instr_no_data1(arm11
, 0xe320f000);
436 dscr
= arm11_read_DSCR(arm11
);
438 DEBUG("DRAIN, DSCR %08x (DONE)", dscr
);
446 arm11_run_instr_data_prepare(arm11
);
451 /** \todo TODO: handle other mode registers */
454 for (i
= 0; i
< 15; i
++)
456 /* MCR p14,0,R?,c0,c5,0 */
457 arm11_run_instr_data_from_core(arm11
, 0xEE000E15 | (i
<< 12), &R(RX
+ i
), 1);
463 /* check rDTRfull in DSCR */
465 if (R(DSCR
) & ARM11_DSCR_RDTR_FULL
)
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
));
472 arm11
->reg_list
[ARM11_RC_RDTR
].valid
= 0;
477 /* MRS r0,CPSR (move CPSR -> r0 (-> wDTR -> local var)) */
478 arm11_run_instr_data_from_core_via_r0(arm11
, 0xE10F0000, &R(CPSR
));
482 /* MOV R0,PC (move PC -> r0 (-> wDTR -> local var)) */
483 arm11_run_instr_data_from_core_via_r0(arm11
, 0xE1A0000F, &R(PC
));
485 /* adjust PC depending on ARM state */
487 if (R(CPSR
) & ARM11_CPSR_J
) /* Java state */
489 arm11
->reg_values
[ARM11_RC_PC
] -= 0;
491 else if (R(CPSR
) & ARM11_CPSR_T
) /* Thumb state */
493 arm11
->reg_values
[ARM11_RC_PC
] -= 4;
497 arm11
->reg_values
[ARM11_RC_PC
] -= 8;
500 // DEBUG("SAVE PC %08x", R(PC));
502 arm11_run_instr_data_finish(arm11
);
506 for(i
= 0; i
< ARM11_REGCACHE_COUNT
; i
++)
508 if (!arm11
->reg_list
[i
].valid
)
510 if (arm11
->reg_history
[i
].valid
)
511 INFO("%8s INVALID (%08x)", arm11_reg_defs
[i
].name
, arm11
->reg_history
[i
].value
);
515 if (arm11
->reg_history
[i
].valid
)
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
);
522 INFO("%8s %08x (INVALID)", arm11_reg_defs
[i
].name
, arm11
->reg_values
[i
]);
529 /** Restore processor state
531 * This is called in preparation for the RESTART function.
534 void arm11_leave_debug_state(arm11_common_t
* arm11
)
538 arm11_run_instr_data_prepare(arm11
);
540 /** \todo TODO: handle other mode registers */
542 /* restore R1 - R14 */
544 for (i
= 1; i
< 15; i
++)
546 if (!arm11
->reg_list
[ARM11_RC_RX
+ i
].dirty
)
549 /* MRC p14,0,r?,c0,c5,0 */
550 arm11_run_instr_data_to_core1(arm11
, 0xee100e15 | (i
<< 12), R(RX
+ i
));
552 // DEBUG("RESTORE R%d %08x", i, R(RX + i));
555 arm11_run_instr_data_finish(arm11
);
558 /* spec says clear wDTR and rDTR; we assume they are clear as
559 otherwide out programming would be sloppy */
562 u32 DSCR
= arm11_read_DSCR(arm11
);
564 if (DSCR
& (ARM11_DSCR_RDTR_FULL
| ARM11_DSCR_WDTR_FULL
))
566 ERROR("wDTR/rDTR inconsistent (DSCR %08x)", DSCR
);
570 arm11_run_instr_data_prepare(arm11
);
572 /* restore original wDTR */
574 if ((R(DSCR
) & ARM11_DSCR_WDTR_FULL
) || arm11
->reg_list
[ARM11_RC_WDTR
].dirty
)
576 /* MCR p14,0,R0,c0,c5,0 */
577 arm11_run_instr_data_to_core_via_r0(arm11
, 0xee000e15, R(WDTR
));
583 arm11_run_instr_data_to_core_via_r0(arm11
, 0xe129f000, R(CPSR
));
589 arm11_run_instr_data_to_core_via_r0(arm11
, 0xe1a0f000, R(PC
));
594 /* MRC p14,0,r0,c0,c5,0 */
595 arm11_run_instr_data_to_core1(arm11
, 0xee100e15, R(R0
));
597 arm11_run_instr_data_finish(arm11
);
602 arm11_write_DSCR(arm11
, R(DSCR
));
607 if (R(DSCR
) & ARM11_DSCR_RDTR_FULL
|| arm11
->reg_list
[ARM11_RC_RDTR
].dirty
)
609 arm11_add_debug_SCAN_N(arm11
, 0x05, -1);
611 arm11_add_IR(arm11
, ARM11_EXTEST
, -1);
613 scan_field_t chain5_fields
[3];
615 u8 Ready
= 0; /* ignored */
616 u8 Valid
= 0; /* ignored */
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);
622 jtag_add_dr_scan_vc(asizeof(chain5_fields
), chain5_fields
, TAP_PD
);
627 for(i
= 0; i
< ARM11_REGCACHE_COUNT
; i
++)
629 arm11
->reg_history
[i
].value
= arm11
->reg_values
[i
];
630 arm11
->reg_history
[i
].valid
= arm11
->reg_list
[i
].valid
;
632 arm11
->reg_list
[i
].valid
= 0;
633 arm11
->reg_list
[i
].dirty
= 0;
638 /* poll current target status */
639 int arm11_poll(struct target_s
*target
)
643 arm11_common_t
* arm11
= target
->arch_info
;
645 if (arm11
->trst_active
)
648 u32 dscr
= arm11_read_DSCR(arm11
);
650 DEBUG("DSCR %08x", dscr
);
652 arm11_check_init(arm11
, &dscr
);
654 if (dscr
& ARM11_DSCR_CORE_HALTED
)
656 // DEBUG("CH %d", target->state);
658 if (target
->state
!= TARGET_HALTED
)
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
);
668 // DEBUG("CR %d", target->state);
670 if (target
->state
!= TARGET_RUNNING
)
672 DEBUG("enter TARGET_RUNNING");
673 target
->state
= TARGET_RUNNING
;
674 target
->debug_reason
= DBG_REASON_NOTHALTED
;
680 /* architecture specific status reply */
681 int arm11_arch_state(struct target_s
*target
)
683 FNC_INFO_NOTIMPLEMENTED
;
689 /* target request support */
690 int arm11_target_request_data(struct target_s
*target
, u32 size
, u8
*buffer
)
692 FNC_INFO_NOTIMPLEMENTED
;
699 /* target execution control */
700 int arm11_halt(struct target_s
*target
)
704 arm11_common_t
* arm11
= target
->arch_info
;
706 DEBUG("target->state: %s", target_state_strings
[target
->state
]);
708 if (target
->state
== TARGET_HALTED
)
710 WARNING("target was already halted");
711 return ERROR_TARGET_ALREADY_HALTED
;
714 if (arm11
->trst_active
)
716 arm11
->halt_requested
= true;
720 arm11_add_IR(arm11
, ARM11_HALT
, TAP_RTI
);
722 jtag_execute_queue();
728 dscr
= arm11_read_DSCR(arm11
);
730 if (dscr
& ARM11_DSCR_CORE_HALTED
)
734 arm11_on_enter_debug_state(arm11
);
736 target
->state
= TARGET_HALTED
;
737 target
->debug_reason
= arm11_get_DSCR_debug_reason(dscr
);
743 int arm11_resume(struct target_s
*target
, int current
, u32 address
, int handle_breakpoints
, int debug_execution
)
747 arm11_common_t
* arm11
= target
->arch_info
;
749 DEBUG("target->state: %s", target_state_strings
[target
->state
]);
751 if (target
->state
!= TARGET_HALTED
)
753 WARNING("target was not halted");
754 return ERROR_TARGET_NOT_HALTED
;
760 target
->state
= TARGET_RUNNING
;
761 target
->debug_reason
= DBG_REASON_NOTHALTED
;
763 arm11_leave_debug_state(arm11
);
765 arm11_add_IR(arm11
, ARM11_RESTART
, TAP_RTI
);
767 jtag_execute_queue();
771 u32 dscr
= arm11_read_DSCR(arm11
);
773 DEBUG("DSCR %08x", dscr
);
775 if (dscr
& ARM11_DSCR_CORE_RESTARTED
)
779 DEBUG("RES %d", target
->state
);
784 int arm11_step(struct target_s
*target
, int current
, u32 address
, int handle_breakpoints
)
788 DEBUG("target->state: %s", target_state_strings
[target
->state
]);
790 if (target
->state
!= TARGET_HALTED
)
792 WARNING("target was not halted");
793 return ERROR_TARGET_NOT_HALTED
;
796 arm11_common_t
* arm11
= target
->arch_info
;
798 /** \todo TODO: check if break-/watchpoints make any sense at all in combination
801 /** \todo TODO: check if disabling IRQs might be a good idea here. Alternatively
802 the VCR might be something worth looking into. */
804 /* Set up breakpoint for stepping */
806 arm11_sc7_action_t brp
[2];
809 brp
[0].address
= ARM11_SC7_BVR0
;
810 brp
[0].value
= R(PC
);
812 brp
[1].address
= ARM11_SC7_BCR0
;
813 brp
[1].value
= 0x1 | (3 << 1) | (0x0F << 5) | (0 << 14) | (0 << 16) | (0 << 20) | (2 << 21);
815 arm11_sc7_run(arm11
, brp
, asizeof(brp
));
819 arm11_leave_debug_state(arm11
);
821 arm11_add_IR(arm11
, ARM11_RESTART
, TAP_RTI
);
823 jtag_execute_queue();
825 /** \todo TODO: add a timeout */
831 u32 dscr
= arm11_read_DSCR(arm11
);
833 DEBUG("DSCR %08x", dscr
);
835 if ((dscr
& (ARM11_DSCR_CORE_RESTARTED
| ARM11_DSCR_CORE_HALTED
)) ==
836 (ARM11_DSCR_CORE_RESTARTED
| ARM11_DSCR_CORE_HALTED
))
841 /* clear breakpoint */
843 arm11_sc7_clear_bw(arm11
);
848 arm11_on_enter_debug_state(arm11
);
850 // target->state = TARGET_HALTED;
851 target
->debug_reason
= DBG_REASON_SINGLESTEP
;
857 /* target reset control */
858 int arm11_assert_reset(struct target_s
*target
)
863 /* assert reset lines */
864 /* resets only the DBGTAP, not the ARM */
866 jtag_add_reset(1, 0);
867 jtag_add_sleep(5000);
869 arm11_common_t
* arm11
= target
->arch_info
;
870 arm11
->trst_active
= true;
876 int arm11_deassert_reset(struct target_s
*target
)
881 DEBUG("target->state: %s", target_state_strings
[target
->state
]);
883 /* deassert reset lines */
884 jtag_add_reset(0, 0);
886 arm11_common_t
* arm11
= target
->arch_info
;
887 arm11
->trst_active
= false;
889 if (arm11
->halt_requested
)
890 return arm11_halt(target
);
896 int arm11_soft_reset_halt(struct target_s
*target
)
898 FNC_INFO_NOTIMPLEMENTED
;
903 int arm11_prepare_reset_halt(struct target_s
*target
)
905 FNC_INFO_NOTIMPLEMENTED
;
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
)
916 arm11_common_t
* arm11
= target
->arch_info
;
918 if (target
->state
!= TARGET_HALTED
)
920 return ERROR_TARGET_NOT_HALTED
;
923 *reg_list_size
= ARM11_GDB_REGISTER_COUNT
;
924 *reg_list
= malloc(sizeof(reg_t
*) * ARM11_GDB_REGISTER_COUNT
);
927 for (i
= 16; i
< 24; i
++)
929 (*reg_list
)[i
] = &arm11_gdb_dummy_fp_reg
;
932 (*reg_list
)[24] = &arm11_gdb_dummy_fps_reg
;
936 for (i
= 0; i
< ARM11_REGCACHE_COUNT
; i
++)
938 if (arm11_reg_defs
[i
].gdb_num
== -1)
941 (*reg_list
)[arm11_reg_defs
[i
].gdb_num
] = arm11
->reg_list
+ i
;
948 /* target memory access
949 * size: 1 = byte (8bit), 2 = half-word (16bit), 4 = word (32bit)
950 * count: number of items of <size>
952 int arm11_read_memory(struct target_s
*target
, u32 address
, u32 size
, u32 count
, u8
*buffer
)
954 /** \todo TODO: check if buffer cast to u32* and u16* might cause alignment problems */
958 DEBUG("ADDR %08x SIZE %08x COUNT %08x", address
, size
, count
);
960 arm11_common_t
* arm11
= target
->arch_info
;
962 arm11_run_instr_data_prepare(arm11
);
964 /* MRC p14,0,r0,c0,c5,0 */
965 arm11_run_instr_data_to_core1(arm11
, 0xee100e15, address
);
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;
975 /* ldrb r1, [r0], #1 */
976 arm11_run_instr_no_data1(arm11
, 0xe4d01001);
979 /* MCR p14,0,R1,c0,c5,0 */
980 arm11_run_instr_data_from_core(arm11
, 0xEE001E15, &res
, 1);
988 arm11
->reg_list
[ARM11_RC_R1
].dirty
= 1;
990 u16
* buf16
= (u16
*)buffer
;
994 /* ldrh r1, [r0], #2 */
995 arm11_run_instr_no_data1(arm11
, 0xe0d010b2);
999 /* MCR p14,0,R1,c0,c5,0 */
1000 arm11_run_instr_data_from_core(arm11
, 0xEE001E15, &res
, 1);
1009 /* LDC p14,c5,[R0],#4 */
1010 arm11_run_instr_data_from_core(arm11
, 0xecb05e01, (u32
*)buffer
, count
);
1014 arm11_run_instr_data_finish(arm11
);
1019 int arm11_write_memory(struct target_s
*target
, u32 address
, u32 size
, u32 count
, u8
*buffer
)
1023 DEBUG("ADDR %08x SIZE %08x COUNT %08x", address
, size
, count
);
1025 arm11_common_t
* arm11
= target
->arch_info
;
1027 arm11_run_instr_data_prepare(arm11
);
1029 /* MRC p14,0,r0,c0,c5,0 */
1030 arm11_run_instr_data_to_core1(arm11
, 0xee100e15, address
);
1035 arm11
->reg_list
[ARM11_RC_R1
].dirty
= 1;
1039 /* MRC p14,0,r1,c0,c5,0 */
1040 arm11_run_instr_data_to_core1(arm11
, 0xee101e15, *buffer
++);
1042 /* strb r1, [r0], #1 */
1043 arm11_run_instr_no_data1(arm11
, 0xe4c01001);
1049 arm11
->reg_list
[ARM11_RC_R1
].dirty
= 1;
1051 u16
* buf16
= (u16
*)buffer
;
1055 /* MRC p14,0,r1,c0,c5,0 */
1056 arm11_run_instr_data_to_core1(arm11
, 0xee101e15, *buf16
++);
1058 /* strh r1, [r0], #2 */
1059 arm11_run_instr_no_data1(arm11
, 0xe0c010b2);
1065 /** \todo TODO: check if buffer cast to u32* might cause alignment problems */
1067 /* STC p14,c5,[R0],#4 */
1068 arm11_run_instr_data_to_core(arm11
, 0xeca05e01, (u32
*)buffer
, count
);
1072 arm11_run_instr_data_finish(arm11
);
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
)
1083 return arm11_write_memory(target
, address
, 4, count
, buffer
);
1087 int arm11_checksum_memory(struct target_s
*target
, u32 address
, u32 count
, u32
* checksum
)
1089 FNC_INFO_NOTIMPLEMENTED
;
1095 /* target break-/watchpoint control
1096 * rw: 0 = write, 1 = read, 2 = access
1098 int arm11_add_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
)
1100 FNC_INFO_NOTIMPLEMENTED
;
1105 int arm11_remove_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
)
1107 FNC_INFO_NOTIMPLEMENTED
;
1112 int arm11_add_watchpoint(struct target_s
*target
, watchpoint_t
*watchpoint
)
1114 FNC_INFO_NOTIMPLEMENTED
;
1119 int arm11_remove_watchpoint(struct target_s
*target
, watchpoint_t
*watchpoint
)
1121 FNC_INFO_NOTIMPLEMENTED
;
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
)
1130 FNC_INFO_NOTIMPLEMENTED
;
1136 int arm11_register_commands(struct command_context_s
*cmd_ctx
)
1143 int arm11_target_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
, struct target_s
*target
)
1149 ERROR("'target arm11' 4th argument <jtag chain pos>");
1153 int chain_pos
= strtoul(args
[3], NULL
, 0);
1155 NEW(arm11_common_t
, arm11
, 1);
1157 arm11
->target
= target
;
1159 /* prepare JTAG information for the new target */
1160 arm11
->jtag_info
.chain_pos
= chain_pos
;
1161 arm11
->jtag_info
.scann_size
= 5;
1163 arm_jtag_setup_connection(&arm11
->jtag_info
);
1165 jtag_device_t
*device
= jtag_get_device(chain_pos
);
1167 if (device
->ir_length
!= 5)
1169 ERROR("'target arm11' expects 'jtag_device 5 0x01 0x1F 0x1E'");
1173 target
->arch_info
= arm11
;
1178 int arm11_init_target(struct command_context_s
*cmd_ctx
, struct target_s
*target
)
1182 arm11_common_t
* arm11
= target
->arch_info
;
1186 arm11_add_IR(arm11
, ARM11_IDCODE
, -1);
1188 scan_field_t idcode_field
;
1190 arm11_setup_field(arm11
, 32, NULL
, &arm11
->device_id
, &idcode_field
);
1192 jtag_add_dr_scan_vc(1, &idcode_field
, TAP_PD
);
1196 arm11_add_debug_SCAN_N(arm11
, 0x00, -1);
1198 arm11_add_IR(arm11
, ARM11_INTEST
, -1);
1200 scan_field_t chain0_fields
[2];
1202 arm11_setup_field(arm11
, 32, NULL
, &arm11
->didr
, chain0_fields
+ 0);
1203 arm11_setup_field(arm11
, 8, NULL
, &arm11
->implementor
, chain0_fields
+ 1);
1205 jtag_add_dr_scan_vc(asizeof(chain0_fields
), chain0_fields
, TAP_RTI
);
1207 jtag_execute_queue();
1210 switch (arm11
->device_id
& 0x0FFFF000)
1212 case 0x07B36000: INFO("found ARM1136"); break;
1213 case 0x07B56000: INFO("found ARM1156"); break;
1214 case 0x07B76000: INFO("found ARM1176"); break;
1217 ERROR("'target arm11' expects IDCODE 0x*7B*7****");
1222 arm11
->brp
= ((arm11
->didr
>> 24) & 0x0F) + 1;
1223 arm11
->wrp
= ((arm11
->didr
>> 28) & 0x0F) + 1;
1226 DEBUG("IDCODE %08x IMPLEMENTOR %02x DIDR %08x",
1231 arm11_build_reg_cache(target
);
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.
1239 arm11_check_init(arm11
, NULL
);
1244 int arm11_quit(void)
1246 FNC_INFO_NOTIMPLEMENTED
;
1251 /** Load a register that is marked !valid in the register cache */
1252 int arm11_get_reg(reg_t
*reg
)
1256 target_t
* target
= ((arm11_reg_state_t
*)reg
->arch_info
)->target
;
1258 if (target
->state
!= TARGET_HALTED
)
1260 return ERROR_TARGET_NOT_HALTED
;
1263 /** \todo TODO: Check this. We assume that all registers are fetched debug entry. */
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
;
1273 /** Change a value in the register cache */
1274 int arm11_set_reg(reg_t
*reg
, u8
*buf
)
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;
1282 arm11
->reg_values
[((arm11_reg_state_t
*)reg
->arch_info
)->def_index
] = buf_get_u32(buf
, 0, 32);
1290 void arm11_build_reg_cache(target_t
*target
)
1292 arm11_common_t
*arm11
= target
->arch_info
;
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
);
1298 if (arm11_regs_arch_type
== -1)
1299 arm11_regs_arch_type
= register_reg_arch_type(arm11_get_reg
, arm11_set_reg
);
1301 arm11
->reg_list
= reg_list
;
1303 /* Build the process context cache */
1304 cache
->name
= "arm11 registers";
1306 cache
->reg_list
= reg_list
;
1307 cache
->num_regs
= ARM11_REGCACHE_COUNT
;
1309 reg_cache_t
**cache_p
= register_get_last_cache_p(&target
->reg_cache
);
1312 // armv7m->core_cache = cache;
1313 // armv7m->process_context = cache;
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
)
1322 ERROR("arm11->reg_values inconsistent (%d %d %d %d)", ARM11_REGCACHE_COUNT
, asizeof(arm11
->reg_values
), asizeof(arm11_reg_defs
), ARM11_RC_MAX
);
1326 for (i
= 0; i
< ARM11_REGCACHE_COUNT
; i
++)
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
;
1334 r
->value
= (u8
*)(arm11
->reg_values
+ i
);
1337 r
->bitfield_desc
= NULL
;
1338 r
->num_bitfields
= 0;
1339 r
->arch_type
= arm11_regs_arch_type
;
1343 rs
->target
= target
;
1348 arm11_run_instr_data_prepare(arm11
);
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);
1355 arm11_run_instr_data_finish(arm11
);
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)