1 /***************************************************************************
2 * Copyright (C) 2005 by Dominic Rath *
3 * Dominic.Rath@gmx.de *
5 * Copyright (C) 2008 by Spencer Oliver *
6 * spen@spen-soft.co.uk *
8 * Copyright (C) 2008 by Hongtao Zheng *
11 * This program is free software; you can redistribute it and/or modify *
12 * it under the terms of the GNU General Public License as published by *
13 * the Free Software Foundation; either version 2 of the License, or *
14 * (at your option) any later version. *
16 * This program is distributed in the hope that it will be useful, *
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
19 * GNU General Public License for more details. *
21 * You should have received a copy of the GNU General Public License *
22 * along with this program; if not, write to the *
23 * Free Software Foundation, Inc., *
24 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
25 ***************************************************************************/
31 #include "target_type.h"
35 * NOTE: this holds code that's used with multiple ARM9 processors:
36 * - ARM9TDMI (ARMv4T) ... in ARM920, ARM922, and ARM940 cores
37 * - ARM9E-S (ARMv5TE) ... in ARM946, ARM966, and ARM968 cores
38 * - ARM9EJS (ARMv5TEJ) ... in ARM926 core
40 * In short, the file name is a misnomer ... it is NOT specific to
41 * that first generation ARM9 processor, or cores using it.
45 #define _DEBUG_INSTRUCTION_EXECUTION_
48 /* forward declarations */
49 static int arm9tdmi_target_create(struct target_s
*target
, Jim_Interp
*interp
);
50 static int arm9tdmi_quit(void);
52 target_type_t arm9tdmi_target
=
57 .arch_state
= armv4_5_arch_state
,
59 .target_request_data
= arm7_9_target_request_data
,
62 .resume
= arm7_9_resume
,
65 .assert_reset
= arm7_9_assert_reset
,
66 .deassert_reset
= arm7_9_deassert_reset
,
67 .soft_reset_halt
= arm7_9_soft_reset_halt
,
69 .get_gdb_reg_list
= armv4_5_get_gdb_reg_list
,
71 .read_memory
= arm7_9_read_memory
,
72 .write_memory
= arm7_9_write_memory
,
73 .bulk_write_memory
= arm7_9_bulk_write_memory
,
74 .checksum_memory
= arm7_9_checksum_memory
,
75 .blank_check_memory
= arm7_9_blank_check_memory
,
77 .run_algorithm
= armv4_5_run_algorithm
,
79 .add_breakpoint
= arm7_9_add_breakpoint
,
80 .remove_breakpoint
= arm7_9_remove_breakpoint
,
81 .add_watchpoint
= arm7_9_add_watchpoint
,
82 .remove_watchpoint
= arm7_9_remove_watchpoint
,
84 .register_commands
= arm9tdmi_register_commands
,
85 .target_create
= arm9tdmi_target_create
,
86 .init_target
= arm9tdmi_init_target
,
87 .examine
= arm9tdmi_examine
,
91 static arm9tdmi_vector_t arm9tdmi_vectors
[] =
93 {"reset", ARM9TDMI_RESET_VECTOR
},
94 {"undef", ARM9TDMI_UNDEF_VECTOR
},
95 {"swi", ARM9TDMI_SWI_VECTOR
},
96 {"pabt", ARM9TDMI_PABT_VECTOR
},
97 {"dabt", ARM9TDMI_DABT_VECTOR
},
98 {"irq", ARM9TDMI_IRQ_VECTOR
},
99 {"fiq", ARM9TDMI_FIQ_VECTOR
},
103 int arm9tdmi_examine_debug_reason(target_t
*target
)
105 int retval
= ERROR_OK
;
106 /* get pointers to arch-specific information */
107 armv4_5_common_t
*armv4_5
= target
->arch_info
;
108 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
110 /* only check the debug reason if we don't know it already */
111 if ((target
->debug_reason
!= DBG_REASON_DBGRQ
)
112 && (target
->debug_reason
!= DBG_REASON_SINGLESTEP
))
114 scan_field_t fields
[3];
116 uint8_t instructionbus
[4];
117 uint8_t debug_reason
;
119 jtag_set_end_state(TAP_DRPAUSE
);
121 fields
[0].tap
= arm7_9
->jtag_info
.tap
;
122 fields
[0].num_bits
= 32;
123 fields
[0].out_value
= NULL
;
124 fields
[0].in_value
= databus
;
126 fields
[1].tap
= arm7_9
->jtag_info
.tap
;
127 fields
[1].num_bits
= 3;
128 fields
[1].out_value
= NULL
;
129 fields
[1].in_value
= &debug_reason
;
131 fields
[2].tap
= arm7_9
->jtag_info
.tap
;
132 fields
[2].num_bits
= 32;
133 fields
[2].out_value
= NULL
;
134 fields
[2].in_value
= instructionbus
;
136 if ((retval
= arm_jtag_scann(&arm7_9
->jtag_info
, 0x1)) != ERROR_OK
)
140 arm_jtag_set_instr(&arm7_9
->jtag_info
, arm7_9
->jtag_info
.intest_instr
, NULL
);
142 jtag_add_dr_scan(3, fields
, jtag_set_end_state(TAP_DRPAUSE
));
143 if ((retval
= jtag_execute_queue()) != ERROR_OK
)
148 fields
[0].in_value
= NULL
;
149 fields
[0].out_value
= databus
;
150 fields
[1].in_value
= NULL
;
151 fields
[1].out_value
= &debug_reason
;
152 fields
[2].in_value
= NULL
;
153 fields
[2].out_value
= instructionbus
;
155 jtag_add_dr_scan(3, fields
, jtag_set_end_state(TAP_DRPAUSE
));
157 if (debug_reason
& 0x4)
158 if (debug_reason
& 0x2)
159 target
->debug_reason
= DBG_REASON_WPTANDBKPT
;
161 target
->debug_reason
= DBG_REASON_WATCHPOINT
;
163 target
->debug_reason
= DBG_REASON_BREAKPOINT
;
169 /* put an instruction in the ARM9TDMI pipeline or write the data bus, and optionally read data */
170 int arm9tdmi_clock_out(arm_jtag_t
*jtag_info
, uint32_t instr
, uint32_t out
, uint32_t *in
, int sysspeed
)
172 int retval
= ERROR_OK
;
173 scan_field_t fields
[3];
175 uint8_t instr_buf
[4];
176 uint8_t sysspeed_buf
= 0x0;
179 buf_set_u32(out_buf
, 0, 32, out
);
181 buf_set_u32(instr_buf
, 0, 32, flip_u32(instr
, 32));
184 buf_set_u32(&sysspeed_buf
, 2, 1, 1);
186 jtag_set_end_state(TAP_DRPAUSE
);
187 if ((retval
= arm_jtag_scann(jtag_info
, 0x1)) != ERROR_OK
)
192 arm_jtag_set_instr(jtag_info
, jtag_info
->intest_instr
, NULL
);
194 fields
[0].tap
= jtag_info
->tap
;
195 fields
[0].num_bits
= 32;
196 fields
[0].out_value
= out_buf
;
197 fields
[0].in_value
= NULL
;
199 fields
[1].tap
= jtag_info
->tap
;
200 fields
[1].num_bits
= 3;
201 fields
[1].out_value
= &sysspeed_buf
;
202 fields
[1].in_value
= NULL
;
204 fields
[2].tap
= jtag_info
->tap
;
205 fields
[2].num_bits
= 32;
206 fields
[2].out_value
= instr_buf
;
207 fields
[2].in_value
= NULL
;
211 fields
[0].in_value
= (uint8_t *)in
;
212 jtag_add_dr_scan(3, fields
, jtag_get_end_state());
214 jtag_add_callback(arm_le_to_h_u32
, (jtag_callback_data_t
)in
);
218 jtag_add_dr_scan(3, fields
, jtag_get_end_state());
221 jtag_add_runtest(0, jtag_get_end_state());
223 #ifdef _DEBUG_INSTRUCTION_EXECUTION_
225 if ((retval
= jtag_execute_queue()) != ERROR_OK
)
232 LOG_DEBUG("instr: 0x%8.8x, out: 0x%8.8x, in: 0x%8.8x", instr
, out
, *in
);
235 LOG_DEBUG("instr: 0x%8.8x, out: 0x%8.8x", instr
, out
);
242 /* just read data (instruction and data-out = don't care) */
243 int arm9tdmi_clock_data_in(arm_jtag_t
*jtag_info
, uint32_t *in
)
245 int retval
= ERROR_OK
;;
246 scan_field_t fields
[3];
248 jtag_set_end_state(TAP_DRPAUSE
);
249 if ((retval
= arm_jtag_scann(jtag_info
, 0x1)) != ERROR_OK
)
254 arm_jtag_set_instr(jtag_info
, jtag_info
->intest_instr
, NULL
);
256 fields
[0].tap
= jtag_info
->tap
;
257 fields
[0].num_bits
= 32;
258 fields
[0].out_value
= NULL
;
259 fields
[0].in_value
= (uint8_t *)in
;
261 fields
[1].tap
= jtag_info
->tap
;
262 fields
[1].num_bits
= 3;
263 fields
[1].out_value
= NULL
;
264 fields
[1].in_value
= NULL
;
266 fields
[2].tap
= jtag_info
->tap
;
267 fields
[2].num_bits
= 32;
268 fields
[2].out_value
= NULL
;
269 fields
[2].in_value
= NULL
;
271 jtag_add_dr_scan(3, fields
, jtag_get_end_state());
273 jtag_add_callback(arm_le_to_h_u32
, (jtag_callback_data_t
)in
);
275 jtag_add_runtest(0, jtag_get_end_state());
277 #ifdef _DEBUG_INSTRUCTION_EXECUTION_
279 if ((retval
= jtag_execute_queue()) != ERROR_OK
)
286 LOG_DEBUG("in: 0x%8.8x", *in
);
290 LOG_ERROR("BUG: called with in == NULL");
298 extern void arm_endianness(uint8_t *tmp
, void *in
, int size
, int be
, int flip
);
300 static int arm9endianness(jtag_callback_data_t arg
, jtag_callback_data_t size
, jtag_callback_data_t be
, jtag_callback_data_t captured
)
302 uint8_t *in
= (uint8_t *)arg
;
303 arm_endianness((uint8_t *)captured
, in
, (int)size
, (int)be
, 0);
307 /* clock the target, and read the databus
308 * the *in pointer points to a buffer where elements of 'size' bytes
309 * are stored in big (be == 1) or little (be == 0) endianness
311 int arm9tdmi_clock_data_in_endianness(arm_jtag_t
*jtag_info
, void *in
, int size
, int be
)
313 int retval
= ERROR_OK
;
314 scan_field_t fields
[3];
316 jtag_set_end_state(TAP_DRPAUSE
);
317 if ((retval
= arm_jtag_scann(jtag_info
, 0x1)) != ERROR_OK
)
322 arm_jtag_set_instr(jtag_info
, jtag_info
->intest_instr
, NULL
);
324 fields
[0].tap
= jtag_info
->tap
;
325 fields
[0].num_bits
= 32;
326 fields
[0].out_value
= NULL
;
327 jtag_alloc_in_value32(&fields
[0]);
329 fields
[1].tap
= jtag_info
->tap
;
330 fields
[1].num_bits
= 3;
331 fields
[1].out_value
= NULL
;
332 fields
[1].in_value
= NULL
;
334 fields
[2].tap
= jtag_info
->tap
;
335 fields
[2].num_bits
= 32;
336 fields
[2].out_value
= NULL
;
337 fields
[2].in_value
= NULL
;
339 jtag_add_dr_scan(3, fields
, jtag_get_end_state());
341 jtag_add_callback4(arm9endianness
, (jtag_callback_data_t
)in
, (jtag_callback_data_t
)size
, (jtag_callback_data_t
)be
, (jtag_callback_data_t
)fields
[0].in_value
);
343 jtag_add_runtest(0, jtag_get_end_state());
345 #ifdef _DEBUG_INSTRUCTION_EXECUTION_
347 if ((retval
= jtag_execute_queue()) != ERROR_OK
)
354 LOG_DEBUG("in: 0x%8.8x", *(uint32_t*)in
);
358 LOG_ERROR("BUG: called with in == NULL");
366 static void arm9tdmi_change_to_arm(target_t
*target
,
367 uint32_t *r0
, uint32_t *pc
)
369 int retval
= ERROR_OK
;
370 /* get pointers to arch-specific information */
371 armv4_5_common_t
*armv4_5
= target
->arch_info
;
372 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
373 arm_jtag_t
*jtag_info
= &arm7_9
->jtag_info
;
375 /* save r0 before using it and put system in ARM state
376 * to allow common handling of ARM and THUMB debugging */
378 /* fetch STR r0, [r0] */
379 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_STR(0, 0), 0, NULL
, 0);
380 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, 0, NULL
, 0);
381 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, 0, NULL
, 0);
382 /* STR r0, [r0] in Memory */
383 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, 0, r0
, 0);
385 /* MOV r0, r15 fetched, STR in Decode */
386 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_MOV(0, 15), 0, NULL
, 0);
387 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, 0, NULL
, 0);
388 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_STR(0, 0), 0, NULL
, 0);
389 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, 0, NULL
, 0);
390 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, 0, NULL
, 0);
391 /* nothing fetched, STR r0, [r0] in Memory */
392 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, 0, pc
, 0);
394 /* use pc-relative LDR to clear r0[1:0] (for switch to ARM mode) */
395 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_LDR_PCREL(0), 0, NULL
, 0);
397 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, 0, NULL
, 0);
399 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, 0, NULL
, 0);
400 /* LDR in Memory (to account for interlock) */
401 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, 0, NULL
, 0);
404 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_BX(0), 0, NULL
, 0);
405 /* NOP fetched, BX in Decode, MOV in Execute */
406 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, 0, NULL
, 0);
407 /* NOP fetched, BX in Execute (1) */
408 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, 0, NULL
, 0);
410 if ((retval
= jtag_execute_queue()) != ERROR_OK
)
415 /* fix program counter:
416 * MOV r0, r15 was the 5th instruction (+8)
417 * reading PC in Thumb state gives address of instruction + 4
422 void arm9tdmi_read_core_regs(target_t
*target
, uint32_t mask
, uint32_t* core_regs
[16])
425 /* get pointers to arch-specific information */
426 armv4_5_common_t
*armv4_5
= target
->arch_info
;
427 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
428 arm_jtag_t
*jtag_info
= &arm7_9
->jtag_info
;
430 /* STMIA r0-15, [r0] at debug speed
431 * register values will start to appear on 4th DCLK
433 arm9tdmi_clock_out(jtag_info
, ARMV4_5_STMIA(0, mask
& 0xffff, 0, 0), 0, NULL
, 0);
435 /* fetch NOP, STM in DECODE stage */
436 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
437 /* fetch NOP, STM in EXECUTE stage (1st cycle) */
438 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
440 for (i
= 0; i
<= 15; i
++)
443 /* nothing fetched, STM in MEMORY (i'th cycle) */
444 arm9tdmi_clock_data_in(jtag_info
, core_regs
[i
]);
448 static void arm9tdmi_read_core_regs_target_buffer(target_t
*target
,
449 uint32_t mask
, void* buffer
, int size
)
452 /* get pointers to arch-specific information */
453 armv4_5_common_t
*armv4_5
= target
->arch_info
;
454 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
455 arm_jtag_t
*jtag_info
= &arm7_9
->jtag_info
;
456 int be
= (target
->endianness
== TARGET_BIG_ENDIAN
) ? 1 : 0;
457 uint32_t *buf_u32
= buffer
;
458 uint16_t *buf_u16
= buffer
;
459 uint8_t *buf_u8
= buffer
;
461 /* STMIA r0-15, [r0] at debug speed
462 * register values will start to appear on 4th DCLK
464 arm9tdmi_clock_out(jtag_info
, ARMV4_5_STMIA(0, mask
& 0xffff, 0, 0), 0, NULL
, 0);
466 /* fetch NOP, STM in DECODE stage */
467 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
468 /* fetch NOP, STM in EXECUTE stage (1st cycle) */
469 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
471 for (i
= 0; i
<= 15; i
++)
474 /* nothing fetched, STM in MEMORY (i'th cycle) */
478 arm9tdmi_clock_data_in_endianness(jtag_info
, buf_u32
++, 4, be
);
481 arm9tdmi_clock_data_in_endianness(jtag_info
, buf_u16
++, 2, be
);
484 arm9tdmi_clock_data_in_endianness(jtag_info
, buf_u8
++, 1, be
);
490 static void arm9tdmi_read_xpsr(target_t
*target
, uint32_t *xpsr
, int spsr
)
492 /* get pointers to arch-specific information */
493 armv4_5_common_t
*armv4_5
= target
->arch_info
;
494 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
495 arm_jtag_t
*jtag_info
= &arm7_9
->jtag_info
;
498 arm9tdmi_clock_out(jtag_info
, ARMV4_5_MRS(0, spsr
& 1), 0, NULL
, 0);
499 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
500 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
501 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
502 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
505 arm9tdmi_clock_out(jtag_info
, ARMV4_5_STR(0, 15), 0, NULL
, 0);
506 /* fetch NOP, STR in DECODE stage */
507 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
508 /* fetch NOP, STR in EXECUTE stage (1st cycle) */
509 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
510 /* nothing fetched, STR in MEMORY */
511 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, xpsr
, 0);
514 static void arm9tdmi_write_xpsr(target_t
*target
, uint32_t xpsr
, int spsr
)
516 /* get pointers to arch-specific information */
517 armv4_5_common_t
*armv4_5
= target
->arch_info
;
518 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
519 arm_jtag_t
*jtag_info
= &arm7_9
->jtag_info
;
521 LOG_DEBUG("xpsr: %8.8" PRIx32
", spsr: %i", xpsr
, spsr
);
524 arm9tdmi_clock_out(jtag_info
, ARMV4_5_MSR_IM(xpsr
& 0xff, 0, 1, spsr
), 0, NULL
, 0);
525 /* MSR2 fetched, MSR1 in DECODE */
526 arm9tdmi_clock_out(jtag_info
, ARMV4_5_MSR_IM((xpsr
& 0xff00) >> 8, 0xc, 2, spsr
), 0, NULL
, 0);
527 /* MSR3 fetched, MSR1 in EXECUTE (1), MSR2 in DECODE */
528 arm9tdmi_clock_out(jtag_info
, ARMV4_5_MSR_IM((xpsr
& 0xff0000) >> 16, 0x8, 4, spsr
), 0, NULL
, 0);
529 /* nothing fetched, MSR1 in EXECUTE (2) */
530 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
531 /* nothing fetched, MSR1 in EXECUTE (3) */
532 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
533 /* MSR4 fetched, MSR2 in EXECUTE (1), MSR3 in DECODE */
534 arm9tdmi_clock_out(jtag_info
, ARMV4_5_MSR_IM((xpsr
& 0xff000000) >> 24, 0x4, 8, spsr
), 0, NULL
, 0);
535 /* nothing fetched, MSR2 in EXECUTE (2) */
536 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
537 /* nothing fetched, MSR2 in EXECUTE (3) */
538 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
539 /* NOP fetched, MSR3 in EXECUTE (1), MSR4 in DECODE */
540 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
541 /* nothing fetched, MSR3 in EXECUTE (2) */
542 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
543 /* nothing fetched, MSR3 in EXECUTE (3) */
544 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
545 /* NOP fetched, MSR4 in EXECUTE (1) */
546 /* last MSR writes flags, which takes only one cycle */
547 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
550 static void arm9tdmi_write_xpsr_im8(target_t
*target
,
551 uint8_t xpsr_im
, int rot
, int spsr
)
553 /* get pointers to arch-specific information */
554 armv4_5_common_t
*armv4_5
= target
->arch_info
;
555 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
556 arm_jtag_t
*jtag_info
= &arm7_9
->jtag_info
;
558 LOG_DEBUG("xpsr_im: %2.2x, rot: %i, spsr: %i", xpsr_im
, rot
, spsr
);
561 arm9tdmi_clock_out(jtag_info
, ARMV4_5_MSR_IM(xpsr_im
, rot
, 1, spsr
), 0, NULL
, 0);
562 /* NOP fetched, MSR in DECODE */
563 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
564 /* NOP fetched, MSR in EXECUTE (1) */
565 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
567 /* rot == 4 writes flags, which takes only one cycle */
570 /* nothing fetched, MSR in EXECUTE (2) */
571 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
572 /* nothing fetched, MSR in EXECUTE (3) */
573 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
577 void arm9tdmi_write_core_regs(target_t
*target
, uint32_t mask
, uint32_t core_regs
[16])
580 /* get pointers to arch-specific information */
581 armv4_5_common_t
*armv4_5
= target
->arch_info
;
582 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
583 arm_jtag_t
*jtag_info
= &arm7_9
->jtag_info
;
585 /* LDMIA r0-15, [r0] at debug speed
586 * register values will start to appear on 4th DCLK
588 arm9tdmi_clock_out(jtag_info
, ARMV4_5_LDMIA(0, mask
& 0xffff, 0, 0), 0, NULL
, 0);
590 /* fetch NOP, LDM in DECODE stage */
591 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
592 /* fetch NOP, LDM in EXECUTE stage (1st cycle) */
593 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
595 for (i
= 0; i
<= 15; i
++)
598 /* nothing fetched, LDM still in EXECUTE (1 + i cycle) */
599 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, core_regs
[i
], NULL
, 0);
601 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
604 void arm9tdmi_load_word_regs(target_t
*target
, uint32_t mask
)
606 /* get pointers to arch-specific information */
607 armv4_5_common_t
*armv4_5
= target
->arch_info
;
608 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
609 arm_jtag_t
*jtag_info
= &arm7_9
->jtag_info
;
611 /* put system-speed load-multiple into the pipeline */
612 arm9tdmi_clock_out(jtag_info
, ARMV4_5_LDMIA(0, mask
& 0xffff, 0, 1), 0, NULL
, 0);
613 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 1);
616 void arm9tdmi_load_hword_reg(target_t
*target
, int num
)
618 /* get pointers to arch-specific information */
619 armv4_5_common_t
*armv4_5
= target
->arch_info
;
620 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
621 arm_jtag_t
*jtag_info
= &arm7_9
->jtag_info
;
623 /* put system-speed load half-word into the pipeline */
624 arm9tdmi_clock_out(jtag_info
, ARMV4_5_LDRH_IP(num
, 0), 0, NULL
, 0);
625 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 1);
628 void arm9tdmi_load_byte_reg(target_t
*target
, int num
)
630 /* get pointers to arch-specific information */
631 armv4_5_common_t
*armv4_5
= target
->arch_info
;
632 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
633 arm_jtag_t
*jtag_info
= &arm7_9
->jtag_info
;
635 /* put system-speed load byte into the pipeline */
636 arm9tdmi_clock_out(jtag_info
, ARMV4_5_LDRB_IP(num
, 0), 0, NULL
, 0);
637 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 1);
640 void arm9tdmi_store_word_regs(target_t
*target
, uint32_t mask
)
642 /* get pointers to arch-specific information */
643 armv4_5_common_t
*armv4_5
= target
->arch_info
;
644 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
645 arm_jtag_t
*jtag_info
= &arm7_9
->jtag_info
;
647 /* put system-speed store-multiple into the pipeline */
648 arm9tdmi_clock_out(jtag_info
, ARMV4_5_STMIA(0, mask
, 0, 1), 0, NULL
, 0);
649 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 1);
652 void arm9tdmi_store_hword_reg(target_t
*target
, int num
)
654 /* get pointers to arch-specific information */
655 armv4_5_common_t
*armv4_5
= target
->arch_info
;
656 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
657 arm_jtag_t
*jtag_info
= &arm7_9
->jtag_info
;
659 /* put system-speed store half-word into the pipeline */
660 arm9tdmi_clock_out(jtag_info
, ARMV4_5_STRH_IP(num
, 0), 0, NULL
, 0);
661 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 1);
664 void arm9tdmi_store_byte_reg(target_t
*target
, int num
)
666 /* get pointers to arch-specific information */
667 armv4_5_common_t
*armv4_5
= target
->arch_info
;
668 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
669 arm_jtag_t
*jtag_info
= &arm7_9
->jtag_info
;
671 /* put system-speed store byte into the pipeline */
672 arm9tdmi_clock_out(jtag_info
, ARMV4_5_STRB_IP(num
, 0), 0, NULL
, 0);
673 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 1);
676 static void arm9tdmi_write_pc(target_t
*target
, uint32_t pc
)
678 /* get pointers to arch-specific information */
679 armv4_5_common_t
*armv4_5
= target
->arch_info
;
680 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
681 arm_jtag_t
*jtag_info
= &arm7_9
->jtag_info
;
683 /* LDMIA r0-15, [r0] at debug speed
684 * register values will start to appear on 4th DCLK
686 arm9tdmi_clock_out(jtag_info
, ARMV4_5_LDMIA(0, 0x8000, 0, 0), 0, NULL
, 0);
688 /* fetch NOP, LDM in DECODE stage */
689 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
690 /* fetch NOP, LDM in EXECUTE stage (1st cycle) */
691 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
692 /* nothing fetched, LDM in EXECUTE stage (2nd cycle) (output data) */
693 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, pc
, NULL
, 0);
694 /* nothing fetched, LDM in EXECUTE stage (3rd cycle) */
695 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
696 /* fetch NOP, LDM in EXECUTE stage (4th cycle) */
697 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
698 /* fetch NOP, LDM in EXECUTE stage (5th cycle) */
699 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
702 void arm9tdmi_branch_resume(target_t
*target
)
704 /* get pointers to arch-specific information */
705 armv4_5_common_t
*armv4_5
= target
->arch_info
;
706 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
707 arm_jtag_t
*jtag_info
= &arm7_9
->jtag_info
;
709 arm9tdmi_clock_out(jtag_info
, ARMV4_5_B(0xfffffc, 0), 0, NULL
, 0);
710 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 1);
713 static void arm9tdmi_branch_resume_thumb(target_t
*target
)
717 /* get pointers to arch-specific information */
718 armv4_5_common_t
*armv4_5
= target
->arch_info
;
719 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
720 arm_jtag_t
*jtag_info
= &arm7_9
->jtag_info
;
721 reg_t
*dbg_stat
= &arm7_9
->eice_cache
->reg_list
[EICE_DBG_STAT
];
723 /* LDMIA r0-15, [r0] at debug speed
724 * register values will start to appear on 4th DCLK
726 arm9tdmi_clock_out(jtag_info
, ARMV4_5_LDMIA(0, 0x1, 0, 0), 0, NULL
, 0);
728 /* fetch NOP, LDM in DECODE stage */
729 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
730 /* fetch NOP, LDM in EXECUTE stage (1st cycle) */
731 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
732 /* nothing fetched, LDM in EXECUTE stage (2nd cycle) */
733 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32) | 1, NULL
, 0);
734 /* nothing fetched, LDM in EXECUTE stage (3rd cycle) */
735 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
737 /* Branch and eXchange */
738 arm9tdmi_clock_out(jtag_info
, ARMV4_5_BX(0), 0, NULL
, 0);
740 embeddedice_read_reg(dbg_stat
);
742 /* fetch NOP, BX in DECODE stage */
743 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
745 embeddedice_read_reg(dbg_stat
);
747 /* fetch NOP, BX in EXECUTE stage (1st cycle) */
748 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
750 /* target is now in Thumb state */
751 embeddedice_read_reg(dbg_stat
);
753 /* load r0 value, MOV_IM in Decode*/
754 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_LDR_PCREL(0), 0, NULL
, 0);
755 /* fetch NOP, LDR in Decode, MOV_IM in Execute */
756 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, 0, NULL
, 0);
757 /* fetch NOP, LDR in Execute */
758 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, 0, NULL
, 0);
759 /* nothing fetched, LDR in EXECUTE stage (2nd cycle) */
760 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, buf_get_u32(armv4_5
->core_cache
->reg_list
[0].value
, 0, 32), NULL
, 0);
761 /* nothing fetched, LDR in EXECUTE stage (3rd cycle) */
762 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, 0, NULL
, 0);
764 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, 0, NULL
, 0);
765 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, 0, NULL
, 0);
767 embeddedice_read_reg(dbg_stat
);
769 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_B(0x7f7), 0, NULL
, 1);
770 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, 0, NULL
, 0);
773 void arm9tdmi_enable_single_step(target_t
*target
, uint32_t next_pc
)
775 /* get pointers to arch-specific information */
776 armv4_5_common_t
*armv4_5
= target
->arch_info
;
777 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
779 if (arm7_9
->has_single_step
)
781 buf_set_u32(arm7_9
->eice_cache
->reg_list
[EICE_DBG_CTRL
].value
, 3, 1, 1);
782 embeddedice_store_reg(&arm7_9
->eice_cache
->reg_list
[EICE_DBG_CTRL
]);
786 arm7_9_enable_eice_step(target
, next_pc
);
790 void arm9tdmi_disable_single_step(target_t
*target
)
792 /* get pointers to arch-specific information */
793 armv4_5_common_t
*armv4_5
= target
->arch_info
;
794 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
796 if (arm7_9
->has_single_step
)
798 buf_set_u32(arm7_9
->eice_cache
->reg_list
[EICE_DBG_CTRL
].value
, 3, 1, 0);
799 embeddedice_store_reg(&arm7_9
->eice_cache
->reg_list
[EICE_DBG_CTRL
]);
803 arm7_9_disable_eice_step(target
);
807 static void arm9tdmi_build_reg_cache(target_t
*target
)
809 reg_cache_t
**cache_p
= register_get_last_cache_p(&target
->reg_cache
);
810 /* get pointers to arch-specific information */
811 armv4_5_common_t
*armv4_5
= target
->arch_info
;
813 (*cache_p
) = armv4_5_build_reg_cache(target
, armv4_5
);
814 armv4_5
->core_cache
= (*cache_p
);
817 int arm9tdmi_examine(struct target_s
*target
)
819 /* get pointers to arch-specific information */
821 armv4_5_common_t
*armv4_5
= target
->arch_info
;
822 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
823 if (!target_was_examined(target
))
825 reg_cache_t
**cache_p
= register_get_last_cache_p(&target
->reg_cache
);
827 /* one extra register (vector catch) */
828 t
= embeddedice_build_reg_cache(target
, arm7_9
);
832 arm7_9
->eice_cache
= (*cache_p
);
836 arm_jtag_t
*jtag_info
= &arm7_9
->jtag_info
;
837 (*cache_p
)->next
= etm_build_reg_cache(target
, jtag_info
, arm7_9
->etm_ctx
);
838 arm7_9
->etm_ctx
->reg_cache
= (*cache_p
)->next
;
840 target_set_examined(target
);
842 if ((retval
= embeddedice_setup(target
)) != ERROR_OK
)
844 if ((retval
= arm7_9_setup(target
)) != ERROR_OK
)
848 if ((retval
= etm_setup(target
)) != ERROR_OK
)
854 int arm9tdmi_init_target(struct command_context_s
*cmd_ctx
, struct target_s
*target
)
857 arm9tdmi_build_reg_cache(target
);
862 static int arm9tdmi_quit(void)
867 int arm9tdmi_init_arch_info(target_t
*target
, arm9tdmi_common_t
*arm9tdmi
, jtag_tap_t
*tap
)
869 armv4_5_common_t
*armv4_5
;
870 arm7_9_common_t
*arm7_9
;
872 arm7_9
= &arm9tdmi
->arm7_9_common
;
873 armv4_5
= &arm7_9
->armv4_5_common
;
875 /* prepare JTAG information for the new target */
876 arm7_9
->jtag_info
.tap
= tap
;
877 arm7_9
->jtag_info
.scann_size
= 5;
879 /* register arch-specific functions */
880 arm7_9
->examine_debug_reason
= arm9tdmi_examine_debug_reason
;
881 arm7_9
->change_to_arm
= arm9tdmi_change_to_arm
;
882 arm7_9
->read_core_regs
= arm9tdmi_read_core_regs
;
883 arm7_9
->read_core_regs_target_buffer
= arm9tdmi_read_core_regs_target_buffer
;
884 arm7_9
->read_xpsr
= arm9tdmi_read_xpsr
;
886 arm7_9
->write_xpsr
= arm9tdmi_write_xpsr
;
887 arm7_9
->write_xpsr_im8
= arm9tdmi_write_xpsr_im8
;
888 arm7_9
->write_core_regs
= arm9tdmi_write_core_regs
;
890 arm7_9
->load_word_regs
= arm9tdmi_load_word_regs
;
891 arm7_9
->load_hword_reg
= arm9tdmi_load_hword_reg
;
892 arm7_9
->load_byte_reg
= arm9tdmi_load_byte_reg
;
894 arm7_9
->store_word_regs
= arm9tdmi_store_word_regs
;
895 arm7_9
->store_hword_reg
= arm9tdmi_store_hword_reg
;
896 arm7_9
->store_byte_reg
= arm9tdmi_store_byte_reg
;
898 arm7_9
->write_pc
= arm9tdmi_write_pc
;
899 arm7_9
->branch_resume
= arm9tdmi_branch_resume
;
900 arm7_9
->branch_resume_thumb
= arm9tdmi_branch_resume_thumb
;
902 arm7_9
->enable_single_step
= arm9tdmi_enable_single_step
;
903 arm7_9
->disable_single_step
= arm9tdmi_disable_single_step
;
905 arm7_9
->pre_debug_entry
= NULL
;
906 arm7_9
->post_debug_entry
= NULL
;
908 arm7_9
->pre_restore_context
= NULL
;
909 arm7_9
->post_restore_context
= NULL
;
911 /* initialize arch-specific breakpoint handling */
912 arm7_9
->arm_bkpt
= 0xdeeedeee;
913 arm7_9
->thumb_bkpt
= 0xdeee;
915 arm7_9
->dbgreq_adjust_pc
= 3;
916 arm7_9
->arch_info
= arm9tdmi
;
918 arm9tdmi
->common_magic
= ARM9TDMI_COMMON_MAGIC
;
919 arm9tdmi
->arch_info
= NULL
;
921 arm7_9_init_arch_info(target
, arm7_9
);
923 /* override use of DBGRQ, this is safe on ARM9TDMI */
924 arm7_9
->use_dbgrq
= 1;
926 /* all ARM9s have the vector catch register */
927 arm7_9
->has_vector_catch
= 1;
932 static int arm9tdmi_get_arch_pointers(target_t
*target
,
933 armv4_5_common_t
**armv4_5_p
, arm7_9_common_t
**arm7_9_p
,
934 arm9tdmi_common_t
**arm9tdmi_p
)
936 armv4_5_common_t
*armv4_5
= target
->arch_info
;
937 arm7_9_common_t
*arm7_9
;
938 arm9tdmi_common_t
*arm9tdmi
;
940 if (armv4_5
->common_magic
!= ARMV4_5_COMMON_MAGIC
)
945 arm7_9
= armv4_5
->arch_info
;
946 if (arm7_9
->common_magic
!= ARM7_9_COMMON_MAGIC
)
951 arm9tdmi
= arm7_9
->arch_info
;
952 if (arm9tdmi
->common_magic
!= ARM9TDMI_COMMON_MAGIC
)
957 *armv4_5_p
= armv4_5
;
959 *arm9tdmi_p
= arm9tdmi
;
964 static int arm9tdmi_target_create(struct target_s
*target
, Jim_Interp
*interp
)
966 arm9tdmi_common_t
*arm9tdmi
= calloc(1,sizeof(arm9tdmi_common_t
));
968 arm9tdmi_init_arch_info(target
, arm9tdmi
, target
->tap
);
969 arm9tdmi
->arm7_9_common
.armv4_5_common
.is_armv4
= true;
974 static int handle_arm9tdmi_catch_vectors_command(
975 struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
977 target_t
*target
= get_current_target(cmd_ctx
);
978 armv4_5_common_t
*armv4_5
;
979 arm7_9_common_t
*arm7_9
;
980 arm9tdmi_common_t
*arm9tdmi
;
982 uint32_t vector_catch_value
;
985 if (arm9tdmi_get_arch_pointers(target
, &armv4_5
, &arm7_9
, &arm9tdmi
) != ERROR_OK
)
987 command_print(cmd_ctx
, "current target isn't an ARM9 based target");
991 vector_catch
= &arm7_9
->eice_cache
->reg_list
[EICE_VEC_CATCH
];
993 /* read the vector catch register if necessary */
994 if (!vector_catch
->valid
)
995 embeddedice_read_reg(vector_catch
);
997 /* get the current setting */
998 vector_catch_value
= buf_get_u32(vector_catch
->value
, 0, 8);
1002 vector_catch_value
= 0x0;
1003 if (strcmp(args
[0], "all") == 0)
1005 vector_catch_value
= 0xdf;
1007 else if (strcmp(args
[0], "none") == 0)
1013 for (i
= 0; i
< argc
; i
++)
1015 /* go through list of vectors */
1016 for (j
= 0; arm9tdmi_vectors
[j
].name
; j
++)
1018 if (strcmp(args
[i
], arm9tdmi_vectors
[j
].name
) == 0)
1020 vector_catch_value
|= arm9tdmi_vectors
[j
].value
;
1025 /* complain if vector wasn't found */
1026 if (!arm9tdmi_vectors
[j
].name
)
1028 command_print(cmd_ctx
, "vector '%s' not found, leaving current setting unchanged", args
[i
]);
1030 /* reread current setting */
1031 vector_catch_value
= buf_get_u32(
1032 vector_catch
->value
,
1040 /* store new settings */
1041 buf_set_u32(vector_catch
->value
, 0, 8, vector_catch_value
);
1042 embeddedice_store_reg(vector_catch
);
1045 /* output current settings (skip RESERVED vector) */
1046 for (i
= 0; i
< 8; i
++)
1050 command_print(cmd_ctx
, "%s: %s", arm9tdmi_vectors
[i
].name
,
1051 (vector_catch_value
& (1 << i
)) ? "catch" : "don't catch");
1058 int arm9tdmi_register_commands(struct command_context_s
*cmd_ctx
)
1061 command_t
*arm9tdmi_cmd
;
1063 retval
= arm7_9_register_commands(cmd_ctx
);
1064 arm9tdmi_cmd
= register_command(cmd_ctx
, NULL
, "arm9",
1066 "arm9 specific commands");
1067 register_command(cmd_ctx
, arm9tdmi_cmd
, "vector_catch",
1068 handle_arm9tdmi_catch_vectors_command
, COMMAND_EXEC
,
1069 "arm9 vector_catch [all|none|reset|undef|swi|pabt|dabt|irq|fiq] ...");
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)