1 /***************************************************************************
2 * Copyright (C) 2005 by Dominic Rath *
3 * Dominic.Rath@gmx.de *
5 * Copyright (C) 2008 by Spencer Oliver *
6 * spen@spen-soft.co.uk *
8 * Copyright (C) 2008 by Hongtao Zheng *
11 * This program is free software; you can redistribute it and/or modify *
12 * it under the terms of the GNU General Public License as published by *
13 * the Free Software Foundation; either version 2 of the License, or *
14 * (at your option) any later version. *
16 * This program is distributed in the hope that it will be useful, *
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
19 * GNU General Public License for more details. *
21 * You should have received a copy of the GNU General Public License *
22 * along with this program; if not, write to the *
23 * Free Software Foundation, Inc., *
24 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
25 ***************************************************************************/
31 #include "target_type.h"
35 * NOTE: this holds code that's used with multiple ARM9 processors:
36 * - ARM9TDMI (ARMv4T) ... in ARM920, ARM922, and ARM940 cores
37 * - ARM9E-S (ARMv5TE) ... in ARM946, ARM966, and ARM968 cores
38 * - ARM9EJS (ARMv5TEJ) ... in ARM926 core
40 * In short, the file name is a misnomer ... it is NOT specific to
41 * that first generation ARM9 processor, or cores using it.
45 #define _DEBUG_INSTRUCTION_EXECUTION_
48 static const arm9tdmi_vector_t arm9tdmi_vectors
[] =
50 {"reset", ARM9TDMI_RESET_VECTOR
},
51 {"undef", ARM9TDMI_UNDEF_VECTOR
},
52 {"swi", ARM9TDMI_SWI_VECTOR
},
53 {"pabt", ARM9TDMI_PABT_VECTOR
},
54 {"dabt", ARM9TDMI_DABT_VECTOR
},
55 {"irq", ARM9TDMI_IRQ_VECTOR
},
56 {"fiq", ARM9TDMI_FIQ_VECTOR
},
60 int arm9tdmi_examine_debug_reason(target_t
*target
)
62 int retval
= ERROR_OK
;
63 /* get pointers to arch-specific information */
64 armv4_5_common_t
*armv4_5
= target
->arch_info
;
65 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
67 /* only check the debug reason if we don't know it already */
68 if ((target
->debug_reason
!= DBG_REASON_DBGRQ
)
69 && (target
->debug_reason
!= DBG_REASON_SINGLESTEP
))
71 scan_field_t fields
[3];
73 uint8_t instructionbus
[4];
76 jtag_set_end_state(TAP_DRPAUSE
);
78 fields
[0].tap
= arm7_9
->jtag_info
.tap
;
79 fields
[0].num_bits
= 32;
80 fields
[0].out_value
= NULL
;
81 fields
[0].in_value
= databus
;
83 fields
[1].tap
= arm7_9
->jtag_info
.tap
;
84 fields
[1].num_bits
= 3;
85 fields
[1].out_value
= NULL
;
86 fields
[1].in_value
= &debug_reason
;
88 fields
[2].tap
= arm7_9
->jtag_info
.tap
;
89 fields
[2].num_bits
= 32;
90 fields
[2].out_value
= NULL
;
91 fields
[2].in_value
= instructionbus
;
93 if ((retval
= arm_jtag_scann(&arm7_9
->jtag_info
, 0x1)) != ERROR_OK
)
97 arm_jtag_set_instr(&arm7_9
->jtag_info
, arm7_9
->jtag_info
.intest_instr
, NULL
);
99 jtag_add_dr_scan(3, fields
, jtag_set_end_state(TAP_DRPAUSE
));
100 if ((retval
= jtag_execute_queue()) != ERROR_OK
)
105 fields
[0].in_value
= NULL
;
106 fields
[0].out_value
= databus
;
107 fields
[1].in_value
= NULL
;
108 fields
[1].out_value
= &debug_reason
;
109 fields
[2].in_value
= NULL
;
110 fields
[2].out_value
= instructionbus
;
112 jtag_add_dr_scan(3, fields
, jtag_set_end_state(TAP_DRPAUSE
));
114 if (debug_reason
& 0x4)
115 if (debug_reason
& 0x2)
116 target
->debug_reason
= DBG_REASON_WPTANDBKPT
;
118 target
->debug_reason
= DBG_REASON_WATCHPOINT
;
120 target
->debug_reason
= DBG_REASON_BREAKPOINT
;
126 /* put an instruction in the ARM9TDMI pipeline or write the data bus,
127 * and optionally read data
129 int arm9tdmi_clock_out(arm_jtag_t
*jtag_info
, uint32_t instr
,
130 uint32_t out
, uint32_t *in
, int sysspeed
)
132 int retval
= ERROR_OK
;
133 scan_field_t fields
[3];
135 uint8_t instr_buf
[4];
136 uint8_t sysspeed_buf
= 0x0;
139 buf_set_u32(out_buf
, 0, 32, out
);
141 buf_set_u32(instr_buf
, 0, 32, flip_u32(instr
, 32));
144 buf_set_u32(&sysspeed_buf
, 2, 1, 1);
146 jtag_set_end_state(TAP_DRPAUSE
);
147 if ((retval
= arm_jtag_scann(jtag_info
, 0x1)) != ERROR_OK
)
152 arm_jtag_set_instr(jtag_info
, jtag_info
->intest_instr
, NULL
);
154 fields
[0].tap
= jtag_info
->tap
;
155 fields
[0].num_bits
= 32;
156 fields
[0].out_value
= out_buf
;
157 fields
[0].in_value
= NULL
;
159 fields
[1].tap
= jtag_info
->tap
;
160 fields
[1].num_bits
= 3;
161 fields
[1].out_value
= &sysspeed_buf
;
162 fields
[1].in_value
= NULL
;
164 fields
[2].tap
= jtag_info
->tap
;
165 fields
[2].num_bits
= 32;
166 fields
[2].out_value
= instr_buf
;
167 fields
[2].in_value
= NULL
;
171 fields
[0].in_value
= (uint8_t *)in
;
172 jtag_add_dr_scan(3, fields
, jtag_get_end_state());
174 jtag_add_callback(arm_le_to_h_u32
, (jtag_callback_data_t
)in
);
178 jtag_add_dr_scan(3, fields
, jtag_get_end_state());
181 jtag_add_runtest(0, jtag_get_end_state());
183 #ifdef _DEBUG_INSTRUCTION_EXECUTION_
185 if ((retval
= jtag_execute_queue()) != ERROR_OK
)
192 LOG_DEBUG("instr: 0x%8.8x, out: 0x%8.8x, in: 0x%8.8x", instr
, out
, *in
);
195 LOG_DEBUG("instr: 0x%8.8x, out: 0x%8.8x", instr
, out
);
202 /* just read data (instruction and data-out = don't care) */
203 int arm9tdmi_clock_data_in(arm_jtag_t
*jtag_info
, uint32_t *in
)
205 int retval
= ERROR_OK
;;
206 scan_field_t fields
[3];
208 jtag_set_end_state(TAP_DRPAUSE
);
209 if ((retval
= arm_jtag_scann(jtag_info
, 0x1)) != ERROR_OK
)
214 arm_jtag_set_instr(jtag_info
, jtag_info
->intest_instr
, NULL
);
216 fields
[0].tap
= jtag_info
->tap
;
217 fields
[0].num_bits
= 32;
218 fields
[0].out_value
= NULL
;
219 fields
[0].in_value
= (uint8_t *)in
;
221 fields
[1].tap
= jtag_info
->tap
;
222 fields
[1].num_bits
= 3;
223 fields
[1].out_value
= NULL
;
224 fields
[1].in_value
= NULL
;
226 fields
[2].tap
= jtag_info
->tap
;
227 fields
[2].num_bits
= 32;
228 fields
[2].out_value
= NULL
;
229 fields
[2].in_value
= NULL
;
231 jtag_add_dr_scan(3, fields
, jtag_get_end_state());
233 jtag_add_callback(arm_le_to_h_u32
, (jtag_callback_data_t
)in
);
235 jtag_add_runtest(0, jtag_get_end_state());
237 #ifdef _DEBUG_INSTRUCTION_EXECUTION_
239 if ((retval
= jtag_execute_queue()) != ERROR_OK
)
246 LOG_DEBUG("in: 0x%8.8x", *in
);
250 LOG_ERROR("BUG: called with in == NULL");
258 extern void arm_endianness(uint8_t *tmp
, void *in
, int size
, int be
, int flip
);
260 static int arm9endianness(jtag_callback_data_t arg
,
261 jtag_callback_data_t size
, jtag_callback_data_t be
,
262 jtag_callback_data_t captured
)
264 uint8_t *in
= (uint8_t *)arg
;
266 arm_endianness((uint8_t *)captured
, in
, (int)size
, (int)be
, 0);
270 /* clock the target, and read the databus
271 * the *in pointer points to a buffer where elements of 'size' bytes
272 * are stored in big (be == 1) or little (be == 0) endianness
274 int arm9tdmi_clock_data_in_endianness(arm_jtag_t
*jtag_info
,
275 void *in
, int size
, int be
)
277 int retval
= ERROR_OK
;
278 scan_field_t fields
[3];
280 jtag_set_end_state(TAP_DRPAUSE
);
281 if ((retval
= arm_jtag_scann(jtag_info
, 0x1)) != ERROR_OK
)
286 arm_jtag_set_instr(jtag_info
, jtag_info
->intest_instr
, NULL
);
288 fields
[0].tap
= jtag_info
->tap
;
289 fields
[0].num_bits
= 32;
290 fields
[0].out_value
= NULL
;
291 jtag_alloc_in_value32(&fields
[0]);
293 fields
[1].tap
= jtag_info
->tap
;
294 fields
[1].num_bits
= 3;
295 fields
[1].out_value
= NULL
;
296 fields
[1].in_value
= NULL
;
298 fields
[2].tap
= jtag_info
->tap
;
299 fields
[2].num_bits
= 32;
300 fields
[2].out_value
= NULL
;
301 fields
[2].in_value
= NULL
;
303 jtag_add_dr_scan(3, fields
, jtag_get_end_state());
305 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
);
307 jtag_add_runtest(0, jtag_get_end_state());
309 #ifdef _DEBUG_INSTRUCTION_EXECUTION_
311 if ((retval
= jtag_execute_queue()) != ERROR_OK
)
318 LOG_DEBUG("in: 0x%8.8x", *(uint32_t*)in
);
322 LOG_ERROR("BUG: called with in == NULL");
330 static void arm9tdmi_change_to_arm(target_t
*target
,
331 uint32_t *r0
, uint32_t *pc
)
333 int retval
= ERROR_OK
;
334 /* get pointers to arch-specific information */
335 armv4_5_common_t
*armv4_5
= target
->arch_info
;
336 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
337 arm_jtag_t
*jtag_info
= &arm7_9
->jtag_info
;
339 /* save r0 before using it and put system in ARM state
340 * to allow common handling of ARM and THUMB debugging */
342 /* fetch STR r0, [r0] */
343 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_STR(0, 0), 0, NULL
, 0);
344 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, 0, NULL
, 0);
345 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, 0, NULL
, 0);
346 /* STR r0, [r0] in Memory */
347 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, 0, r0
, 0);
349 /* MOV r0, r15 fetched, STR in Decode */
350 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_MOV(0, 15), 0, NULL
, 0);
351 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, 0, NULL
, 0);
352 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_STR(0, 0), 0, NULL
, 0);
353 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, 0, NULL
, 0);
354 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, 0, NULL
, 0);
355 /* nothing fetched, STR r0, [r0] in Memory */
356 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, 0, pc
, 0);
358 /* use pc-relative LDR to clear r0[1:0] (for switch to ARM mode) */
359 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_LDR_PCREL(0), 0, NULL
, 0);
361 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, 0, NULL
, 0);
363 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, 0, NULL
, 0);
364 /* LDR in Memory (to account for interlock) */
365 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, 0, NULL
, 0);
368 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_BX(0), 0, NULL
, 0);
369 /* NOP fetched, BX in Decode, MOV in Execute */
370 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, 0, NULL
, 0);
371 /* NOP fetched, BX in Execute (1) */
372 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, 0, NULL
, 0);
374 if ((retval
= jtag_execute_queue()) != ERROR_OK
)
379 /* fix program counter:
380 * MOV r0, r15 was the 5th instruction (+8)
381 * reading PC in Thumb state gives address of instruction + 4
386 void arm9tdmi_read_core_regs(target_t
*target
,
387 uint32_t mask
, uint32_t* core_regs
[16])
390 /* get pointers to arch-specific information */
391 armv4_5_common_t
*armv4_5
= target
->arch_info
;
392 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
393 arm_jtag_t
*jtag_info
= &arm7_9
->jtag_info
;
395 /* STMIA r0-15, [r0] at debug speed
396 * register values will start to appear on 4th DCLK
398 arm9tdmi_clock_out(jtag_info
, ARMV4_5_STMIA(0, mask
& 0xffff, 0, 0), 0, NULL
, 0);
400 /* fetch NOP, STM in DECODE stage */
401 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
402 /* fetch NOP, STM in EXECUTE stage (1st cycle) */
403 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
405 for (i
= 0; i
<= 15; i
++)
408 /* nothing fetched, STM in MEMORY (i'th cycle) */
409 arm9tdmi_clock_data_in(jtag_info
, core_regs
[i
]);
413 static void arm9tdmi_read_core_regs_target_buffer(target_t
*target
,
414 uint32_t mask
, void* buffer
, int size
)
417 /* get pointers to arch-specific information */
418 armv4_5_common_t
*armv4_5
= target
->arch_info
;
419 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
420 arm_jtag_t
*jtag_info
= &arm7_9
->jtag_info
;
421 int be
= (target
->endianness
== TARGET_BIG_ENDIAN
) ? 1 : 0;
422 uint32_t *buf_u32
= buffer
;
423 uint16_t *buf_u16
= buffer
;
424 uint8_t *buf_u8
= buffer
;
426 /* STMIA r0-15, [r0] at debug speed
427 * register values will start to appear on 4th DCLK
429 arm9tdmi_clock_out(jtag_info
, ARMV4_5_STMIA(0, mask
& 0xffff, 0, 0), 0, NULL
, 0);
431 /* fetch NOP, STM in DECODE stage */
432 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
433 /* fetch NOP, STM in EXECUTE stage (1st cycle) */
434 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
436 for (i
= 0; i
<= 15; i
++)
439 /* nothing fetched, STM in MEMORY (i'th cycle) */
443 arm9tdmi_clock_data_in_endianness(jtag_info
, buf_u32
++, 4, be
);
446 arm9tdmi_clock_data_in_endianness(jtag_info
, buf_u16
++, 2, be
);
449 arm9tdmi_clock_data_in_endianness(jtag_info
, buf_u8
++, 1, be
);
455 static void arm9tdmi_read_xpsr(target_t
*target
, uint32_t *xpsr
, int spsr
)
457 /* get pointers to arch-specific information */
458 armv4_5_common_t
*armv4_5
= target
->arch_info
;
459 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
460 arm_jtag_t
*jtag_info
= &arm7_9
->jtag_info
;
463 arm9tdmi_clock_out(jtag_info
, ARMV4_5_MRS(0, spsr
& 1), 0, NULL
, 0);
464 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
465 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
466 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
467 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
470 arm9tdmi_clock_out(jtag_info
, ARMV4_5_STR(0, 15), 0, NULL
, 0);
471 /* fetch NOP, STR in DECODE stage */
472 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
473 /* fetch NOP, STR in EXECUTE stage (1st cycle) */
474 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
475 /* nothing fetched, STR in MEMORY */
476 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, xpsr
, 0);
479 static void arm9tdmi_write_xpsr(target_t
*target
, uint32_t 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
;
486 LOG_DEBUG("xpsr: %8.8" PRIx32
", spsr: %i", xpsr
, spsr
);
489 arm9tdmi_clock_out(jtag_info
, ARMV4_5_MSR_IM(xpsr
& 0xff, 0, 1, spsr
), 0, NULL
, 0);
490 /* MSR2 fetched, MSR1 in DECODE */
491 arm9tdmi_clock_out(jtag_info
, ARMV4_5_MSR_IM((xpsr
& 0xff00) >> 8, 0xc, 2, spsr
), 0, NULL
, 0);
492 /* MSR3 fetched, MSR1 in EXECUTE (1), MSR2 in DECODE */
493 arm9tdmi_clock_out(jtag_info
, ARMV4_5_MSR_IM((xpsr
& 0xff0000) >> 16, 0x8, 4, spsr
), 0, NULL
, 0);
494 /* nothing fetched, MSR1 in EXECUTE (2) */
495 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
496 /* nothing fetched, MSR1 in EXECUTE (3) */
497 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
498 /* MSR4 fetched, MSR2 in EXECUTE (1), MSR3 in DECODE */
499 arm9tdmi_clock_out(jtag_info
, ARMV4_5_MSR_IM((xpsr
& 0xff000000) >> 24, 0x4, 8, spsr
), 0, NULL
, 0);
500 /* nothing fetched, MSR2 in EXECUTE (2) */
501 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
502 /* nothing fetched, MSR2 in EXECUTE (3) */
503 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
504 /* NOP fetched, MSR3 in EXECUTE (1), MSR4 in DECODE */
505 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
506 /* nothing fetched, MSR3 in EXECUTE (2) */
507 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
508 /* nothing fetched, MSR3 in EXECUTE (3) */
509 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
510 /* NOP fetched, MSR4 in EXECUTE (1) */
511 /* last MSR writes flags, which takes only one cycle */
512 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
515 static void arm9tdmi_write_xpsr_im8(target_t
*target
,
516 uint8_t xpsr_im
, int rot
, int spsr
)
518 /* get pointers to arch-specific information */
519 armv4_5_common_t
*armv4_5
= target
->arch_info
;
520 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
521 arm_jtag_t
*jtag_info
= &arm7_9
->jtag_info
;
523 LOG_DEBUG("xpsr_im: %2.2x, rot: %i, spsr: %i", xpsr_im
, rot
, spsr
);
526 arm9tdmi_clock_out(jtag_info
, ARMV4_5_MSR_IM(xpsr_im
, rot
, 1, spsr
), 0, NULL
, 0);
527 /* NOP fetched, MSR in DECODE */
528 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
529 /* NOP fetched, MSR in EXECUTE (1) */
530 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
532 /* rot == 4 writes flags, which takes only one cycle */
535 /* nothing fetched, MSR in EXECUTE (2) */
536 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
537 /* nothing fetched, MSR in EXECUTE (3) */
538 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
542 void arm9tdmi_write_core_regs(target_t
*target
,
543 uint32_t mask
, uint32_t core_regs
[16])
546 /* get pointers to arch-specific information */
547 armv4_5_common_t
*armv4_5
= target
->arch_info
;
548 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
549 arm_jtag_t
*jtag_info
= &arm7_9
->jtag_info
;
551 /* LDMIA r0-15, [r0] at debug speed
552 * register values will start to appear on 4th DCLK
554 arm9tdmi_clock_out(jtag_info
, ARMV4_5_LDMIA(0, mask
& 0xffff, 0, 0), 0, NULL
, 0);
556 /* fetch NOP, LDM in DECODE stage */
557 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
558 /* fetch NOP, LDM in EXECUTE stage (1st cycle) */
559 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
561 for (i
= 0; i
<= 15; i
++)
564 /* nothing fetched, LDM still in EXECUTE (1 + i cycle) */
565 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, core_regs
[i
], NULL
, 0);
567 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
570 void arm9tdmi_load_word_regs(target_t
*target
, uint32_t mask
)
572 /* get pointers to arch-specific information */
573 armv4_5_common_t
*armv4_5
= target
->arch_info
;
574 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
575 arm_jtag_t
*jtag_info
= &arm7_9
->jtag_info
;
577 /* put system-speed load-multiple into the pipeline */
578 arm9tdmi_clock_out(jtag_info
, ARMV4_5_LDMIA(0, mask
& 0xffff, 0, 1), 0, NULL
, 0);
579 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 1);
582 void arm9tdmi_load_hword_reg(target_t
*target
, int num
)
584 /* get pointers to arch-specific information */
585 armv4_5_common_t
*armv4_5
= target
->arch_info
;
586 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
587 arm_jtag_t
*jtag_info
= &arm7_9
->jtag_info
;
589 /* put system-speed load half-word into the pipeline */
590 arm9tdmi_clock_out(jtag_info
, ARMV4_5_LDRH_IP(num
, 0), 0, NULL
, 0);
591 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 1);
594 void arm9tdmi_load_byte_reg(target_t
*target
, int num
)
596 /* get pointers to arch-specific information */
597 armv4_5_common_t
*armv4_5
= target
->arch_info
;
598 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
599 arm_jtag_t
*jtag_info
= &arm7_9
->jtag_info
;
601 /* put system-speed load byte into the pipeline */
602 arm9tdmi_clock_out(jtag_info
, ARMV4_5_LDRB_IP(num
, 0), 0, NULL
, 0);
603 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 1);
606 void arm9tdmi_store_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 store-multiple into the pipeline */
614 arm9tdmi_clock_out(jtag_info
, ARMV4_5_STMIA(0, mask
, 0, 1), 0, NULL
, 0);
615 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 1);
618 void arm9tdmi_store_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 store half-word into the pipeline */
626 arm9tdmi_clock_out(jtag_info
, ARMV4_5_STRH_IP(num
, 0), 0, NULL
, 0);
627 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 1);
630 void arm9tdmi_store_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 store byte into the pipeline */
638 arm9tdmi_clock_out(jtag_info
, ARMV4_5_STRB_IP(num
, 0), 0, NULL
, 0);
639 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 1);
642 static void arm9tdmi_write_pc(target_t
*target
, uint32_t pc
)
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 /* LDMIA r0-15, [r0] at debug speed
650 * register values will start to appear on 4th DCLK
652 arm9tdmi_clock_out(jtag_info
, ARMV4_5_LDMIA(0, 0x8000, 0, 0), 0, NULL
, 0);
654 /* fetch NOP, LDM in DECODE stage */
655 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
656 /* fetch NOP, LDM in EXECUTE stage (1st cycle) */
657 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
658 /* nothing fetched, LDM in EXECUTE stage (2nd cycle) (output data) */
659 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, pc
, NULL
, 0);
660 /* nothing fetched, LDM in EXECUTE stage (3rd cycle) */
661 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
662 /* fetch NOP, LDM in EXECUTE stage (4th cycle) */
663 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
664 /* fetch NOP, LDM in EXECUTE stage (5th cycle) */
665 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
668 void arm9tdmi_branch_resume(target_t
*target
)
670 /* get pointers to arch-specific information */
671 armv4_5_common_t
*armv4_5
= target
->arch_info
;
672 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
673 arm_jtag_t
*jtag_info
= &arm7_9
->jtag_info
;
675 arm9tdmi_clock_out(jtag_info
, ARMV4_5_B(0xfffffc, 0), 0, NULL
, 0);
676 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 1);
679 static void arm9tdmi_branch_resume_thumb(target_t
*target
)
683 /* get pointers to arch-specific information */
684 armv4_5_common_t
*armv4_5
= target
->arch_info
;
685 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
686 arm_jtag_t
*jtag_info
= &arm7_9
->jtag_info
;
687 reg_t
*dbg_stat
= &arm7_9
->eice_cache
->reg_list
[EICE_DBG_STAT
];
689 /* LDMIA r0-15, [r0] at debug speed
690 * register values will start to appear on 4th DCLK
692 arm9tdmi_clock_out(jtag_info
, ARMV4_5_LDMIA(0, 0x1, 0, 0), 0, NULL
, 0);
694 /* fetch NOP, LDM in DECODE stage */
695 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
696 /* fetch NOP, LDM in EXECUTE stage (1st cycle) */
697 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
698 /* nothing fetched, LDM in EXECUTE stage (2nd cycle) */
699 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32) | 1, NULL
, 0);
700 /* nothing fetched, LDM in EXECUTE stage (3rd cycle) */
701 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
703 /* Branch and eXchange */
704 arm9tdmi_clock_out(jtag_info
, ARMV4_5_BX(0), 0, NULL
, 0);
706 embeddedice_read_reg(dbg_stat
);
708 /* fetch NOP, BX in DECODE stage */
709 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
711 embeddedice_read_reg(dbg_stat
);
713 /* fetch NOP, BX in EXECUTE stage (1st cycle) */
714 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
716 /* target is now in Thumb state */
717 embeddedice_read_reg(dbg_stat
);
719 /* load r0 value, MOV_IM in Decode*/
720 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_LDR_PCREL(0), 0, NULL
, 0);
721 /* fetch NOP, LDR in Decode, MOV_IM in Execute */
722 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, 0, NULL
, 0);
723 /* fetch NOP, LDR in Execute */
724 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, 0, NULL
, 0);
725 /* nothing fetched, LDR in EXECUTE stage (2nd cycle) */
726 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, buf_get_u32(armv4_5
->core_cache
->reg_list
[0].value
, 0, 32), NULL
, 0);
727 /* nothing fetched, LDR in EXECUTE stage (3rd cycle) */
728 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, 0, NULL
, 0);
730 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, 0, NULL
, 0);
731 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, 0, NULL
, 0);
733 embeddedice_read_reg(dbg_stat
);
735 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_B(0x7f7), 0, NULL
, 1);
736 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, 0, NULL
, 0);
739 void arm9tdmi_enable_single_step(target_t
*target
, uint32_t next_pc
)
741 /* get pointers to arch-specific information */
742 armv4_5_common_t
*armv4_5
= target
->arch_info
;
743 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
745 if (arm7_9
->has_single_step
)
747 buf_set_u32(arm7_9
->eice_cache
->reg_list
[EICE_DBG_CTRL
].value
, 3, 1, 1);
748 embeddedice_store_reg(&arm7_9
->eice_cache
->reg_list
[EICE_DBG_CTRL
]);
752 arm7_9_enable_eice_step(target
, next_pc
);
756 void arm9tdmi_disable_single_step(target_t
*target
)
758 /* get pointers to arch-specific information */
759 armv4_5_common_t
*armv4_5
= target
->arch_info
;
760 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
762 if (arm7_9
->has_single_step
)
764 buf_set_u32(arm7_9
->eice_cache
->reg_list
[EICE_DBG_CTRL
].value
, 3, 1, 0);
765 embeddedice_store_reg(&arm7_9
->eice_cache
->reg_list
[EICE_DBG_CTRL
]);
769 arm7_9_disable_eice_step(target
);
773 static void arm9tdmi_build_reg_cache(target_t
*target
)
775 reg_cache_t
**cache_p
= register_get_last_cache_p(&target
->reg_cache
);
776 /* get pointers to arch-specific information */
777 armv4_5_common_t
*armv4_5
= target
->arch_info
;
779 (*cache_p
) = armv4_5_build_reg_cache(target
, armv4_5
);
780 armv4_5
->core_cache
= (*cache_p
);
783 int arm9tdmi_examine(struct target_s
*target
)
785 /* get pointers to arch-specific information */
787 armv4_5_common_t
*armv4_5
= target
->arch_info
;
788 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
789 if (!target_was_examined(target
))
791 reg_cache_t
**cache_p
= register_get_last_cache_p(&target
->reg_cache
);
793 /* one extra register (vector catch) */
794 t
= embeddedice_build_reg_cache(target
, arm7_9
);
798 arm7_9
->eice_cache
= (*cache_p
);
802 arm_jtag_t
*jtag_info
= &arm7_9
->jtag_info
;
803 (*cache_p
)->next
= etm_build_reg_cache(target
, jtag_info
, arm7_9
->etm_ctx
);
804 arm7_9
->etm_ctx
->reg_cache
= (*cache_p
)->next
;
806 target_set_examined(target
);
808 if ((retval
= embeddedice_setup(target
)) != ERROR_OK
)
810 if ((retval
= arm7_9_setup(target
)) != ERROR_OK
)
814 if ((retval
= etm_setup(target
)) != ERROR_OK
)
820 int arm9tdmi_init_target(struct command_context_s
*cmd_ctx
,
821 struct target_s
*target
)
823 arm9tdmi_build_reg_cache(target
);
827 int arm9tdmi_init_arch_info(target_t
*target
, arm9tdmi_common_t
*arm9tdmi
, jtag_tap_t
*tap
)
829 armv4_5_common_t
*armv4_5
;
830 arm7_9_common_t
*arm7_9
;
832 arm7_9
= &arm9tdmi
->arm7_9_common
;
833 armv4_5
= &arm7_9
->armv4_5_common
;
835 /* prepare JTAG information for the new target */
836 arm7_9
->jtag_info
.tap
= tap
;
837 arm7_9
->jtag_info
.scann_size
= 5;
839 /* register arch-specific functions */
840 arm7_9
->examine_debug_reason
= arm9tdmi_examine_debug_reason
;
841 arm7_9
->change_to_arm
= arm9tdmi_change_to_arm
;
842 arm7_9
->read_core_regs
= arm9tdmi_read_core_regs
;
843 arm7_9
->read_core_regs_target_buffer
= arm9tdmi_read_core_regs_target_buffer
;
844 arm7_9
->read_xpsr
= arm9tdmi_read_xpsr
;
846 arm7_9
->write_xpsr
= arm9tdmi_write_xpsr
;
847 arm7_9
->write_xpsr_im8
= arm9tdmi_write_xpsr_im8
;
848 arm7_9
->write_core_regs
= arm9tdmi_write_core_regs
;
850 arm7_9
->load_word_regs
= arm9tdmi_load_word_regs
;
851 arm7_9
->load_hword_reg
= arm9tdmi_load_hword_reg
;
852 arm7_9
->load_byte_reg
= arm9tdmi_load_byte_reg
;
854 arm7_9
->store_word_regs
= arm9tdmi_store_word_regs
;
855 arm7_9
->store_hword_reg
= arm9tdmi_store_hword_reg
;
856 arm7_9
->store_byte_reg
= arm9tdmi_store_byte_reg
;
858 arm7_9
->write_pc
= arm9tdmi_write_pc
;
859 arm7_9
->branch_resume
= arm9tdmi_branch_resume
;
860 arm7_9
->branch_resume_thumb
= arm9tdmi_branch_resume_thumb
;
862 arm7_9
->enable_single_step
= arm9tdmi_enable_single_step
;
863 arm7_9
->disable_single_step
= arm9tdmi_disable_single_step
;
865 arm7_9
->post_debug_entry
= NULL
;
867 arm7_9
->pre_restore_context
= NULL
;
868 arm7_9
->post_restore_context
= NULL
;
870 /* initialize arch-specific breakpoint handling */
871 arm7_9
->arm_bkpt
= 0xdeeedeee;
872 arm7_9
->thumb_bkpt
= 0xdeee;
874 arm7_9
->dbgreq_adjust_pc
= 3;
875 arm7_9
->arch_info
= arm9tdmi
;
877 arm9tdmi
->common_magic
= ARM9TDMI_COMMON_MAGIC
;
878 arm9tdmi
->arch_info
= NULL
;
880 arm7_9_init_arch_info(target
, arm7_9
);
882 /* override use of DBGRQ, this is safe on ARM9TDMI */
883 arm7_9
->use_dbgrq
= 1;
885 /* all ARM9s have the vector catch register */
886 arm7_9
->has_vector_catch
= 1;
891 static int arm9tdmi_get_arch_pointers(target_t
*target
,
892 armv4_5_common_t
**armv4_5_p
, arm7_9_common_t
**arm7_9_p
,
893 arm9tdmi_common_t
**arm9tdmi_p
)
895 armv4_5_common_t
*armv4_5
= target
->arch_info
;
896 arm7_9_common_t
*arm7_9
;
897 arm9tdmi_common_t
*arm9tdmi
;
899 if (armv4_5
->common_magic
!= ARMV4_5_COMMON_MAGIC
)
904 arm7_9
= armv4_5
->arch_info
;
905 if (arm7_9
->common_magic
!= ARM7_9_COMMON_MAGIC
)
910 arm9tdmi
= arm7_9
->arch_info
;
911 if (arm9tdmi
->common_magic
!= ARM9TDMI_COMMON_MAGIC
)
916 *armv4_5_p
= armv4_5
;
918 *arm9tdmi_p
= arm9tdmi
;
923 static int arm9tdmi_target_create(struct target_s
*target
, Jim_Interp
*interp
)
925 arm9tdmi_common_t
*arm9tdmi
= calloc(1,sizeof(arm9tdmi_common_t
));
927 arm9tdmi_init_arch_info(target
, arm9tdmi
, target
->tap
);
928 arm9tdmi
->arm7_9_common
.armv4_5_common
.is_armv4
= true;
933 static int handle_arm9tdmi_catch_vectors_command(
934 struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
936 target_t
*target
= get_current_target(cmd_ctx
);
937 armv4_5_common_t
*armv4_5
;
938 arm7_9_common_t
*arm7_9
;
939 arm9tdmi_common_t
*arm9tdmi
;
941 uint32_t vector_catch_value
;
944 if (arm9tdmi_get_arch_pointers(target
, &armv4_5
, &arm7_9
, &arm9tdmi
) != ERROR_OK
)
946 command_print(cmd_ctx
, "current target isn't an ARM9 based target");
950 vector_catch
= &arm7_9
->eice_cache
->reg_list
[EICE_VEC_CATCH
];
952 /* read the vector catch register if necessary */
953 if (!vector_catch
->valid
)
954 embeddedice_read_reg(vector_catch
);
956 /* get the current setting */
957 vector_catch_value
= buf_get_u32(vector_catch
->value
, 0, 8);
961 vector_catch_value
= 0x0;
962 if (strcmp(args
[0], "all") == 0)
964 vector_catch_value
= 0xdf;
966 else if (strcmp(args
[0], "none") == 0)
972 for (i
= 0; i
< argc
; i
++)
974 /* go through list of vectors */
975 for (j
= 0; arm9tdmi_vectors
[j
].name
; j
++)
977 if (strcmp(args
[i
], arm9tdmi_vectors
[j
].name
) == 0)
979 vector_catch_value
|= arm9tdmi_vectors
[j
].value
;
984 /* complain if vector wasn't found */
985 if (!arm9tdmi_vectors
[j
].name
)
987 command_print(cmd_ctx
, "vector '%s' not found, leaving current setting unchanged", args
[i
]);
989 /* reread current setting */
990 vector_catch_value
= buf_get_u32(
999 /* store new settings */
1000 buf_set_u32(vector_catch
->value
, 0, 8, vector_catch_value
);
1001 embeddedice_store_reg(vector_catch
);
1004 /* output current settings */
1005 for (i
= 0; arm9tdmi_vectors
[i
].name
; i
++) {
1006 command_print(cmd_ctx
, "%s: %s", arm9tdmi_vectors
[i
].name
,
1007 (vector_catch_value
& arm9tdmi_vectors
[i
].value
)
1008 ? "catch" : "don't catch");
1014 int arm9tdmi_register_commands(struct command_context_s
*cmd_ctx
)
1017 command_t
*arm9tdmi_cmd
;
1019 retval
= arm7_9_register_commands(cmd_ctx
);
1020 arm9tdmi_cmd
= register_command(cmd_ctx
, NULL
, "arm9",
1022 "arm9 specific commands");
1023 register_command(cmd_ctx
, arm9tdmi_cmd
, "vector_catch",
1024 handle_arm9tdmi_catch_vectors_command
, COMMAND_EXEC
,
1025 "arm9 vector_catch [all|none|reset|undef|swi|pabt|dabt|irq|fiq] ...");
1030 /** Holds methods for ARM9TDMI targets. */
1031 target_type_t arm9tdmi_target
=
1035 .poll
= arm7_9_poll
,
1036 .arch_state
= armv4_5_arch_state
,
1038 .target_request_data
= arm7_9_target_request_data
,
1040 .halt
= arm7_9_halt
,
1041 .resume
= arm7_9_resume
,
1042 .step
= arm7_9_step
,
1044 .assert_reset
= arm7_9_assert_reset
,
1045 .deassert_reset
= arm7_9_deassert_reset
,
1046 .soft_reset_halt
= arm7_9_soft_reset_halt
,
1048 .get_gdb_reg_list
= armv4_5_get_gdb_reg_list
,
1050 .read_memory
= arm7_9_read_memory
,
1051 .write_memory
= arm7_9_write_memory
,
1052 .bulk_write_memory
= arm7_9_bulk_write_memory
,
1053 .checksum_memory
= arm7_9_checksum_memory
,
1054 .blank_check_memory
= arm7_9_blank_check_memory
,
1056 .run_algorithm
= armv4_5_run_algorithm
,
1058 .add_breakpoint
= arm7_9_add_breakpoint
,
1059 .remove_breakpoint
= arm7_9_remove_breakpoint
,
1060 .add_watchpoint
= arm7_9_add_watchpoint
,
1061 .remove_watchpoint
= arm7_9_remove_watchpoint
,
1063 .register_commands
= arm9tdmi_register_commands
,
1064 .target_create
= arm9tdmi_target_create
,
1065 .init_target
= arm9tdmi_init_target
,
1066 .examine
= arm9tdmi_examine
,
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)