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_
49 int handle_arm9tdmi_catch_vectors_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
51 /* forward declarations */
52 int arm9tdmi_target_create(struct target_s
*target
, Jim_Interp
*interp
);
54 int arm9tdmi_quit(void);
56 target_type_t arm9tdmi_target
=
61 .arch_state
= armv4_5_arch_state
,
63 .target_request_data
= arm7_9_target_request_data
,
66 .resume
= arm7_9_resume
,
69 .assert_reset
= arm7_9_assert_reset
,
70 .deassert_reset
= arm7_9_deassert_reset
,
71 .soft_reset_halt
= arm7_9_soft_reset_halt
,
73 .get_gdb_reg_list
= armv4_5_get_gdb_reg_list
,
75 .read_memory
= arm7_9_read_memory
,
76 .write_memory
= arm7_9_write_memory
,
77 .bulk_write_memory
= arm7_9_bulk_write_memory
,
78 .checksum_memory
= arm7_9_checksum_memory
,
79 .blank_check_memory
= arm7_9_blank_check_memory
,
81 .run_algorithm
= armv4_5_run_algorithm
,
83 .add_breakpoint
= arm7_9_add_breakpoint
,
84 .remove_breakpoint
= arm7_9_remove_breakpoint
,
85 .add_watchpoint
= arm7_9_add_watchpoint
,
86 .remove_watchpoint
= arm7_9_remove_watchpoint
,
88 .register_commands
= arm9tdmi_register_commands
,
89 .target_create
= arm9tdmi_target_create
,
90 .init_target
= arm9tdmi_init_target
,
91 .examine
= arm9tdmi_examine
,
95 arm9tdmi_vector_t arm9tdmi_vectors
[] =
97 {"reset", ARM9TDMI_RESET_VECTOR
},
98 {"undef", ARM9TDMI_UNDEF_VECTOR
},
99 {"swi", ARM9TDMI_SWI_VECTOR
},
100 {"pabt", ARM9TDMI_PABT_VECTOR
},
101 {"dabt", ARM9TDMI_DABT_VECTOR
},
102 {"reserved", ARM9TDMI_RESERVED_VECTOR
},
103 {"irq", ARM9TDMI_IRQ_VECTOR
},
104 {"fiq", ARM9TDMI_FIQ_VECTOR
},
108 int arm9tdmi_examine_debug_reason(target_t
*target
)
110 int retval
= ERROR_OK
;
111 /* get pointers to arch-specific information */
112 armv4_5_common_t
*armv4_5
= target
->arch_info
;
113 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
115 /* only check the debug reason if we don't know it already */
116 if ((target
->debug_reason
!= DBG_REASON_DBGRQ
)
117 && (target
->debug_reason
!= DBG_REASON_SINGLESTEP
))
119 scan_field_t fields
[3];
121 uint8_t instructionbus
[4];
122 uint8_t debug_reason
;
124 jtag_set_end_state(TAP_DRPAUSE
);
126 fields
[0].tap
= arm7_9
->jtag_info
.tap
;
127 fields
[0].num_bits
= 32;
128 fields
[0].out_value
= NULL
;
129 fields
[0].in_value
= databus
;
131 fields
[1].tap
= arm7_9
->jtag_info
.tap
;
132 fields
[1].num_bits
= 3;
133 fields
[1].out_value
= NULL
;
134 fields
[1].in_value
= &debug_reason
;
136 fields
[2].tap
= arm7_9
->jtag_info
.tap
;
137 fields
[2].num_bits
= 32;
138 fields
[2].out_value
= NULL
;
139 fields
[2].in_value
= instructionbus
;
141 if ((retval
= arm_jtag_scann(&arm7_9
->jtag_info
, 0x1)) != ERROR_OK
)
145 arm_jtag_set_instr(&arm7_9
->jtag_info
, arm7_9
->jtag_info
.intest_instr
, NULL
);
147 jtag_add_dr_scan(3, fields
, jtag_set_end_state(TAP_DRPAUSE
));
148 if ((retval
= jtag_execute_queue()) != ERROR_OK
)
153 fields
[0].in_value
= NULL
;
154 fields
[0].out_value
= databus
;
155 fields
[1].in_value
= NULL
;
156 fields
[1].out_value
= &debug_reason
;
157 fields
[2].in_value
= NULL
;
158 fields
[2].out_value
= instructionbus
;
160 jtag_add_dr_scan(3, fields
, jtag_set_end_state(TAP_DRPAUSE
));
162 if (debug_reason
& 0x4)
163 if (debug_reason
& 0x2)
164 target
->debug_reason
= DBG_REASON_WPTANDBKPT
;
166 target
->debug_reason
= DBG_REASON_WATCHPOINT
;
168 target
->debug_reason
= DBG_REASON_BREAKPOINT
;
174 /* put an instruction in the ARM9TDMI pipeline or write the data bus, and optionally read data */
175 int arm9tdmi_clock_out(arm_jtag_t
*jtag_info
, uint32_t instr
, uint32_t out
, uint32_t *in
, int sysspeed
)
177 int retval
= ERROR_OK
;
178 scan_field_t fields
[3];
180 uint8_t instr_buf
[4];
181 uint8_t sysspeed_buf
= 0x0;
184 buf_set_u32(out_buf
, 0, 32, out
);
186 buf_set_u32(instr_buf
, 0, 32, flip_u32(instr
, 32));
189 buf_set_u32(&sysspeed_buf
, 2, 1, 1);
191 jtag_set_end_state(TAP_DRPAUSE
);
192 if ((retval
= arm_jtag_scann(jtag_info
, 0x1)) != ERROR_OK
)
197 arm_jtag_set_instr(jtag_info
, jtag_info
->intest_instr
, NULL
);
199 fields
[0].tap
= jtag_info
->tap
;
200 fields
[0].num_bits
= 32;
201 fields
[0].out_value
= out_buf
;
202 fields
[0].in_value
= NULL
;
204 fields
[1].tap
= jtag_info
->tap
;
205 fields
[1].num_bits
= 3;
206 fields
[1].out_value
= &sysspeed_buf
;
207 fields
[1].in_value
= NULL
;
209 fields
[2].tap
= jtag_info
->tap
;
210 fields
[2].num_bits
= 32;
211 fields
[2].out_value
= instr_buf
;
212 fields
[2].in_value
= NULL
;
216 fields
[0].in_value
= (uint8_t *)in
;
217 jtag_add_dr_scan(3, fields
, jtag_get_end_state());
219 jtag_add_callback(arm_le_to_h_u32
, (jtag_callback_data_t
)in
);
223 jtag_add_dr_scan(3, fields
, jtag_get_end_state());
226 jtag_add_runtest(0, jtag_get_end_state());
228 #ifdef _DEBUG_INSTRUCTION_EXECUTION_
230 if ((retval
= jtag_execute_queue()) != ERROR_OK
)
237 LOG_DEBUG("instr: 0x%8.8x, out: 0x%8.8x, in: 0x%8.8x", instr
, out
, *in
);
240 LOG_DEBUG("instr: 0x%8.8x, out: 0x%8.8x", instr
, out
);
247 /* just read data (instruction and data-out = don't care) */
248 int arm9tdmi_clock_data_in(arm_jtag_t
*jtag_info
, uint32_t *in
)
250 int retval
= ERROR_OK
;;
251 scan_field_t fields
[3];
253 jtag_set_end_state(TAP_DRPAUSE
);
254 if ((retval
= arm_jtag_scann(jtag_info
, 0x1)) != ERROR_OK
)
259 arm_jtag_set_instr(jtag_info
, jtag_info
->intest_instr
, NULL
);
261 fields
[0].tap
= jtag_info
->tap
;
262 fields
[0].num_bits
= 32;
263 fields
[0].out_value
= NULL
;
264 fields
[0].in_value
= (uint8_t *)in
;
266 fields
[1].tap
= jtag_info
->tap
;
267 fields
[1].num_bits
= 3;
268 fields
[1].out_value
= NULL
;
269 fields
[1].in_value
= NULL
;
271 fields
[2].tap
= jtag_info
->tap
;
272 fields
[2].num_bits
= 32;
273 fields
[2].out_value
= NULL
;
274 fields
[2].in_value
= NULL
;
276 jtag_add_dr_scan(3, fields
, jtag_get_end_state());
278 jtag_add_callback(arm_le_to_h_u32
, (jtag_callback_data_t
)in
);
280 jtag_add_runtest(0, jtag_get_end_state());
282 #ifdef _DEBUG_INSTRUCTION_EXECUTION_
284 if ((retval
= jtag_execute_queue()) != ERROR_OK
)
291 LOG_DEBUG("in: 0x%8.8x", *in
);
295 LOG_ERROR("BUG: called with in == NULL");
303 extern void arm_endianness(uint8_t *tmp
, void *in
, int size
, int be
, int flip
);
305 static int arm9endianness(jtag_callback_data_t arg
, jtag_callback_data_t size
, jtag_callback_data_t be
, jtag_callback_data_t captured
)
307 uint8_t *in
= (uint8_t *)arg
;
308 arm_endianness((uint8_t *)captured
, in
, (int)size
, (int)be
, 0);
312 /* clock the target, and read the databus
313 * the *in pointer points to a buffer where elements of 'size' bytes
314 * are stored in big (be == 1) or little (be == 0) endianness
316 int arm9tdmi_clock_data_in_endianness(arm_jtag_t
*jtag_info
, void *in
, int size
, int be
)
318 int retval
= ERROR_OK
;
319 scan_field_t fields
[3];
321 jtag_set_end_state(TAP_DRPAUSE
);
322 if ((retval
= arm_jtag_scann(jtag_info
, 0x1)) != ERROR_OK
)
327 arm_jtag_set_instr(jtag_info
, jtag_info
->intest_instr
, NULL
);
329 fields
[0].tap
= jtag_info
->tap
;
330 fields
[0].num_bits
= 32;
331 fields
[0].out_value
= NULL
;
332 jtag_alloc_in_value32(&fields
[0]);
334 fields
[1].tap
= jtag_info
->tap
;
335 fields
[1].num_bits
= 3;
336 fields
[1].out_value
= NULL
;
337 fields
[1].in_value
= NULL
;
339 fields
[2].tap
= jtag_info
->tap
;
340 fields
[2].num_bits
= 32;
341 fields
[2].out_value
= NULL
;
342 fields
[2].in_value
= NULL
;
344 jtag_add_dr_scan(3, fields
, jtag_get_end_state());
346 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
);
348 jtag_add_runtest(0, jtag_get_end_state());
350 #ifdef _DEBUG_INSTRUCTION_EXECUTION_
352 if ((retval
= jtag_execute_queue()) != ERROR_OK
)
359 LOG_DEBUG("in: 0x%8.8x", *(uint32_t*)in
);
363 LOG_ERROR("BUG: called with in == NULL");
371 void arm9tdmi_change_to_arm(target_t
*target
, uint32_t *r0
, uint32_t *pc
)
373 int retval
= ERROR_OK
;
374 /* get pointers to arch-specific information */
375 armv4_5_common_t
*armv4_5
= target
->arch_info
;
376 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
377 arm_jtag_t
*jtag_info
= &arm7_9
->jtag_info
;
379 /* save r0 before using it and put system in ARM state
380 * to allow common handling of ARM and THUMB debugging */
382 /* fetch STR r0, [r0] */
383 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_STR(0, 0), 0, NULL
, 0);
384 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, 0, NULL
, 0);
385 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, 0, NULL
, 0);
386 /* STR r0, [r0] in Memory */
387 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, 0, r0
, 0);
389 /* MOV r0, r15 fetched, STR in Decode */
390 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_MOV(0, 15), 0, NULL
, 0);
391 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, 0, NULL
, 0);
392 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_STR(0, 0), 0, NULL
, 0);
393 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, 0, NULL
, 0);
394 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, 0, NULL
, 0);
395 /* nothing fetched, STR r0, [r0] in Memory */
396 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, 0, pc
, 0);
398 /* use pc-relative LDR to clear r0[1:0] (for switch to ARM mode) */
399 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_LDR_PCREL(0), 0, NULL
, 0);
401 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, 0, NULL
, 0);
403 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, 0, NULL
, 0);
404 /* LDR in Memory (to account for interlock) */
405 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, 0, NULL
, 0);
408 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_BX(0), 0, NULL
, 0);
409 /* NOP fetched, BX in Decode, MOV in Execute */
410 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, 0, NULL
, 0);
411 /* NOP fetched, BX in Execute (1) */
412 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, 0, NULL
, 0);
414 if ((retval
= jtag_execute_queue()) != ERROR_OK
)
419 /* fix program counter:
420 * MOV r0, r15 was the 5th instruction (+8)
421 * reading PC in Thumb state gives address of instruction + 4
426 void arm9tdmi_read_core_regs(target_t
*target
, uint32_t mask
, uint32_t* core_regs
[16])
429 /* get pointers to arch-specific information */
430 armv4_5_common_t
*armv4_5
= target
->arch_info
;
431 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
432 arm_jtag_t
*jtag_info
= &arm7_9
->jtag_info
;
434 /* STMIA r0-15, [r0] at debug speed
435 * register values will start to appear on 4th DCLK
437 arm9tdmi_clock_out(jtag_info
, ARMV4_5_STMIA(0, mask
& 0xffff, 0, 0), 0, NULL
, 0);
439 /* fetch NOP, STM in DECODE stage */
440 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
441 /* fetch NOP, STM in EXECUTE stage (1st cycle) */
442 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
444 for (i
= 0; i
<= 15; i
++)
447 /* nothing fetched, STM in MEMORY (i'th cycle) */
448 arm9tdmi_clock_data_in(jtag_info
, core_regs
[i
]);
452 void arm9tdmi_read_core_regs_target_buffer(target_t
*target
, uint32_t mask
, void* buffer
, int size
)
455 /* get pointers to arch-specific information */
456 armv4_5_common_t
*armv4_5
= target
->arch_info
;
457 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
458 arm_jtag_t
*jtag_info
= &arm7_9
->jtag_info
;
459 int be
= (target
->endianness
== TARGET_BIG_ENDIAN
) ? 1 : 0;
460 uint32_t *buf_u32
= buffer
;
461 uint16_t *buf_u16
= buffer
;
462 uint8_t *buf_u8
= buffer
;
464 /* STMIA r0-15, [r0] at debug speed
465 * register values will start to appear on 4th DCLK
467 arm9tdmi_clock_out(jtag_info
, ARMV4_5_STMIA(0, mask
& 0xffff, 0, 0), 0, NULL
, 0);
469 /* fetch NOP, STM in DECODE stage */
470 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
471 /* fetch NOP, STM in EXECUTE stage (1st cycle) */
472 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
474 for (i
= 0; i
<= 15; i
++)
477 /* nothing fetched, STM in MEMORY (i'th cycle) */
481 arm9tdmi_clock_data_in_endianness(jtag_info
, buf_u32
++, 4, be
);
484 arm9tdmi_clock_data_in_endianness(jtag_info
, buf_u16
++, 2, be
);
487 arm9tdmi_clock_data_in_endianness(jtag_info
, buf_u8
++, 1, be
);
493 void arm9tdmi_read_xpsr(target_t
*target
, uint32_t *xpsr
, int spsr
)
495 /* get pointers to arch-specific information */
496 armv4_5_common_t
*armv4_5
= target
->arch_info
;
497 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
498 arm_jtag_t
*jtag_info
= &arm7_9
->jtag_info
;
501 arm9tdmi_clock_out(jtag_info
, ARMV4_5_MRS(0, spsr
& 1), 0, NULL
, 0);
502 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
503 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
504 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
505 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
508 arm9tdmi_clock_out(jtag_info
, ARMV4_5_STR(0, 15), 0, NULL
, 0);
509 /* fetch NOP, STR in DECODE stage */
510 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
511 /* fetch NOP, STR in EXECUTE stage (1st cycle) */
512 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
513 /* nothing fetched, STR in MEMORY */
514 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, xpsr
, 0);
517 void arm9tdmi_write_xpsr(target_t
*target
, uint32_t xpsr
, int spsr
)
519 /* get pointers to arch-specific information */
520 armv4_5_common_t
*armv4_5
= target
->arch_info
;
521 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
522 arm_jtag_t
*jtag_info
= &arm7_9
->jtag_info
;
524 LOG_DEBUG("xpsr: %8.8" PRIx32
", spsr: %i", xpsr
, spsr
);
527 arm9tdmi_clock_out(jtag_info
, ARMV4_5_MSR_IM(xpsr
& 0xff, 0, 1, spsr
), 0, NULL
, 0);
528 /* MSR2 fetched, MSR1 in DECODE */
529 arm9tdmi_clock_out(jtag_info
, ARMV4_5_MSR_IM((xpsr
& 0xff00) >> 8, 0xc, 2, spsr
), 0, NULL
, 0);
530 /* MSR3 fetched, MSR1 in EXECUTE (1), MSR2 in DECODE */
531 arm9tdmi_clock_out(jtag_info
, ARMV4_5_MSR_IM((xpsr
& 0xff0000) >> 16, 0x8, 4, spsr
), 0, NULL
, 0);
532 /* nothing fetched, MSR1 in EXECUTE (2) */
533 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
534 /* nothing fetched, MSR1 in EXECUTE (3) */
535 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
536 /* MSR4 fetched, MSR2 in EXECUTE (1), MSR3 in DECODE */
537 arm9tdmi_clock_out(jtag_info
, ARMV4_5_MSR_IM((xpsr
& 0xff000000) >> 24, 0x4, 8, spsr
), 0, NULL
, 0);
538 /* nothing fetched, MSR2 in EXECUTE (2) */
539 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
540 /* nothing fetched, MSR2 in EXECUTE (3) */
541 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
542 /* NOP fetched, MSR3 in EXECUTE (1), MSR4 in DECODE */
543 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
544 /* nothing fetched, MSR3 in EXECUTE (2) */
545 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
546 /* nothing fetched, MSR3 in EXECUTE (3) */
547 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
548 /* NOP fetched, MSR4 in EXECUTE (1) */
549 /* last MSR writes flags, which takes only one cycle */
550 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
553 void arm9tdmi_write_xpsr_im8(target_t
*target
, uint8_t xpsr_im
, int rot
, int spsr
)
555 /* get pointers to arch-specific information */
556 armv4_5_common_t
*armv4_5
= target
->arch_info
;
557 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
558 arm_jtag_t
*jtag_info
= &arm7_9
->jtag_info
;
560 LOG_DEBUG("xpsr_im: %2.2x, rot: %i, spsr: %i", xpsr_im
, rot
, spsr
);
563 arm9tdmi_clock_out(jtag_info
, ARMV4_5_MSR_IM(xpsr_im
, rot
, 1, spsr
), 0, NULL
, 0);
564 /* NOP fetched, MSR in DECODE */
565 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
566 /* NOP fetched, MSR in EXECUTE (1) */
567 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
569 /* rot == 4 writes flags, which takes only one cycle */
572 /* nothing fetched, MSR in EXECUTE (2) */
573 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
574 /* nothing fetched, MSR in EXECUTE (3) */
575 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
579 void arm9tdmi_write_core_regs(target_t
*target
, uint32_t mask
, uint32_t core_regs
[16])
582 /* get pointers to arch-specific information */
583 armv4_5_common_t
*armv4_5
= target
->arch_info
;
584 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
585 arm_jtag_t
*jtag_info
= &arm7_9
->jtag_info
;
587 /* LDMIA r0-15, [r0] at debug speed
588 * register values will start to appear on 4th DCLK
590 arm9tdmi_clock_out(jtag_info
, ARMV4_5_LDMIA(0, mask
& 0xffff, 0, 0), 0, NULL
, 0);
592 /* fetch NOP, LDM in DECODE stage */
593 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
594 /* fetch NOP, LDM in EXECUTE stage (1st cycle) */
595 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
597 for (i
= 0; i
<= 15; i
++)
600 /* nothing fetched, LDM still in EXECUTE (1 + i cycle) */
601 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, core_regs
[i
], NULL
, 0);
603 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
606 void arm9tdmi_load_word_regs(target_t
*target
, uint32_t mask
)
608 /* get pointers to arch-specific information */
609 armv4_5_common_t
*armv4_5
= target
->arch_info
;
610 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
611 arm_jtag_t
*jtag_info
= &arm7_9
->jtag_info
;
613 /* put system-speed load-multiple into the pipeline */
614 arm9tdmi_clock_out(jtag_info
, ARMV4_5_LDMIA(0, mask
& 0xffff, 0, 1), 0, NULL
, 0);
615 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 1);
618 void arm9tdmi_load_hword_reg(target_t
*target
, int num
)
620 /* get pointers to arch-specific information */
621 armv4_5_common_t
*armv4_5
= target
->arch_info
;
622 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
623 arm_jtag_t
*jtag_info
= &arm7_9
->jtag_info
;
625 /* put system-speed load half-word into the pipeline */
626 arm9tdmi_clock_out(jtag_info
, ARMV4_5_LDRH_IP(num
, 0), 0, NULL
, 0);
627 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 1);
630 void arm9tdmi_load_byte_reg(target_t
*target
, int num
)
632 /* get pointers to arch-specific information */
633 armv4_5_common_t
*armv4_5
= target
->arch_info
;
634 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
635 arm_jtag_t
*jtag_info
= &arm7_9
->jtag_info
;
637 /* put system-speed load byte into the pipeline */
638 arm9tdmi_clock_out(jtag_info
, ARMV4_5_LDRB_IP(num
, 0), 0, NULL
, 0);
639 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 1);
642 void arm9tdmi_store_word_regs(target_t
*target
, uint32_t mask
)
644 /* get pointers to arch-specific information */
645 armv4_5_common_t
*armv4_5
= target
->arch_info
;
646 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
647 arm_jtag_t
*jtag_info
= &arm7_9
->jtag_info
;
649 /* put system-speed store-multiple into the pipeline */
650 arm9tdmi_clock_out(jtag_info
, ARMV4_5_STMIA(0, mask
, 0, 1), 0, NULL
, 0);
651 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 1);
654 void arm9tdmi_store_hword_reg(target_t
*target
, int num
)
656 /* get pointers to arch-specific information */
657 armv4_5_common_t
*armv4_5
= target
->arch_info
;
658 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
659 arm_jtag_t
*jtag_info
= &arm7_9
->jtag_info
;
661 /* put system-speed store half-word into the pipeline */
662 arm9tdmi_clock_out(jtag_info
, ARMV4_5_STRH_IP(num
, 0), 0, NULL
, 0);
663 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 1);
666 void arm9tdmi_store_byte_reg(target_t
*target
, int num
)
668 /* get pointers to arch-specific information */
669 armv4_5_common_t
*armv4_5
= target
->arch_info
;
670 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
671 arm_jtag_t
*jtag_info
= &arm7_9
->jtag_info
;
673 /* put system-speed store byte into the pipeline */
674 arm9tdmi_clock_out(jtag_info
, ARMV4_5_STRB_IP(num
, 0), 0, NULL
, 0);
675 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 1);
678 void arm9tdmi_write_pc(target_t
*target
, uint32_t pc
)
680 /* get pointers to arch-specific information */
681 armv4_5_common_t
*armv4_5
= target
->arch_info
;
682 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
683 arm_jtag_t
*jtag_info
= &arm7_9
->jtag_info
;
685 /* LDMIA r0-15, [r0] at debug speed
686 * register values will start to appear on 4th DCLK
688 arm9tdmi_clock_out(jtag_info
, ARMV4_5_LDMIA(0, 0x8000, 0, 0), 0, NULL
, 0);
690 /* fetch NOP, LDM in DECODE stage */
691 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
692 /* fetch NOP, LDM in EXECUTE stage (1st cycle) */
693 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
694 /* nothing fetched, LDM in EXECUTE stage (2nd cycle) (output data) */
695 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, pc
, NULL
, 0);
696 /* nothing fetched, LDM in EXECUTE stage (3rd cycle) */
697 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
698 /* fetch NOP, LDM in EXECUTE stage (4th cycle) */
699 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
700 /* fetch NOP, LDM in EXECUTE stage (5th cycle) */
701 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
704 void arm9tdmi_branch_resume(target_t
*target
)
706 /* get pointers to arch-specific information */
707 armv4_5_common_t
*armv4_5
= target
->arch_info
;
708 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
709 arm_jtag_t
*jtag_info
= &arm7_9
->jtag_info
;
711 arm9tdmi_clock_out(jtag_info
, ARMV4_5_B(0xfffffc, 0), 0, NULL
, 0);
712 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 1);
715 void arm9tdmi_branch_resume_thumb(target_t
*target
)
719 /* get pointers to arch-specific information */
720 armv4_5_common_t
*armv4_5
= target
->arch_info
;
721 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
722 arm_jtag_t
*jtag_info
= &arm7_9
->jtag_info
;
723 reg_t
*dbg_stat
= &arm7_9
->eice_cache
->reg_list
[EICE_DBG_STAT
];
725 /* LDMIA r0-15, [r0] at debug speed
726 * register values will start to appear on 4th DCLK
728 arm9tdmi_clock_out(jtag_info
, ARMV4_5_LDMIA(0, 0x1, 0, 0), 0, NULL
, 0);
730 /* fetch NOP, LDM in DECODE stage */
731 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
732 /* fetch NOP, LDM in EXECUTE stage (1st cycle) */
733 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
734 /* nothing fetched, LDM in EXECUTE stage (2nd cycle) */
735 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32) | 1, NULL
, 0);
736 /* nothing fetched, LDM in EXECUTE stage (3rd cycle) */
737 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
739 /* Branch and eXchange */
740 arm9tdmi_clock_out(jtag_info
, ARMV4_5_BX(0), 0, NULL
, 0);
742 embeddedice_read_reg(dbg_stat
);
744 /* fetch NOP, BX in DECODE stage */
745 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
747 embeddedice_read_reg(dbg_stat
);
749 /* fetch NOP, BX in EXECUTE stage (1st cycle) */
750 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
752 /* target is now in Thumb state */
753 embeddedice_read_reg(dbg_stat
);
755 /* load r0 value, MOV_IM in Decode*/
756 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_LDR_PCREL(0), 0, NULL
, 0);
757 /* fetch NOP, LDR in Decode, MOV_IM in Execute */
758 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, 0, NULL
, 0);
759 /* fetch NOP, LDR in Execute */
760 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, 0, NULL
, 0);
761 /* nothing fetched, LDR in EXECUTE stage (2nd cycle) */
762 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, buf_get_u32(armv4_5
->core_cache
->reg_list
[0].value
, 0, 32), NULL
, 0);
763 /* nothing fetched, LDR in EXECUTE stage (3rd cycle) */
764 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, 0, NULL
, 0);
766 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, 0, NULL
, 0);
767 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, 0, NULL
, 0);
769 embeddedice_read_reg(dbg_stat
);
771 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_B(0x7f7), 0, NULL
, 1);
772 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, 0, NULL
, 0);
775 void arm9tdmi_enable_single_step(target_t
*target
, uint32_t next_pc
)
777 /* get pointers to arch-specific information */
778 armv4_5_common_t
*armv4_5
= target
->arch_info
;
779 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
781 if (arm7_9
->has_single_step
)
783 buf_set_u32(arm7_9
->eice_cache
->reg_list
[EICE_DBG_CTRL
].value
, 3, 1, 1);
784 embeddedice_store_reg(&arm7_9
->eice_cache
->reg_list
[EICE_DBG_CTRL
]);
788 arm7_9_enable_eice_step(target
, next_pc
);
792 void arm9tdmi_disable_single_step(target_t
*target
)
794 /* get pointers to arch-specific information */
795 armv4_5_common_t
*armv4_5
= target
->arch_info
;
796 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
798 if (arm7_9
->has_single_step
)
800 buf_set_u32(arm7_9
->eice_cache
->reg_list
[EICE_DBG_CTRL
].value
, 3, 1, 0);
801 embeddedice_store_reg(&arm7_9
->eice_cache
->reg_list
[EICE_DBG_CTRL
]);
805 arm7_9_disable_eice_step(target
);
809 void arm9tdmi_build_reg_cache(target_t
*target
)
811 reg_cache_t
**cache_p
= register_get_last_cache_p(&target
->reg_cache
);
812 /* get pointers to arch-specific information */
813 armv4_5_common_t
*armv4_5
= target
->arch_info
;
815 (*cache_p
) = armv4_5_build_reg_cache(target
, armv4_5
);
816 armv4_5
->core_cache
= (*cache_p
);
819 int arm9tdmi_examine(struct target_s
*target
)
821 /* get pointers to arch-specific information */
823 armv4_5_common_t
*armv4_5
= target
->arch_info
;
824 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
825 if (!target_was_examined(target
))
827 reg_cache_t
**cache_p
= register_get_last_cache_p(&target
->reg_cache
);
829 /* one extra register (vector catch) */
830 t
= embeddedice_build_reg_cache(target
, arm7_9
);
834 arm7_9
->eice_cache
= (*cache_p
);
838 arm_jtag_t
*jtag_info
= &arm7_9
->jtag_info
;
839 (*cache_p
)->next
= etm_build_reg_cache(target
, jtag_info
, arm7_9
->etm_ctx
);
840 arm7_9
->etm_ctx
->reg_cache
= (*cache_p
)->next
;
842 target_set_examined(target
);
844 if ((retval
= embeddedice_setup(target
)) != ERROR_OK
)
846 if ((retval
= arm7_9_setup(target
)) != ERROR_OK
)
850 if ((retval
= etm_setup(target
)) != ERROR_OK
)
856 int arm9tdmi_init_target(struct command_context_s
*cmd_ctx
, struct target_s
*target
)
859 arm9tdmi_build_reg_cache(target
);
864 int arm9tdmi_quit(void)
869 int arm9tdmi_init_arch_info(target_t
*target
, arm9tdmi_common_t
*arm9tdmi
, jtag_tap_t
*tap
)
871 armv4_5_common_t
*armv4_5
;
872 arm7_9_common_t
*arm7_9
;
874 arm7_9
= &arm9tdmi
->arm7_9_common
;
875 armv4_5
= &arm7_9
->armv4_5_common
;
877 /* prepare JTAG information for the new target */
878 arm7_9
->jtag_info
.tap
= tap
;
879 arm7_9
->jtag_info
.scann_size
= 5;
881 /* register arch-specific functions */
882 arm7_9
->examine_debug_reason
= arm9tdmi_examine_debug_reason
;
883 arm7_9
->change_to_arm
= arm9tdmi_change_to_arm
;
884 arm7_9
->read_core_regs
= arm9tdmi_read_core_regs
;
885 arm7_9
->read_core_regs_target_buffer
= arm9tdmi_read_core_regs_target_buffer
;
886 arm7_9
->read_xpsr
= arm9tdmi_read_xpsr
;
888 arm7_9
->write_xpsr
= arm9tdmi_write_xpsr
;
889 arm7_9
->write_xpsr_im8
= arm9tdmi_write_xpsr_im8
;
890 arm7_9
->write_core_regs
= arm9tdmi_write_core_regs
;
892 arm7_9
->load_word_regs
= arm9tdmi_load_word_regs
;
893 arm7_9
->load_hword_reg
= arm9tdmi_load_hword_reg
;
894 arm7_9
->load_byte_reg
= arm9tdmi_load_byte_reg
;
896 arm7_9
->store_word_regs
= arm9tdmi_store_word_regs
;
897 arm7_9
->store_hword_reg
= arm9tdmi_store_hword_reg
;
898 arm7_9
->store_byte_reg
= arm9tdmi_store_byte_reg
;
900 arm7_9
->write_pc
= arm9tdmi_write_pc
;
901 arm7_9
->branch_resume
= arm9tdmi_branch_resume
;
902 arm7_9
->branch_resume_thumb
= arm9tdmi_branch_resume_thumb
;
904 arm7_9
->enable_single_step
= arm9tdmi_enable_single_step
;
905 arm7_9
->disable_single_step
= arm9tdmi_disable_single_step
;
907 arm7_9
->pre_debug_entry
= NULL
;
908 arm7_9
->post_debug_entry
= NULL
;
910 arm7_9
->pre_restore_context
= NULL
;
911 arm7_9
->post_restore_context
= NULL
;
913 /* initialize arch-specific breakpoint handling */
914 arm7_9
->arm_bkpt
= 0xdeeedeee;
915 arm7_9
->thumb_bkpt
= 0xdeee;
917 arm7_9
->dbgreq_adjust_pc
= 3;
918 arm7_9
->arch_info
= arm9tdmi
;
920 arm9tdmi
->common_magic
= ARM9TDMI_COMMON_MAGIC
;
921 arm9tdmi
->arch_info
= NULL
;
923 arm7_9_init_arch_info(target
, arm7_9
);
925 /* override use of DBGRQ, this is safe on ARM9TDMI */
926 arm7_9
->use_dbgrq
= 1;
928 /* all ARM9s have the vector catch register */
929 arm7_9
->has_vector_catch
= 1;
934 int arm9tdmi_get_arch_pointers(target_t
*target
, armv4_5_common_t
**armv4_5_p
, arm7_9_common_t
**arm7_9_p
, 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 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 int arm9tdmi_register_commands(struct command_context_s
*cmd_ctx
)
977 command_t
*arm9tdmi_cmd
;
979 retval
= arm7_9_register_commands(cmd_ctx
);
980 arm9tdmi_cmd
= register_command(cmd_ctx
, NULL
, "arm9tdmi",
982 "arm9tdmi specific commands");
983 register_command(cmd_ctx
, arm9tdmi_cmd
, "vector_catch",
984 handle_arm9tdmi_catch_vectors_command
, COMMAND_EXEC
,
985 "catch arm9 vectors ['all'|'none'|'<vec1 vec2 ...>']");
990 int handle_arm9tdmi_catch_vectors_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
992 target_t
*target
= get_current_target(cmd_ctx
);
993 armv4_5_common_t
*armv4_5
;
994 arm7_9_common_t
*arm7_9
;
995 arm9tdmi_common_t
*arm9tdmi
;
997 uint32_t vector_catch_value
;
1000 if (arm9tdmi_get_arch_pointers(target
, &armv4_5
, &arm7_9
, &arm9tdmi
) != ERROR_OK
)
1002 command_print(cmd_ctx
, "current target isn't an ARM9 based target");
1006 vector_catch
= &arm7_9
->eice_cache
->reg_list
[EICE_VEC_CATCH
];
1008 /* read the vector catch register if necessary */
1009 if (!vector_catch
->valid
)
1010 embeddedice_read_reg(vector_catch
);
1012 /* get the current setting */
1013 vector_catch_value
= buf_get_u32(vector_catch
->value
, 0, 8);
1017 vector_catch_value
= 0x0;
1018 if (strcmp(args
[0], "all") == 0)
1020 vector_catch_value
= 0xdf;
1022 else if (strcmp(args
[0], "none") == 0)
1028 for (i
= 0; i
< argc
; i
++)
1030 /* go through list of vectors */
1031 for (j
= 0; arm9tdmi_vectors
[j
].name
; j
++)
1033 if (strcmp(args
[i
], arm9tdmi_vectors
[j
].name
) == 0)
1035 vector_catch_value
|= arm9tdmi_vectors
[j
].value
;
1040 /* complain if vector wasn't found */
1041 if (!arm9tdmi_vectors
[j
].name
)
1043 command_print(cmd_ctx
, "vector '%s' not found, leaving current setting unchanged", args
[i
]);
1045 /* reread current setting */
1046 vector_catch_value
= buf_get_u32(
1047 vector_catch
->value
,
1055 /* store new settings */
1056 buf_set_u32(vector_catch
->value
, 0, 8, vector_catch_value
);
1057 embeddedice_store_reg(vector_catch
);
1060 /* output current settings (skip RESERVED vector) */
1061 for (i
= 0; i
< 8; i
++)
1065 command_print(cmd_ctx
, "%s: %s", arm9tdmi_vectors
[i
].name
,
1066 (vector_catch_value
& (1 << i
)) ? "catch" : "don't catch");
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)