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"
33 #include "arm_opcodes.h"
37 * For information about ARM7TDMI, see ARM DDI 0210C (r4p1)
38 * or ARM DDI 0029G (r3). "Debug In Depth", Appendix B,
39 * covers JTAG support.
43 #define _DEBUG_INSTRUCTION_EXECUTION_
46 static int arm7tdmi_examine_debug_reason(struct target
*target
)
48 int retval
= ERROR_OK
;
49 struct arm7_9_common
*arm7_9
= target_to_arm7_9(target
);
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 struct scan_field fields
[2];
59 fields
[0].num_bits
= 1;
60 fields
[0].out_value
= NULL
;
61 fields
[0].in_value
= &breakpoint
;
63 fields
[1].num_bits
= 32;
64 fields
[1].out_value
= NULL
;
65 fields
[1].in_value
= databus
;
67 if ((retval
= arm_jtag_scann(&arm7_9
->jtag_info
, 0x1, TAP_DRPAUSE
)) != ERROR_OK
)
71 arm_jtag_set_instr(&arm7_9
->jtag_info
, arm7_9
->jtag_info
.intest_instr
, NULL
, TAP_DRPAUSE
);
73 jtag_add_dr_scan(arm7_9
->jtag_info
.tap
, 2, fields
, TAP_DRPAUSE
);
74 if ((retval
= jtag_execute_queue()) != ERROR_OK
)
79 fields
[0].in_value
= NULL
;
80 fields
[0].out_value
= &breakpoint
;
81 fields
[1].in_value
= NULL
;
82 fields
[1].out_value
= databus
;
84 jtag_add_dr_scan(arm7_9
->jtag_info
.tap
, 2, fields
, TAP_DRPAUSE
);
87 target
->debug_reason
= DBG_REASON_WATCHPOINT
;
89 target
->debug_reason
= DBG_REASON_BREAKPOINT
;
95 static const int arm7tdmi_num_bits
[] = {1, 32};
97 static __inline
int arm7tdmi_clock_out_inner(struct arm_jtag
*jtag_info
, uint32_t out
, int breakpoint
)
99 uint32_t values
[2]={breakpoint
, flip_u32(out
, 32)};
101 jtag_add_dr_out(jtag_info
->tap
,
107 jtag_add_runtest(0, TAP_DRPAUSE
);
112 /* put an instruction in the ARM7TDMI pipeline or write the data bus,
113 * and optionally read data
115 * FIXME remove the unused "deprecated" parameter
117 static __inline
int arm7tdmi_clock_out(struct arm_jtag
*jtag_info
,
118 uint32_t out
, uint32_t *deprecated
, int breakpoint
)
120 arm_jtag_scann(jtag_info
, 0x1, TAP_DRPAUSE
);
121 arm_jtag_set_instr(jtag_info
, jtag_info
->intest_instr
, NULL
, TAP_DRPAUSE
);
123 return arm7tdmi_clock_out_inner(jtag_info
, out
, breakpoint
);
126 /* clock the target, reading the databus */
127 static int arm7tdmi_clock_data_in(struct arm_jtag
*jtag_info
, uint32_t *in
)
129 int retval
= ERROR_OK
;
130 struct scan_field fields
[2];
132 if ((retval
= arm_jtag_scann(jtag_info
, 0x1, TAP_DRPAUSE
)) != ERROR_OK
)
136 arm_jtag_set_instr(jtag_info
, jtag_info
->intest_instr
, NULL
, TAP_DRPAUSE
);
138 fields
[0].num_bits
= 1;
139 fields
[0].out_value
= NULL
;
140 fields
[0].in_value
= NULL
;
142 fields
[1].num_bits
= 32;
143 fields
[1].out_value
= NULL
;
144 fields
[1].in_value
= (uint8_t *)in
;
146 jtag_add_dr_scan(jtag_info
->tap
, 2, fields
, TAP_DRPAUSE
);
148 jtag_add_callback(arm7flip32
, (jtag_callback_data_t
)in
);
150 jtag_add_runtest(0, TAP_DRPAUSE
);
152 #ifdef _DEBUG_INSTRUCTION_EXECUTION_
153 if ((retval
= jtag_execute_queue()) != ERROR_OK
)
157 LOG_DEBUG("in: 0x%8.8x", *in
);
159 LOG_ERROR("BUG: called with in == NULL");
165 void arm_endianness(uint8_t *tmp
, void *in
, int size
, int be
, int flip
)
167 uint32_t readback
= le_to_h_u32(tmp
);
169 readback
= flip_u32(readback
, 32);
175 h_u32_to_be(((uint8_t*)in
), readback
);
178 h_u32_to_le(((uint8_t*)in
), readback
);
184 h_u16_to_be(((uint8_t*)in
), readback
& 0xffff);
187 h_u16_to_le(((uint8_t*)in
), readback
& 0xffff);
191 *((uint8_t *)in
)= readback
& 0xff;
196 static int arm7endianness(jtag_callback_data_t arg
,
197 jtag_callback_data_t size
, jtag_callback_data_t be
,
198 jtag_callback_data_t captured
)
200 uint8_t *in
= (uint8_t *)arg
;
202 arm_endianness((uint8_t *)captured
, in
, (int)size
, (int)be
, 1);
206 /* clock the target, and read the databus
207 * the *in pointer points to a buffer where elements of 'size' bytes
208 * are stored in big (be == 1) or little (be == 0) endianness
210 static int arm7tdmi_clock_data_in_endianness(struct arm_jtag
*jtag_info
,
211 void *in
, int size
, int be
)
213 int retval
= ERROR_OK
;
214 struct scan_field fields
[2];
216 if ((retval
= arm_jtag_scann(jtag_info
, 0x1, TAP_DRPAUSE
)) != ERROR_OK
)
220 arm_jtag_set_instr(jtag_info
, jtag_info
->intest_instr
, NULL
, TAP_DRPAUSE
);
222 fields
[0].num_bits
= 1;
223 fields
[0].out_value
= NULL
;
224 fields
[0].in_value
= NULL
;
226 fields
[1].num_bits
= 32;
227 fields
[1].out_value
= NULL
;
228 jtag_alloc_in_value32(&fields
[1]);
230 jtag_add_dr_scan(jtag_info
->tap
, 2, fields
, TAP_DRPAUSE
);
232 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
);
234 jtag_add_runtest(0, TAP_DRPAUSE
);
236 #ifdef _DEBUG_INSTRUCTION_EXECUTION_
238 if ((retval
= jtag_execute_queue()) != ERROR_OK
)
245 LOG_DEBUG("in: 0x%8.8x", *(uint32_t*)in
);
249 LOG_ERROR("BUG: called with in == NULL");
257 static void arm7tdmi_change_to_arm(struct target
*target
,
258 uint32_t *r0
, uint32_t *pc
)
260 struct arm7_9_common
*arm7_9
= target_to_arm7_9(target
);
261 struct arm_jtag
*jtag_info
= &arm7_9
->jtag_info
;
263 /* save r0 before using it and put system in ARM state
264 * to allow common handling of ARM and THUMB debugging */
266 /* fetch STR r0, [r0] */
267 arm7tdmi_clock_out(jtag_info
, ARMV4_5_T_STR(0, 0), NULL
, 0);
268 arm7tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, NULL
, 0);
269 arm7tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, NULL
, 0);
270 /* nothing fetched, STR r0, [r0] in Execute (2) */
271 arm7tdmi_clock_data_in(jtag_info
, r0
);
273 /* MOV r0, r15 fetched, STR in Decode */
274 arm7tdmi_clock_out(jtag_info
, ARMV4_5_T_MOV(0, 15), NULL
, 0);
275 arm7tdmi_clock_out(jtag_info
, ARMV4_5_T_STR(0, 0), NULL
, 0);
276 arm7tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, NULL
, 0);
277 arm7tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, NULL
, 0);
278 /* nothing fetched, STR r0, [r0] in Execute (2) */
279 arm7tdmi_clock_data_in(jtag_info
, pc
);
281 /* use pc-relative LDR to clear r0[1:0] (for switch to ARM mode) */
282 arm7tdmi_clock_out(jtag_info
, ARMV4_5_T_LDR_PCREL(0), NULL
, 0);
283 arm7tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, NULL
, 0);
284 arm7tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, NULL
, 0);
285 /* nothing fetched, data for LDR r0, [PC, #0] */
286 arm7tdmi_clock_out(jtag_info
, 0x0, NULL
, 0);
287 /* nothing fetched, data from previous cycle is written to register */
288 arm7tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, NULL
, 0);
291 arm7tdmi_clock_out(jtag_info
, ARMV4_5_T_BX(0), NULL
, 0);
292 /* NOP fetched, BX in Decode, MOV in Execute */
293 arm7tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, NULL
, 0);
294 /* NOP fetched, BX in Execute (1) */
295 arm7tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, NULL
, 0);
297 jtag_execute_queue();
299 /* fix program counter:
300 * MOV r0, r15 was the 4th instruction (+6)
301 * reading PC in Thumb state gives address of instruction + 4
307 /* FIX!!! is this a potential performance bottleneck w.r.t. requiring too many
308 * roundtrips when jtag_execute_queue() has a large overhead(e.g. for USB)s?
310 * The solution is to arrange for a large out/in scan in this loop and
311 * and convert data afterwards.
313 static void arm7tdmi_read_core_regs(struct target
*target
,
314 uint32_t mask
, uint32_t* core_regs
[16])
317 struct arm7_9_common
*arm7_9
= target_to_arm7_9(target
);
318 struct arm_jtag
*jtag_info
= &arm7_9
->jtag_info
;
320 /* STMIA r0-15, [r0] at debug speed
321 * register values will start to appear on 4th DCLK
323 arm7tdmi_clock_out(jtag_info
, ARMV4_5_STMIA(0, mask
& 0xffff, 0, 0), NULL
, 0);
325 /* fetch NOP, STM in DECODE stage */
326 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
327 /* fetch NOP, STM in EXECUTE stage (1st cycle) */
328 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
330 for (i
= 0; i
<= 15; i
++)
333 /* nothing fetched, STM still in EXECUTE (1 + i cycle) */
334 arm7tdmi_clock_data_in(jtag_info
, core_regs
[i
]);
338 static void arm7tdmi_read_core_regs_target_buffer(struct target
*target
,
339 uint32_t mask
, void* buffer
, int size
)
342 struct arm7_9_common
*arm7_9
= target_to_arm7_9(target
);
343 struct arm_jtag
*jtag_info
= &arm7_9
->jtag_info
;
344 int be
= (target
->endianness
== TARGET_BIG_ENDIAN
) ? 1 : 0;
345 uint32_t *buf_u32
= buffer
;
346 uint16_t *buf_u16
= buffer
;
347 uint8_t *buf_u8
= buffer
;
349 /* STMIA r0-15, [r0] at debug speed
350 * register values will start to appear on 4th DCLK
352 arm7tdmi_clock_out(jtag_info
, ARMV4_5_STMIA(0, mask
& 0xffff, 0, 0), NULL
, 0);
354 /* fetch NOP, STM in DECODE stage */
355 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
356 /* fetch NOP, STM in EXECUTE stage (1st cycle) */
357 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
359 for (i
= 0; i
<= 15; i
++)
361 /* nothing fetched, STM still in EXECUTE (1 + i cycle), read databus */
367 arm7tdmi_clock_data_in_endianness(jtag_info
, buf_u32
++, 4, be
);
370 arm7tdmi_clock_data_in_endianness(jtag_info
, buf_u16
++, 2, be
);
373 arm7tdmi_clock_data_in_endianness(jtag_info
, buf_u8
++, 1, be
);
380 static void arm7tdmi_read_xpsr(struct target
*target
, uint32_t *xpsr
, int spsr
)
382 struct arm7_9_common
*arm7_9
= target_to_arm7_9(target
);
383 struct arm_jtag
*jtag_info
= &arm7_9
->jtag_info
;
386 arm7tdmi_clock_out(jtag_info
, ARMV4_5_MRS(0, spsr
& 1), NULL
, 0);
389 arm7tdmi_clock_out(jtag_info
, ARMV4_5_STR(0, 15), NULL
, 0);
390 /* fetch NOP, STR in DECODE stage */
391 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
392 /* fetch NOP, STR in EXECUTE stage (1st cycle) */
393 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
394 /* nothing fetched, STR still in EXECUTE (2nd cycle) */
395 arm7tdmi_clock_data_in(jtag_info
, xpsr
);
398 static void arm7tdmi_write_xpsr(struct target
*target
, uint32_t xpsr
, int spsr
)
400 struct arm7_9_common
*arm7_9
= target_to_arm7_9(target
);
401 struct arm_jtag
*jtag_info
= &arm7_9
->jtag_info
;
403 LOG_DEBUG("xpsr: %8.8" PRIx32
", spsr: %i", xpsr
, spsr
);
406 arm7tdmi_clock_out(jtag_info
, ARMV4_5_MSR_IM(xpsr
& 0xff, 0, 1, spsr
), NULL
, 0);
407 /* MSR2 fetched, MSR1 in DECODE */
408 arm7tdmi_clock_out(jtag_info
, ARMV4_5_MSR_IM((xpsr
& 0xff00) >> 8, 0xc, 2, spsr
), NULL
, 0);
409 /* MSR3 fetched, MSR1 in EXECUTE (1), MSR2 in DECODE */
410 arm7tdmi_clock_out(jtag_info
, ARMV4_5_MSR_IM((xpsr
& 0xff0000) >> 16, 0x8, 4, spsr
), NULL
, 0);
411 /* nothing fetched, MSR1 in EXECUTE (2) */
412 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
413 /* MSR4 fetched, MSR2 in EXECUTE (1), MSR3 in DECODE */
414 arm7tdmi_clock_out(jtag_info
, ARMV4_5_MSR_IM((xpsr
& 0xff000000) >> 24, 0x4, 8, spsr
), NULL
, 0);
415 /* nothing fetched, MSR2 in EXECUTE (2) */
416 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
417 /* NOP fetched, MSR3 in EXECUTE (1), MSR4 in DECODE */
418 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
419 /* nothing fetched, MSR3 in EXECUTE (2) */
420 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
421 /* NOP fetched, MSR4 in EXECUTE (1) */
422 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
423 /* nothing fetched, MSR4 in EXECUTE (2) */
424 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
427 static void arm7tdmi_write_xpsr_im8(struct target
*target
,
428 uint8_t xpsr_im
, int rot
, int spsr
)
430 struct arm7_9_common
*arm7_9
= target_to_arm7_9(target
);
431 struct arm_jtag
*jtag_info
= &arm7_9
->jtag_info
;
433 LOG_DEBUG("xpsr_im: %2.2x, rot: %i, spsr: %i", xpsr_im
, rot
, spsr
);
436 arm7tdmi_clock_out(jtag_info
, ARMV4_5_MSR_IM(xpsr_im
, rot
, 1, spsr
), NULL
, 0);
437 /* NOP fetched, MSR in DECODE */
438 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
439 /* NOP fetched, MSR in EXECUTE (1) */
440 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
441 /* nothing fetched, MSR in EXECUTE (2) */
442 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
445 static void arm7tdmi_write_core_regs(struct target
*target
,
446 uint32_t mask
, uint32_t core_regs
[16])
449 struct arm7_9_common
*arm7_9
= target_to_arm7_9(target
);
450 struct arm_jtag
*jtag_info
= &arm7_9
->jtag_info
;
452 /* LDMIA r0-15, [r0] at debug speed
453 * register values will start to appear on 4th DCLK
455 arm7tdmi_clock_out(jtag_info
, ARMV4_5_LDMIA(0, mask
& 0xffff, 0, 0), NULL
, 0);
457 /* fetch NOP, LDM in DECODE stage */
458 arm7tdmi_clock_out_inner(jtag_info
, ARMV4_5_NOP
, 0);
459 /* fetch NOP, LDM in EXECUTE stage (1st cycle) */
460 arm7tdmi_clock_out_inner(jtag_info
, ARMV4_5_NOP
, 0);
462 for (i
= 0; i
<= 15; i
++)
465 /* nothing fetched, LDM still in EXECUTE (1 + i cycle) */
466 arm7tdmi_clock_out_inner(jtag_info
, core_regs
[i
], 0);
468 arm7tdmi_clock_out_inner(jtag_info
, ARMV4_5_NOP
, 0);
471 static void arm7tdmi_load_word_regs(struct target
*target
, uint32_t mask
)
473 struct arm7_9_common
*arm7_9
= target_to_arm7_9(target
);
474 struct arm_jtag
*jtag_info
= &arm7_9
->jtag_info
;
476 /* put system-speed load-multiple into the pipeline */
477 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
478 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 1);
479 arm7tdmi_clock_out(jtag_info
, ARMV4_5_LDMIA(0, mask
& 0xffff, 0, 1), NULL
, 0);
482 static void arm7tdmi_load_hword_reg(struct target
*target
, int num
)
484 struct arm7_9_common
*arm7_9
= target_to_arm7_9(target
);
485 struct arm_jtag
*jtag_info
= &arm7_9
->jtag_info
;
487 /* put system-speed load half-word into the pipeline */
488 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
489 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 1);
490 arm7tdmi_clock_out(jtag_info
, ARMV4_5_LDRH_IP(num
, 0), NULL
, 0);
493 static void arm7tdmi_load_byte_reg(struct target
*target
, int num
)
495 struct arm7_9_common
*arm7_9
= target_to_arm7_9(target
);
496 struct arm_jtag
*jtag_info
= &arm7_9
->jtag_info
;
498 /* put system-speed load byte into the pipeline */
499 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
500 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 1);
501 arm7tdmi_clock_out(jtag_info
, ARMV4_5_LDRB_IP(num
, 0), NULL
, 0);
504 static void arm7tdmi_store_word_regs(struct target
*target
, uint32_t mask
)
506 struct arm7_9_common
*arm7_9
= target_to_arm7_9(target
);
507 struct arm_jtag
*jtag_info
= &arm7_9
->jtag_info
;
509 /* put system-speed store-multiple into the pipeline */
510 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
511 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 1);
512 arm7tdmi_clock_out(jtag_info
, ARMV4_5_STMIA(0, mask
, 0, 1), NULL
, 0);
515 static void arm7tdmi_store_hword_reg(struct target
*target
, int num
)
517 struct arm7_9_common
*arm7_9
= target_to_arm7_9(target
);
518 struct arm_jtag
*jtag_info
= &arm7_9
->jtag_info
;
520 /* put system-speed store half-word into the pipeline */
521 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
522 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 1);
523 arm7tdmi_clock_out(jtag_info
, ARMV4_5_STRH_IP(num
, 0), NULL
, 0);
526 static void arm7tdmi_store_byte_reg(struct target
*target
, int num
)
528 struct arm7_9_common
*arm7_9
= target_to_arm7_9(target
);
529 struct arm_jtag
*jtag_info
= &arm7_9
->jtag_info
;
531 /* put system-speed store byte into the pipeline */
532 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
533 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 1);
534 arm7tdmi_clock_out(jtag_info
, ARMV4_5_STRB_IP(num
, 0), NULL
, 0);
537 static void arm7tdmi_write_pc(struct target
*target
, uint32_t pc
)
539 struct arm7_9_common
*arm7_9
= target_to_arm7_9(target
);
540 struct arm_jtag
*jtag_info
= &arm7_9
->jtag_info
;
542 /* LDMIA r0-15, [r0] at debug speed
543 * register values will start to appear on 4th DCLK
545 arm7tdmi_clock_out(jtag_info
, ARMV4_5_LDMIA(0, 0x8000, 0, 0), NULL
, 0);
546 /* fetch NOP, LDM in DECODE stage */
547 arm7tdmi_clock_out_inner(jtag_info
, ARMV4_5_NOP
, 0);
548 /* fetch NOP, LDM in EXECUTE stage (1st cycle) */
549 arm7tdmi_clock_out_inner(jtag_info
, ARMV4_5_NOP
, 0);
550 /* nothing fetched, LDM in EXECUTE stage (1st cycle) load register */
551 arm7tdmi_clock_out_inner(jtag_info
, pc
, 0);
552 /* nothing fetched, LDM in EXECUTE stage (2nd cycle) load register */
553 arm7tdmi_clock_out_inner(jtag_info
, ARMV4_5_NOP
, 0);
554 /* nothing fetched, LDM in EXECUTE stage (3rd cycle) load register */
555 arm7tdmi_clock_out_inner(jtag_info
, ARMV4_5_NOP
, 0);
556 /* fetch NOP, LDM in EXECUTE stage (4th cycle) */
557 arm7tdmi_clock_out_inner(jtag_info
, ARMV4_5_NOP
, 0);
558 /* fetch NOP, LDM in EXECUTE stage (5th cycle) */
559 arm7tdmi_clock_out_inner(jtag_info
, ARMV4_5_NOP
, 0);
562 static void arm7tdmi_branch_resume(struct target
*target
)
564 struct arm7_9_common
*arm7_9
= target_to_arm7_9(target
);
565 struct arm_jtag
*jtag_info
= &arm7_9
->jtag_info
;
567 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 1);
568 arm7tdmi_clock_out_inner(jtag_info
, ARMV4_5_B(0xfffffa, 0), 0);
571 static void arm7tdmi_branch_resume_thumb(struct target
*target
)
573 struct arm7_9_common
*arm7_9
= target_to_arm7_9(target
);
574 struct arm
*armv4_5
= &arm7_9
->armv4_5_common
;
575 struct arm_jtag
*jtag_info
= &arm7_9
->jtag_info
;
576 struct reg
*dbg_stat
= &arm7_9
->eice_cache
->reg_list
[EICE_DBG_STAT
];
580 /* LDMIA r0, [r0] at debug speed
581 * register values will start to appear on 4th DCLK
583 arm7tdmi_clock_out(jtag_info
, ARMV4_5_LDMIA(0, 0x1, 0, 0), NULL
, 0);
585 /* fetch NOP, LDM in DECODE stage */
586 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
587 /* fetch NOP, LDM in EXECUTE stage (1st cycle) */
588 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
589 /* nothing fetched, LDM in EXECUTE stage (2nd cycle) */
590 arm7tdmi_clock_out(jtag_info
,
591 buf_get_u32(armv4_5
->pc
->value
, 0, 32) | 1, NULL
, 0);
592 /* nothing fetched, LDM in EXECUTE stage (3rd cycle) */
593 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
595 /* Branch and eXchange */
596 arm7tdmi_clock_out(jtag_info
, ARMV4_5_BX(0), NULL
, 0);
598 embeddedice_read_reg(dbg_stat
);
600 /* fetch NOP, BX in DECODE stage */
601 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
603 /* target is now in Thumb state */
604 embeddedice_read_reg(dbg_stat
);
606 /* fetch NOP, BX in EXECUTE stage (1st cycle) */
607 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
609 /* target is now in Thumb state */
610 embeddedice_read_reg(dbg_stat
);
613 arm7tdmi_clock_out(jtag_info
, ARMV4_5_T_LDR_PCREL(0), NULL
, 0);
614 /* fetch NOP, LDR in Decode */
615 arm7tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, NULL
, 0);
616 /* fetch NOP, LDR in Execute */
617 arm7tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, NULL
, 0);
618 /* nothing fetched, LDR in EXECUTE stage (2nd cycle) */
619 arm7tdmi_clock_out(jtag_info
, buf_get_u32(armv4_5
->core_cache
->reg_list
[0].value
, 0, 32), NULL
, 0);
620 /* nothing fetched, LDR in EXECUTE stage (3rd cycle) */
621 arm7tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, NULL
, 0);
623 arm7tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, NULL
, 0);
624 arm7tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, NULL
, 0);
626 embeddedice_read_reg(dbg_stat
);
628 arm7tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, NULL
, 1);
629 arm7tdmi_clock_out(jtag_info
, ARMV4_5_T_B(0x7f8), NULL
, 0);
632 static void arm7tdmi_build_reg_cache(struct target
*target
)
634 struct reg_cache
**cache_p
= register_get_last_cache_p(&target
->reg_cache
);
635 struct arm
*armv4_5
= target_to_arm(target
);
637 (*cache_p
) = arm_build_reg_cache(target
, armv4_5
);
640 int arm7tdmi_init_target(struct command_context
*cmd_ctx
, struct target
*target
)
642 arm7tdmi_build_reg_cache(target
);
647 int arm7tdmi_init_arch_info(struct target
*target
,
648 struct arm7_9_common
*arm7_9
, struct jtag_tap
*tap
)
650 /* prepare JTAG information for the new target */
651 arm7_9
->jtag_info
.tap
= tap
;
652 arm7_9
->jtag_info
.scann_size
= 4;
654 /* register arch-specific functions */
655 arm7_9
->examine_debug_reason
= arm7tdmi_examine_debug_reason
;
656 arm7_9
->change_to_arm
= arm7tdmi_change_to_arm
;
657 arm7_9
->read_core_regs
= arm7tdmi_read_core_regs
;
658 arm7_9
->read_core_regs_target_buffer
= arm7tdmi_read_core_regs_target_buffer
;
659 arm7_9
->read_xpsr
= arm7tdmi_read_xpsr
;
661 arm7_9
->write_xpsr
= arm7tdmi_write_xpsr
;
662 arm7_9
->write_xpsr_im8
= arm7tdmi_write_xpsr_im8
;
663 arm7_9
->write_core_regs
= arm7tdmi_write_core_regs
;
665 arm7_9
->load_word_regs
= arm7tdmi_load_word_regs
;
666 arm7_9
->load_hword_reg
= arm7tdmi_load_hword_reg
;
667 arm7_9
->load_byte_reg
= arm7tdmi_load_byte_reg
;
669 arm7_9
->store_word_regs
= arm7tdmi_store_word_regs
;
670 arm7_9
->store_hword_reg
= arm7tdmi_store_hword_reg
;
671 arm7_9
->store_byte_reg
= arm7tdmi_store_byte_reg
;
673 arm7_9
->write_pc
= arm7tdmi_write_pc
;
674 arm7_9
->branch_resume
= arm7tdmi_branch_resume
;
675 arm7_9
->branch_resume_thumb
= arm7tdmi_branch_resume_thumb
;
677 arm7_9
->enable_single_step
= arm7_9_enable_eice_step
;
678 arm7_9
->disable_single_step
= arm7_9_disable_eice_step
;
680 arm7_9
->post_debug_entry
= NULL
;
682 arm7_9
->pre_restore_context
= NULL
;
684 /* initialize arch-specific breakpoint handling */
685 arm7_9
->arm_bkpt
= 0xdeeedeee;
686 arm7_9
->thumb_bkpt
= 0xdeee;
688 arm7_9
->dbgreq_adjust_pc
= 2;
690 arm7_9_init_arch_info(target
, arm7_9
);
695 static int arm7tdmi_target_create(struct target
*target
, Jim_Interp
*interp
)
697 struct arm7_9_common
*arm7_9
;
699 arm7_9
= calloc(1,sizeof(struct arm7_9_common
));
700 arm7tdmi_init_arch_info(target
, arm7_9
, target
->tap
);
701 arm7_9
->armv4_5_common
.is_armv4
= true;
706 /** Holds methods for ARM7TDMI targets. */
707 struct target_type arm7tdmi_target
=
712 .arch_state
= arm_arch_state
,
714 .target_request_data
= arm7_9_target_request_data
,
717 .resume
= arm7_9_resume
,
720 .assert_reset
= arm7_9_assert_reset
,
721 .deassert_reset
= arm7_9_deassert_reset
,
722 .soft_reset_halt
= arm7_9_soft_reset_halt
,
724 .get_gdb_reg_list
= arm_get_gdb_reg_list
,
726 .read_memory
= arm7_9_read_memory
,
727 .write_memory
= arm7_9_write_memory
,
728 .bulk_write_memory
= arm7_9_bulk_write_memory
,
730 .checksum_memory
= arm_checksum_memory
,
731 .blank_check_memory
= arm_blank_check_memory
,
733 .run_algorithm
= armv4_5_run_algorithm
,
735 .add_breakpoint
= arm7_9_add_breakpoint
,
736 .remove_breakpoint
= arm7_9_remove_breakpoint
,
737 .add_watchpoint
= arm7_9_add_watchpoint
,
738 .remove_watchpoint
= arm7_9_remove_watchpoint
,
740 .commands
= arm7_9_command_handlers
,
741 .target_create
= arm7tdmi_target_create
,
742 .init_target
= arm7tdmi_init_target
,
743 .examine
= arm7_9_examine
,
744 .check_reset
= arm7_9_check_reset
,
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)