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) 2007,2008 Øyvind Harboe *
9 * oyvind.harboe@zylin.com *
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 * For information about ARM7TDMI, see ARM DDI 0210C (r4p1)
36 * or ARM DDI 0029G (r3). "Debug In Depth", Appendix B,
37 * covers JTAG support.
41 #define _DEBUG_INSTRUCTION_EXECUTION_
44 static int arm7tdmi_examine_debug_reason(target_t
*target
)
46 int retval
= ERROR_OK
;
47 /* get pointers to arch-specific information */
48 armv4_5_common_t
*armv4_5
= target
->arch_info
;
49 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
51 /* only check the debug reason if we don't know it already */
52 if ((target
->debug_reason
!= DBG_REASON_DBGRQ
)
53 && (target
->debug_reason
!= DBG_REASON_SINGLESTEP
))
55 scan_field_t fields
[2];
59 jtag_set_end_state(TAP_DRPAUSE
);
61 fields
[0].tap
= arm7_9
->jtag_info
.tap
;
62 fields
[0].num_bits
= 1;
63 fields
[0].out_value
= NULL
;
64 fields
[0].in_value
= &breakpoint
;
66 fields
[1].tap
= arm7_9
->jtag_info
.tap
;
67 fields
[1].num_bits
= 32;
68 fields
[1].out_value
= NULL
;
69 fields
[1].in_value
= databus
;
71 if ((retval
= arm_jtag_scann(&arm7_9
->jtag_info
, 0x1)) != ERROR_OK
)
75 arm_jtag_set_instr(&arm7_9
->jtag_info
, arm7_9
->jtag_info
.intest_instr
, NULL
);
77 jtag_add_dr_scan(2, fields
, jtag_set_end_state(TAP_DRPAUSE
));
78 if ((retval
= jtag_execute_queue()) != ERROR_OK
)
83 fields
[0].in_value
= NULL
;
84 fields
[0].out_value
= &breakpoint
;
85 fields
[1].in_value
= NULL
;
86 fields
[1].out_value
= databus
;
88 jtag_add_dr_scan(2, fields
, jtag_set_end_state(TAP_DRPAUSE
));
91 target
->debug_reason
= DBG_REASON_WATCHPOINT
;
93 target
->debug_reason
= DBG_REASON_BREAKPOINT
;
99 static const int arm7tdmi_num_bits
[] = {1, 32};
101 static __inline
int arm7tdmi_clock_out_inner(arm_jtag_t
*jtag_info
, uint32_t out
, int breakpoint
)
103 uint32_t values
[2]={breakpoint
, flip_u32(out
, 32)};
105 jtag_add_dr_out(jtag_info
->tap
,
109 jtag_get_end_state());
111 jtag_add_runtest(0, jtag_get_end_state());
116 /* put an instruction in the ARM7TDMI pipeline or write the data bus,
117 * and optionally read data
119 * FIXME remove the unused "deprecated" parameter
121 static __inline
int arm7tdmi_clock_out(arm_jtag_t
*jtag_info
,
122 uint32_t out
, uint32_t *deprecated
, int breakpoint
)
124 jtag_set_end_state(TAP_DRPAUSE
);
125 arm_jtag_scann(jtag_info
, 0x1);
126 arm_jtag_set_instr(jtag_info
, jtag_info
->intest_instr
, NULL
);
128 return arm7tdmi_clock_out_inner(jtag_info
, out
, breakpoint
);
131 /* clock the target, reading the databus */
132 static int arm7tdmi_clock_data_in(arm_jtag_t
*jtag_info
, uint32_t *in
)
134 int retval
= ERROR_OK
;
135 scan_field_t fields
[2];
137 jtag_set_end_state(TAP_DRPAUSE
);
138 if ((retval
= arm_jtag_scann(jtag_info
, 0x1)) != ERROR_OK
)
142 arm_jtag_set_instr(jtag_info
, jtag_info
->intest_instr
, NULL
);
144 fields
[0].tap
= jtag_info
->tap
;
145 fields
[0].num_bits
= 1;
146 fields
[0].out_value
= NULL
;
147 fields
[0].in_value
= NULL
;
149 fields
[1].tap
= jtag_info
->tap
;
150 fields
[1].num_bits
= 32;
151 fields
[1].out_value
= NULL
;
152 fields
[1].in_value
= (uint8_t *)in
;
154 jtag_add_dr_scan(2, fields
, jtag_get_end_state());
156 jtag_add_callback(arm7flip32
, (jtag_callback_data_t
)in
);
158 jtag_add_runtest(0, jtag_get_end_state());
160 #ifdef _DEBUG_INSTRUCTION_EXECUTION_
161 if ((retval
= jtag_execute_queue()) != ERROR_OK
)
165 LOG_DEBUG("in: 0x%8.8x", *in
);
167 LOG_ERROR("BUG: called with in == NULL");
173 void arm_endianness(uint8_t *tmp
, void *in
, int size
, int be
, int flip
)
175 uint32_t readback
= le_to_h_u32(tmp
);
177 readback
= flip_u32(readback
, 32);
183 h_u32_to_be(((uint8_t*)in
), readback
);
186 h_u32_to_le(((uint8_t*)in
), readback
);
192 h_u16_to_be(((uint8_t*)in
), readback
& 0xffff);
195 h_u16_to_le(((uint8_t*)in
), readback
& 0xffff);
199 *((uint8_t *)in
)= readback
& 0xff;
204 static int arm7endianness(jtag_callback_data_t arg
,
205 jtag_callback_data_t size
, jtag_callback_data_t be
,
206 jtag_callback_data_t captured
)
208 uint8_t *in
= (uint8_t *)arg
;
210 arm_endianness((uint8_t *)captured
, in
, (int)size
, (int)be
, 1);
214 /* clock the target, and read the databus
215 * the *in pointer points to a buffer where elements of 'size' bytes
216 * are stored in big (be == 1) or little (be == 0) endianness
218 static int arm7tdmi_clock_data_in_endianness(arm_jtag_t
*jtag_info
,
219 void *in
, int size
, int be
)
221 int retval
= ERROR_OK
;
222 scan_field_t fields
[2];
224 jtag_set_end_state(TAP_DRPAUSE
);
225 if ((retval
= arm_jtag_scann(jtag_info
, 0x1)) != ERROR_OK
)
229 arm_jtag_set_instr(jtag_info
, jtag_info
->intest_instr
, NULL
);
231 fields
[0].tap
= jtag_info
->tap
;
232 fields
[0].num_bits
= 1;
233 fields
[0].out_value
= NULL
;
234 fields
[0].in_value
= NULL
;
236 fields
[1].tap
= jtag_info
->tap
;
237 fields
[1].num_bits
= 32;
238 fields
[1].out_value
= NULL
;
239 jtag_alloc_in_value32(&fields
[1]);
241 jtag_add_dr_scan(2, fields
, jtag_get_end_state());
243 jtag_add_callback4(arm7endianness
, (jtag_callback_data_t
)in
, (jtag_callback_data_t
)size
, (jtag_callback_data_t
)be
, (jtag_callback_data_t
)fields
[1].in_value
);
245 jtag_add_runtest(0, jtag_get_end_state());
247 #ifdef _DEBUG_INSTRUCTION_EXECUTION_
249 if ((retval
= jtag_execute_queue()) != ERROR_OK
)
256 LOG_DEBUG("in: 0x%8.8x", *(uint32_t*)in
);
260 LOG_ERROR("BUG: called with in == NULL");
268 static void arm7tdmi_change_to_arm(target_t
*target
,
269 uint32_t *r0
, uint32_t *pc
)
271 /* get pointers to arch-specific information */
272 armv4_5_common_t
*armv4_5
= target
->arch_info
;
273 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
274 arm_jtag_t
*jtag_info
= &arm7_9
->jtag_info
;
276 /* save r0 before using it and put system in ARM state
277 * to allow common handling of ARM and THUMB debugging */
279 /* fetch STR r0, [r0] */
280 arm7tdmi_clock_out(jtag_info
, ARMV4_5_T_STR(0, 0), NULL
, 0);
281 arm7tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, NULL
, 0);
282 arm7tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, NULL
, 0);
283 /* nothing fetched, STR r0, [r0] in Execute (2) */
284 arm7tdmi_clock_data_in(jtag_info
, r0
);
286 /* MOV r0, r15 fetched, STR in Decode */
287 arm7tdmi_clock_out(jtag_info
, ARMV4_5_T_MOV(0, 15), NULL
, 0);
288 arm7tdmi_clock_out(jtag_info
, ARMV4_5_T_STR(0, 0), NULL
, 0);
289 arm7tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, NULL
, 0);
290 arm7tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, NULL
, 0);
291 /* nothing fetched, STR r0, [r0] in Execute (2) */
292 arm7tdmi_clock_data_in(jtag_info
, pc
);
294 /* use pc-relative LDR to clear r0[1:0] (for switch to ARM mode) */
295 arm7tdmi_clock_out(jtag_info
, ARMV4_5_T_LDR_PCREL(0), NULL
, 0);
296 arm7tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, NULL
, 0);
297 arm7tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, NULL
, 0);
298 /* nothing fetched, data for LDR r0, [PC, #0] */
299 arm7tdmi_clock_out(jtag_info
, 0x0, NULL
, 0);
300 /* nothing fetched, data from previous cycle is written to register */
301 arm7tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, NULL
, 0);
304 arm7tdmi_clock_out(jtag_info
, ARMV4_5_T_BX(0), NULL
, 0);
305 /* NOP fetched, BX in Decode, MOV in Execute */
306 arm7tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, NULL
, 0);
307 /* NOP fetched, BX in Execute (1) */
308 arm7tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, NULL
, 0);
310 jtag_execute_queue();
312 /* fix program counter:
313 * MOV r0, r15 was the 4th instruction (+6)
314 * reading PC in Thumb state gives address of instruction + 4
320 /* FIX!!! is this a potential performance bottleneck w.r.t. requiring too many
321 * roundtrips when jtag_execute_queue() has a large overhead(e.g. for USB)s?
323 * The solution is to arrange for a large out/in scan in this loop and
324 * and convert data afterwards.
326 static void arm7tdmi_read_core_regs(target_t
*target
,
327 uint32_t mask
, uint32_t* core_regs
[16])
330 /* get pointers to arch-specific information */
331 armv4_5_common_t
*armv4_5
= target
->arch_info
;
332 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
333 arm_jtag_t
*jtag_info
= &arm7_9
->jtag_info
;
335 /* STMIA r0-15, [r0] at debug speed
336 * register values will start to appear on 4th DCLK
338 arm7tdmi_clock_out(jtag_info
, ARMV4_5_STMIA(0, mask
& 0xffff, 0, 0), NULL
, 0);
340 /* fetch NOP, STM in DECODE stage */
341 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
342 /* fetch NOP, STM in EXECUTE stage (1st cycle) */
343 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
345 for (i
= 0; i
<= 15; i
++)
348 /* nothing fetched, STM still in EXECUTE (1 + i cycle) */
349 arm7tdmi_clock_data_in(jtag_info
, core_regs
[i
]);
353 static void arm7tdmi_read_core_regs_target_buffer(target_t
*target
,
354 uint32_t mask
, void* buffer
, int size
)
357 /* get pointers to arch-specific information */
358 armv4_5_common_t
*armv4_5
= target
->arch_info
;
359 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
360 arm_jtag_t
*jtag_info
= &arm7_9
->jtag_info
;
361 int be
= (target
->endianness
== TARGET_BIG_ENDIAN
) ? 1 : 0;
362 uint32_t *buf_u32
= buffer
;
363 uint16_t *buf_u16
= buffer
;
364 uint8_t *buf_u8
= buffer
;
366 /* STMIA r0-15, [r0] at debug speed
367 * register values will start to appear on 4th DCLK
369 arm7tdmi_clock_out(jtag_info
, ARMV4_5_STMIA(0, mask
& 0xffff, 0, 0), NULL
, 0);
371 /* fetch NOP, STM in DECODE stage */
372 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
373 /* fetch NOP, STM in EXECUTE stage (1st cycle) */
374 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
376 for (i
= 0; i
<= 15; i
++)
378 /* nothing fetched, STM still in EXECUTE (1 + i cycle), read databus */
384 arm7tdmi_clock_data_in_endianness(jtag_info
, buf_u32
++, 4, be
);
387 arm7tdmi_clock_data_in_endianness(jtag_info
, buf_u16
++, 2, be
);
390 arm7tdmi_clock_data_in_endianness(jtag_info
, buf_u8
++, 1, be
);
397 static void arm7tdmi_read_xpsr(target_t
*target
, uint32_t *xpsr
, int spsr
)
399 /* get pointers to arch-specific information */
400 armv4_5_common_t
*armv4_5
= target
->arch_info
;
401 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
402 arm_jtag_t
*jtag_info
= &arm7_9
->jtag_info
;
405 arm7tdmi_clock_out(jtag_info
, ARMV4_5_MRS(0, spsr
& 1), NULL
, 0);
408 arm7tdmi_clock_out(jtag_info
, ARMV4_5_STR(0, 15), NULL
, 0);
409 /* fetch NOP, STR in DECODE stage */
410 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
411 /* fetch NOP, STR in EXECUTE stage (1st cycle) */
412 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
413 /* nothing fetched, STR still in EXECUTE (2nd cycle) */
414 arm7tdmi_clock_data_in(jtag_info
, xpsr
);
417 static void arm7tdmi_write_xpsr(target_t
*target
, uint32_t xpsr
, int spsr
)
419 /* get pointers to arch-specific information */
420 armv4_5_common_t
*armv4_5
= target
->arch_info
;
421 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
422 arm_jtag_t
*jtag_info
= &arm7_9
->jtag_info
;
424 LOG_DEBUG("xpsr: %8.8" PRIx32
", spsr: %i", xpsr
, spsr
);
427 arm7tdmi_clock_out(jtag_info
, ARMV4_5_MSR_IM(xpsr
& 0xff, 0, 1, spsr
), NULL
, 0);
428 /* MSR2 fetched, MSR1 in DECODE */
429 arm7tdmi_clock_out(jtag_info
, ARMV4_5_MSR_IM((xpsr
& 0xff00) >> 8, 0xc, 2, spsr
), NULL
, 0);
430 /* MSR3 fetched, MSR1 in EXECUTE (1), MSR2 in DECODE */
431 arm7tdmi_clock_out(jtag_info
, ARMV4_5_MSR_IM((xpsr
& 0xff0000) >> 16, 0x8, 4, spsr
), NULL
, 0);
432 /* nothing fetched, MSR1 in EXECUTE (2) */
433 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
434 /* MSR4 fetched, MSR2 in EXECUTE (1), MSR3 in DECODE */
435 arm7tdmi_clock_out(jtag_info
, ARMV4_5_MSR_IM((xpsr
& 0xff000000) >> 24, 0x4, 8, spsr
), NULL
, 0);
436 /* nothing fetched, MSR2 in EXECUTE (2) */
437 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
438 /* NOP fetched, MSR3 in EXECUTE (1), MSR4 in DECODE */
439 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
440 /* nothing fetched, MSR3 in EXECUTE (2) */
441 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
442 /* NOP fetched, MSR4 in EXECUTE (1) */
443 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
444 /* nothing fetched, MSR4 in EXECUTE (2) */
445 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
448 static void arm7tdmi_write_xpsr_im8(target_t
*target
,
449 uint8_t xpsr_im
, int rot
, int spsr
)
451 /* get pointers to arch-specific information */
452 armv4_5_common_t
*armv4_5
= target
->arch_info
;
453 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
454 arm_jtag_t
*jtag_info
= &arm7_9
->jtag_info
;
456 LOG_DEBUG("xpsr_im: %2.2x, rot: %i, spsr: %i", xpsr_im
, rot
, spsr
);
459 arm7tdmi_clock_out(jtag_info
, ARMV4_5_MSR_IM(xpsr_im
, rot
, 1, spsr
), NULL
, 0);
460 /* NOP fetched, MSR in DECODE */
461 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
462 /* NOP fetched, MSR in EXECUTE (1) */
463 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
464 /* nothing fetched, MSR in EXECUTE (2) */
465 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
468 static void arm7tdmi_write_core_regs(target_t
*target
,
469 uint32_t mask
, uint32_t core_regs
[16])
472 /* get pointers to arch-specific information */
473 armv4_5_common_t
*armv4_5
= target
->arch_info
;
474 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
475 arm_jtag_t
*jtag_info
= &arm7_9
->jtag_info
;
477 /* LDMIA r0-15, [r0] at debug speed
478 * register values will start to appear on 4th DCLK
480 arm7tdmi_clock_out(jtag_info
, ARMV4_5_LDMIA(0, mask
& 0xffff, 0, 0), NULL
, 0);
482 /* fetch NOP, LDM in DECODE stage */
483 arm7tdmi_clock_out_inner(jtag_info
, ARMV4_5_NOP
, 0);
484 /* fetch NOP, LDM in EXECUTE stage (1st cycle) */
485 arm7tdmi_clock_out_inner(jtag_info
, ARMV4_5_NOP
, 0);
487 for (i
= 0; i
<= 15; i
++)
490 /* nothing fetched, LDM still in EXECUTE (1 + i cycle) */
491 arm7tdmi_clock_out_inner(jtag_info
, core_regs
[i
], 0);
493 arm7tdmi_clock_out_inner(jtag_info
, ARMV4_5_NOP
, 0);
496 static void arm7tdmi_load_word_regs(target_t
*target
, uint32_t mask
)
498 /* get pointers to arch-specific information */
499 armv4_5_common_t
*armv4_5
= target
->arch_info
;
500 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
501 arm_jtag_t
*jtag_info
= &arm7_9
->jtag_info
;
503 /* put system-speed load-multiple into the pipeline */
504 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
505 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 1);
506 arm7tdmi_clock_out(jtag_info
, ARMV4_5_LDMIA(0, mask
& 0xffff, 0, 1), NULL
, 0);
509 static void arm7tdmi_load_hword_reg(target_t
*target
, int num
)
511 /* get pointers to arch-specific information */
512 armv4_5_common_t
*armv4_5
= target
->arch_info
;
513 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
514 arm_jtag_t
*jtag_info
= &arm7_9
->jtag_info
;
516 /* put system-speed load half-word into the pipeline */
517 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
518 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 1);
519 arm7tdmi_clock_out(jtag_info
, ARMV4_5_LDRH_IP(num
, 0), NULL
, 0);
522 static void arm7tdmi_load_byte_reg(target_t
*target
, int num
)
524 /* get pointers to arch-specific information */
525 armv4_5_common_t
*armv4_5
= target
->arch_info
;
526 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
527 arm_jtag_t
*jtag_info
= &arm7_9
->jtag_info
;
529 /* put system-speed load byte into the pipeline */
530 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
531 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 1);
532 arm7tdmi_clock_out(jtag_info
, ARMV4_5_LDRB_IP(num
, 0), NULL
, 0);
535 static void arm7tdmi_store_word_regs(target_t
*target
, uint32_t mask
)
537 /* get pointers to arch-specific information */
538 armv4_5_common_t
*armv4_5
= target
->arch_info
;
539 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
540 arm_jtag_t
*jtag_info
= &arm7_9
->jtag_info
;
542 /* put system-speed store-multiple into the pipeline */
543 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
544 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 1);
545 arm7tdmi_clock_out(jtag_info
, ARMV4_5_STMIA(0, mask
, 0, 1), NULL
, 0);
548 static void arm7tdmi_store_hword_reg(target_t
*target
, int num
)
550 /* get pointers to arch-specific information */
551 armv4_5_common_t
*armv4_5
= target
->arch_info
;
552 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
553 arm_jtag_t
*jtag_info
= &arm7_9
->jtag_info
;
555 /* put system-speed store half-word into the pipeline */
556 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
557 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 1);
558 arm7tdmi_clock_out(jtag_info
, ARMV4_5_STRH_IP(num
, 0), NULL
, 0);
561 static void arm7tdmi_store_byte_reg(target_t
*target
, int num
)
563 /* get pointers to arch-specific information */
564 armv4_5_common_t
*armv4_5
= target
->arch_info
;
565 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
566 arm_jtag_t
*jtag_info
= &arm7_9
->jtag_info
;
568 /* put system-speed store byte into the pipeline */
569 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
570 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 1);
571 arm7tdmi_clock_out(jtag_info
, ARMV4_5_STRB_IP(num
, 0), NULL
, 0);
574 static void arm7tdmi_write_pc(target_t
*target
, uint32_t pc
)
576 /* get pointers to arch-specific information */
577 armv4_5_common_t
*armv4_5
= target
->arch_info
;
578 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
579 arm_jtag_t
*jtag_info
= &arm7_9
->jtag_info
;
581 /* LDMIA r0-15, [r0] at debug speed
582 * register values will start to appear on 4th DCLK
584 arm7tdmi_clock_out(jtag_info
, ARMV4_5_LDMIA(0, 0x8000, 0, 0), NULL
, 0);
585 /* fetch NOP, LDM in DECODE stage */
586 arm7tdmi_clock_out_inner(jtag_info
, ARMV4_5_NOP
, 0);
587 /* fetch NOP, LDM in EXECUTE stage (1st cycle) */
588 arm7tdmi_clock_out_inner(jtag_info
, ARMV4_5_NOP
, 0);
589 /* nothing fetched, LDM in EXECUTE stage (1st cycle) load register */
590 arm7tdmi_clock_out_inner(jtag_info
, pc
, 0);
591 /* nothing fetched, LDM in EXECUTE stage (2nd cycle) load register */
592 arm7tdmi_clock_out_inner(jtag_info
, ARMV4_5_NOP
, 0);
593 /* nothing fetched, LDM in EXECUTE stage (3rd cycle) load register */
594 arm7tdmi_clock_out_inner(jtag_info
, ARMV4_5_NOP
, 0);
595 /* fetch NOP, LDM in EXECUTE stage (4th cycle) */
596 arm7tdmi_clock_out_inner(jtag_info
, ARMV4_5_NOP
, 0);
597 /* fetch NOP, LDM in EXECUTE stage (5th cycle) */
598 arm7tdmi_clock_out_inner(jtag_info
, ARMV4_5_NOP
, 0);
601 static void arm7tdmi_branch_resume(target_t
*target
)
603 /* get pointers to arch-specific information */
604 armv4_5_common_t
*armv4_5
= target
->arch_info
;
605 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
606 arm_jtag_t
*jtag_info
= &arm7_9
->jtag_info
;
608 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 1);
609 arm7tdmi_clock_out_inner(jtag_info
, ARMV4_5_B(0xfffffa, 0), 0);
612 static void arm7tdmi_branch_resume_thumb(target_t
*target
)
616 /* get pointers to arch-specific information */
617 armv4_5_common_t
*armv4_5
= target
->arch_info
;
618 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
619 arm_jtag_t
*jtag_info
= &arm7_9
->jtag_info
;
620 reg_t
*dbg_stat
= &arm7_9
->eice_cache
->reg_list
[EICE_DBG_STAT
];
622 /* LDMIA r0, [r0] at debug speed
623 * register values will start to appear on 4th DCLK
625 arm7tdmi_clock_out(jtag_info
, ARMV4_5_LDMIA(0, 0x1, 0, 0), NULL
, 0);
627 /* fetch NOP, LDM in DECODE stage */
628 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
629 /* fetch NOP, LDM in EXECUTE stage (1st cycle) */
630 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
631 /* nothing fetched, LDM in EXECUTE stage (2nd cycle) */
632 arm7tdmi_clock_out(jtag_info
, buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32) | 1, NULL
, 0);
633 /* nothing fetched, LDM in EXECUTE stage (3rd cycle) */
634 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
636 /* Branch and eXchange */
637 arm7tdmi_clock_out(jtag_info
, ARMV4_5_BX(0), NULL
, 0);
639 embeddedice_read_reg(dbg_stat
);
641 /* fetch NOP, BX in DECODE stage */
642 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
644 /* target is now in Thumb state */
645 embeddedice_read_reg(dbg_stat
);
647 /* fetch NOP, BX in EXECUTE stage (1st cycle) */
648 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
650 /* target is now in Thumb state */
651 embeddedice_read_reg(dbg_stat
);
654 arm7tdmi_clock_out(jtag_info
, ARMV4_5_T_LDR_PCREL(0), NULL
, 0);
655 /* fetch NOP, LDR in Decode */
656 arm7tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, NULL
, 0);
657 /* fetch NOP, LDR in Execute */
658 arm7tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, NULL
, 0);
659 /* nothing fetched, LDR in EXECUTE stage (2nd cycle) */
660 arm7tdmi_clock_out(jtag_info
, buf_get_u32(armv4_5
->core_cache
->reg_list
[0].value
, 0, 32), NULL
, 0);
661 /* nothing fetched, LDR in EXECUTE stage (3rd cycle) */
662 arm7tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, NULL
, 0);
664 arm7tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, NULL
, 0);
665 arm7tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, NULL
, 0);
667 embeddedice_read_reg(dbg_stat
);
669 arm7tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, NULL
, 1);
670 arm7tdmi_clock_out(jtag_info
, ARMV4_5_T_B(0x7f8), NULL
, 0);
673 static void arm7tdmi_build_reg_cache(target_t
*target
)
675 reg_cache_t
**cache_p
= register_get_last_cache_p(&target
->reg_cache
);
676 /* get pointers to arch-specific information */
677 armv4_5_common_t
*armv4_5
= target
->arch_info
;
679 (*cache_p
) = armv4_5_build_reg_cache(target
, armv4_5
);
680 armv4_5
->core_cache
= (*cache_p
);
683 int arm7tdmi_examine(struct target_s
*target
)
686 armv4_5_common_t
*armv4_5
= target
->arch_info
;
687 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
688 if (!target_was_examined(target
))
690 /* get pointers to arch-specific information */
691 reg_cache_t
**cache_p
= register_get_last_cache_p(&target
->reg_cache
);
692 reg_cache_t
*t
= embeddedice_build_reg_cache(target
, arm7_9
);
697 arm7_9
->eice_cache
= (*cache_p
);
701 arm_jtag_t
*jtag_info
= &arm7_9
->jtag_info
;
702 (*cache_p
)->next
= etm_build_reg_cache(target
, jtag_info
, arm7_9
->etm_ctx
);
703 arm7_9
->etm_ctx
->reg_cache
= (*cache_p
)->next
;
705 target_set_examined(target
);
707 if ((retval
= embeddedice_setup(target
)) != ERROR_OK
)
709 if ((retval
= arm7_9_setup(target
)) != ERROR_OK
)
713 if ((retval
= etm_setup(target
)) != ERROR_OK
)
719 int arm7tdmi_init_target(struct command_context_s
*cmd_ctx
, struct target_s
*target
)
721 arm7tdmi_build_reg_cache(target
);
726 int arm7tdmi_init_arch_info(target_t
*target
, arm7tdmi_common_t
*arm7tdmi
, jtag_tap_t
*tap
)
728 armv4_5_common_t
*armv4_5
;
729 arm7_9_common_t
*arm7_9
;
731 arm7_9
= &arm7tdmi
->arm7_9_common
;
732 armv4_5
= &arm7_9
->armv4_5_common
;
734 /* prepare JTAG information for the new target */
735 arm7_9
->jtag_info
.tap
= tap
;
736 arm7_9
->jtag_info
.scann_size
= 4;
738 /* register arch-specific functions */
739 arm7_9
->examine_debug_reason
= arm7tdmi_examine_debug_reason
;
740 arm7_9
->change_to_arm
= arm7tdmi_change_to_arm
;
741 arm7_9
->read_core_regs
= arm7tdmi_read_core_regs
;
742 arm7_9
->read_core_regs_target_buffer
= arm7tdmi_read_core_regs_target_buffer
;
743 arm7_9
->read_xpsr
= arm7tdmi_read_xpsr
;
745 arm7_9
->write_xpsr
= arm7tdmi_write_xpsr
;
746 arm7_9
->write_xpsr_im8
= arm7tdmi_write_xpsr_im8
;
747 arm7_9
->write_core_regs
= arm7tdmi_write_core_regs
;
749 arm7_9
->load_word_regs
= arm7tdmi_load_word_regs
;
750 arm7_9
->load_hword_reg
= arm7tdmi_load_hword_reg
;
751 arm7_9
->load_byte_reg
= arm7tdmi_load_byte_reg
;
753 arm7_9
->store_word_regs
= arm7tdmi_store_word_regs
;
754 arm7_9
->store_hword_reg
= arm7tdmi_store_hword_reg
;
755 arm7_9
->store_byte_reg
= arm7tdmi_store_byte_reg
;
757 arm7_9
->write_pc
= arm7tdmi_write_pc
;
758 arm7_9
->branch_resume
= arm7tdmi_branch_resume
;
759 arm7_9
->branch_resume_thumb
= arm7tdmi_branch_resume_thumb
;
761 arm7_9
->enable_single_step
= arm7_9_enable_eice_step
;
762 arm7_9
->disable_single_step
= arm7_9_disable_eice_step
;
764 arm7_9
->post_debug_entry
= NULL
;
766 arm7_9
->pre_restore_context
= NULL
;
767 arm7_9
->post_restore_context
= NULL
;
769 /* initialize arch-specific breakpoint handling */
770 arm7_9
->arm_bkpt
= 0xdeeedeee;
771 arm7_9
->thumb_bkpt
= 0xdeee;
773 arm7_9
->dbgreq_adjust_pc
= 2;
774 arm7_9
->arch_info
= arm7tdmi
;
776 arm7tdmi
->arch_info
= NULL
;
777 arm7tdmi
->common_magic
= ARM7TDMI_COMMON_MAGIC
;
779 arm7_9_init_arch_info(target
, arm7_9
);
784 static int arm7tdmi_target_create(struct target_s
*target
, Jim_Interp
*interp
)
786 arm7tdmi_common_t
*arm7tdmi
;
788 arm7tdmi
= calloc(1,sizeof(arm7tdmi_common_t
));
789 arm7tdmi_init_arch_info(target
, arm7tdmi
, target
->tap
);
790 arm7tdmi
->arm7_9_common
.armv4_5_common
.is_armv4
= true;
795 /** Holds methods for ARM7TDMI targets. */
796 target_type_t arm7tdmi_target
=
801 .arch_state
= armv4_5_arch_state
,
803 .target_request_data
= arm7_9_target_request_data
,
806 .resume
= arm7_9_resume
,
809 .assert_reset
= arm7_9_assert_reset
,
810 .deassert_reset
= arm7_9_deassert_reset
,
811 .soft_reset_halt
= arm7_9_soft_reset_halt
,
813 .get_gdb_reg_list
= armv4_5_get_gdb_reg_list
,
815 .read_memory
= arm7_9_read_memory
,
816 .write_memory
= arm7_9_write_memory
,
817 .bulk_write_memory
= arm7_9_bulk_write_memory
,
818 .checksum_memory
= arm7_9_checksum_memory
,
819 .blank_check_memory
= arm7_9_blank_check_memory
,
821 .run_algorithm
= armv4_5_run_algorithm
,
823 .add_breakpoint
= arm7_9_add_breakpoint
,
824 .remove_breakpoint
= arm7_9_remove_breakpoint
,
825 .add_watchpoint
= arm7_9_add_watchpoint
,
826 .remove_watchpoint
= arm7_9_remove_watchpoint
,
828 .register_commands
= arm7_9_register_commands
,
829 .target_create
= arm7tdmi_target_create
,
830 .init_target
= arm7tdmi_init_target
,
831 .examine
= arm7tdmi_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)