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 ***************************************************************************/
34 #define _DEBUG_INSTRUCTION_EXECUTION_
38 int handle_arm9tdmi_catch_vectors_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
40 /* forward declarations */
41 int arm9tdmi_target_create( struct target_s
*target
, Jim_Interp
*interp
);
43 int arm9tdmi_quit(void);
45 target_type_t arm9tdmi_target
=
50 .arch_state
= armv4_5_arch_state
,
52 .target_request_data
= arm7_9_target_request_data
,
55 .resume
= arm7_9_resume
,
58 .assert_reset
= arm7_9_assert_reset
,
59 .deassert_reset
= arm7_9_deassert_reset
,
60 .soft_reset_halt
= arm7_9_soft_reset_halt
,
62 .get_gdb_reg_list
= armv4_5_get_gdb_reg_list
,
64 .read_memory
= arm7_9_read_memory
,
65 .write_memory
= arm7_9_write_memory
,
66 .bulk_write_memory
= arm7_9_bulk_write_memory
,
67 .checksum_memory
= arm7_9_checksum_memory
,
68 .blank_check_memory
= arm7_9_blank_check_memory
,
70 .run_algorithm
= armv4_5_run_algorithm
,
72 .add_breakpoint
= arm7_9_add_breakpoint
,
73 .remove_breakpoint
= arm7_9_remove_breakpoint
,
74 .add_watchpoint
= arm7_9_add_watchpoint
,
75 .remove_watchpoint
= arm7_9_remove_watchpoint
,
77 .register_commands
= arm9tdmi_register_commands
,
78 .target_create
= arm9tdmi_target_create
,
79 .init_target
= arm9tdmi_init_target
,
80 .examine
= arm9tdmi_examine
,
84 arm9tdmi_vector_t arm9tdmi_vectors
[] =
86 {"reset", ARM9TDMI_RESET_VECTOR
},
87 {"undef", ARM9TDMI_UNDEF_VECTOR
},
88 {"swi", ARM9TDMI_SWI_VECTOR
},
89 {"pabt", ARM9TDMI_PABT_VECTOR
},
90 {"dabt", ARM9TDMI_DABT_VECTOR
},
91 {"reserved", ARM9TDMI_RESERVED_VECTOR
},
92 {"irq", ARM9TDMI_IRQ_VECTOR
},
93 {"fiq", ARM9TDMI_FIQ_VECTOR
},
97 int arm9tdmi_examine_debug_reason(target_t
*target
)
99 int retval
= ERROR_OK
;
100 /* get pointers to arch-specific information */
101 armv4_5_common_t
*armv4_5
= target
->arch_info
;
102 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
104 /* only check the debug reason if we don't know it already */
105 if ((target
->debug_reason
!= DBG_REASON_DBGRQ
)
106 && (target
->debug_reason
!= DBG_REASON_SINGLESTEP
))
108 scan_field_t fields
[3];
110 u8 instructionbus
[4];
113 jtag_add_end_state(TAP_DRPAUSE
);
115 fields
[0].tap
= arm7_9
->jtag_info
.tap
;
116 fields
[0].num_bits
= 32;
117 fields
[0].out_value
= NULL
;
118 fields
[0].in_value
= databus
;
120 fields
[1].tap
= arm7_9
->jtag_info
.tap
;
121 fields
[1].num_bits
= 3;
122 fields
[1].out_value
= NULL
;
123 fields
[1].in_value
= &debug_reason
;
125 fields
[2].tap
= arm7_9
->jtag_info
.tap
;
126 fields
[2].num_bits
= 32;
127 fields
[2].out_value
= NULL
;
128 fields
[2].in_value
= instructionbus
;
130 if ((retval
= arm_jtag_scann(&arm7_9
->jtag_info
, 0x1)) != ERROR_OK
)
134 arm_jtag_set_instr(&arm7_9
->jtag_info
, arm7_9
->jtag_info
.intest_instr
, NULL
);
136 jtag_add_dr_scan(3, fields
, TAP_DRPAUSE
);
137 if ((retval
= jtag_execute_queue()) != ERROR_OK
)
142 fields
[0].in_value
= NULL
;
143 fields
[0].out_value
= databus
;
144 fields
[1].in_value
= NULL
;
145 fields
[1].out_value
= &debug_reason
;
146 fields
[2].in_value
= NULL
;
147 fields
[2].out_value
= instructionbus
;
149 jtag_add_dr_scan(3, fields
, TAP_DRPAUSE
);
151 if (debug_reason
& 0x4)
152 if (debug_reason
& 0x2)
153 target
->debug_reason
= DBG_REASON_WPTANDBKPT
;
155 target
->debug_reason
= DBG_REASON_WATCHPOINT
;
157 target
->debug_reason
= DBG_REASON_BREAKPOINT
;
163 /* put an instruction in the ARM9TDMI pipeline or write the data bus, and optionally read data */
164 int arm9tdmi_clock_out(arm_jtag_t
*jtag_info
, u32 instr
, u32 out
, u32
*in
, int sysspeed
)
166 int retval
= ERROR_OK
;
167 scan_field_t fields
[3];
170 u8 sysspeed_buf
= 0x0;
173 buf_set_u32(out_buf
, 0, 32, out
);
175 buf_set_u32(instr_buf
, 0, 32, flip_u32(instr
, 32));
178 buf_set_u32(&sysspeed_buf
, 2, 1, 1);
180 jtag_add_end_state(TAP_DRPAUSE
);
181 if ((retval
= arm_jtag_scann(jtag_info
, 0x1)) != ERROR_OK
)
186 arm_jtag_set_instr(jtag_info
, jtag_info
->intest_instr
, NULL
);
188 fields
[0].tap
= jtag_info
->tap
;
189 fields
[0].num_bits
= 32;
190 fields
[0].out_value
= out_buf
;
191 fields
[0].in_value
= NULL
;
193 fields
[1].tap
= jtag_info
->tap
;
194 fields
[1].num_bits
= 3;
195 fields
[1].out_value
= &sysspeed_buf
;
196 fields
[1].in_value
= NULL
;
198 fields
[2].tap
= jtag_info
->tap
;
199 fields
[2].num_bits
= 32;
200 fields
[2].out_value
= instr_buf
;
201 fields
[2].in_value
= NULL
;
206 fields
[0].in_value
=tmp
;
207 jtag_add_dr_scan_now(3, fields
, TAP_INVALID
);
209 *in
=le_to_h_u32(tmp
);
213 jtag_add_dr_scan(3, fields
, TAP_INVALID
);
216 jtag_add_runtest(0, TAP_INVALID
);
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_add_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
;
255 fields
[0].in_value
= tmp
;
257 fields
[1].tap
= jtag_info
->tap
;
258 fields
[1].num_bits
= 3;
259 fields
[1].out_value
= NULL
;
260 fields
[1].in_value
= NULL
;
262 fields
[2].tap
= jtag_info
->tap
;
263 fields
[2].num_bits
= 32;
264 fields
[2].out_value
= NULL
;
265 fields
[2].in_value
= NULL
;
267 jtag_add_dr_scan_now(3, fields
, TAP_INVALID
);
269 *in
=le_to_h_u32(tmp
);
271 jtag_add_runtest(0, TAP_INVALID
);
273 #ifdef _DEBUG_INSTRUCTION_EXECUTION_
275 if ((retval
= jtag_execute_queue()) != ERROR_OK
)
282 LOG_DEBUG("in: 0x%8.8x", *in
);
286 LOG_ERROR("BUG: called with in == NULL");
294 extern void arm_endianness(u8
*tmp
, void *in
, int size
, int be
, int flip
);
296 /* clock the target, and read the databus
297 * the *in pointer points to a buffer where elements of 'size' bytes
298 * are stored in big (be==1) or little (be==0) endianness
300 int arm9tdmi_clock_data_in_endianness(arm_jtag_t
*jtag_info
, void *in
, int size
, int be
)
302 int retval
= ERROR_OK
;
303 scan_field_t fields
[3];
305 jtag_add_end_state(TAP_DRPAUSE
);
306 if ((retval
= arm_jtag_scann(jtag_info
, 0x1)) != ERROR_OK
)
311 arm_jtag_set_instr(jtag_info
, jtag_info
->intest_instr
, NULL
);
313 fields
[0].tap
= jtag_info
->tap
;
314 fields
[0].num_bits
= 32;
315 fields
[0].out_value
= NULL
;
317 fields
[0].in_value
= tmp
;
319 fields
[1].tap
= jtag_info
->tap
;
320 fields
[1].num_bits
= 3;
321 fields
[1].out_value
= NULL
;
322 fields
[1].in_value
= NULL
;
324 fields
[2].tap
= jtag_info
->tap
;
325 fields
[2].num_bits
= 32;
326 fields
[2].out_value
= NULL
;
327 fields
[2].in_value
= NULL
;
329 jtag_add_dr_scan_now(3, fields
, TAP_INVALID
);
331 arm_endianness(tmp
, in
, size
, be
, 0);
334 jtag_add_runtest(0, TAP_INVALID
);
336 #ifdef _DEBUG_INSTRUCTION_EXECUTION_
338 if ((retval
= jtag_execute_queue()) != ERROR_OK
)
345 LOG_DEBUG("in: 0x%8.8x", *(u32
*)in
);
349 LOG_ERROR("BUG: called with in == NULL");
357 void arm9tdmi_change_to_arm(target_t
*target
, u32
*r0
, u32
*pc
)
359 int retval
= ERROR_OK
;
360 /* get pointers to arch-specific information */
361 armv4_5_common_t
*armv4_5
= target
->arch_info
;
362 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
363 arm_jtag_t
*jtag_info
= &arm7_9
->jtag_info
;
365 /* save r0 before using it and put system in ARM state
366 * to allow common handling of ARM and THUMB debugging */
368 /* fetch STR r0, [r0] */
369 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_STR(0, 0), 0, NULL
, 0);
370 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, 0, NULL
, 0);
371 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, 0, NULL
, 0);
372 /* STR r0, [r0] in Memory */
373 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, 0, r0
, 0);
375 /* MOV r0, r15 fetched, STR in Decode */
376 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_MOV(0, 15), 0, NULL
, 0);
377 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, 0, NULL
, 0);
378 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_STR(0, 0), 0, NULL
, 0);
379 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, 0, NULL
, 0);
380 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, 0, NULL
, 0);
381 /* nothing fetched, STR r0, [r0] in Memory */
382 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, 0, pc
, 0);
384 /* use pc-relative LDR to clear r0[1:0] (for switch to ARM mode) */
385 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_LDR_PCREL(0), 0, NULL
, 0);
387 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, 0, NULL
, 0);
389 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, 0, NULL
, 0);
390 /* LDR in Memory (to account for interlock) */
391 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, 0, NULL
, 0);
394 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_BX(0), 0, NULL
, 0);
395 /* NOP fetched, BX in Decode, MOV in Execute */
396 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, 0, NULL
, 0);
397 /* NOP fetched, BX in Execute (1) */
398 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, 0, NULL
, 0);
400 if ((retval
= jtag_execute_queue()) != ERROR_OK
)
405 /* fix program counter:
406 * MOV r0, r15 was the 5th instruction (+8)
407 * reading PC in Thumb state gives address of instruction + 4
412 void arm9tdmi_read_core_regs(target_t
*target
, u32 mask
, u32
* core_regs
[16])
415 /* get pointers to arch-specific information */
416 armv4_5_common_t
*armv4_5
= target
->arch_info
;
417 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
418 arm_jtag_t
*jtag_info
= &arm7_9
->jtag_info
;
420 /* STMIA r0-15, [r0] at debug speed
421 * register values will start to appear on 4th DCLK
423 arm9tdmi_clock_out(jtag_info
, ARMV4_5_STMIA(0, mask
& 0xffff, 0, 0), 0, NULL
, 0);
425 /* fetch NOP, STM in DECODE stage */
426 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
427 /* fetch NOP, STM in EXECUTE stage (1st cycle) */
428 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
430 for (i
= 0; i
<= 15; i
++)
433 /* nothing fetched, STM in MEMORY (i'th cycle) */
434 arm9tdmi_clock_data_in(jtag_info
, core_regs
[i
]);
438 void arm9tdmi_read_core_regs_target_buffer(target_t
*target
, u32 mask
, void* buffer
, int size
)
441 /* get pointers to arch-specific information */
442 armv4_5_common_t
*armv4_5
= target
->arch_info
;
443 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
444 arm_jtag_t
*jtag_info
= &arm7_9
->jtag_info
;
445 int be
= (target
->endianness
== TARGET_BIG_ENDIAN
) ? 1 : 0;
446 u32
*buf_u32
= buffer
;
447 u16
*buf_u16
= buffer
;
450 /* STMIA r0-15, [r0] at debug speed
451 * register values will start to appear on 4th DCLK
453 arm9tdmi_clock_out(jtag_info
, ARMV4_5_STMIA(0, mask
& 0xffff, 0, 0), 0, NULL
, 0);
455 /* fetch NOP, STM in DECODE stage */
456 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
457 /* fetch NOP, STM in EXECUTE stage (1st cycle) */
458 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
460 for (i
= 0; i
<= 15; i
++)
463 /* nothing fetched, STM in MEMORY (i'th cycle) */
467 arm9tdmi_clock_data_in_endianness(jtag_info
, buf_u32
++, 4, be
);
470 arm9tdmi_clock_data_in_endianness(jtag_info
, buf_u16
++, 2, be
);
473 arm9tdmi_clock_data_in_endianness(jtag_info
, buf_u8
++, 1, be
);
479 void arm9tdmi_read_xpsr(target_t
*target
, u32
*xpsr
, int spsr
)
481 /* get pointers to arch-specific information */
482 armv4_5_common_t
*armv4_5
= target
->arch_info
;
483 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
484 arm_jtag_t
*jtag_info
= &arm7_9
->jtag_info
;
487 arm9tdmi_clock_out(jtag_info
, ARMV4_5_MRS(0, spsr
& 1), 0, NULL
, 0);
488 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
489 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
490 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
491 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
494 arm9tdmi_clock_out(jtag_info
, ARMV4_5_STR(0, 15), 0, NULL
, 0);
495 /* fetch NOP, STR in DECODE stage */
496 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
497 /* fetch NOP, STR in EXECUTE stage (1st cycle) */
498 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
499 /* nothing fetched, STR in MEMORY */
500 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, xpsr
, 0);
503 void arm9tdmi_write_xpsr(target_t
*target
, u32 xpsr
, int spsr
)
505 /* get pointers to arch-specific information */
506 armv4_5_common_t
*armv4_5
= target
->arch_info
;
507 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
508 arm_jtag_t
*jtag_info
= &arm7_9
->jtag_info
;
510 LOG_DEBUG("xpsr: %8.8x, spsr: %i", xpsr
, spsr
);
513 arm9tdmi_clock_out(jtag_info
, ARMV4_5_MSR_IM(xpsr
& 0xff, 0, 1, spsr
), 0, NULL
, 0);
514 /* MSR2 fetched, MSR1 in DECODE */
515 arm9tdmi_clock_out(jtag_info
, ARMV4_5_MSR_IM((xpsr
& 0xff00) >> 8, 0xc, 2, spsr
), 0, NULL
, 0);
516 /* MSR3 fetched, MSR1 in EXECUTE (1), MSR2 in DECODE */
517 arm9tdmi_clock_out(jtag_info
, ARMV4_5_MSR_IM((xpsr
& 0xff0000) >> 16, 0x8, 4, spsr
), 0, NULL
, 0);
518 /* nothing fetched, MSR1 in EXECUTE (2) */
519 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
520 /* nothing fetched, MSR1 in EXECUTE (3) */
521 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
522 /* MSR4 fetched, MSR2 in EXECUTE (1), MSR3 in DECODE */
523 arm9tdmi_clock_out(jtag_info
, ARMV4_5_MSR_IM((xpsr
& 0xff000000) >> 24, 0x4, 8, spsr
), 0, NULL
, 0);
524 /* nothing fetched, MSR2 in EXECUTE (2) */
525 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
526 /* nothing fetched, MSR2 in EXECUTE (3) */
527 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
528 /* NOP fetched, MSR3 in EXECUTE (1), MSR4 in DECODE */
529 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
530 /* nothing fetched, MSR3 in EXECUTE (2) */
531 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
532 /* nothing fetched, MSR3 in EXECUTE (3) */
533 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
534 /* NOP fetched, MSR4 in EXECUTE (1) */
535 /* last MSR writes flags, which takes only one cycle */
536 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
539 void arm9tdmi_write_xpsr_im8(target_t
*target
, u8 xpsr_im
, int rot
, int spsr
)
541 /* get pointers to arch-specific information */
542 armv4_5_common_t
*armv4_5
= target
->arch_info
;
543 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
544 arm_jtag_t
*jtag_info
= &arm7_9
->jtag_info
;
546 LOG_DEBUG("xpsr_im: %2.2x, rot: %i, spsr: %i", xpsr_im
, rot
, spsr
);
549 arm9tdmi_clock_out(jtag_info
, ARMV4_5_MSR_IM(xpsr_im
, rot
, 1, spsr
), 0, NULL
, 0);
550 /* NOP fetched, MSR in DECODE */
551 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
552 /* NOP fetched, MSR in EXECUTE (1) */
553 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
555 /* rot == 4 writes flags, which takes only one cycle */
558 /* nothing fetched, MSR in EXECUTE (2) */
559 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
560 /* nothing fetched, MSR in EXECUTE (3) */
561 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
565 void arm9tdmi_write_core_regs(target_t
*target
, u32 mask
, u32 core_regs
[16])
568 /* get pointers to arch-specific information */
569 armv4_5_common_t
*armv4_5
= target
->arch_info
;
570 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
571 arm_jtag_t
*jtag_info
= &arm7_9
->jtag_info
;
573 /* LDMIA r0-15, [r0] at debug speed
574 * register values will start to appear on 4th DCLK
576 arm9tdmi_clock_out(jtag_info
, ARMV4_5_LDMIA(0, mask
& 0xffff, 0, 0), 0, NULL
, 0);
578 /* fetch NOP, LDM in DECODE stage */
579 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
580 /* fetch NOP, LDM in EXECUTE stage (1st cycle) */
581 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
583 for (i
= 0; i
<= 15; i
++)
586 /* nothing fetched, LDM still in EXECUTE (1+i cycle) */
587 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, core_regs
[i
], NULL
, 0);
589 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
592 void arm9tdmi_load_word_regs(target_t
*target
, u32 mask
)
594 /* get pointers to arch-specific information */
595 armv4_5_common_t
*armv4_5
= target
->arch_info
;
596 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
597 arm_jtag_t
*jtag_info
= &arm7_9
->jtag_info
;
599 /* put system-speed load-multiple into the pipeline */
600 arm9tdmi_clock_out(jtag_info
, ARMV4_5_LDMIA(0, mask
& 0xffff, 0, 1), 0, NULL
, 0);
601 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 1);
604 void arm9tdmi_load_hword_reg(target_t
*target
, int num
)
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 half-word into the pipeline */
612 arm9tdmi_clock_out(jtag_info
, ARMV4_5_LDRH_IP(num
, 0), 0, NULL
, 0);
613 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 1);
616 void arm9tdmi_load_byte_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 byte into the pipeline */
624 arm9tdmi_clock_out(jtag_info
, ARMV4_5_LDRB_IP(num
, 0), 0, NULL
, 0);
625 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 1);
628 void arm9tdmi_store_word_regs(target_t
*target
, u32 mask
)
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 store-multiple into the pipeline */
636 arm9tdmi_clock_out(jtag_info
, ARMV4_5_STMIA(0, mask
, 0, 1), 0, NULL
, 0);
637 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 1);
640 void arm9tdmi_store_hword_reg(target_t
*target
, int num
)
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 half-word into the pipeline */
648 arm9tdmi_clock_out(jtag_info
, ARMV4_5_STRH_IP(num
, 0), 0, NULL
, 0);
649 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 1);
652 void arm9tdmi_store_byte_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 byte into the pipeline */
660 arm9tdmi_clock_out(jtag_info
, ARMV4_5_STRB_IP(num
, 0), 0, NULL
, 0);
661 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 1);
664 void arm9tdmi_write_pc(target_t
*target
, u32 pc
)
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 /* LDMIA r0-15, [r0] at debug speed
672 * register values will start to appear on 4th DCLK
674 arm9tdmi_clock_out(jtag_info
, ARMV4_5_LDMIA(0, 0x8000, 0, 0), 0, NULL
, 0);
676 /* fetch NOP, LDM in DECODE stage */
677 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
678 /* fetch NOP, LDM in EXECUTE stage (1st cycle) */
679 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
680 /* nothing fetched, LDM in EXECUTE stage (2nd cycle) (output data) */
681 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, pc
, NULL
, 0);
682 /* nothing fetched, LDM in EXECUTE stage (3rd cycle) */
683 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
684 /* fetch NOP, LDM in EXECUTE stage (4th cycle) */
685 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
686 /* fetch NOP, LDM in EXECUTE stage (5th cycle) */
687 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
690 void arm9tdmi_branch_resume(target_t
*target
)
692 /* get pointers to arch-specific information */
693 armv4_5_common_t
*armv4_5
= target
->arch_info
;
694 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
695 arm_jtag_t
*jtag_info
= &arm7_9
->jtag_info
;
697 arm9tdmi_clock_out(jtag_info
, ARMV4_5_B(0xfffffc, 0), 0, NULL
, 0);
698 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 1);
701 void arm9tdmi_branch_resume_thumb(target_t
*target
)
705 /* get pointers to arch-specific information */
706 armv4_5_common_t
*armv4_5
= target
->arch_info
;
707 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
708 arm_jtag_t
*jtag_info
= &arm7_9
->jtag_info
;
709 reg_t
*dbg_stat
= &arm7_9
->eice_cache
->reg_list
[EICE_DBG_STAT
];
711 /* LDMIA r0-15, [r0] at debug speed
712 * register values will start to appear on 4th DCLK
714 arm9tdmi_clock_out(jtag_info
, ARMV4_5_LDMIA(0, 0x1, 0, 0), 0, NULL
, 0);
716 /* fetch NOP, LDM in DECODE stage */
717 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
718 /* fetch NOP, LDM in EXECUTE stage (1st cycle) */
719 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
720 /* nothing fetched, LDM in EXECUTE stage (2nd cycle) */
721 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32) | 1, NULL
, 0);
722 /* nothing fetched, LDM in EXECUTE stage (3rd cycle) */
723 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
725 /* Branch and eXchange */
726 arm9tdmi_clock_out(jtag_info
, ARMV4_5_BX(0), 0, NULL
, 0);
728 embeddedice_read_reg(dbg_stat
);
730 /* fetch NOP, BX in DECODE stage */
731 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
733 embeddedice_read_reg(dbg_stat
);
735 /* fetch NOP, BX in EXECUTE stage (1st cycle) */
736 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
738 /* target is now in Thumb state */
739 embeddedice_read_reg(dbg_stat
);
741 /* load r0 value, MOV_IM in Decode*/
742 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_LDR_PCREL(0), 0, NULL
, 0);
743 /* fetch NOP, LDR in Decode, MOV_IM in Execute */
744 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, 0, NULL
, 0);
745 /* fetch NOP, LDR in Execute */
746 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, 0, NULL
, 0);
747 /* nothing fetched, LDR in EXECUTE stage (2nd cycle) */
748 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, buf_get_u32(armv4_5
->core_cache
->reg_list
[0].value
, 0, 32), NULL
, 0);
749 /* nothing fetched, LDR in EXECUTE stage (3rd cycle) */
750 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, 0, NULL
, 0);
752 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, 0, NULL
, 0);
753 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, 0, NULL
, 0);
755 embeddedice_read_reg(dbg_stat
);
757 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_B(0x7f7), 0, NULL
, 1);
758 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, 0, NULL
, 0);
761 void arm9tdmi_enable_single_step(target_t
*target
, u32 next_pc
)
763 /* get pointers to arch-specific information */
764 armv4_5_common_t
*armv4_5
= target
->arch_info
;
765 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
767 if (arm7_9
->has_single_step
)
769 buf_set_u32(arm7_9
->eice_cache
->reg_list
[EICE_DBG_CTRL
].value
, 3, 1, 1);
770 embeddedice_store_reg(&arm7_9
->eice_cache
->reg_list
[EICE_DBG_CTRL
]);
774 arm7_9_enable_eice_step(target
, next_pc
);
778 void arm9tdmi_disable_single_step(target_t
*target
)
780 /* get pointers to arch-specific information */
781 armv4_5_common_t
*armv4_5
= target
->arch_info
;
782 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
784 if (arm7_9
->has_single_step
)
786 buf_set_u32(arm7_9
->eice_cache
->reg_list
[EICE_DBG_CTRL
].value
, 3, 1, 0);
787 embeddedice_store_reg(&arm7_9
->eice_cache
->reg_list
[EICE_DBG_CTRL
]);
791 arm7_9_disable_eice_step(target
);
795 void arm9tdmi_build_reg_cache(target_t
*target
)
797 reg_cache_t
**cache_p
= register_get_last_cache_p(&target
->reg_cache
);
798 /* get pointers to arch-specific information */
799 armv4_5_common_t
*armv4_5
= target
->arch_info
;
801 (*cache_p
) = armv4_5_build_reg_cache(target
, armv4_5
);
802 armv4_5
->core_cache
= (*cache_p
);
805 int arm9tdmi_examine(struct target_s
*target
)
807 /* get pointers to arch-specific information */
809 armv4_5_common_t
*armv4_5
= target
->arch_info
;
810 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
811 if (!target
->type
->examined
)
813 reg_cache_t
**cache_p
= register_get_last_cache_p(&target
->reg_cache
);
815 /* one extra register (vector catch) */
816 t
=embeddedice_build_reg_cache(target
, arm7_9
);
820 arm7_9
->eice_cache
= (*cache_p
);
824 arm_jtag_t
*jtag_info
= &arm7_9
->jtag_info
;
825 (*cache_p
)->next
= etm_build_reg_cache(target
, jtag_info
, arm7_9
->etm_ctx
);
826 arm7_9
->etm_ctx
->reg_cache
= (*cache_p
)->next
;
828 target
->type
->examined
= 1;
830 if ((retval
=embeddedice_setup(target
))!=ERROR_OK
)
832 if ((retval
=arm7_9_setup(target
))!=ERROR_OK
)
836 if ((retval
=etm_setup(target
))!=ERROR_OK
)
842 int arm9tdmi_init_target(struct command_context_s
*cmd_ctx
, struct target_s
*target
)
845 arm9tdmi_build_reg_cache(target
);
850 int arm9tdmi_quit(void)
855 int arm9tdmi_init_arch_info(target_t
*target
, arm9tdmi_common_t
*arm9tdmi
, jtag_tap_t
*tap
)
857 armv4_5_common_t
*armv4_5
;
858 arm7_9_common_t
*arm7_9
;
860 arm7_9
= &arm9tdmi
->arm7_9_common
;
861 armv4_5
= &arm7_9
->armv4_5_common
;
863 /* prepare JTAG information for the new target */
864 arm7_9
->jtag_info
.tap
= tap
;
865 arm7_9
->jtag_info
.scann_size
= 5;
867 /* register arch-specific functions */
868 arm7_9
->examine_debug_reason
= arm9tdmi_examine_debug_reason
;
869 arm7_9
->change_to_arm
= arm9tdmi_change_to_arm
;
870 arm7_9
->read_core_regs
= arm9tdmi_read_core_regs
;
871 arm7_9
->read_core_regs_target_buffer
= arm9tdmi_read_core_regs_target_buffer
;
872 arm7_9
->read_xpsr
= arm9tdmi_read_xpsr
;
874 arm7_9
->write_xpsr
= arm9tdmi_write_xpsr
;
875 arm7_9
->write_xpsr_im8
= arm9tdmi_write_xpsr_im8
;
876 arm7_9
->write_core_regs
= arm9tdmi_write_core_regs
;
878 arm7_9
->load_word_regs
= arm9tdmi_load_word_regs
;
879 arm7_9
->load_hword_reg
= arm9tdmi_load_hword_reg
;
880 arm7_9
->load_byte_reg
= arm9tdmi_load_byte_reg
;
882 arm7_9
->store_word_regs
= arm9tdmi_store_word_regs
;
883 arm7_9
->store_hword_reg
= arm9tdmi_store_hword_reg
;
884 arm7_9
->store_byte_reg
= arm9tdmi_store_byte_reg
;
886 arm7_9
->write_pc
= arm9tdmi_write_pc
;
887 arm7_9
->branch_resume
= arm9tdmi_branch_resume
;
888 arm7_9
->branch_resume_thumb
= arm9tdmi_branch_resume_thumb
;
890 arm7_9
->enable_single_step
= arm9tdmi_enable_single_step
;
891 arm7_9
->disable_single_step
= arm9tdmi_disable_single_step
;
893 arm7_9
->pre_debug_entry
= NULL
;
894 arm7_9
->post_debug_entry
= NULL
;
896 arm7_9
->pre_restore_context
= NULL
;
897 arm7_9
->post_restore_context
= NULL
;
899 /* initialize arch-specific breakpoint handling */
900 arm7_9
->arm_bkpt
= 0xdeeedeee;
901 arm7_9
->thumb_bkpt
= 0xdeee;
903 arm7_9
->dbgreq_adjust_pc
= 3;
904 arm7_9
->arch_info
= arm9tdmi
;
906 arm9tdmi
->common_magic
= ARM9TDMI_COMMON_MAGIC
;
907 arm9tdmi
->arch_info
= NULL
;
909 arm7_9_init_arch_info(target
, arm7_9
);
911 /* override use of DBGRQ, this is safe on ARM9TDMI */
912 arm7_9
->use_dbgrq
= 1;
914 /* all ARM9s have the vector catch register */
915 arm7_9
->has_vector_catch
= 1;
920 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
)
922 armv4_5_common_t
*armv4_5
= target
->arch_info
;
923 arm7_9_common_t
*arm7_9
;
924 arm9tdmi_common_t
*arm9tdmi
;
926 if (armv4_5
->common_magic
!= ARMV4_5_COMMON_MAGIC
)
931 arm7_9
= armv4_5
->arch_info
;
932 if (arm7_9
->common_magic
!= ARM7_9_COMMON_MAGIC
)
937 arm9tdmi
= arm7_9
->arch_info
;
938 if (arm9tdmi
->common_magic
!= ARM9TDMI_COMMON_MAGIC
)
943 *armv4_5_p
= armv4_5
;
945 *arm9tdmi_p
= arm9tdmi
;
950 int arm9tdmi_target_create(struct target_s
*target
, Jim_Interp
*interp
)
952 arm9tdmi_common_t
*arm9tdmi
= calloc(1,sizeof(arm9tdmi_common_t
));
954 arm9tdmi_init_arch_info(target
, arm9tdmi
, target
->tap
);
959 int arm9tdmi_register_commands(struct command_context_s
*cmd_ctx
)
962 command_t
*arm9tdmi_cmd
;
964 retval
= arm7_9_register_commands(cmd_ctx
);
965 arm9tdmi_cmd
= register_command(cmd_ctx
, NULL
, "arm9tdmi", NULL
, COMMAND_ANY
, "arm9tdmi specific commands");
966 register_command(cmd_ctx
, arm9tdmi_cmd
, "vector_catch", handle_arm9tdmi_catch_vectors_command
, COMMAND_EXEC
, "catch arm920t vectors ['all'|'none'|'<vec1 vec2 ...>']");
971 int handle_arm9tdmi_catch_vectors_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
973 target_t
*target
= get_current_target(cmd_ctx
);
974 armv4_5_common_t
*armv4_5
;
975 arm7_9_common_t
*arm7_9
;
976 arm9tdmi_common_t
*arm9tdmi
;
978 u32 vector_catch_value
;
981 if (arm9tdmi_get_arch_pointers(target
, &armv4_5
, &arm7_9
, &arm9tdmi
) != ERROR_OK
)
983 command_print(cmd_ctx
, "current target isn't an ARM9TDMI based target");
987 vector_catch
= &arm7_9
->eice_cache
->reg_list
[EICE_VEC_CATCH
];
989 /* read the vector catch register if necessary */
990 if (!vector_catch
->valid
)
991 embeddedice_read_reg(vector_catch
);
993 /* get the current setting */
994 vector_catch_value
= buf_get_u32(vector_catch
->value
, 0, 32);
998 vector_catch_value
= 0x0;
999 if (strcmp(args
[0], "all") == 0)
1001 vector_catch_value
= 0xdf;
1003 else if (strcmp(args
[0], "none") == 0)
1009 for (i
= 0; i
< argc
; i
++)
1011 /* go through list of vectors */
1012 for (j
= 0; arm9tdmi_vectors
[j
].name
; j
++)
1014 if (strcmp(args
[i
], arm9tdmi_vectors
[j
].name
) == 0)
1016 vector_catch_value
|= arm9tdmi_vectors
[j
].value
;
1021 /* complain if vector wasn't found */
1022 if (!arm9tdmi_vectors
[j
].name
)
1024 command_print(cmd_ctx
, "vector '%s' not found, leaving current setting unchanged", args
[i
]);
1026 /* reread current setting */
1027 vector_catch_value
= buf_get_u32(vector_catch
->value
, 0, 32);
1034 /* store new settings */
1035 buf_set_u32(vector_catch
->value
, 0, 32, vector_catch_value
);
1036 embeddedice_store_reg(vector_catch
);
1039 /* output current settings (skip RESERVED vector) */
1040 for (i
= 0; i
< 8; i
++)
1044 command_print(cmd_ctx
, "%s: %s", arm9tdmi_vectors
[i
].name
,
1045 (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)