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"
36 * NOTE: this holds code that's used with multiple ARM9 processors:
37 * - ARM9TDMI (ARMv4T) ... in ARM920, ARM922, and ARM940 cores
38 * - ARM9E-S (ARMv5TE) ... in ARM946, ARM966, and ARM968 cores
39 * - ARM9EJS (ARMv5TEJ) ... in ARM926 core
41 * In short, the file name is a misnomer ... it is NOT specific to
42 * that first generation ARM9 processor, or cores using it.
46 #define _DEBUG_INSTRUCTION_EXECUTION_
49 enum arm9tdmi_vector_bit
51 ARM9TDMI_RESET_VECTOR
= 0x01,
52 ARM9TDMI_UNDEF_VECTOR
= 0x02,
53 ARM9TDMI_SWI_VECTOR
= 0x04,
54 ARM9TDMI_PABT_VECTOR
= 0x08,
55 ARM9TDMI_DABT_VECTOR
= 0x10,
56 /* BIT(5) reserved -- must be zero */
57 ARM9TDMI_IRQ_VECTOR
= 0x40,
58 ARM9TDMI_FIQ_VECTOR
= 0x80,
61 static const struct arm9tdmi_vector
{
64 } arm9tdmi_vectors
[] = {
65 {"reset", ARM9TDMI_RESET_VECTOR
},
66 {"undef", ARM9TDMI_UNDEF_VECTOR
},
67 {"swi", ARM9TDMI_SWI_VECTOR
},
68 {"pabt", ARM9TDMI_PABT_VECTOR
},
69 {"dabt", ARM9TDMI_DABT_VECTOR
},
70 {"irq", ARM9TDMI_IRQ_VECTOR
},
71 {"fiq", ARM9TDMI_FIQ_VECTOR
},
75 int arm9tdmi_examine_debug_reason(struct target
*target
)
77 int retval
= ERROR_OK
;
78 struct arm7_9_common
*arm7_9
= target_to_arm7_9(target
);
80 /* only check the debug reason if we don't know it already */
81 if ((target
->debug_reason
!= DBG_REASON_DBGRQ
)
82 && (target
->debug_reason
!= DBG_REASON_SINGLESTEP
))
84 struct scan_field fields
[3];
86 uint8_t instructionbus
[4];
89 jtag_set_end_state(TAP_DRPAUSE
);
91 fields
[0].tap
= arm7_9
->jtag_info
.tap
;
92 fields
[0].num_bits
= 32;
93 fields
[0].out_value
= NULL
;
94 fields
[0].in_value
= databus
;
96 fields
[1].tap
= arm7_9
->jtag_info
.tap
;
97 fields
[1].num_bits
= 3;
98 fields
[1].out_value
= NULL
;
99 fields
[1].in_value
= &debug_reason
;
101 fields
[2].tap
= arm7_9
->jtag_info
.tap
;
102 fields
[2].num_bits
= 32;
103 fields
[2].out_value
= NULL
;
104 fields
[2].in_value
= instructionbus
;
106 if ((retval
= arm_jtag_scann(&arm7_9
->jtag_info
, 0x1)) != ERROR_OK
)
110 arm_jtag_set_instr(&arm7_9
->jtag_info
, arm7_9
->jtag_info
.intest_instr
, NULL
);
112 jtag_add_dr_scan(3, fields
, jtag_set_end_state(TAP_DRPAUSE
));
113 if ((retval
= jtag_execute_queue()) != ERROR_OK
)
118 fields
[0].in_value
= NULL
;
119 fields
[0].out_value
= databus
;
120 fields
[1].in_value
= NULL
;
121 fields
[1].out_value
= &debug_reason
;
122 fields
[2].in_value
= NULL
;
123 fields
[2].out_value
= instructionbus
;
125 jtag_add_dr_scan(3, fields
, jtag_set_end_state(TAP_DRPAUSE
));
127 if (debug_reason
& 0x4)
128 if (debug_reason
& 0x2)
129 target
->debug_reason
= DBG_REASON_WPTANDBKPT
;
131 target
->debug_reason
= DBG_REASON_WATCHPOINT
;
133 target
->debug_reason
= DBG_REASON_BREAKPOINT
;
139 /* put an instruction in the ARM9TDMI pipeline or write the data bus,
140 * and optionally read data
142 int arm9tdmi_clock_out(struct arm_jtag
*jtag_info
, uint32_t instr
,
143 uint32_t out
, uint32_t *in
, int sysspeed
)
145 int retval
= ERROR_OK
;
146 struct scan_field fields
[3];
148 uint8_t instr_buf
[4];
149 uint8_t sysspeed_buf
= 0x0;
152 buf_set_u32(out_buf
, 0, 32, out
);
154 buf_set_u32(instr_buf
, 0, 32, flip_u32(instr
, 32));
157 buf_set_u32(&sysspeed_buf
, 2, 1, 1);
159 jtag_set_end_state(TAP_DRPAUSE
);
160 if ((retval
= arm_jtag_scann(jtag_info
, 0x1)) != ERROR_OK
)
165 arm_jtag_set_instr(jtag_info
, jtag_info
->intest_instr
, NULL
);
167 fields
[0].tap
= jtag_info
->tap
;
168 fields
[0].num_bits
= 32;
169 fields
[0].out_value
= out_buf
;
170 fields
[0].in_value
= NULL
;
172 fields
[1].tap
= jtag_info
->tap
;
173 fields
[1].num_bits
= 3;
174 fields
[1].out_value
= &sysspeed_buf
;
175 fields
[1].in_value
= NULL
;
177 fields
[2].tap
= jtag_info
->tap
;
178 fields
[2].num_bits
= 32;
179 fields
[2].out_value
= instr_buf
;
180 fields
[2].in_value
= NULL
;
184 fields
[0].in_value
= (uint8_t *)in
;
185 jtag_add_dr_scan(3, fields
, jtag_get_end_state());
187 jtag_add_callback(arm_le_to_h_u32
, (jtag_callback_data_t
)in
);
191 jtag_add_dr_scan(3, fields
, jtag_get_end_state());
194 jtag_add_runtest(0, jtag_get_end_state());
196 #ifdef _DEBUG_INSTRUCTION_EXECUTION_
198 if ((retval
= jtag_execute_queue()) != ERROR_OK
)
205 LOG_DEBUG("instr: 0x%8.8x, out: 0x%8.8x, in: 0x%8.8x", instr
, out
, *in
);
208 LOG_DEBUG("instr: 0x%8.8x, out: 0x%8.8x", instr
, out
);
215 /* just read data (instruction and data-out = don't care) */
216 int arm9tdmi_clock_data_in(struct arm_jtag
*jtag_info
, uint32_t *in
)
218 int retval
= ERROR_OK
;;
219 struct scan_field fields
[3];
221 jtag_set_end_state(TAP_DRPAUSE
);
222 if ((retval
= arm_jtag_scann(jtag_info
, 0x1)) != ERROR_OK
)
227 arm_jtag_set_instr(jtag_info
, jtag_info
->intest_instr
, NULL
);
229 fields
[0].tap
= jtag_info
->tap
;
230 fields
[0].num_bits
= 32;
231 fields
[0].out_value
= NULL
;
232 fields
[0].in_value
= (uint8_t *)in
;
234 fields
[1].tap
= jtag_info
->tap
;
235 fields
[1].num_bits
= 3;
236 fields
[1].out_value
= NULL
;
237 fields
[1].in_value
= NULL
;
239 fields
[2].tap
= jtag_info
->tap
;
240 fields
[2].num_bits
= 32;
241 fields
[2].out_value
= NULL
;
242 fields
[2].in_value
= NULL
;
244 jtag_add_dr_scan(3, fields
, jtag_get_end_state());
246 jtag_add_callback(arm_le_to_h_u32
, (jtag_callback_data_t
)in
);
248 jtag_add_runtest(0, jtag_get_end_state());
250 #ifdef _DEBUG_INSTRUCTION_EXECUTION_
252 if ((retval
= jtag_execute_queue()) != ERROR_OK
)
259 LOG_DEBUG("in: 0x%8.8x", *in
);
263 LOG_ERROR("BUG: called with in == NULL");
271 extern void arm_endianness(uint8_t *tmp
, void *in
, int size
, int be
, int flip
);
273 static int arm9endianness(jtag_callback_data_t arg
,
274 jtag_callback_data_t size
, jtag_callback_data_t be
,
275 jtag_callback_data_t captured
)
277 uint8_t *in
= (uint8_t *)arg
;
279 arm_endianness((uint8_t *)captured
, in
, (int)size
, (int)be
, 0);
283 /* clock the target, and read the databus
284 * the *in pointer points to a buffer where elements of 'size' bytes
285 * are stored in big (be == 1) or little (be == 0) endianness
287 int arm9tdmi_clock_data_in_endianness(struct arm_jtag
*jtag_info
,
288 void *in
, int size
, int be
)
290 int retval
= ERROR_OK
;
291 struct scan_field fields
[3];
293 jtag_set_end_state(TAP_DRPAUSE
);
294 if ((retval
= arm_jtag_scann(jtag_info
, 0x1)) != ERROR_OK
)
299 arm_jtag_set_instr(jtag_info
, jtag_info
->intest_instr
, NULL
);
301 fields
[0].tap
= jtag_info
->tap
;
302 fields
[0].num_bits
= 32;
303 fields
[0].out_value
= NULL
;
304 jtag_alloc_in_value32(&fields
[0]);
306 fields
[1].tap
= jtag_info
->tap
;
307 fields
[1].num_bits
= 3;
308 fields
[1].out_value
= NULL
;
309 fields
[1].in_value
= NULL
;
311 fields
[2].tap
= jtag_info
->tap
;
312 fields
[2].num_bits
= 32;
313 fields
[2].out_value
= NULL
;
314 fields
[2].in_value
= NULL
;
316 jtag_add_dr_scan(3, fields
, jtag_get_end_state());
318 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
);
320 jtag_add_runtest(0, jtag_get_end_state());
322 #ifdef _DEBUG_INSTRUCTION_EXECUTION_
324 if ((retval
= jtag_execute_queue()) != ERROR_OK
)
331 LOG_DEBUG("in: 0x%8.8x", *(uint32_t*)in
);
335 LOG_ERROR("BUG: called with in == NULL");
343 static void arm9tdmi_change_to_arm(struct target
*target
,
344 uint32_t *r0
, uint32_t *pc
)
346 int retval
= ERROR_OK
;
347 struct arm7_9_common
*arm7_9
= target_to_arm7_9(target
);
348 struct arm_jtag
*jtag_info
= &arm7_9
->jtag_info
;
350 /* save r0 before using it and put system in ARM state
351 * to allow common handling of ARM and THUMB debugging */
353 /* fetch STR r0, [r0] */
354 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_STR(0, 0), 0, NULL
, 0);
355 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, 0, NULL
, 0);
356 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, 0, NULL
, 0);
357 /* STR r0, [r0] in Memory */
358 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, 0, r0
, 0);
360 /* MOV r0, r15 fetched, STR in Decode */
361 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_MOV(0, 15), 0, NULL
, 0);
362 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, 0, NULL
, 0);
363 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_STR(0, 0), 0, NULL
, 0);
364 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, 0, NULL
, 0);
365 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, 0, NULL
, 0);
366 /* nothing fetched, STR r0, [r0] in Memory */
367 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, 0, pc
, 0);
369 /* use pc-relative LDR to clear r0[1:0] (for switch to ARM mode) */
370 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_LDR_PCREL(0), 0, NULL
, 0);
372 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 /* LDR in Memory (to account for interlock) */
376 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, 0, NULL
, 0);
379 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_BX(0), 0, NULL
, 0);
380 /* NOP fetched, BX in Decode, MOV in Execute */
381 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, 0, NULL
, 0);
382 /* NOP fetched, BX in Execute (1) */
383 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, 0, NULL
, 0);
385 if ((retval
= jtag_execute_queue()) != ERROR_OK
)
390 /* fix program counter:
391 * MOV r0, r15 was the 5th instruction (+8)
392 * reading PC in Thumb state gives address of instruction + 4
397 void arm9tdmi_read_core_regs(struct target
*target
,
398 uint32_t mask
, uint32_t* core_regs
[16])
401 struct arm7_9_common
*arm7_9
= target_to_arm7_9(target
);
402 struct arm_jtag
*jtag_info
= &arm7_9
->jtag_info
;
404 /* STMIA r0-15, [r0] at debug speed
405 * register values will start to appear on 4th DCLK
407 arm9tdmi_clock_out(jtag_info
, ARMV4_5_STMIA(0, mask
& 0xffff, 0, 0), 0, NULL
, 0);
409 /* fetch NOP, STM in DECODE stage */
410 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
411 /* fetch NOP, STM in EXECUTE stage (1st cycle) */
412 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
414 for (i
= 0; i
<= 15; i
++)
417 /* nothing fetched, STM in MEMORY (i'th cycle) */
418 arm9tdmi_clock_data_in(jtag_info
, core_regs
[i
]);
422 static void arm9tdmi_read_core_regs_target_buffer(struct target
*target
,
423 uint32_t mask
, void* buffer
, int size
)
426 struct arm7_9_common
*arm7_9
= target_to_arm7_9(target
);
427 struct arm_jtag
*jtag_info
= &arm7_9
->jtag_info
;
428 int be
= (target
->endianness
== TARGET_BIG_ENDIAN
) ? 1 : 0;
429 uint32_t *buf_u32
= buffer
;
430 uint16_t *buf_u16
= buffer
;
431 uint8_t *buf_u8
= buffer
;
433 /* STMIA r0-15, [r0] at debug speed
434 * register values will start to appear on 4th DCLK
436 arm9tdmi_clock_out(jtag_info
, ARMV4_5_STMIA(0, mask
& 0xffff, 0, 0), 0, NULL
, 0);
438 /* fetch NOP, STM in DECODE stage */
439 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
440 /* fetch NOP, STM in EXECUTE stage (1st cycle) */
441 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
443 for (i
= 0; i
<= 15; i
++)
446 /* nothing fetched, STM in MEMORY (i'th cycle) */
450 arm9tdmi_clock_data_in_endianness(jtag_info
, buf_u32
++, 4, be
);
453 arm9tdmi_clock_data_in_endianness(jtag_info
, buf_u16
++, 2, be
);
456 arm9tdmi_clock_data_in_endianness(jtag_info
, buf_u8
++, 1, be
);
462 static void arm9tdmi_read_xpsr(struct target
*target
, uint32_t *xpsr
, int spsr
)
464 struct arm7_9_common
*arm7_9
= target_to_arm7_9(target
);
465 struct arm_jtag
*jtag_info
= &arm7_9
->jtag_info
;
468 arm9tdmi_clock_out(jtag_info
, ARMV4_5_MRS(0, spsr
& 1), 0, NULL
, 0);
469 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
470 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
471 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
472 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
475 arm9tdmi_clock_out(jtag_info
, ARMV4_5_STR(0, 15), 0, NULL
, 0);
476 /* fetch NOP, STR in DECODE stage */
477 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
478 /* fetch NOP, STR in EXECUTE stage (1st cycle) */
479 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
480 /* nothing fetched, STR in MEMORY */
481 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, xpsr
, 0);
484 static void arm9tdmi_write_xpsr(struct target
*target
, uint32_t xpsr
, int spsr
)
486 struct arm7_9_common
*arm7_9
= target_to_arm7_9(target
);
487 struct arm_jtag
*jtag_info
= &arm7_9
->jtag_info
;
489 LOG_DEBUG("xpsr: %8.8" PRIx32
", spsr: %i", xpsr
, spsr
);
492 arm9tdmi_clock_out(jtag_info
, ARMV4_5_MSR_IM(xpsr
& 0xff, 0, 1, spsr
), 0, NULL
, 0);
493 /* MSR2 fetched, MSR1 in DECODE */
494 arm9tdmi_clock_out(jtag_info
, ARMV4_5_MSR_IM((xpsr
& 0xff00) >> 8, 0xc, 2, spsr
), 0, NULL
, 0);
495 /* MSR3 fetched, MSR1 in EXECUTE (1), MSR2 in DECODE */
496 arm9tdmi_clock_out(jtag_info
, ARMV4_5_MSR_IM((xpsr
& 0xff0000) >> 16, 0x8, 4, spsr
), 0, NULL
, 0);
497 /* nothing fetched, MSR1 in EXECUTE (2) */
498 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
499 /* nothing fetched, MSR1 in EXECUTE (3) */
500 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
501 /* MSR4 fetched, MSR2 in EXECUTE (1), MSR3 in DECODE */
502 arm9tdmi_clock_out(jtag_info
, ARMV4_5_MSR_IM((xpsr
& 0xff000000) >> 24, 0x4, 8, spsr
), 0, NULL
, 0);
503 /* nothing fetched, MSR2 in EXECUTE (2) */
504 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
505 /* nothing fetched, MSR2 in EXECUTE (3) */
506 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
507 /* NOP fetched, MSR3 in EXECUTE (1), MSR4 in DECODE */
508 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
509 /* nothing fetched, MSR3 in EXECUTE (2) */
510 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
511 /* nothing fetched, MSR3 in EXECUTE (3) */
512 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
513 /* NOP fetched, MSR4 in EXECUTE (1) */
514 /* last MSR writes flags, which takes only one cycle */
515 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
518 static void arm9tdmi_write_xpsr_im8(struct target
*target
,
519 uint8_t xpsr_im
, int rot
, int spsr
)
521 struct arm7_9_common
*arm7_9
= target_to_arm7_9(target
);
522 struct arm_jtag
*jtag_info
= &arm7_9
->jtag_info
;
524 LOG_DEBUG("xpsr_im: %2.2x, rot: %i, spsr: %i", xpsr_im
, rot
, spsr
);
527 arm9tdmi_clock_out(jtag_info
, ARMV4_5_MSR_IM(xpsr_im
, rot
, 1, spsr
), 0, NULL
, 0);
528 /* NOP fetched, MSR in DECODE */
529 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
530 /* NOP fetched, MSR in EXECUTE (1) */
531 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
533 /* rot == 4 writes flags, which takes only one cycle */
536 /* nothing fetched, MSR in EXECUTE (2) */
537 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
538 /* nothing fetched, MSR in EXECUTE (3) */
539 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
543 void arm9tdmi_write_core_regs(struct target
*target
,
544 uint32_t mask
, uint32_t core_regs
[16])
547 struct arm7_9_common
*arm7_9
= target_to_arm7_9(target
);
548 struct arm_jtag
*jtag_info
= &arm7_9
->jtag_info
;
550 /* LDMIA r0-15, [r0] at debug speed
551 * register values will start to appear on 4th DCLK
553 arm9tdmi_clock_out(jtag_info
, ARMV4_5_LDMIA(0, mask
& 0xffff, 0, 0), 0, NULL
, 0);
555 /* fetch NOP, LDM in DECODE stage */
556 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
557 /* fetch NOP, LDM in EXECUTE stage (1st cycle) */
558 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
560 for (i
= 0; i
<= 15; i
++)
563 /* nothing fetched, LDM still in EXECUTE (1 + i cycle) */
564 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, core_regs
[i
], NULL
, 0);
566 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
569 void arm9tdmi_load_word_regs(struct target
*target
, uint32_t mask
)
571 struct arm7_9_common
*arm7_9
= target_to_arm7_9(target
);
572 struct arm_jtag
*jtag_info
= &arm7_9
->jtag_info
;
574 /* put system-speed load-multiple into the pipeline */
575 arm9tdmi_clock_out(jtag_info
, ARMV4_5_LDMIA(0, mask
& 0xffff, 0, 1), 0, NULL
, 0);
576 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 1);
579 void arm9tdmi_load_hword_reg(struct target
*target
, int num
)
581 struct arm7_9_common
*arm7_9
= target_to_arm7_9(target
);
582 struct arm_jtag
*jtag_info
= &arm7_9
->jtag_info
;
584 /* put system-speed load half-word into the pipeline */
585 arm9tdmi_clock_out(jtag_info
, ARMV4_5_LDRH_IP(num
, 0), 0, NULL
, 0);
586 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 1);
589 void arm9tdmi_load_byte_reg(struct target
*target
, int num
)
591 struct arm7_9_common
*arm7_9
= target_to_arm7_9(target
);
592 struct arm_jtag
*jtag_info
= &arm7_9
->jtag_info
;
594 /* put system-speed load byte into the pipeline */
595 arm9tdmi_clock_out(jtag_info
, ARMV4_5_LDRB_IP(num
, 0), 0, NULL
, 0);
596 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 1);
599 void arm9tdmi_store_word_regs(struct target
*target
, uint32_t mask
)
601 struct arm7_9_common
*arm7_9
= target_to_arm7_9(target
);
602 struct arm_jtag
*jtag_info
= &arm7_9
->jtag_info
;
604 /* put system-speed store-multiple into the pipeline */
605 arm9tdmi_clock_out(jtag_info
, ARMV4_5_STMIA(0, mask
, 0, 1), 0, NULL
, 0);
606 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 1);
609 void arm9tdmi_store_hword_reg(struct target
*target
, int num
)
611 struct arm7_9_common
*arm7_9
= target_to_arm7_9(target
);
612 struct arm_jtag
*jtag_info
= &arm7_9
->jtag_info
;
614 /* put system-speed store half-word into the pipeline */
615 arm9tdmi_clock_out(jtag_info
, ARMV4_5_STRH_IP(num
, 0), 0, NULL
, 0);
616 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 1);
619 void arm9tdmi_store_byte_reg(struct target
*target
, int num
)
621 struct arm7_9_common
*arm7_9
= target_to_arm7_9(target
);
622 struct arm_jtag
*jtag_info
= &arm7_9
->jtag_info
;
624 /* put system-speed store byte into the pipeline */
625 arm9tdmi_clock_out(jtag_info
, ARMV4_5_STRB_IP(num
, 0), 0, NULL
, 0);
626 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 1);
629 static void arm9tdmi_write_pc(struct target
*target
, uint32_t pc
)
631 struct arm7_9_common
*arm7_9
= target_to_arm7_9(target
);
632 struct arm_jtag
*jtag_info
= &arm7_9
->jtag_info
;
634 /* LDMIA r0-15, [r0] at debug speed
635 * register values will start to appear on 4th DCLK
637 arm9tdmi_clock_out(jtag_info
, ARMV4_5_LDMIA(0, 0x8000, 0, 0), 0, NULL
, 0);
639 /* fetch NOP, LDM in DECODE stage */
640 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
641 /* fetch NOP, LDM in EXECUTE stage (1st cycle) */
642 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
643 /* nothing fetched, LDM in EXECUTE stage (2nd cycle) (output data) */
644 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, pc
, NULL
, 0);
645 /* nothing fetched, LDM in EXECUTE stage (3rd cycle) */
646 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
647 /* fetch NOP, LDM in EXECUTE stage (4th cycle) */
648 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
649 /* fetch NOP, LDM in EXECUTE stage (5th cycle) */
650 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
653 void arm9tdmi_branch_resume(struct target
*target
)
655 struct arm7_9_common
*arm7_9
= target_to_arm7_9(target
);
656 struct arm_jtag
*jtag_info
= &arm7_9
->jtag_info
;
658 arm9tdmi_clock_out(jtag_info
, ARMV4_5_B(0xfffffc, 0), 0, NULL
, 0);
659 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 1);
662 static void arm9tdmi_branch_resume_thumb(struct target
*target
)
666 struct arm7_9_common
*arm7_9
= target_to_arm7_9(target
);
667 struct arm
*armv4_5
= &arm7_9
->armv4_5_common
;
668 struct arm_jtag
*jtag_info
= &arm7_9
->jtag_info
;
669 struct reg
*dbg_stat
= &arm7_9
->eice_cache
->reg_list
[EICE_DBG_STAT
];
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, 0x1, 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) */
681 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32) | 1, NULL
, 0);
682 /* nothing fetched, LDM in EXECUTE stage (3rd cycle) */
683 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
685 /* Branch and eXchange */
686 arm9tdmi_clock_out(jtag_info
, ARMV4_5_BX(0), 0, NULL
, 0);
688 embeddedice_read_reg(dbg_stat
);
690 /* fetch NOP, BX in DECODE stage */
691 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
693 embeddedice_read_reg(dbg_stat
);
695 /* fetch NOP, BX in EXECUTE stage (1st cycle) */
696 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
698 /* target is now in Thumb state */
699 embeddedice_read_reg(dbg_stat
);
701 /* load r0 value, MOV_IM in Decode*/
702 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_LDR_PCREL(0), 0, NULL
, 0);
703 /* fetch NOP, LDR in Decode, MOV_IM in Execute */
704 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, 0, NULL
, 0);
705 /* fetch NOP, LDR in Execute */
706 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, 0, NULL
, 0);
707 /* nothing fetched, LDR in EXECUTE stage (2nd cycle) */
708 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, buf_get_u32(armv4_5
->core_cache
->reg_list
[0].value
, 0, 32), NULL
, 0);
709 /* nothing fetched, LDR in EXECUTE stage (3rd cycle) */
710 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, 0, NULL
, 0);
712 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, 0, NULL
, 0);
713 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, 0, NULL
, 0);
715 embeddedice_read_reg(dbg_stat
);
717 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_B(0x7f7), 0, NULL
, 1);
718 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, 0, NULL
, 0);
721 void arm9tdmi_enable_single_step(struct target
*target
, uint32_t next_pc
)
723 struct arm7_9_common
*arm7_9
= target_to_arm7_9(target
);
725 if (arm7_9
->has_single_step
)
727 buf_set_u32(arm7_9
->eice_cache
->reg_list
[EICE_DBG_CTRL
].value
, 3, 1, 1);
728 embeddedice_store_reg(&arm7_9
->eice_cache
->reg_list
[EICE_DBG_CTRL
]);
732 arm7_9_enable_eice_step(target
, next_pc
);
736 void arm9tdmi_disable_single_step(struct target
*target
)
738 struct arm7_9_common
*arm7_9
= target_to_arm7_9(target
);
740 if (arm7_9
->has_single_step
)
742 buf_set_u32(arm7_9
->eice_cache
->reg_list
[EICE_DBG_CTRL
].value
, 3, 1, 0);
743 embeddedice_store_reg(&arm7_9
->eice_cache
->reg_list
[EICE_DBG_CTRL
]);
747 arm7_9_disable_eice_step(target
);
751 static void arm9tdmi_build_reg_cache(struct target
*target
)
753 struct reg_cache
**cache_p
= register_get_last_cache_p(&target
->reg_cache
);
754 struct arm
*armv4_5
= target_to_armv4_5(target
);
756 (*cache_p
) = armv4_5_build_reg_cache(target
, armv4_5
);
759 int arm9tdmi_init_target(struct command_context
*cmd_ctx
,
760 struct target
*target
)
762 arm9tdmi_build_reg_cache(target
);
766 int arm9tdmi_init_arch_info(struct target
*target
,
767 struct arm7_9_common
*arm7_9
, struct jtag_tap
*tap
)
769 /* prepare JTAG information for the new target */
770 arm7_9
->jtag_info
.tap
= tap
;
771 arm7_9
->jtag_info
.scann_size
= 5;
773 /* register arch-specific functions */
774 arm7_9
->examine_debug_reason
= arm9tdmi_examine_debug_reason
;
775 arm7_9
->change_to_arm
= arm9tdmi_change_to_arm
;
776 arm7_9
->read_core_regs
= arm9tdmi_read_core_regs
;
777 arm7_9
->read_core_regs_target_buffer
= arm9tdmi_read_core_regs_target_buffer
;
778 arm7_9
->read_xpsr
= arm9tdmi_read_xpsr
;
780 arm7_9
->write_xpsr
= arm9tdmi_write_xpsr
;
781 arm7_9
->write_xpsr_im8
= arm9tdmi_write_xpsr_im8
;
782 arm7_9
->write_core_regs
= arm9tdmi_write_core_regs
;
784 arm7_9
->load_word_regs
= arm9tdmi_load_word_regs
;
785 arm7_9
->load_hword_reg
= arm9tdmi_load_hword_reg
;
786 arm7_9
->load_byte_reg
= arm9tdmi_load_byte_reg
;
788 arm7_9
->store_word_regs
= arm9tdmi_store_word_regs
;
789 arm7_9
->store_hword_reg
= arm9tdmi_store_hword_reg
;
790 arm7_9
->store_byte_reg
= arm9tdmi_store_byte_reg
;
792 arm7_9
->write_pc
= arm9tdmi_write_pc
;
793 arm7_9
->branch_resume
= arm9tdmi_branch_resume
;
794 arm7_9
->branch_resume_thumb
= arm9tdmi_branch_resume_thumb
;
796 arm7_9
->enable_single_step
= arm9tdmi_enable_single_step
;
797 arm7_9
->disable_single_step
= arm9tdmi_disable_single_step
;
799 arm7_9
->post_debug_entry
= NULL
;
801 arm7_9
->pre_restore_context
= NULL
;
802 arm7_9
->post_restore_context
= NULL
;
804 /* initialize arch-specific breakpoint handling */
805 arm7_9
->arm_bkpt
= 0xdeeedeee;
806 arm7_9
->thumb_bkpt
= 0xdeee;
808 arm7_9
->dbgreq_adjust_pc
= 3;
810 arm7_9_init_arch_info(target
, arm7_9
);
812 /* override use of DBGRQ, this is safe on ARM9TDMI */
813 arm7_9
->use_dbgrq
= 1;
815 /* all ARM9s have the vector catch register */
816 arm7_9
->has_vector_catch
= 1;
821 static int arm9tdmi_target_create(struct target
*target
, Jim_Interp
*interp
)
823 struct arm7_9_common
*arm7_9
= calloc(1,sizeof(struct arm7_9_common
));
825 arm9tdmi_init_arch_info(target
, arm7_9
, target
->tap
);
826 arm7_9
->armv4_5_common
.is_armv4
= true;
831 COMMAND_HANDLER(handle_arm9tdmi_catch_vectors_command
)
833 struct target
*target
= get_current_target(CMD_CTX
);
834 struct arm7_9_common
*arm7_9
= target_to_arm7_9(target
);
835 struct reg
*vector_catch
;
836 uint32_t vector_catch_value
;
838 /* it's uncommon, but some ARM7 chips can support this */
839 if (arm7_9
->common_magic
!= ARM7_9_COMMON_MAGIC
840 || !arm7_9
->has_vector_catch
) {
841 command_print(CMD_CTX
, "target doesn't have EmbeddedICE "
842 "with vector_catch");
843 return ERROR_TARGET_INVALID
;
846 vector_catch
= &arm7_9
->eice_cache
->reg_list
[EICE_VEC_CATCH
];
848 /* read the vector catch register if necessary */
849 if (!vector_catch
->valid
)
850 embeddedice_read_reg(vector_catch
);
852 /* get the current setting */
853 vector_catch_value
= buf_get_u32(vector_catch
->value
, 0, 8);
857 vector_catch_value
= 0x0;
858 if (strcmp(CMD_ARGV
[0], "all") == 0)
860 vector_catch_value
= 0xdf;
862 else if (strcmp(CMD_ARGV
[0], "none") == 0)
868 for (unsigned i
= 0; i
< CMD_ARGC
; i
++)
870 /* go through list of vectors */
872 for (j
= 0; arm9tdmi_vectors
[j
].name
; j
++)
874 if (strcmp(CMD_ARGV
[i
], arm9tdmi_vectors
[j
].name
) == 0)
876 vector_catch_value
|= arm9tdmi_vectors
[j
].value
;
881 /* complain if vector wasn't found */
882 if (!arm9tdmi_vectors
[j
].name
)
884 command_print(CMD_CTX
, "vector '%s' not found, leaving current setting unchanged", CMD_ARGV
[i
]);
886 /* reread current setting */
887 vector_catch_value
= buf_get_u32(
896 /* store new settings */
897 buf_set_u32(vector_catch
->value
, 0, 8, vector_catch_value
);
898 embeddedice_store_reg(vector_catch
);
901 /* output current settings */
902 for (unsigned i
= 0; arm9tdmi_vectors
[i
].name
; i
++) {
903 command_print(CMD_CTX
, "%s: %s", arm9tdmi_vectors
[i
].name
,
904 (vector_catch_value
& arm9tdmi_vectors
[i
].value
)
905 ? "catch" : "don't catch");
911 static const struct command_registration arm9tdmi_exec_command_handlers
[] = {
913 .name
= "vector_catch",
914 .handler
= handle_arm9tdmi_catch_vectors_command
,
915 .mode
= COMMAND_EXEC
,
916 .usage
= "[all|none|reset|undef|swi|pabt|dabt|irq|fiq] ...",
918 COMMAND_REGISTRATION_DONE
920 const struct command_registration arm9tdmi_command_handlers
[] = {
922 .chain
= arm7_9_command_handlers
,
927 .help
= "arm9tdmi command group",
928 .chain
= arm9tdmi_exec_command_handlers
,
930 COMMAND_REGISTRATION_DONE
933 /** Holds methods for ARM9TDMI targets. */
934 struct target_type arm9tdmi_target
=
939 .arch_state
= armv4_5_arch_state
,
941 .target_request_data
= arm7_9_target_request_data
,
944 .resume
= arm7_9_resume
,
947 .assert_reset
= arm7_9_assert_reset
,
948 .deassert_reset
= arm7_9_deassert_reset
,
949 .soft_reset_halt
= arm7_9_soft_reset_halt
,
951 .get_gdb_reg_list
= armv4_5_get_gdb_reg_list
,
953 .read_memory
= arm7_9_read_memory
,
954 .write_memory
= arm7_9_write_memory
,
955 .bulk_write_memory
= arm7_9_bulk_write_memory
,
957 .checksum_memory
= arm_checksum_memory
,
958 .blank_check_memory
= arm_blank_check_memory
,
960 .run_algorithm
= armv4_5_run_algorithm
,
962 .add_breakpoint
= arm7_9_add_breakpoint
,
963 .remove_breakpoint
= arm7_9_remove_breakpoint
,
964 .add_watchpoint
= arm7_9_add_watchpoint
,
965 .remove_watchpoint
= arm7_9_remove_watchpoint
,
967 .commands
= arm9tdmi_command_handlers
,
968 .target_create
= arm9tdmi_target_create
,
969 .init_target
= arm9tdmi_init_target
,
970 .examine
= arm7_9_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)