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 #define _DEBUG_INSTRUCTION_EXECUTION_
39 int handle_arm9tdmi_catch_vectors_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
41 /* forward declarations */
42 int arm9tdmi_target_create( struct target_s
*target
, Jim_Interp
*interp
);
44 int arm9tdmi_quit(void);
46 target_type_t arm9tdmi_target
=
51 .arch_state
= armv4_5_arch_state
,
53 .target_request_data
= arm7_9_target_request_data
,
56 .resume
= arm7_9_resume
,
59 .assert_reset
= arm7_9_assert_reset
,
60 .deassert_reset
= arm7_9_deassert_reset
,
61 .soft_reset_halt
= arm7_9_soft_reset_halt
,
63 .get_gdb_reg_list
= armv4_5_get_gdb_reg_list
,
65 .read_memory
= arm7_9_read_memory
,
66 .write_memory
= arm7_9_write_memory
,
67 .bulk_write_memory
= arm7_9_bulk_write_memory
,
68 .checksum_memory
= arm7_9_checksum_memory
,
69 .blank_check_memory
= arm7_9_blank_check_memory
,
71 .run_algorithm
= armv4_5_run_algorithm
,
73 .add_breakpoint
= arm7_9_add_breakpoint
,
74 .remove_breakpoint
= arm7_9_remove_breakpoint
,
75 .add_watchpoint
= arm7_9_add_watchpoint
,
76 .remove_watchpoint
= arm7_9_remove_watchpoint
,
78 .register_commands
= arm9tdmi_register_commands
,
79 .target_create
= arm9tdmi_target_create
,
80 .init_target
= arm9tdmi_init_target
,
81 .examine
= arm9tdmi_examine
,
85 arm9tdmi_vector_t arm9tdmi_vectors
[] =
87 {"reset", ARM9TDMI_RESET_VECTOR
},
88 {"undef", ARM9TDMI_UNDEF_VECTOR
},
89 {"swi", ARM9TDMI_SWI_VECTOR
},
90 {"pabt", ARM9TDMI_PABT_VECTOR
},
91 {"dabt", ARM9TDMI_DABT_VECTOR
},
92 {"reserved", ARM9TDMI_RESERVED_VECTOR
},
93 {"irq", ARM9TDMI_IRQ_VECTOR
},
94 {"fiq", ARM9TDMI_FIQ_VECTOR
},
98 int arm9tdmi_examine_debug_reason(target_t
*target
)
100 int retval
= ERROR_OK
;
101 /* get pointers to arch-specific information */
102 armv4_5_common_t
*armv4_5
= target
->arch_info
;
103 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
105 /* only check the debug reason if we don't know it already */
106 if ((target
->debug_reason
!= DBG_REASON_DBGRQ
)
107 && (target
->debug_reason
!= DBG_REASON_SINGLESTEP
))
109 scan_field_t fields
[3];
111 u8 instructionbus
[4];
114 jtag_set_end_state(TAP_DRPAUSE
);
116 fields
[0].tap
= arm7_9
->jtag_info
.tap
;
117 fields
[0].num_bits
= 32;
118 fields
[0].out_value
= NULL
;
119 fields
[0].in_value
= databus
;
121 fields
[1].tap
= arm7_9
->jtag_info
.tap
;
122 fields
[1].num_bits
= 3;
123 fields
[1].out_value
= NULL
;
124 fields
[1].in_value
= &debug_reason
;
126 fields
[2].tap
= arm7_9
->jtag_info
.tap
;
127 fields
[2].num_bits
= 32;
128 fields
[2].out_value
= NULL
;
129 fields
[2].in_value
= instructionbus
;
131 if ((retval
= arm_jtag_scann(&arm7_9
->jtag_info
, 0x1)) != ERROR_OK
)
135 arm_jtag_set_instr(&arm7_9
->jtag_info
, arm7_9
->jtag_info
.intest_instr
, NULL
);
137 jtag_add_dr_scan(3, fields
, jtag_set_end_state(TAP_DRPAUSE
));
138 if ((retval
= jtag_execute_queue()) != ERROR_OK
)
143 fields
[0].in_value
= NULL
;
144 fields
[0].out_value
= databus
;
145 fields
[1].in_value
= NULL
;
146 fields
[1].out_value
= &debug_reason
;
147 fields
[2].in_value
= NULL
;
148 fields
[2].out_value
= instructionbus
;
150 jtag_add_dr_scan(3, fields
, jtag_set_end_state(TAP_DRPAUSE
));
152 if (debug_reason
& 0x4)
153 if (debug_reason
& 0x2)
154 target
->debug_reason
= DBG_REASON_WPTANDBKPT
;
156 target
->debug_reason
= DBG_REASON_WATCHPOINT
;
158 target
->debug_reason
= DBG_REASON_BREAKPOINT
;
164 /* put an instruction in the ARM9TDMI pipeline or write the data bus, and optionally read data */
165 int arm9tdmi_clock_out(arm_jtag_t
*jtag_info
, u32 instr
, u32 out
, u32
*in
, int sysspeed
)
167 int retval
= ERROR_OK
;
168 scan_field_t fields
[3];
171 u8 sysspeed_buf
= 0x0;
174 buf_set_u32(out_buf
, 0, 32, out
);
176 buf_set_u32(instr_buf
, 0, 32, flip_u32(instr
, 32));
179 buf_set_u32(&sysspeed_buf
, 2, 1, 1);
181 jtag_set_end_state(TAP_DRPAUSE
);
182 if ((retval
= arm_jtag_scann(jtag_info
, 0x1)) != ERROR_OK
)
187 arm_jtag_set_instr(jtag_info
, jtag_info
->intest_instr
, NULL
);
189 fields
[0].tap
= jtag_info
->tap
;
190 fields
[0].num_bits
= 32;
191 fields
[0].out_value
= out_buf
;
192 fields
[0].in_value
= NULL
;
194 fields
[1].tap
= jtag_info
->tap
;
195 fields
[1].num_bits
= 3;
196 fields
[1].out_value
= &sysspeed_buf
;
197 fields
[1].in_value
= NULL
;
199 fields
[2].tap
= jtag_info
->tap
;
200 fields
[2].num_bits
= 32;
201 fields
[2].out_value
= instr_buf
;
202 fields
[2].in_value
= NULL
;
206 fields
[0].in_value
=(u8
*)in
;
207 jtag_add_dr_scan(3, fields
, jtag_get_end_state());
209 jtag_add_callback(arm_le_to_h_u32
, (u8
*)in
);
213 jtag_add_dr_scan(3, fields
, jtag_get_end_state());
216 jtag_add_runtest(0, jtag_get_end_state());
218 #ifdef _DEBUG_INSTRUCTION_EXECUTION_
220 if ((retval
= jtag_execute_queue()) != ERROR_OK
)
227 LOG_DEBUG("instr: 0x%8.8x, out: 0x%8.8x, in: 0x%8.8x", instr
, out
, *in
);
230 LOG_DEBUG("instr: 0x%8.8x, out: 0x%8.8x", instr
, out
);
237 /* just read data (instruction and data-out = don't care) */
238 int arm9tdmi_clock_data_in(arm_jtag_t
*jtag_info
, u32
*in
)
240 int retval
= ERROR_OK
;;
241 scan_field_t fields
[3];
243 jtag_set_end_state(TAP_DRPAUSE
);
244 if ((retval
= arm_jtag_scann(jtag_info
, 0x1)) != ERROR_OK
)
249 arm_jtag_set_instr(jtag_info
, jtag_info
->intest_instr
, NULL
);
251 fields
[0].tap
= jtag_info
->tap
;
252 fields
[0].num_bits
= 32;
253 fields
[0].out_value
= NULL
;
254 fields
[0].in_value
= (u8
*)in
;
256 fields
[1].tap
= jtag_info
->tap
;
257 fields
[1].num_bits
= 3;
258 fields
[1].out_value
= NULL
;
259 fields
[1].in_value
= NULL
;
261 fields
[2].tap
= jtag_info
->tap
;
262 fields
[2].num_bits
= 32;
263 fields
[2].out_value
= NULL
;
264 fields
[2].in_value
= NULL
;
266 jtag_add_dr_scan(3, fields
, jtag_get_end_state());
268 jtag_add_callback(arm_le_to_h_u32
, (u8
*)in
);
270 jtag_add_runtest(0, jtag_get_end_state());
272 #ifdef _DEBUG_INSTRUCTION_EXECUTION_
274 if ((retval
= jtag_execute_queue()) != ERROR_OK
)
281 LOG_DEBUG("in: 0x%8.8x", *in
);
285 LOG_ERROR("BUG: called with in == NULL");
293 extern void arm_endianness(u8
*tmp
, void *in
, int size
, int be
, int flip
);
295 static int arm9endianness(u8
*in
, jtag_callback_data_t size
, jtag_callback_data_t be
, jtag_callback_data_t captured
)
297 arm_endianness((u8
*)captured
, in
, (int)size
, (int)be
, 0);
301 /* clock the target, and read the databus
302 * the *in pointer points to a buffer where elements of 'size' bytes
303 * are stored in big (be==1) or little (be==0) endianness
305 int arm9tdmi_clock_data_in_endianness(arm_jtag_t
*jtag_info
, void *in
, int size
, int be
)
307 int retval
= ERROR_OK
;
308 scan_field_t fields
[3];
310 jtag_set_end_state(TAP_DRPAUSE
);
311 if ((retval
= arm_jtag_scann(jtag_info
, 0x1)) != ERROR_OK
)
316 arm_jtag_set_instr(jtag_info
, jtag_info
->intest_instr
, NULL
);
318 fields
[0].tap
= jtag_info
->tap
;
319 fields
[0].num_bits
= 32;
320 fields
[0].out_value
= NULL
;
321 jtag_alloc_in_value32(&fields
[0]);
323 fields
[1].tap
= jtag_info
->tap
;
324 fields
[1].num_bits
= 3;
325 fields
[1].out_value
= NULL
;
326 fields
[1].in_value
= NULL
;
328 fields
[2].tap
= jtag_info
->tap
;
329 fields
[2].num_bits
= 32;
330 fields
[2].out_value
= NULL
;
331 fields
[2].in_value
= NULL
;
333 jtag_add_dr_scan(3, fields
, jtag_get_end_state());
335 jtag_add_callback4(arm9endianness
, in
, (jtag_callback_data_t
)size
, (jtag_callback_data_t
)be
, (jtag_callback_data_t
)fields
[0].in_value
);
337 jtag_add_runtest(0, jtag_get_end_state());
339 #ifdef _DEBUG_INSTRUCTION_EXECUTION_
341 if ((retval
= jtag_execute_queue()) != ERROR_OK
)
348 LOG_DEBUG("in: 0x%8.8x", *(u32
*)in
);
352 LOG_ERROR("BUG: called with in == NULL");
360 void arm9tdmi_change_to_arm(target_t
*target
, u32
*r0
, u32
*pc
)
362 int retval
= ERROR_OK
;
363 /* get pointers to arch-specific information */
364 armv4_5_common_t
*armv4_5
= target
->arch_info
;
365 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
366 arm_jtag_t
*jtag_info
= &arm7_9
->jtag_info
;
368 /* save r0 before using it and put system in ARM state
369 * to allow common handling of ARM and THUMB debugging */
371 /* fetch STR r0, [r0] */
372 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_STR(0, 0), 0, NULL
, 0);
373 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, 0, NULL
, 0);
374 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, 0, NULL
, 0);
375 /* STR r0, [r0] in Memory */
376 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, 0, r0
, 0);
378 /* MOV r0, r15 fetched, STR in Decode */
379 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_MOV(0, 15), 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_STR(0, 0), 0, NULL
, 0);
382 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, 0, NULL
, 0);
383 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, 0, NULL
, 0);
384 /* nothing fetched, STR r0, [r0] in Memory */
385 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, 0, pc
, 0);
387 /* use pc-relative LDR to clear r0[1:0] (for switch to ARM mode) */
388 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_LDR_PCREL(0), 0, NULL
, 0);
390 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, 0, NULL
, 0);
392 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, 0, NULL
, 0);
393 /* LDR in Memory (to account for interlock) */
394 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, 0, NULL
, 0);
397 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_BX(0), 0, NULL
, 0);
398 /* NOP fetched, BX in Decode, MOV in Execute */
399 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, 0, NULL
, 0);
400 /* NOP fetched, BX in Execute (1) */
401 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, 0, NULL
, 0);
403 if ((retval
= jtag_execute_queue()) != ERROR_OK
)
408 /* fix program counter:
409 * MOV r0, r15 was the 5th instruction (+8)
410 * reading PC in Thumb state gives address of instruction + 4
415 void arm9tdmi_read_core_regs(target_t
*target
, u32 mask
, u32
* core_regs
[16])
418 /* get pointers to arch-specific information */
419 armv4_5_common_t
*armv4_5
= target
->arch_info
;
420 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
421 arm_jtag_t
*jtag_info
= &arm7_9
->jtag_info
;
423 /* STMIA r0-15, [r0] at debug speed
424 * register values will start to appear on 4th DCLK
426 arm9tdmi_clock_out(jtag_info
, ARMV4_5_STMIA(0, mask
& 0xffff, 0, 0), 0, NULL
, 0);
428 /* fetch NOP, STM in DECODE stage */
429 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
430 /* fetch NOP, STM in EXECUTE stage (1st cycle) */
431 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
433 for (i
= 0; i
<= 15; i
++)
436 /* nothing fetched, STM in MEMORY (i'th cycle) */
437 arm9tdmi_clock_data_in(jtag_info
, core_regs
[i
]);
441 void arm9tdmi_read_core_regs_target_buffer(target_t
*target
, u32 mask
, void* buffer
, int size
)
444 /* get pointers to arch-specific information */
445 armv4_5_common_t
*armv4_5
= target
->arch_info
;
446 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
447 arm_jtag_t
*jtag_info
= &arm7_9
->jtag_info
;
448 int be
= (target
->endianness
== TARGET_BIG_ENDIAN
) ? 1 : 0;
449 u32
*buf_u32
= buffer
;
450 u16
*buf_u16
= buffer
;
453 /* STMIA r0-15, [r0] at debug speed
454 * register values will start to appear on 4th DCLK
456 arm9tdmi_clock_out(jtag_info
, ARMV4_5_STMIA(0, mask
& 0xffff, 0, 0), 0, NULL
, 0);
458 /* fetch NOP, STM in DECODE stage */
459 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
460 /* fetch NOP, STM in EXECUTE stage (1st cycle) */
461 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
463 for (i
= 0; i
<= 15; i
++)
466 /* nothing fetched, STM in MEMORY (i'th cycle) */
470 arm9tdmi_clock_data_in_endianness(jtag_info
, buf_u32
++, 4, be
);
473 arm9tdmi_clock_data_in_endianness(jtag_info
, buf_u16
++, 2, be
);
476 arm9tdmi_clock_data_in_endianness(jtag_info
, buf_u8
++, 1, be
);
482 void arm9tdmi_read_xpsr(target_t
*target
, u32
*xpsr
, int spsr
)
484 /* get pointers to arch-specific information */
485 armv4_5_common_t
*armv4_5
= target
->arch_info
;
486 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
487 arm_jtag_t
*jtag_info
= &arm7_9
->jtag_info
;
490 arm9tdmi_clock_out(jtag_info
, ARMV4_5_MRS(0, spsr
& 1), 0, NULL
, 0);
491 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
492 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
493 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
494 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
497 arm9tdmi_clock_out(jtag_info
, ARMV4_5_STR(0, 15), 0, NULL
, 0);
498 /* fetch NOP, STR in DECODE stage */
499 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
500 /* fetch NOP, STR in EXECUTE stage (1st cycle) */
501 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
502 /* nothing fetched, STR in MEMORY */
503 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, xpsr
, 0);
506 void arm9tdmi_write_xpsr(target_t
*target
, u32 xpsr
, int spsr
)
508 /* get pointers to arch-specific information */
509 armv4_5_common_t
*armv4_5
= target
->arch_info
;
510 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
511 arm_jtag_t
*jtag_info
= &arm7_9
->jtag_info
;
513 LOG_DEBUG("xpsr: %8.8x, spsr: %i", xpsr
, spsr
);
516 arm9tdmi_clock_out(jtag_info
, ARMV4_5_MSR_IM(xpsr
& 0xff, 0, 1, spsr
), 0, NULL
, 0);
517 /* MSR2 fetched, MSR1 in DECODE */
518 arm9tdmi_clock_out(jtag_info
, ARMV4_5_MSR_IM((xpsr
& 0xff00) >> 8, 0xc, 2, spsr
), 0, NULL
, 0);
519 /* MSR3 fetched, MSR1 in EXECUTE (1), MSR2 in DECODE */
520 arm9tdmi_clock_out(jtag_info
, ARMV4_5_MSR_IM((xpsr
& 0xff0000) >> 16, 0x8, 4, spsr
), 0, NULL
, 0);
521 /* nothing fetched, MSR1 in EXECUTE (2) */
522 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
523 /* nothing fetched, MSR1 in EXECUTE (3) */
524 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
525 /* MSR4 fetched, MSR2 in EXECUTE (1), MSR3 in DECODE */
526 arm9tdmi_clock_out(jtag_info
, ARMV4_5_MSR_IM((xpsr
& 0xff000000) >> 24, 0x4, 8, spsr
), 0, NULL
, 0);
527 /* nothing fetched, MSR2 in EXECUTE (2) */
528 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
529 /* nothing fetched, MSR2 in EXECUTE (3) */
530 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
531 /* NOP fetched, MSR3 in EXECUTE (1), MSR4 in DECODE */
532 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
533 /* nothing fetched, MSR3 in EXECUTE (2) */
534 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
535 /* nothing fetched, MSR3 in EXECUTE (3) */
536 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
537 /* NOP fetched, MSR4 in EXECUTE (1) */
538 /* last MSR writes flags, which takes only one cycle */
539 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
542 void arm9tdmi_write_xpsr_im8(target_t
*target
, u8 xpsr_im
, int rot
, int spsr
)
544 /* get pointers to arch-specific information */
545 armv4_5_common_t
*armv4_5
= target
->arch_info
;
546 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
547 arm_jtag_t
*jtag_info
= &arm7_9
->jtag_info
;
549 LOG_DEBUG("xpsr_im: %2.2x, rot: %i, spsr: %i", xpsr_im
, rot
, spsr
);
552 arm9tdmi_clock_out(jtag_info
, ARMV4_5_MSR_IM(xpsr_im
, rot
, 1, spsr
), 0, NULL
, 0);
553 /* NOP fetched, MSR in DECODE */
554 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
555 /* NOP fetched, MSR in EXECUTE (1) */
556 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
558 /* rot == 4 writes flags, which takes only one cycle */
561 /* nothing fetched, MSR in EXECUTE (2) */
562 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
563 /* nothing fetched, MSR in EXECUTE (3) */
564 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
568 void arm9tdmi_write_core_regs(target_t
*target
, u32 mask
, u32 core_regs
[16])
571 /* get pointers to arch-specific information */
572 armv4_5_common_t
*armv4_5
= target
->arch_info
;
573 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
574 arm_jtag_t
*jtag_info
= &arm7_9
->jtag_info
;
576 /* LDMIA r0-15, [r0] at debug speed
577 * register values will start to appear on 4th DCLK
579 arm9tdmi_clock_out(jtag_info
, ARMV4_5_LDMIA(0, mask
& 0xffff, 0, 0), 0, NULL
, 0);
581 /* fetch NOP, LDM in DECODE stage */
582 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
583 /* fetch NOP, LDM in EXECUTE stage (1st cycle) */
584 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
586 for (i
= 0; i
<= 15; i
++)
589 /* nothing fetched, LDM still in EXECUTE (1+i cycle) */
590 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, core_regs
[i
], NULL
, 0);
592 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
595 void arm9tdmi_load_word_regs(target_t
*target
, u32 mask
)
597 /* get pointers to arch-specific information */
598 armv4_5_common_t
*armv4_5
= target
->arch_info
;
599 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
600 arm_jtag_t
*jtag_info
= &arm7_9
->jtag_info
;
602 /* put system-speed load-multiple into the pipeline */
603 arm9tdmi_clock_out(jtag_info
, ARMV4_5_LDMIA(0, mask
& 0xffff, 0, 1), 0, NULL
, 0);
604 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 1);
607 void arm9tdmi_load_hword_reg(target_t
*target
, int num
)
609 /* get pointers to arch-specific information */
610 armv4_5_common_t
*armv4_5
= target
->arch_info
;
611 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
612 arm_jtag_t
*jtag_info
= &arm7_9
->jtag_info
;
614 /* put system-speed load half-word into the pipeline */
615 arm9tdmi_clock_out(jtag_info
, ARMV4_5_LDRH_IP(num
, 0), 0, NULL
, 0);
616 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 1);
619 void arm9tdmi_load_byte_reg(target_t
*target
, int num
)
621 /* get pointers to arch-specific information */
622 armv4_5_common_t
*armv4_5
= target
->arch_info
;
623 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
624 arm_jtag_t
*jtag_info
= &arm7_9
->jtag_info
;
626 /* put system-speed load byte into the pipeline */
627 arm9tdmi_clock_out(jtag_info
, ARMV4_5_LDRB_IP(num
, 0), 0, NULL
, 0);
628 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 1);
631 void arm9tdmi_store_word_regs(target_t
*target
, u32 mask
)
633 /* get pointers to arch-specific information */
634 armv4_5_common_t
*armv4_5
= target
->arch_info
;
635 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
636 arm_jtag_t
*jtag_info
= &arm7_9
->jtag_info
;
638 /* put system-speed store-multiple into the pipeline */
639 arm9tdmi_clock_out(jtag_info
, ARMV4_5_STMIA(0, mask
, 0, 1), 0, NULL
, 0);
640 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 1);
643 void arm9tdmi_store_hword_reg(target_t
*target
, int num
)
645 /* get pointers to arch-specific information */
646 armv4_5_common_t
*armv4_5
= target
->arch_info
;
647 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
648 arm_jtag_t
*jtag_info
= &arm7_9
->jtag_info
;
650 /* put system-speed store half-word into the pipeline */
651 arm9tdmi_clock_out(jtag_info
, ARMV4_5_STRH_IP(num
, 0), 0, NULL
, 0);
652 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 1);
655 void arm9tdmi_store_byte_reg(target_t
*target
, int num
)
657 /* get pointers to arch-specific information */
658 armv4_5_common_t
*armv4_5
= target
->arch_info
;
659 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
660 arm_jtag_t
*jtag_info
= &arm7_9
->jtag_info
;
662 /* put system-speed store byte into the pipeline */
663 arm9tdmi_clock_out(jtag_info
, ARMV4_5_STRB_IP(num
, 0), 0, NULL
, 0);
664 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 1);
667 void arm9tdmi_write_pc(target_t
*target
, u32 pc
)
669 /* get pointers to arch-specific information */
670 armv4_5_common_t
*armv4_5
= target
->arch_info
;
671 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
672 arm_jtag_t
*jtag_info
= &arm7_9
->jtag_info
;
674 /* LDMIA r0-15, [r0] at debug speed
675 * register values will start to appear on 4th DCLK
677 arm9tdmi_clock_out(jtag_info
, ARMV4_5_LDMIA(0, 0x8000, 0, 0), 0, NULL
, 0);
679 /* fetch NOP, LDM in DECODE stage */
680 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
681 /* fetch NOP, LDM in EXECUTE stage (1st cycle) */
682 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
683 /* nothing fetched, LDM in EXECUTE stage (2nd cycle) (output data) */
684 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, pc
, NULL
, 0);
685 /* nothing fetched, LDM in EXECUTE stage (3rd cycle) */
686 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
687 /* fetch NOP, LDM in EXECUTE stage (4th cycle) */
688 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
689 /* fetch NOP, LDM in EXECUTE stage (5th cycle) */
690 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
693 void arm9tdmi_branch_resume(target_t
*target
)
695 /* get pointers to arch-specific information */
696 armv4_5_common_t
*armv4_5
= target
->arch_info
;
697 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
698 arm_jtag_t
*jtag_info
= &arm7_9
->jtag_info
;
700 arm9tdmi_clock_out(jtag_info
, ARMV4_5_B(0xfffffc, 0), 0, NULL
, 0);
701 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 1);
704 void arm9tdmi_branch_resume_thumb(target_t
*target
)
708 /* get pointers to arch-specific information */
709 armv4_5_common_t
*armv4_5
= target
->arch_info
;
710 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
711 arm_jtag_t
*jtag_info
= &arm7_9
->jtag_info
;
712 reg_t
*dbg_stat
= &arm7_9
->eice_cache
->reg_list
[EICE_DBG_STAT
];
714 /* LDMIA r0-15, [r0] at debug speed
715 * register values will start to appear on 4th DCLK
717 arm9tdmi_clock_out(jtag_info
, ARMV4_5_LDMIA(0, 0x1, 0, 0), 0, NULL
, 0);
719 /* fetch NOP, LDM in DECODE stage */
720 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
721 /* fetch NOP, LDM in EXECUTE stage (1st cycle) */
722 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
723 /* nothing fetched, LDM in EXECUTE stage (2nd cycle) */
724 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32) | 1, NULL
, 0);
725 /* nothing fetched, LDM in EXECUTE stage (3rd cycle) */
726 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
728 /* Branch and eXchange */
729 arm9tdmi_clock_out(jtag_info
, ARMV4_5_BX(0), 0, NULL
, 0);
731 embeddedice_read_reg(dbg_stat
);
733 /* fetch NOP, BX in DECODE stage */
734 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
736 embeddedice_read_reg(dbg_stat
);
738 /* fetch NOP, BX in EXECUTE stage (1st cycle) */
739 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
741 /* target is now in Thumb state */
742 embeddedice_read_reg(dbg_stat
);
744 /* load r0 value, MOV_IM in Decode*/
745 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_LDR_PCREL(0), 0, NULL
, 0);
746 /* fetch NOP, LDR in Decode, MOV_IM in Execute */
747 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, 0, NULL
, 0);
748 /* fetch NOP, LDR in Execute */
749 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, 0, NULL
, 0);
750 /* nothing fetched, LDR in EXECUTE stage (2nd cycle) */
751 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, buf_get_u32(armv4_5
->core_cache
->reg_list
[0].value
, 0, 32), NULL
, 0);
752 /* nothing fetched, LDR in EXECUTE stage (3rd cycle) */
753 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, 0, NULL
, 0);
755 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, 0, NULL
, 0);
756 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, 0, NULL
, 0);
758 embeddedice_read_reg(dbg_stat
);
760 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_B(0x7f7), 0, NULL
, 1);
761 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, 0, NULL
, 0);
764 void arm9tdmi_enable_single_step(target_t
*target
, u32 next_pc
)
766 /* get pointers to arch-specific information */
767 armv4_5_common_t
*armv4_5
= target
->arch_info
;
768 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
770 if (arm7_9
->has_single_step
)
772 buf_set_u32(arm7_9
->eice_cache
->reg_list
[EICE_DBG_CTRL
].value
, 3, 1, 1);
773 embeddedice_store_reg(&arm7_9
->eice_cache
->reg_list
[EICE_DBG_CTRL
]);
777 arm7_9_enable_eice_step(target
, next_pc
);
781 void arm9tdmi_disable_single_step(target_t
*target
)
783 /* get pointers to arch-specific information */
784 armv4_5_common_t
*armv4_5
= target
->arch_info
;
785 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
787 if (arm7_9
->has_single_step
)
789 buf_set_u32(arm7_9
->eice_cache
->reg_list
[EICE_DBG_CTRL
].value
, 3, 1, 0);
790 embeddedice_store_reg(&arm7_9
->eice_cache
->reg_list
[EICE_DBG_CTRL
]);
794 arm7_9_disable_eice_step(target
);
798 void arm9tdmi_build_reg_cache(target_t
*target
)
800 reg_cache_t
**cache_p
= register_get_last_cache_p(&target
->reg_cache
);
801 /* get pointers to arch-specific information */
802 armv4_5_common_t
*armv4_5
= target
->arch_info
;
804 (*cache_p
) = armv4_5_build_reg_cache(target
, armv4_5
);
805 armv4_5
->core_cache
= (*cache_p
);
808 int arm9tdmi_examine(struct target_s
*target
)
810 /* get pointers to arch-specific information */
812 armv4_5_common_t
*armv4_5
= target
->arch_info
;
813 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
814 if (!target_was_examined(target
))
816 reg_cache_t
**cache_p
= register_get_last_cache_p(&target
->reg_cache
);
818 /* one extra register (vector catch) */
819 t
=embeddedice_build_reg_cache(target
, arm7_9
);
823 arm7_9
->eice_cache
= (*cache_p
);
827 arm_jtag_t
*jtag_info
= &arm7_9
->jtag_info
;
828 (*cache_p
)->next
= etm_build_reg_cache(target
, jtag_info
, arm7_9
->etm_ctx
);
829 arm7_9
->etm_ctx
->reg_cache
= (*cache_p
)->next
;
831 target_set_examined(target
);
833 if ((retval
=embeddedice_setup(target
))!=ERROR_OK
)
835 if ((retval
=arm7_9_setup(target
))!=ERROR_OK
)
839 if ((retval
=etm_setup(target
))!=ERROR_OK
)
845 int arm9tdmi_init_target(struct command_context_s
*cmd_ctx
, struct target_s
*target
)
848 arm9tdmi_build_reg_cache(target
);
853 int arm9tdmi_quit(void)
858 int arm9tdmi_init_arch_info(target_t
*target
, arm9tdmi_common_t
*arm9tdmi
, jtag_tap_t
*tap
)
860 armv4_5_common_t
*armv4_5
;
861 arm7_9_common_t
*arm7_9
;
863 arm7_9
= &arm9tdmi
->arm7_9_common
;
864 armv4_5
= &arm7_9
->armv4_5_common
;
866 /* prepare JTAG information for the new target */
867 arm7_9
->jtag_info
.tap
= tap
;
868 arm7_9
->jtag_info
.scann_size
= 5;
870 /* register arch-specific functions */
871 arm7_9
->examine_debug_reason
= arm9tdmi_examine_debug_reason
;
872 arm7_9
->change_to_arm
= arm9tdmi_change_to_arm
;
873 arm7_9
->read_core_regs
= arm9tdmi_read_core_regs
;
874 arm7_9
->read_core_regs_target_buffer
= arm9tdmi_read_core_regs_target_buffer
;
875 arm7_9
->read_xpsr
= arm9tdmi_read_xpsr
;
877 arm7_9
->write_xpsr
= arm9tdmi_write_xpsr
;
878 arm7_9
->write_xpsr_im8
= arm9tdmi_write_xpsr_im8
;
879 arm7_9
->write_core_regs
= arm9tdmi_write_core_regs
;
881 arm7_9
->load_word_regs
= arm9tdmi_load_word_regs
;
882 arm7_9
->load_hword_reg
= arm9tdmi_load_hword_reg
;
883 arm7_9
->load_byte_reg
= arm9tdmi_load_byte_reg
;
885 arm7_9
->store_word_regs
= arm9tdmi_store_word_regs
;
886 arm7_9
->store_hword_reg
= arm9tdmi_store_hword_reg
;
887 arm7_9
->store_byte_reg
= arm9tdmi_store_byte_reg
;
889 arm7_9
->write_pc
= arm9tdmi_write_pc
;
890 arm7_9
->branch_resume
= arm9tdmi_branch_resume
;
891 arm7_9
->branch_resume_thumb
= arm9tdmi_branch_resume_thumb
;
893 arm7_9
->enable_single_step
= arm9tdmi_enable_single_step
;
894 arm7_9
->disable_single_step
= arm9tdmi_disable_single_step
;
896 arm7_9
->pre_debug_entry
= NULL
;
897 arm7_9
->post_debug_entry
= NULL
;
899 arm7_9
->pre_restore_context
= NULL
;
900 arm7_9
->post_restore_context
= NULL
;
902 /* initialize arch-specific breakpoint handling */
903 arm7_9
->arm_bkpt
= 0xdeeedeee;
904 arm7_9
->thumb_bkpt
= 0xdeee;
906 arm7_9
->dbgreq_adjust_pc
= 3;
907 arm7_9
->arch_info
= arm9tdmi
;
909 arm9tdmi
->common_magic
= ARM9TDMI_COMMON_MAGIC
;
910 arm9tdmi
->arch_info
= NULL
;
912 arm7_9_init_arch_info(target
, arm7_9
);
914 /* override use of DBGRQ, this is safe on ARM9TDMI */
915 arm7_9
->use_dbgrq
= 1;
917 /* all ARM9s have the vector catch register */
918 arm7_9
->has_vector_catch
= 1;
923 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
)
925 armv4_5_common_t
*armv4_5
= target
->arch_info
;
926 arm7_9_common_t
*arm7_9
;
927 arm9tdmi_common_t
*arm9tdmi
;
929 if (armv4_5
->common_magic
!= ARMV4_5_COMMON_MAGIC
)
934 arm7_9
= armv4_5
->arch_info
;
935 if (arm7_9
->common_magic
!= ARM7_9_COMMON_MAGIC
)
940 arm9tdmi
= arm7_9
->arch_info
;
941 if (arm9tdmi
->common_magic
!= ARM9TDMI_COMMON_MAGIC
)
946 *armv4_5_p
= armv4_5
;
948 *arm9tdmi_p
= arm9tdmi
;
953 int arm9tdmi_target_create(struct target_s
*target
, Jim_Interp
*interp
)
955 arm9tdmi_common_t
*arm9tdmi
= calloc(1,sizeof(arm9tdmi_common_t
));
957 arm9tdmi_init_arch_info(target
, arm9tdmi
, target
->tap
);
962 int arm9tdmi_register_commands(struct command_context_s
*cmd_ctx
)
965 command_t
*arm9tdmi_cmd
;
967 retval
= arm7_9_register_commands(cmd_ctx
);
968 arm9tdmi_cmd
= register_command(cmd_ctx
, NULL
, "arm9tdmi", NULL
, COMMAND_ANY
, "arm9tdmi specific commands");
969 register_command(cmd_ctx
, arm9tdmi_cmd
, "vector_catch", handle_arm9tdmi_catch_vectors_command
, COMMAND_EXEC
, "catch arm920t vectors ['all'|'none'|'<vec1 vec2 ...>']");
974 int handle_arm9tdmi_catch_vectors_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
976 target_t
*target
= get_current_target(cmd_ctx
);
977 armv4_5_common_t
*armv4_5
;
978 arm7_9_common_t
*arm7_9
;
979 arm9tdmi_common_t
*arm9tdmi
;
981 u32 vector_catch_value
;
984 if (arm9tdmi_get_arch_pointers(target
, &armv4_5
, &arm7_9
, &arm9tdmi
) != ERROR_OK
)
986 command_print(cmd_ctx
, "current target isn't an ARM9TDMI based target");
990 vector_catch
= &arm7_9
->eice_cache
->reg_list
[EICE_VEC_CATCH
];
992 /* read the vector catch register if necessary */
993 if (!vector_catch
->valid
)
994 embeddedice_read_reg(vector_catch
);
996 /* get the current setting */
997 vector_catch_value
= buf_get_u32(vector_catch
->value
, 0, 32);
1001 vector_catch_value
= 0x0;
1002 if (strcmp(args
[0], "all") == 0)
1004 vector_catch_value
= 0xdf;
1006 else if (strcmp(args
[0], "none") == 0)
1012 for (i
= 0; i
< argc
; i
++)
1014 /* go through list of vectors */
1015 for (j
= 0; arm9tdmi_vectors
[j
].name
; j
++)
1017 if (strcmp(args
[i
], arm9tdmi_vectors
[j
].name
) == 0)
1019 vector_catch_value
|= arm9tdmi_vectors
[j
].value
;
1024 /* complain if vector wasn't found */
1025 if (!arm9tdmi_vectors
[j
].name
)
1027 command_print(cmd_ctx
, "vector '%s' not found, leaving current setting unchanged", args
[i
]);
1029 /* reread current setting */
1030 vector_catch_value
= buf_get_u32(vector_catch
->value
, 0, 32);
1037 /* store new settings */
1038 buf_set_u32(vector_catch
->value
, 0, 32, vector_catch_value
);
1039 embeddedice_store_reg(vector_catch
);
1042 /* output current settings (skip RESERVED vector) */
1043 for (i
= 0; i
< 8; i
++)
1047 command_print(cmd_ctx
, "%s: %s", arm9tdmi_vectors
[i
].name
,
1048 (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)