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"
33 #include "arm_opcodes.h"
37 * NOTE: this holds code that's used with multiple ARM9 processors:
38 * - ARM9TDMI (ARMv4T) ... in ARM920, ARM922, and ARM940 cores
39 * - ARM9E-S (ARMv5TE) ... in ARM946, ARM966, and ARM968 cores
40 * - ARM9EJS (ARMv5TEJ) ... in ARM926 core
42 * In short, the file name is a misnomer ... it is NOT specific to
43 * that first generation ARM9 processor, or cores using it.
47 #define _DEBUG_INSTRUCTION_EXECUTION_
50 enum arm9tdmi_vector_bit
52 ARM9TDMI_RESET_VECTOR
= 0x01,
53 ARM9TDMI_UNDEF_VECTOR
= 0x02,
54 ARM9TDMI_SWI_VECTOR
= 0x04,
55 ARM9TDMI_PABT_VECTOR
= 0x08,
56 ARM9TDMI_DABT_VECTOR
= 0x10,
57 /* BIT(5) reserved -- must be zero */
58 ARM9TDMI_IRQ_VECTOR
= 0x40,
59 ARM9TDMI_FIQ_VECTOR
= 0x80,
62 static const struct arm9tdmi_vector
{
65 } arm9tdmi_vectors
[] = {
66 {"reset", ARM9TDMI_RESET_VECTOR
},
67 {"undef", ARM9TDMI_UNDEF_VECTOR
},
68 {"swi", ARM9TDMI_SWI_VECTOR
},
69 {"pabt", ARM9TDMI_PABT_VECTOR
},
70 {"dabt", ARM9TDMI_DABT_VECTOR
},
71 {"irq", ARM9TDMI_IRQ_VECTOR
},
72 {"fiq", ARM9TDMI_FIQ_VECTOR
},
76 int arm9tdmi_examine_debug_reason(struct target
*target
)
78 int retval
= ERROR_OK
;
79 struct arm7_9_common
*arm7_9
= target_to_arm7_9(target
);
81 /* only check the debug reason if we don't know it already */
82 if ((target
->debug_reason
!= DBG_REASON_DBGRQ
)
83 && (target
->debug_reason
!= DBG_REASON_SINGLESTEP
))
85 struct scan_field fields
[3];
87 uint8_t instructionbus
[4];
90 jtag_set_end_state(TAP_DRPAUSE
);
92 fields
[0].tap
= arm7_9
->jtag_info
.tap
;
93 fields
[0].num_bits
= 32;
94 fields
[0].out_value
= NULL
;
95 fields
[0].in_value
= databus
;
97 fields
[1].tap
= arm7_9
->jtag_info
.tap
;
98 fields
[1].num_bits
= 3;
99 fields
[1].out_value
= NULL
;
100 fields
[1].in_value
= &debug_reason
;
102 fields
[2].tap
= arm7_9
->jtag_info
.tap
;
103 fields
[2].num_bits
= 32;
104 fields
[2].out_value
= NULL
;
105 fields
[2].in_value
= instructionbus
;
107 if ((retval
= arm_jtag_scann(&arm7_9
->jtag_info
, 0x1)) != ERROR_OK
)
111 arm_jtag_set_instr(&arm7_9
->jtag_info
, arm7_9
->jtag_info
.intest_instr
, NULL
);
113 jtag_add_dr_scan(3, fields
, jtag_set_end_state(TAP_DRPAUSE
));
114 if ((retval
= jtag_execute_queue()) != ERROR_OK
)
119 fields
[0].in_value
= NULL
;
120 fields
[0].out_value
= databus
;
121 fields
[1].in_value
= NULL
;
122 fields
[1].out_value
= &debug_reason
;
123 fields
[2].in_value
= NULL
;
124 fields
[2].out_value
= instructionbus
;
126 jtag_add_dr_scan(3, fields
, jtag_set_end_state(TAP_DRPAUSE
));
128 if (debug_reason
& 0x4)
129 if (debug_reason
& 0x2)
130 target
->debug_reason
= DBG_REASON_WPTANDBKPT
;
132 target
->debug_reason
= DBG_REASON_WATCHPOINT
;
134 target
->debug_reason
= DBG_REASON_BREAKPOINT
;
140 /* put an instruction in the ARM9TDMI pipeline or write the data bus,
141 * and optionally read data
143 int arm9tdmi_clock_out(struct arm_jtag
*jtag_info
, uint32_t instr
,
144 uint32_t out
, uint32_t *in
, int sysspeed
)
146 int retval
= ERROR_OK
;
147 struct scan_field fields
[3];
149 uint8_t instr_buf
[4];
150 uint8_t sysspeed_buf
= 0x0;
153 buf_set_u32(out_buf
, 0, 32, out
);
155 buf_set_u32(instr_buf
, 0, 32, flip_u32(instr
, 32));
158 buf_set_u32(&sysspeed_buf
, 2, 1, 1);
160 jtag_set_end_state(TAP_DRPAUSE
);
161 if ((retval
= arm_jtag_scann(jtag_info
, 0x1)) != ERROR_OK
)
166 arm_jtag_set_instr(jtag_info
, jtag_info
->intest_instr
, NULL
);
168 fields
[0].tap
= jtag_info
->tap
;
169 fields
[0].num_bits
= 32;
170 fields
[0].out_value
= out_buf
;
171 fields
[0].in_value
= NULL
;
173 fields
[1].tap
= jtag_info
->tap
;
174 fields
[1].num_bits
= 3;
175 fields
[1].out_value
= &sysspeed_buf
;
176 fields
[1].in_value
= NULL
;
178 fields
[2].tap
= jtag_info
->tap
;
179 fields
[2].num_bits
= 32;
180 fields
[2].out_value
= instr_buf
;
181 fields
[2].in_value
= NULL
;
185 fields
[0].in_value
= (uint8_t *)in
;
186 jtag_add_dr_scan(3, fields
, jtag_get_end_state());
188 jtag_add_callback(arm_le_to_h_u32
, (jtag_callback_data_t
)in
);
192 jtag_add_dr_scan(3, fields
, jtag_get_end_state());
195 jtag_add_runtest(0, jtag_get_end_state());
197 #ifdef _DEBUG_INSTRUCTION_EXECUTION_
199 if ((retval
= jtag_execute_queue()) != ERROR_OK
)
206 LOG_DEBUG("instr: 0x%8.8x, out: 0x%8.8x, in: 0x%8.8x", instr
, out
, *in
);
209 LOG_DEBUG("instr: 0x%8.8x, out: 0x%8.8x", instr
, out
);
216 /* just read data (instruction and data-out = don't care) */
217 int arm9tdmi_clock_data_in(struct arm_jtag
*jtag_info
, uint32_t *in
)
219 int retval
= ERROR_OK
;;
220 struct scan_field fields
[3];
222 jtag_set_end_state(TAP_DRPAUSE
);
223 if ((retval
= arm_jtag_scann(jtag_info
, 0x1)) != ERROR_OK
)
228 arm_jtag_set_instr(jtag_info
, jtag_info
->intest_instr
, NULL
);
230 fields
[0].tap
= jtag_info
->tap
;
231 fields
[0].num_bits
= 32;
232 fields
[0].out_value
= NULL
;
233 fields
[0].in_value
= (uint8_t *)in
;
235 fields
[1].tap
= jtag_info
->tap
;
236 fields
[1].num_bits
= 3;
237 fields
[1].out_value
= NULL
;
238 fields
[1].in_value
= NULL
;
240 fields
[2].tap
= jtag_info
->tap
;
241 fields
[2].num_bits
= 32;
242 fields
[2].out_value
= NULL
;
243 fields
[2].in_value
= NULL
;
245 jtag_add_dr_scan(3, fields
, jtag_get_end_state());
247 jtag_add_callback(arm_le_to_h_u32
, (jtag_callback_data_t
)in
);
249 jtag_add_runtest(0, jtag_get_end_state());
251 #ifdef _DEBUG_INSTRUCTION_EXECUTION_
253 if ((retval
= jtag_execute_queue()) != ERROR_OK
)
260 LOG_DEBUG("in: 0x%8.8x", *in
);
264 LOG_ERROR("BUG: called with in == NULL");
272 static int arm9endianness(jtag_callback_data_t arg
,
273 jtag_callback_data_t size
, jtag_callback_data_t be
,
274 jtag_callback_data_t captured
)
276 uint8_t *in
= (uint8_t *)arg
;
278 arm_endianness((uint8_t *)captured
, in
, (int)size
, (int)be
, 0);
282 /* clock the target, and read the databus
283 * the *in pointer points to a buffer where elements of 'size' bytes
284 * are stored in big (be == 1) or little (be == 0) endianness
286 int arm9tdmi_clock_data_in_endianness(struct arm_jtag
*jtag_info
,
287 void *in
, int size
, int be
)
289 int retval
= ERROR_OK
;
290 struct scan_field fields
[3];
292 jtag_set_end_state(TAP_DRPAUSE
);
293 if ((retval
= arm_jtag_scann(jtag_info
, 0x1)) != ERROR_OK
)
298 arm_jtag_set_instr(jtag_info
, jtag_info
->intest_instr
, NULL
);
300 fields
[0].tap
= jtag_info
->tap
;
301 fields
[0].num_bits
= 32;
302 fields
[0].out_value
= NULL
;
303 jtag_alloc_in_value32(&fields
[0]);
305 fields
[1].tap
= jtag_info
->tap
;
306 fields
[1].num_bits
= 3;
307 fields
[1].out_value
= NULL
;
308 fields
[1].in_value
= NULL
;
310 fields
[2].tap
= jtag_info
->tap
;
311 fields
[2].num_bits
= 32;
312 fields
[2].out_value
= NULL
;
313 fields
[2].in_value
= NULL
;
315 jtag_add_dr_scan(3, fields
, jtag_get_end_state());
317 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
);
319 jtag_add_runtest(0, jtag_get_end_state());
321 #ifdef _DEBUG_INSTRUCTION_EXECUTION_
323 if ((retval
= jtag_execute_queue()) != ERROR_OK
)
330 LOG_DEBUG("in: 0x%8.8x", *(uint32_t*)in
);
334 LOG_ERROR("BUG: called with in == NULL");
342 static void arm9tdmi_change_to_arm(struct target
*target
,
343 uint32_t *r0
, uint32_t *pc
)
345 int retval
= ERROR_OK
;
346 struct arm7_9_common
*arm7_9
= target_to_arm7_9(target
);
347 struct arm_jtag
*jtag_info
= &arm7_9
->jtag_info
;
349 /* save r0 before using it and put system in ARM state
350 * to allow common handling of ARM and THUMB debugging */
352 /* fetch STR r0, [r0] */
353 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_STR(0, 0), 0, NULL
, 0);
354 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, 0, NULL
, 0);
355 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, 0, NULL
, 0);
356 /* STR r0, [r0] in Memory */
357 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, 0, r0
, 0);
359 /* MOV r0, r15 fetched, STR in Decode */
360 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_MOV(0, 15), 0, NULL
, 0);
361 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, 0, NULL
, 0);
362 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_STR(0, 0), 0, NULL
, 0);
363 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, 0, NULL
, 0);
364 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, 0, NULL
, 0);
365 /* nothing fetched, STR r0, [r0] in Memory */
366 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, 0, pc
, 0);
368 /* use pc-relative LDR to clear r0[1:0] (for switch to ARM mode) */
369 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_LDR_PCREL(0), 0, NULL
, 0);
371 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, 0, NULL
, 0);
373 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, 0, NULL
, 0);
374 /* LDR in Memory (to account for interlock) */
375 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, 0, NULL
, 0);
378 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_BX(0), 0, NULL
, 0);
379 /* NOP fetched, BX in Decode, MOV in Execute */
380 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, 0, NULL
, 0);
381 /* NOP fetched, BX in Execute (1) */
382 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, 0, NULL
, 0);
384 if ((retval
= jtag_execute_queue()) != ERROR_OK
)
389 /* fix program counter:
390 * MOV r0, r15 was the 5th instruction (+8)
391 * reading PC in Thumb state gives address of instruction + 4
396 void arm9tdmi_read_core_regs(struct target
*target
,
397 uint32_t mask
, uint32_t* core_regs
[16])
400 struct arm7_9_common
*arm7_9
= target_to_arm7_9(target
);
401 struct arm_jtag
*jtag_info
= &arm7_9
->jtag_info
;
403 /* STMIA r0-15, [r0] at debug speed
404 * register values will start to appear on 4th DCLK
406 arm9tdmi_clock_out(jtag_info
, ARMV4_5_STMIA(0, mask
& 0xffff, 0, 0), 0, NULL
, 0);
408 /* fetch NOP, STM in DECODE stage */
409 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
410 /* fetch NOP, STM in EXECUTE stage (1st cycle) */
411 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
413 for (i
= 0; i
<= 15; i
++)
416 /* nothing fetched, STM in MEMORY (i'th cycle) */
417 arm9tdmi_clock_data_in(jtag_info
, core_regs
[i
]);
421 static void arm9tdmi_read_core_regs_target_buffer(struct target
*target
,
422 uint32_t mask
, void* buffer
, int size
)
425 struct arm7_9_common
*arm7_9
= target_to_arm7_9(target
);
426 struct arm_jtag
*jtag_info
= &arm7_9
->jtag_info
;
427 int be
= (target
->endianness
== TARGET_BIG_ENDIAN
) ? 1 : 0;
428 uint32_t *buf_u32
= buffer
;
429 uint16_t *buf_u16
= buffer
;
430 uint8_t *buf_u8
= buffer
;
432 /* STMIA r0-15, [r0] at debug speed
433 * register values will start to appear on 4th DCLK
435 arm9tdmi_clock_out(jtag_info
, ARMV4_5_STMIA(0, mask
& 0xffff, 0, 0), 0, NULL
, 0);
437 /* fetch NOP, STM in DECODE stage */
438 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
439 /* fetch NOP, STM in EXECUTE stage (1st cycle) */
440 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
442 for (i
= 0; i
<= 15; i
++)
445 /* nothing fetched, STM in MEMORY (i'th cycle) */
449 arm9tdmi_clock_data_in_endianness(jtag_info
, buf_u32
++, 4, be
);
452 arm9tdmi_clock_data_in_endianness(jtag_info
, buf_u16
++, 2, be
);
455 arm9tdmi_clock_data_in_endianness(jtag_info
, buf_u8
++, 1, be
);
461 static void arm9tdmi_read_xpsr(struct target
*target
, uint32_t *xpsr
, int spsr
)
463 struct arm7_9_common
*arm7_9
= target_to_arm7_9(target
);
464 struct arm_jtag
*jtag_info
= &arm7_9
->jtag_info
;
467 arm9tdmi_clock_out(jtag_info
, ARMV4_5_MRS(0, spsr
& 1), 0, NULL
, 0);
468 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 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);
474 arm9tdmi_clock_out(jtag_info
, ARMV4_5_STR(0, 15), 0, NULL
, 0);
475 /* fetch NOP, STR in DECODE stage */
476 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
477 /* fetch NOP, STR in EXECUTE stage (1st cycle) */
478 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
479 /* nothing fetched, STR in MEMORY */
480 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, xpsr
, 0);
483 static void arm9tdmi_write_xpsr(struct target
*target
, uint32_t xpsr
, int spsr
)
485 struct arm7_9_common
*arm7_9
= target_to_arm7_9(target
);
486 struct arm_jtag
*jtag_info
= &arm7_9
->jtag_info
;
488 LOG_DEBUG("xpsr: %8.8" PRIx32
", spsr: %i", xpsr
, spsr
);
491 arm9tdmi_clock_out(jtag_info
, ARMV4_5_MSR_IM(xpsr
& 0xff, 0, 1, spsr
), 0, NULL
, 0);
492 /* MSR2 fetched, MSR1 in DECODE */
493 arm9tdmi_clock_out(jtag_info
, ARMV4_5_MSR_IM((xpsr
& 0xff00) >> 8, 0xc, 2, spsr
), 0, NULL
, 0);
494 /* MSR3 fetched, MSR1 in EXECUTE (1), MSR2 in DECODE */
495 arm9tdmi_clock_out(jtag_info
, ARMV4_5_MSR_IM((xpsr
& 0xff0000) >> 16, 0x8, 4, spsr
), 0, NULL
, 0);
496 /* nothing fetched, MSR1 in EXECUTE (2) */
497 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
498 /* nothing fetched, MSR1 in EXECUTE (3) */
499 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
500 /* MSR4 fetched, MSR2 in EXECUTE (1), MSR3 in DECODE */
501 arm9tdmi_clock_out(jtag_info
, ARMV4_5_MSR_IM((xpsr
& 0xff000000) >> 24, 0x4, 8, spsr
), 0, NULL
, 0);
502 /* nothing fetched, MSR2 in EXECUTE (2) */
503 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
504 /* nothing fetched, MSR2 in EXECUTE (3) */
505 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
506 /* NOP fetched, MSR3 in EXECUTE (1), MSR4 in DECODE */
507 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
508 /* nothing fetched, MSR3 in EXECUTE (2) */
509 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
510 /* nothing fetched, MSR3 in EXECUTE (3) */
511 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
512 /* NOP fetched, MSR4 in EXECUTE (1) */
513 /* last MSR writes flags, which takes only one cycle */
514 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
517 static void arm9tdmi_write_xpsr_im8(struct target
*target
,
518 uint8_t xpsr_im
, int rot
, int spsr
)
520 struct arm7_9_common
*arm7_9
= target_to_arm7_9(target
);
521 struct arm_jtag
*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(struct target
*target
,
543 uint32_t mask
, uint32_t core_regs
[16])
546 struct arm7_9_common
*arm7_9
= target_to_arm7_9(target
);
547 struct arm_jtag
*jtag_info
= &arm7_9
->jtag_info
;
549 /* LDMIA r0-15, [r0] at debug speed
550 * register values will start to appear on 4th DCLK
552 arm9tdmi_clock_out(jtag_info
, ARMV4_5_LDMIA(0, mask
& 0xffff, 0, 0), 0, NULL
, 0);
554 /* fetch NOP, LDM in DECODE stage */
555 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
556 /* fetch NOP, LDM in EXECUTE stage (1st cycle) */
557 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
559 for (i
= 0; i
<= 15; i
++)
562 /* nothing fetched, LDM still in EXECUTE (1 + i cycle) */
563 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, core_regs
[i
], NULL
, 0);
565 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
568 void arm9tdmi_load_word_regs(struct target
*target
, uint32_t mask
)
570 struct arm7_9_common
*arm7_9
= target_to_arm7_9(target
);
571 struct arm_jtag
*jtag_info
= &arm7_9
->jtag_info
;
573 /* put system-speed load-multiple into the pipeline */
574 arm9tdmi_clock_out(jtag_info
, ARMV4_5_LDMIA(0, mask
& 0xffff, 0, 1), 0, NULL
, 0);
575 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 1);
578 void arm9tdmi_load_hword_reg(struct target
*target
, int num
)
580 struct arm7_9_common
*arm7_9
= target_to_arm7_9(target
);
581 struct arm_jtag
*jtag_info
= &arm7_9
->jtag_info
;
583 /* put system-speed load half-word into the pipeline */
584 arm9tdmi_clock_out(jtag_info
, ARMV4_5_LDRH_IP(num
, 0), 0, NULL
, 0);
585 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 1);
588 void arm9tdmi_load_byte_reg(struct target
*target
, int num
)
590 struct arm7_9_common
*arm7_9
= target_to_arm7_9(target
);
591 struct arm_jtag
*jtag_info
= &arm7_9
->jtag_info
;
593 /* put system-speed load byte into the pipeline */
594 arm9tdmi_clock_out(jtag_info
, ARMV4_5_LDRB_IP(num
, 0), 0, NULL
, 0);
595 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 1);
598 void arm9tdmi_store_word_regs(struct target
*target
, uint32_t mask
)
600 struct arm7_9_common
*arm7_9
= target_to_arm7_9(target
);
601 struct arm_jtag
*jtag_info
= &arm7_9
->jtag_info
;
603 /* put system-speed store-multiple into the pipeline */
604 arm9tdmi_clock_out(jtag_info
, ARMV4_5_STMIA(0, mask
, 0, 1), 0, NULL
, 0);
605 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 1);
608 void arm9tdmi_store_hword_reg(struct target
*target
, int num
)
610 struct arm7_9_common
*arm7_9
= target_to_arm7_9(target
);
611 struct arm_jtag
*jtag_info
= &arm7_9
->jtag_info
;
613 /* put system-speed store half-word into the pipeline */
614 arm9tdmi_clock_out(jtag_info
, ARMV4_5_STRH_IP(num
, 0), 0, NULL
, 0);
615 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 1);
618 void arm9tdmi_store_byte_reg(struct target
*target
, int num
)
620 struct arm7_9_common
*arm7_9
= target_to_arm7_9(target
);
621 struct arm_jtag
*jtag_info
= &arm7_9
->jtag_info
;
623 /* put system-speed store byte into the pipeline */
624 arm9tdmi_clock_out(jtag_info
, ARMV4_5_STRB_IP(num
, 0), 0, NULL
, 0);
625 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 1);
628 static void arm9tdmi_write_pc(struct target
*target
, uint32_t pc
)
630 struct arm7_9_common
*arm7_9
= target_to_arm7_9(target
);
631 struct arm_jtag
*jtag_info
= &arm7_9
->jtag_info
;
633 /* LDMIA r0-15, [r0] at debug speed
634 * register values will start to appear on 4th DCLK
636 arm9tdmi_clock_out(jtag_info
, ARMV4_5_LDMIA(0, 0x8000, 0, 0), 0, NULL
, 0);
638 /* fetch NOP, LDM in DECODE stage */
639 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
640 /* fetch NOP, LDM in EXECUTE stage (1st cycle) */
641 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
642 /* nothing fetched, LDM in EXECUTE stage (2nd cycle) (output data) */
643 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, pc
, NULL
, 0);
644 /* nothing fetched, LDM in EXECUTE stage (3rd cycle) */
645 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
646 /* fetch NOP, LDM in EXECUTE stage (4th cycle) */
647 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
648 /* fetch NOP, LDM in EXECUTE stage (5th cycle) */
649 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
652 void arm9tdmi_branch_resume(struct target
*target
)
654 struct arm7_9_common
*arm7_9
= target_to_arm7_9(target
);
655 struct arm_jtag
*jtag_info
= &arm7_9
->jtag_info
;
657 arm9tdmi_clock_out(jtag_info
, ARMV4_5_B(0xfffffc, 0), 0, NULL
, 0);
658 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 1);
661 static void arm9tdmi_branch_resume_thumb(struct target
*target
)
665 struct arm7_9_common
*arm7_9
= target_to_arm7_9(target
);
666 struct arm
*armv4_5
= &arm7_9
->armv4_5_common
;
667 struct arm_jtag
*jtag_info
= &arm7_9
->jtag_info
;
668 struct reg
*dbg_stat
= &arm7_9
->eice_cache
->reg_list
[EICE_DBG_STAT
];
670 /* LDMIA r0-15, [r0] at debug speed
671 * register values will start to appear on 4th DCLK
673 arm9tdmi_clock_out(jtag_info
, ARMV4_5_LDMIA(0, 0x1, 0, 0), 0, NULL
, 0);
675 /* fetch NOP, LDM in DECODE stage */
676 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
677 /* fetch NOP, LDM in EXECUTE stage (1st cycle) */
678 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
679 /* nothing fetched, LDM in EXECUTE stage (2nd cycle) */
680 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32) | 1, NULL
, 0);
681 /* nothing fetched, LDM in EXECUTE stage (3rd cycle) */
682 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
684 /* Branch and eXchange */
685 arm9tdmi_clock_out(jtag_info
, ARMV4_5_BX(0), 0, NULL
, 0);
687 embeddedice_read_reg(dbg_stat
);
689 /* fetch NOP, BX in DECODE stage */
690 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
692 embeddedice_read_reg(dbg_stat
);
694 /* fetch NOP, BX in EXECUTE stage (1st cycle) */
695 arm9tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, 0, NULL
, 0);
697 /* target is now in Thumb state */
698 embeddedice_read_reg(dbg_stat
);
700 /* load r0 value, MOV_IM in Decode*/
701 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_LDR_PCREL(0), 0, NULL
, 0);
702 /* fetch NOP, LDR in Decode, MOV_IM in Execute */
703 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, 0, NULL
, 0);
704 /* fetch NOP, LDR in Execute */
705 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, 0, NULL
, 0);
706 /* nothing fetched, LDR in EXECUTE stage (2nd cycle) */
707 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, buf_get_u32(armv4_5
->core_cache
->reg_list
[0].value
, 0, 32), NULL
, 0);
708 /* nothing fetched, LDR in EXECUTE stage (3rd cycle) */
709 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, 0, NULL
, 0);
711 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);
714 embeddedice_read_reg(dbg_stat
);
716 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_B(0x7f7), 0, NULL
, 1);
717 arm9tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, 0, NULL
, 0);
720 void arm9tdmi_enable_single_step(struct target
*target
, uint32_t next_pc
)
722 struct arm7_9_common
*arm7_9
= target_to_arm7_9(target
);
724 if (arm7_9
->has_single_step
)
726 buf_set_u32(arm7_9
->eice_cache
->reg_list
[EICE_DBG_CTRL
].value
, 3, 1, 1);
727 embeddedice_store_reg(&arm7_9
->eice_cache
->reg_list
[EICE_DBG_CTRL
]);
731 arm7_9_enable_eice_step(target
, next_pc
);
735 void arm9tdmi_disable_single_step(struct target
*target
)
737 struct arm7_9_common
*arm7_9
= target_to_arm7_9(target
);
739 if (arm7_9
->has_single_step
)
741 buf_set_u32(arm7_9
->eice_cache
->reg_list
[EICE_DBG_CTRL
].value
, 3, 1, 0);
742 embeddedice_store_reg(&arm7_9
->eice_cache
->reg_list
[EICE_DBG_CTRL
]);
746 arm7_9_disable_eice_step(target
);
750 static void arm9tdmi_build_reg_cache(struct target
*target
)
752 struct reg_cache
**cache_p
= register_get_last_cache_p(&target
->reg_cache
);
753 struct arm
*armv4_5
= target_to_arm(target
);
755 (*cache_p
) = arm_build_reg_cache(target
, armv4_5
);
758 int arm9tdmi_init_target(struct command_context
*cmd_ctx
,
759 struct target
*target
)
761 arm9tdmi_build_reg_cache(target
);
765 int arm9tdmi_init_arch_info(struct target
*target
,
766 struct arm7_9_common
*arm7_9
, struct jtag_tap
*tap
)
768 /* prepare JTAG information for the new target */
769 arm7_9
->jtag_info
.tap
= tap
;
770 arm7_9
->jtag_info
.scann_size
= 5;
772 /* register arch-specific functions */
773 arm7_9
->examine_debug_reason
= arm9tdmi_examine_debug_reason
;
774 arm7_9
->change_to_arm
= arm9tdmi_change_to_arm
;
775 arm7_9
->read_core_regs
= arm9tdmi_read_core_regs
;
776 arm7_9
->read_core_regs_target_buffer
= arm9tdmi_read_core_regs_target_buffer
;
777 arm7_9
->read_xpsr
= arm9tdmi_read_xpsr
;
779 arm7_9
->write_xpsr
= arm9tdmi_write_xpsr
;
780 arm7_9
->write_xpsr_im8
= arm9tdmi_write_xpsr_im8
;
781 arm7_9
->write_core_regs
= arm9tdmi_write_core_regs
;
783 arm7_9
->load_word_regs
= arm9tdmi_load_word_regs
;
784 arm7_9
->load_hword_reg
= arm9tdmi_load_hword_reg
;
785 arm7_9
->load_byte_reg
= arm9tdmi_load_byte_reg
;
787 arm7_9
->store_word_regs
= arm9tdmi_store_word_regs
;
788 arm7_9
->store_hword_reg
= arm9tdmi_store_hword_reg
;
789 arm7_9
->store_byte_reg
= arm9tdmi_store_byte_reg
;
791 arm7_9
->write_pc
= arm9tdmi_write_pc
;
792 arm7_9
->branch_resume
= arm9tdmi_branch_resume
;
793 arm7_9
->branch_resume_thumb
= arm9tdmi_branch_resume_thumb
;
795 arm7_9
->enable_single_step
= arm9tdmi_enable_single_step
;
796 arm7_9
->disable_single_step
= arm9tdmi_disable_single_step
;
798 arm7_9
->post_debug_entry
= NULL
;
800 arm7_9
->pre_restore_context
= NULL
;
801 arm7_9
->post_restore_context
= NULL
;
803 /* initialize arch-specific breakpoint handling */
804 arm7_9
->arm_bkpt
= 0xdeeedeee;
805 arm7_9
->thumb_bkpt
= 0xdeee;
807 arm7_9
->dbgreq_adjust_pc
= 3;
809 arm7_9_init_arch_info(target
, arm7_9
);
811 /* override use of DBGRQ, this is safe on ARM9TDMI */
812 arm7_9
->use_dbgrq
= 1;
814 /* all ARM9s have the vector catch register */
815 arm7_9
->has_vector_catch
= 1;
820 static int arm9tdmi_target_create(struct target
*target
, Jim_Interp
*interp
)
822 struct arm7_9_common
*arm7_9
= calloc(1,sizeof(struct arm7_9_common
));
824 arm9tdmi_init_arch_info(target
, arm7_9
, target
->tap
);
825 arm7_9
->armv4_5_common
.is_armv4
= true;
830 COMMAND_HANDLER(handle_arm9tdmi_catch_vectors_command
)
832 struct target
*target
= get_current_target(CMD_CTX
);
833 struct arm7_9_common
*arm7_9
= target_to_arm7_9(target
);
834 struct reg
*vector_catch
;
835 uint32_t vector_catch_value
;
837 if (!target_was_examined(target
))
839 LOG_ERROR("Target not examined yet");
843 /* it's uncommon, but some ARM7 chips can support this */
844 if (arm7_9
->common_magic
!= ARM7_9_COMMON_MAGIC
845 || !arm7_9
->has_vector_catch
) {
846 command_print(CMD_CTX
, "target doesn't have EmbeddedICE "
847 "with vector_catch");
848 return ERROR_TARGET_INVALID
;
851 vector_catch
= &arm7_9
->eice_cache
->reg_list
[EICE_VEC_CATCH
];
853 /* read the vector catch register if necessary */
854 if (!vector_catch
->valid
)
855 embeddedice_read_reg(vector_catch
);
857 /* get the current setting */
858 vector_catch_value
= buf_get_u32(vector_catch
->value
, 0, 8);
862 vector_catch_value
= 0x0;
863 if (strcmp(CMD_ARGV
[0], "all") == 0)
865 vector_catch_value
= 0xdf;
867 else if (strcmp(CMD_ARGV
[0], "none") == 0)
873 for (unsigned i
= 0; i
< CMD_ARGC
; i
++)
875 /* go through list of vectors */
877 for (j
= 0; arm9tdmi_vectors
[j
].name
; j
++)
879 if (strcmp(CMD_ARGV
[i
], arm9tdmi_vectors
[j
].name
) == 0)
881 vector_catch_value
|= arm9tdmi_vectors
[j
].value
;
886 /* complain if vector wasn't found */
887 if (!arm9tdmi_vectors
[j
].name
)
889 command_print(CMD_CTX
, "vector '%s' not found, leaving current setting unchanged", CMD_ARGV
[i
]);
891 /* reread current setting */
892 vector_catch_value
= buf_get_u32(
901 /* store new settings */
902 buf_set_u32(vector_catch
->value
, 0, 8, vector_catch_value
);
903 embeddedice_store_reg(vector_catch
);
906 /* output current settings */
907 for (unsigned i
= 0; arm9tdmi_vectors
[i
].name
; i
++) {
908 command_print(CMD_CTX
, "%s: %s", arm9tdmi_vectors
[i
].name
,
909 (vector_catch_value
& arm9tdmi_vectors
[i
].value
)
910 ? "catch" : "don't catch");
916 static const struct command_registration arm9tdmi_exec_command_handlers
[] = {
918 .name
= "vector_catch",
919 .handler
= handle_arm9tdmi_catch_vectors_command
,
920 .mode
= COMMAND_EXEC
,
921 .usage
= "[all|none|reset|undef|swi|pabt|dabt|irq|fiq] ...",
923 COMMAND_REGISTRATION_DONE
925 const struct command_registration arm9tdmi_command_handlers
[] = {
927 .chain
= arm7_9_command_handlers
,
932 .help
= "arm9tdmi command group",
933 .chain
= arm9tdmi_exec_command_handlers
,
935 COMMAND_REGISTRATION_DONE
938 /** Holds methods for ARM9TDMI targets. */
939 struct target_type arm9tdmi_target
=
944 .arch_state
= arm_arch_state
,
946 .target_request_data
= arm7_9_target_request_data
,
949 .resume
= arm7_9_resume
,
952 .assert_reset
= arm7_9_assert_reset
,
953 .deassert_reset
= arm7_9_deassert_reset
,
954 .soft_reset_halt
= arm7_9_soft_reset_halt
,
956 .get_gdb_reg_list
= arm_get_gdb_reg_list
,
958 .read_memory
= arm7_9_read_memory
,
959 .write_memory
= arm7_9_write_memory
,
960 .bulk_write_memory
= arm7_9_bulk_write_memory
,
962 .checksum_memory
= arm_checksum_memory
,
963 .blank_check_memory
= arm_blank_check_memory
,
965 .run_algorithm
= armv4_5_run_algorithm
,
967 .add_breakpoint
= arm7_9_add_breakpoint
,
968 .remove_breakpoint
= arm7_9_remove_breakpoint
,
969 .add_watchpoint
= arm7_9_add_watchpoint
,
970 .remove_watchpoint
= arm7_9_remove_watchpoint
,
972 .commands
= arm9tdmi_command_handlers
,
973 .target_create
= arm9tdmi_target_create
,
974 .init_target
= arm9tdmi_init_target
,
975 .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)