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 jtag_set_end_state(TAP_DRPAUSE
);
61 fields
[0].num_bits
= 1;
62 fields
[0].out_value
= NULL
;
63 fields
[0].in_value
= &breakpoint
;
65 fields
[1].num_bits
= 32;
66 fields
[1].out_value
= NULL
;
67 fields
[1].in_value
= databus
;
69 if ((retval
= arm_jtag_scann(&arm7_9
->jtag_info
, 0x1)) != ERROR_OK
)
73 arm_jtag_set_instr(&arm7_9
->jtag_info
, arm7_9
->jtag_info
.intest_instr
, NULL
);
75 jtag_add_dr_scan(arm7_9
->jtag_info
.tap
, 2, fields
, TAP_DRPAUSE
);
76 if ((retval
= jtag_execute_queue()) != ERROR_OK
)
81 fields
[0].in_value
= NULL
;
82 fields
[0].out_value
= &breakpoint
;
83 fields
[1].in_value
= NULL
;
84 fields
[1].out_value
= databus
;
86 jtag_add_dr_scan(arm7_9
->jtag_info
.tap
, 2, fields
, TAP_DRPAUSE
);
89 target
->debug_reason
= DBG_REASON_WATCHPOINT
;
91 target
->debug_reason
= DBG_REASON_BREAKPOINT
;
97 static const int arm7tdmi_num_bits
[] = {1, 32};
99 static __inline
int arm7tdmi_clock_out_inner(struct arm_jtag
*jtag_info
, uint32_t out
, int breakpoint
)
101 uint32_t values
[2]={breakpoint
, flip_u32(out
, 32)};
103 jtag_add_dr_out(jtag_info
->tap
,
107 jtag_get_end_state());
109 jtag_add_runtest(0, jtag_get_end_state());
114 /* put an instruction in the ARM7TDMI pipeline or write the data bus,
115 * and optionally read data
117 * FIXME remove the unused "deprecated" parameter
119 static __inline
int arm7tdmi_clock_out(struct arm_jtag
*jtag_info
,
120 uint32_t out
, uint32_t *deprecated
, int breakpoint
)
122 jtag_set_end_state(TAP_DRPAUSE
);
123 arm_jtag_scann(jtag_info
, 0x1);
124 arm_jtag_set_instr(jtag_info
, jtag_info
->intest_instr
, NULL
);
126 return arm7tdmi_clock_out_inner(jtag_info
, out
, breakpoint
);
129 /* clock the target, reading the databus */
130 static int arm7tdmi_clock_data_in(struct arm_jtag
*jtag_info
, uint32_t *in
)
132 int retval
= ERROR_OK
;
133 struct scan_field fields
[2];
135 jtag_set_end_state(TAP_DRPAUSE
);
136 if ((retval
= arm_jtag_scann(jtag_info
, 0x1)) != ERROR_OK
)
140 arm_jtag_set_instr(jtag_info
, jtag_info
->intest_instr
, NULL
);
142 fields
[0].num_bits
= 1;
143 fields
[0].out_value
= NULL
;
144 fields
[0].in_value
= NULL
;
146 fields
[1].num_bits
= 32;
147 fields
[1].out_value
= NULL
;
148 fields
[1].in_value
= (uint8_t *)in
;
150 jtag_add_dr_scan(jtag_info
->tap
, 2, fields
, TAP_DRPAUSE
);
152 jtag_add_callback(arm7flip32
, (jtag_callback_data_t
)in
);
154 jtag_add_runtest(0, TAP_DRPAUSE
);
156 #ifdef _DEBUG_INSTRUCTION_EXECUTION_
157 if ((retval
= jtag_execute_queue()) != ERROR_OK
)
161 LOG_DEBUG("in: 0x%8.8x", *in
);
163 LOG_ERROR("BUG: called with in == NULL");
169 void arm_endianness(uint8_t *tmp
, void *in
, int size
, int be
, int flip
)
171 uint32_t readback
= le_to_h_u32(tmp
);
173 readback
= flip_u32(readback
, 32);
179 h_u32_to_be(((uint8_t*)in
), readback
);
182 h_u32_to_le(((uint8_t*)in
), readback
);
188 h_u16_to_be(((uint8_t*)in
), readback
& 0xffff);
191 h_u16_to_le(((uint8_t*)in
), readback
& 0xffff);
195 *((uint8_t *)in
)= readback
& 0xff;
200 static int arm7endianness(jtag_callback_data_t arg
,
201 jtag_callback_data_t size
, jtag_callback_data_t be
,
202 jtag_callback_data_t captured
)
204 uint8_t *in
= (uint8_t *)arg
;
206 arm_endianness((uint8_t *)captured
, in
, (int)size
, (int)be
, 1);
210 /* clock the target, and read the databus
211 * the *in pointer points to a buffer where elements of 'size' bytes
212 * are stored in big (be == 1) or little (be == 0) endianness
214 static int arm7tdmi_clock_data_in_endianness(struct arm_jtag
*jtag_info
,
215 void *in
, int size
, int be
)
217 int retval
= ERROR_OK
;
218 struct scan_field fields
[2];
220 jtag_set_end_state(TAP_DRPAUSE
);
221 if ((retval
= arm_jtag_scann(jtag_info
, 0x1)) != ERROR_OK
)
225 arm_jtag_set_instr(jtag_info
, jtag_info
->intest_instr
, NULL
);
227 fields
[0].num_bits
= 1;
228 fields
[0].out_value
= NULL
;
229 fields
[0].in_value
= NULL
;
231 fields
[1].num_bits
= 32;
232 fields
[1].out_value
= NULL
;
233 jtag_alloc_in_value32(&fields
[1]);
235 jtag_add_dr_scan(jtag_info
->tap
, 2, fields
, TAP_DRPAUSE
);
237 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
);
239 jtag_add_runtest(0, TAP_DRPAUSE
);
241 #ifdef _DEBUG_INSTRUCTION_EXECUTION_
243 if ((retval
= jtag_execute_queue()) != ERROR_OK
)
250 LOG_DEBUG("in: 0x%8.8x", *(uint32_t*)in
);
254 LOG_ERROR("BUG: called with in == NULL");
262 static void arm7tdmi_change_to_arm(struct target
*target
,
263 uint32_t *r0
, uint32_t *pc
)
265 struct arm7_9_common
*arm7_9
= target_to_arm7_9(target
);
266 struct arm_jtag
*jtag_info
= &arm7_9
->jtag_info
;
268 /* save r0 before using it and put system in ARM state
269 * to allow common handling of ARM and THUMB debugging */
271 /* fetch STR r0, [r0] */
272 arm7tdmi_clock_out(jtag_info
, ARMV4_5_T_STR(0, 0), NULL
, 0);
273 arm7tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, NULL
, 0);
274 arm7tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, NULL
, 0);
275 /* nothing fetched, STR r0, [r0] in Execute (2) */
276 arm7tdmi_clock_data_in(jtag_info
, r0
);
278 /* MOV r0, r15 fetched, STR in Decode */
279 arm7tdmi_clock_out(jtag_info
, ARMV4_5_T_MOV(0, 15), NULL
, 0);
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
, pc
);
286 /* use pc-relative LDR to clear r0[1:0] (for switch to ARM mode) */
287 arm7tdmi_clock_out(jtag_info
, ARMV4_5_T_LDR_PCREL(0), NULL
, 0);
288 arm7tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, NULL
, 0);
289 arm7tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, NULL
, 0);
290 /* nothing fetched, data for LDR r0, [PC, #0] */
291 arm7tdmi_clock_out(jtag_info
, 0x0, NULL
, 0);
292 /* nothing fetched, data from previous cycle is written to register */
293 arm7tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, NULL
, 0);
296 arm7tdmi_clock_out(jtag_info
, ARMV4_5_T_BX(0), NULL
, 0);
297 /* NOP fetched, BX in Decode, MOV in Execute */
298 arm7tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, NULL
, 0);
299 /* NOP fetched, BX in Execute (1) */
300 arm7tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, NULL
, 0);
302 jtag_execute_queue();
304 /* fix program counter:
305 * MOV r0, r15 was the 4th instruction (+6)
306 * reading PC in Thumb state gives address of instruction + 4
312 /* FIX!!! is this a potential performance bottleneck w.r.t. requiring too many
313 * roundtrips when jtag_execute_queue() has a large overhead(e.g. for USB)s?
315 * The solution is to arrange for a large out/in scan in this loop and
316 * and convert data afterwards.
318 static void arm7tdmi_read_core_regs(struct target
*target
,
319 uint32_t mask
, uint32_t* core_regs
[16])
322 struct arm7_9_common
*arm7_9
= target_to_arm7_9(target
);
323 struct arm_jtag
*jtag_info
= &arm7_9
->jtag_info
;
325 /* STMIA r0-15, [r0] at debug speed
326 * register values will start to appear on 4th DCLK
328 arm7tdmi_clock_out(jtag_info
, ARMV4_5_STMIA(0, mask
& 0xffff, 0, 0), NULL
, 0);
330 /* fetch NOP, STM in DECODE stage */
331 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
332 /* fetch NOP, STM in EXECUTE stage (1st cycle) */
333 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
335 for (i
= 0; i
<= 15; i
++)
338 /* nothing fetched, STM still in EXECUTE (1 + i cycle) */
339 arm7tdmi_clock_data_in(jtag_info
, core_regs
[i
]);
343 static void arm7tdmi_read_core_regs_target_buffer(struct target
*target
,
344 uint32_t mask
, void* buffer
, int size
)
347 struct arm7_9_common
*arm7_9
= target_to_arm7_9(target
);
348 struct arm_jtag
*jtag_info
= &arm7_9
->jtag_info
;
349 int be
= (target
->endianness
== TARGET_BIG_ENDIAN
) ? 1 : 0;
350 uint32_t *buf_u32
= buffer
;
351 uint16_t *buf_u16
= buffer
;
352 uint8_t *buf_u8
= buffer
;
354 /* STMIA r0-15, [r0] at debug speed
355 * register values will start to appear on 4th DCLK
357 arm7tdmi_clock_out(jtag_info
, ARMV4_5_STMIA(0, mask
& 0xffff, 0, 0), NULL
, 0);
359 /* fetch NOP, STM in DECODE stage */
360 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
361 /* fetch NOP, STM in EXECUTE stage (1st cycle) */
362 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
364 for (i
= 0; i
<= 15; i
++)
366 /* nothing fetched, STM still in EXECUTE (1 + i cycle), read databus */
372 arm7tdmi_clock_data_in_endianness(jtag_info
, buf_u32
++, 4, be
);
375 arm7tdmi_clock_data_in_endianness(jtag_info
, buf_u16
++, 2, be
);
378 arm7tdmi_clock_data_in_endianness(jtag_info
, buf_u8
++, 1, be
);
385 static void arm7tdmi_read_xpsr(struct target
*target
, uint32_t *xpsr
, int spsr
)
387 struct arm7_9_common
*arm7_9
= target_to_arm7_9(target
);
388 struct arm_jtag
*jtag_info
= &arm7_9
->jtag_info
;
391 arm7tdmi_clock_out(jtag_info
, ARMV4_5_MRS(0, spsr
& 1), NULL
, 0);
394 arm7tdmi_clock_out(jtag_info
, ARMV4_5_STR(0, 15), NULL
, 0);
395 /* fetch NOP, STR in DECODE stage */
396 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
397 /* fetch NOP, STR in EXECUTE stage (1st cycle) */
398 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
399 /* nothing fetched, STR still in EXECUTE (2nd cycle) */
400 arm7tdmi_clock_data_in(jtag_info
, xpsr
);
403 static void arm7tdmi_write_xpsr(struct target
*target
, uint32_t xpsr
, int spsr
)
405 struct arm7_9_common
*arm7_9
= target_to_arm7_9(target
);
406 struct arm_jtag
*jtag_info
= &arm7_9
->jtag_info
;
408 LOG_DEBUG("xpsr: %8.8" PRIx32
", spsr: %i", xpsr
, spsr
);
411 arm7tdmi_clock_out(jtag_info
, ARMV4_5_MSR_IM(xpsr
& 0xff, 0, 1, spsr
), NULL
, 0);
412 /* MSR2 fetched, MSR1 in DECODE */
413 arm7tdmi_clock_out(jtag_info
, ARMV4_5_MSR_IM((xpsr
& 0xff00) >> 8, 0xc, 2, spsr
), NULL
, 0);
414 /* MSR3 fetched, MSR1 in EXECUTE (1), MSR2 in DECODE */
415 arm7tdmi_clock_out(jtag_info
, ARMV4_5_MSR_IM((xpsr
& 0xff0000) >> 16, 0x8, 4, spsr
), NULL
, 0);
416 /* nothing fetched, MSR1 in EXECUTE (2) */
417 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
418 /* MSR4 fetched, MSR2 in EXECUTE (1), MSR3 in DECODE */
419 arm7tdmi_clock_out(jtag_info
, ARMV4_5_MSR_IM((xpsr
& 0xff000000) >> 24, 0x4, 8, spsr
), NULL
, 0);
420 /* nothing fetched, MSR2 in EXECUTE (2) */
421 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
422 /* NOP fetched, MSR3 in EXECUTE (1), MSR4 in DECODE */
423 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
424 /* nothing fetched, MSR3 in EXECUTE (2) */
425 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
426 /* NOP fetched, MSR4 in EXECUTE (1) */
427 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
428 /* nothing fetched, MSR4 in EXECUTE (2) */
429 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
432 static void arm7tdmi_write_xpsr_im8(struct target
*target
,
433 uint8_t xpsr_im
, int rot
, int spsr
)
435 struct arm7_9_common
*arm7_9
= target_to_arm7_9(target
);
436 struct arm_jtag
*jtag_info
= &arm7_9
->jtag_info
;
438 LOG_DEBUG("xpsr_im: %2.2x, rot: %i, spsr: %i", xpsr_im
, rot
, spsr
);
441 arm7tdmi_clock_out(jtag_info
, ARMV4_5_MSR_IM(xpsr_im
, rot
, 1, spsr
), NULL
, 0);
442 /* NOP fetched, MSR in DECODE */
443 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
444 /* NOP fetched, MSR in EXECUTE (1) */
445 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
446 /* nothing fetched, MSR in EXECUTE (2) */
447 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
450 static void arm7tdmi_write_core_regs(struct target
*target
,
451 uint32_t mask
, uint32_t core_regs
[16])
454 struct arm7_9_common
*arm7_9
= target_to_arm7_9(target
);
455 struct arm_jtag
*jtag_info
= &arm7_9
->jtag_info
;
457 /* LDMIA r0-15, [r0] at debug speed
458 * register values will start to appear on 4th DCLK
460 arm7tdmi_clock_out(jtag_info
, ARMV4_5_LDMIA(0, mask
& 0xffff, 0, 0), NULL
, 0);
462 /* fetch NOP, LDM in DECODE stage */
463 arm7tdmi_clock_out_inner(jtag_info
, ARMV4_5_NOP
, 0);
464 /* fetch NOP, LDM in EXECUTE stage (1st cycle) */
465 arm7tdmi_clock_out_inner(jtag_info
, ARMV4_5_NOP
, 0);
467 for (i
= 0; i
<= 15; i
++)
470 /* nothing fetched, LDM still in EXECUTE (1 + i cycle) */
471 arm7tdmi_clock_out_inner(jtag_info
, core_regs
[i
], 0);
473 arm7tdmi_clock_out_inner(jtag_info
, ARMV4_5_NOP
, 0);
476 static void arm7tdmi_load_word_regs(struct target
*target
, uint32_t mask
)
478 struct arm7_9_common
*arm7_9
= target_to_arm7_9(target
);
479 struct arm_jtag
*jtag_info
= &arm7_9
->jtag_info
;
481 /* put system-speed load-multiple into the pipeline */
482 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
483 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 1);
484 arm7tdmi_clock_out(jtag_info
, ARMV4_5_LDMIA(0, mask
& 0xffff, 0, 1), NULL
, 0);
487 static void arm7tdmi_load_hword_reg(struct target
*target
, int num
)
489 struct arm7_9_common
*arm7_9
= target_to_arm7_9(target
);
490 struct arm_jtag
*jtag_info
= &arm7_9
->jtag_info
;
492 /* put system-speed load half-word into the pipeline */
493 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
494 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 1);
495 arm7tdmi_clock_out(jtag_info
, ARMV4_5_LDRH_IP(num
, 0), NULL
, 0);
498 static void arm7tdmi_load_byte_reg(struct target
*target
, int num
)
500 struct arm7_9_common
*arm7_9
= target_to_arm7_9(target
);
501 struct arm_jtag
*jtag_info
= &arm7_9
->jtag_info
;
503 /* put system-speed load byte 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_LDRB_IP(num
, 0), NULL
, 0);
509 static void arm7tdmi_store_word_regs(struct target
*target
, uint32_t mask
)
511 struct arm7_9_common
*arm7_9
= target_to_arm7_9(target
);
512 struct arm_jtag
*jtag_info
= &arm7_9
->jtag_info
;
514 /* put system-speed store-multiple into the pipeline */
515 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
516 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 1);
517 arm7tdmi_clock_out(jtag_info
, ARMV4_5_STMIA(0, mask
, 0, 1), NULL
, 0);
520 static void arm7tdmi_store_hword_reg(struct target
*target
, int num
)
522 struct arm7_9_common
*arm7_9
= target_to_arm7_9(target
);
523 struct arm_jtag
*jtag_info
= &arm7_9
->jtag_info
;
525 /* put system-speed store half-word into the pipeline */
526 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
527 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 1);
528 arm7tdmi_clock_out(jtag_info
, ARMV4_5_STRH_IP(num
, 0), NULL
, 0);
531 static void arm7tdmi_store_byte_reg(struct target
*target
, int num
)
533 struct arm7_9_common
*arm7_9
= target_to_arm7_9(target
);
534 struct arm_jtag
*jtag_info
= &arm7_9
->jtag_info
;
536 /* put system-speed store byte into the pipeline */
537 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
538 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 1);
539 arm7tdmi_clock_out(jtag_info
, ARMV4_5_STRB_IP(num
, 0), NULL
, 0);
542 static void arm7tdmi_write_pc(struct target
*target
, uint32_t pc
)
544 struct arm7_9_common
*arm7_9
= target_to_arm7_9(target
);
545 struct arm_jtag
*jtag_info
= &arm7_9
->jtag_info
;
547 /* LDMIA r0-15, [r0] at debug speed
548 * register values will start to appear on 4th DCLK
550 arm7tdmi_clock_out(jtag_info
, ARMV4_5_LDMIA(0, 0x8000, 0, 0), NULL
, 0);
551 /* fetch NOP, LDM in DECODE stage */
552 arm7tdmi_clock_out_inner(jtag_info
, ARMV4_5_NOP
, 0);
553 /* fetch NOP, LDM in EXECUTE stage (1st cycle) */
554 arm7tdmi_clock_out_inner(jtag_info
, ARMV4_5_NOP
, 0);
555 /* nothing fetched, LDM in EXECUTE stage (1st cycle) load register */
556 arm7tdmi_clock_out_inner(jtag_info
, pc
, 0);
557 /* nothing fetched, LDM in EXECUTE stage (2nd cycle) load register */
558 arm7tdmi_clock_out_inner(jtag_info
, ARMV4_5_NOP
, 0);
559 /* nothing fetched, LDM in EXECUTE stage (3rd cycle) load register */
560 arm7tdmi_clock_out_inner(jtag_info
, ARMV4_5_NOP
, 0);
561 /* fetch NOP, LDM in EXECUTE stage (4th cycle) */
562 arm7tdmi_clock_out_inner(jtag_info
, ARMV4_5_NOP
, 0);
563 /* fetch NOP, LDM in EXECUTE stage (5th cycle) */
564 arm7tdmi_clock_out_inner(jtag_info
, ARMV4_5_NOP
, 0);
567 static void arm7tdmi_branch_resume(struct target
*target
)
569 struct arm7_9_common
*arm7_9
= target_to_arm7_9(target
);
570 struct arm_jtag
*jtag_info
= &arm7_9
->jtag_info
;
572 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 1);
573 arm7tdmi_clock_out_inner(jtag_info
, ARMV4_5_B(0xfffffa, 0), 0);
576 static void arm7tdmi_branch_resume_thumb(struct target
*target
)
578 struct arm7_9_common
*arm7_9
= target_to_arm7_9(target
);
579 struct arm
*armv4_5
= &arm7_9
->armv4_5_common
;
580 struct arm_jtag
*jtag_info
= &arm7_9
->jtag_info
;
581 struct reg
*dbg_stat
= &arm7_9
->eice_cache
->reg_list
[EICE_DBG_STAT
];
585 /* LDMIA r0, [r0] at debug speed
586 * register values will start to appear on 4th DCLK
588 arm7tdmi_clock_out(jtag_info
, ARMV4_5_LDMIA(0, 0x1, 0, 0), NULL
, 0);
590 /* fetch NOP, LDM in DECODE stage */
591 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
592 /* fetch NOP, LDM in EXECUTE stage (1st cycle) */
593 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
594 /* nothing fetched, LDM in EXECUTE stage (2nd cycle) */
595 arm7tdmi_clock_out(jtag_info
,
596 buf_get_u32(armv4_5
->pc
->value
, 0, 32) | 1, NULL
, 0);
597 /* nothing fetched, LDM in EXECUTE stage (3rd cycle) */
598 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
600 /* Branch and eXchange */
601 arm7tdmi_clock_out(jtag_info
, ARMV4_5_BX(0), NULL
, 0);
603 embeddedice_read_reg(dbg_stat
);
605 /* fetch NOP, BX in DECODE stage */
606 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
608 /* target is now in Thumb state */
609 embeddedice_read_reg(dbg_stat
);
611 /* fetch NOP, BX in EXECUTE stage (1st cycle) */
612 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
614 /* target is now in Thumb state */
615 embeddedice_read_reg(dbg_stat
);
618 arm7tdmi_clock_out(jtag_info
, ARMV4_5_T_LDR_PCREL(0), NULL
, 0);
619 /* fetch NOP, LDR in Decode */
620 arm7tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, NULL
, 0);
621 /* fetch NOP, LDR in Execute */
622 arm7tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, NULL
, 0);
623 /* nothing fetched, LDR in EXECUTE stage (2nd cycle) */
624 arm7tdmi_clock_out(jtag_info
, buf_get_u32(armv4_5
->core_cache
->reg_list
[0].value
, 0, 32), NULL
, 0);
625 /* nothing fetched, LDR in EXECUTE stage (3rd cycle) */
626 arm7tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, NULL
, 0);
628 arm7tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, NULL
, 0);
629 arm7tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, NULL
, 0);
631 embeddedice_read_reg(dbg_stat
);
633 arm7tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, NULL
, 1);
634 arm7tdmi_clock_out(jtag_info
, ARMV4_5_T_B(0x7f8), NULL
, 0);
637 static void arm7tdmi_build_reg_cache(struct target
*target
)
639 struct reg_cache
**cache_p
= register_get_last_cache_p(&target
->reg_cache
);
640 struct arm
*armv4_5
= target_to_arm(target
);
642 (*cache_p
) = arm_build_reg_cache(target
, armv4_5
);
645 int arm7tdmi_init_target(struct command_context
*cmd_ctx
, struct target
*target
)
647 arm7tdmi_build_reg_cache(target
);
652 int arm7tdmi_init_arch_info(struct target
*target
,
653 struct arm7_9_common
*arm7_9
, struct jtag_tap
*tap
)
655 /* prepare JTAG information for the new target */
656 arm7_9
->jtag_info
.tap
= tap
;
657 arm7_9
->jtag_info
.scann_size
= 4;
659 /* register arch-specific functions */
660 arm7_9
->examine_debug_reason
= arm7tdmi_examine_debug_reason
;
661 arm7_9
->change_to_arm
= arm7tdmi_change_to_arm
;
662 arm7_9
->read_core_regs
= arm7tdmi_read_core_regs
;
663 arm7_9
->read_core_regs_target_buffer
= arm7tdmi_read_core_regs_target_buffer
;
664 arm7_9
->read_xpsr
= arm7tdmi_read_xpsr
;
666 arm7_9
->write_xpsr
= arm7tdmi_write_xpsr
;
667 arm7_9
->write_xpsr_im8
= arm7tdmi_write_xpsr_im8
;
668 arm7_9
->write_core_regs
= arm7tdmi_write_core_regs
;
670 arm7_9
->load_word_regs
= arm7tdmi_load_word_regs
;
671 arm7_9
->load_hword_reg
= arm7tdmi_load_hword_reg
;
672 arm7_9
->load_byte_reg
= arm7tdmi_load_byte_reg
;
674 arm7_9
->store_word_regs
= arm7tdmi_store_word_regs
;
675 arm7_9
->store_hword_reg
= arm7tdmi_store_hword_reg
;
676 arm7_9
->store_byte_reg
= arm7tdmi_store_byte_reg
;
678 arm7_9
->write_pc
= arm7tdmi_write_pc
;
679 arm7_9
->branch_resume
= arm7tdmi_branch_resume
;
680 arm7_9
->branch_resume_thumb
= arm7tdmi_branch_resume_thumb
;
682 arm7_9
->enable_single_step
= arm7_9_enable_eice_step
;
683 arm7_9
->disable_single_step
= arm7_9_disable_eice_step
;
685 arm7_9
->post_debug_entry
= NULL
;
687 arm7_9
->pre_restore_context
= NULL
;
689 /* initialize arch-specific breakpoint handling */
690 arm7_9
->arm_bkpt
= 0xdeeedeee;
691 arm7_9
->thumb_bkpt
= 0xdeee;
693 arm7_9
->dbgreq_adjust_pc
= 2;
695 arm7_9_init_arch_info(target
, arm7_9
);
700 static int arm7tdmi_target_create(struct target
*target
, Jim_Interp
*interp
)
702 struct arm7_9_common
*arm7_9
;
704 arm7_9
= calloc(1,sizeof(struct arm7_9_common
));
705 arm7tdmi_init_arch_info(target
, arm7_9
, target
->tap
);
706 arm7_9
->armv4_5_common
.is_armv4
= true;
711 /** Holds methods for ARM7TDMI targets. */
712 struct target_type arm7tdmi_target
=
717 .arch_state
= arm_arch_state
,
719 .target_request_data
= arm7_9_target_request_data
,
722 .resume
= arm7_9_resume
,
725 .assert_reset
= arm7_9_assert_reset
,
726 .deassert_reset
= arm7_9_deassert_reset
,
727 .soft_reset_halt
= arm7_9_soft_reset_halt
,
729 .get_gdb_reg_list
= arm_get_gdb_reg_list
,
731 .read_memory
= arm7_9_read_memory
,
732 .write_memory
= arm7_9_write_memory
,
733 .bulk_write_memory
= arm7_9_bulk_write_memory
,
735 .checksum_memory
= arm_checksum_memory
,
736 .blank_check_memory
= arm_blank_check_memory
,
738 .run_algorithm
= armv4_5_run_algorithm
,
740 .add_breakpoint
= arm7_9_add_breakpoint
,
741 .remove_breakpoint
= arm7_9_remove_breakpoint
,
742 .add_watchpoint
= arm7_9_add_watchpoint
,
743 .remove_watchpoint
= arm7_9_remove_watchpoint
,
745 .commands
= arm7_9_command_handlers
,
746 .target_create
= arm7tdmi_target_create
,
747 .init_target
= arm7tdmi_init_target
,
748 .examine
= arm7_9_examine
,
749 .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)