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, see <http://www.gnu.org/licenses/>. *
23 ***************************************************************************/
30 #include "target_type.h"
32 #include "arm_opcodes.h"
33 #include "arm_semihosting.h"
36 * For information about ARM7TDMI, see ARM DDI 0210C (r4p1)
37 * or ARM DDI 0029G (r3). "Debug In Depth", Appendix B,
38 * covers JTAG support.
42 #define _DEBUG_INSTRUCTION_EXECUTION_
45 static int arm7tdmi_examine_debug_reason(struct target
*target
)
47 int retval
= ERROR_OK
;
48 struct arm7_9_common
*arm7_9
= target_to_arm7_9(target
);
50 /* only check the debug reason if we don't know it already */
51 if ((target
->debug_reason
!= DBG_REASON_DBGRQ
)
52 && (target
->debug_reason
!= DBG_REASON_SINGLESTEP
)) {
53 struct scan_field fields
[2];
57 fields
[0].num_bits
= 1;
58 fields
[0].out_value
= NULL
;
59 fields
[0].in_value
= &breakpoint
;
61 fields
[1].num_bits
= 32;
62 fields
[1].out_value
= NULL
;
63 fields
[1].in_value
= databus
;
65 retval
= arm_jtag_scann(&arm7_9
->jtag_info
, 0x1, TAP_DRPAUSE
);
66 if (retval
!= ERROR_OK
)
68 retval
= arm_jtag_set_instr(arm7_9
->jtag_info
.tap
, arm7_9
->jtag_info
.intest_instr
, NULL
, TAP_DRPAUSE
);
69 if (retval
!= ERROR_OK
)
72 jtag_add_dr_scan(arm7_9
->jtag_info
.tap
, 2, fields
, TAP_DRPAUSE
);
73 retval
= jtag_execute_queue();
74 if (retval
!= ERROR_OK
)
77 fields
[0].in_value
= NULL
;
78 fields
[0].out_value
= &breakpoint
;
79 fields
[1].in_value
= NULL
;
80 fields
[1].out_value
= databus
;
82 jtag_add_dr_scan(arm7_9
->jtag_info
.tap
, 2, fields
, TAP_DRPAUSE
);
85 target
->debug_reason
= DBG_REASON_WATCHPOINT
;
87 target
->debug_reason
= DBG_REASON_BREAKPOINT
;
93 static const int arm7tdmi_num_bits
[] = {1, 32};
95 static inline int arm7tdmi_clock_out_inner(struct arm_jtag
*jtag_info
, uint32_t out
, int breakpoint
)
97 uint8_t bp
= breakpoint
? 1 : 0;
99 buf_set_u32(out_value
, 0, 32, flip_u32(out
, 32));
101 struct scan_field fields
[2] = {
102 { .num_bits
= arm7tdmi_num_bits
[0], .out_value
= &bp
},
103 { .num_bits
= arm7tdmi_num_bits
[1], .out_value
= out_value
},
106 jtag_add_dr_scan(jtag_info
->tap
,
111 jtag_add_runtest(0, TAP_DRPAUSE
);
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(struct arm_jtag
*jtag_info
,
122 uint32_t out
, uint32_t *deprecated
, int breakpoint
)
125 retval
= arm_jtag_scann(jtag_info
, 0x1, TAP_DRPAUSE
);
126 if (retval
!= ERROR_OK
)
128 retval
= arm_jtag_set_instr(jtag_info
->tap
, jtag_info
->intest_instr
, NULL
, TAP_DRPAUSE
);
129 if (retval
!= ERROR_OK
)
132 return arm7tdmi_clock_out_inner(jtag_info
, out
, breakpoint
);
135 /* clock the target, reading the databus */
136 static int arm7tdmi_clock_data_in(struct arm_jtag
*jtag_info
, uint32_t *in
)
138 int retval
= ERROR_OK
;
139 struct scan_field fields
[2];
141 retval
= arm_jtag_scann(jtag_info
, 0x1, TAP_DRPAUSE
);
142 if (retval
!= ERROR_OK
)
144 retval
= arm_jtag_set_instr(jtag_info
->tap
, jtag_info
->intest_instr
, NULL
, TAP_DRPAUSE
);
145 if (retval
!= ERROR_OK
)
148 fields
[0].num_bits
= 1;
149 fields
[0].out_value
= NULL
;
150 fields
[0].in_value
= NULL
;
152 fields
[1].num_bits
= 32;
153 fields
[1].out_value
= NULL
;
154 fields
[1].in_value
= (uint8_t *)in
;
156 jtag_add_dr_scan(jtag_info
->tap
, 2, fields
, TAP_DRPAUSE
);
158 jtag_add_callback(arm7flip32
, (jtag_callback_data_t
)in
);
160 jtag_add_runtest(0, TAP_DRPAUSE
);
162 #ifdef _DEBUG_INSTRUCTION_EXECUTION_
163 retval
= jtag_execute_queue();
164 if (retval
!= ERROR_OK
)
168 LOG_DEBUG("in: 0x%8.8x", *in
);
170 LOG_ERROR("BUG: called with in == NULL");
176 /* clock the target, and read the databus
177 * the *in pointer points to a buffer where elements of 'size' bytes
178 * are stored in big (be == 1) or little (be == 0) endianness
180 static int arm7tdmi_clock_data_in_endianness(struct arm_jtag
*jtag_info
,
181 void *in
, int size
, int be
)
183 int retval
= ERROR_OK
;
184 struct scan_field fields
[3];
186 retval
= arm_jtag_scann(jtag_info
, 0x1, TAP_DRPAUSE
);
187 if (retval
!= ERROR_OK
)
189 retval
= arm_jtag_set_instr(jtag_info
->tap
, jtag_info
->intest_instr
, NULL
, TAP_DRPAUSE
);
190 if (retval
!= ERROR_OK
)
193 fields
[0].num_bits
= 1;
194 fields
[0].out_value
= NULL
;
195 fields
[0].in_value
= NULL
;
198 fields
[1].num_bits
= 32;
199 fields
[1].out_value
= NULL
;
200 fields
[1].in_value
= in
;
202 /* Discard irrelevant bits of the scan, making sure we don't write more
203 * than size bytes to in */
204 fields
[1].num_bits
= 32 - size
* 8;
205 fields
[1].out_value
= NULL
;
206 fields
[1].in_value
= NULL
;
208 fields
[2].num_bits
= size
* 8;
209 fields
[2].out_value
= NULL
;
210 fields
[2].in_value
= in
;
213 jtag_add_dr_scan(jtag_info
->tap
, size
== 4 ? 2 : 3, fields
, TAP_DRPAUSE
);
215 jtag_add_callback4(arm7_9_endianness_callback
,
216 (jtag_callback_data_t
)in
,
217 (jtag_callback_data_t
)size
,
218 (jtag_callback_data_t
)be
,
219 (jtag_callback_data_t
)1);
221 jtag_add_runtest(0, TAP_DRPAUSE
);
223 #ifdef _DEBUG_INSTRUCTION_EXECUTION_
225 retval
= jtag_execute_queue();
226 if (retval
!= ERROR_OK
)
230 LOG_DEBUG("in: 0x%8.8x", *(uint32_t *)in
);
232 LOG_ERROR("BUG: called with in == NULL");
239 static void arm7tdmi_change_to_arm(struct target
*target
,
240 uint32_t *r0
, uint32_t *pc
)
242 struct arm7_9_common
*arm7_9
= target_to_arm7_9(target
);
243 struct arm_jtag
*jtag_info
= &arm7_9
->jtag_info
;
245 /* save r0 before using it and put system in ARM state
246 * to allow common handling of ARM and THUMB debugging */
248 /* fetch STR r0, [r0] */
249 arm7tdmi_clock_out(jtag_info
, ARMV4_5_T_STR(0, 0), NULL
, 0);
250 arm7tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, NULL
, 0);
251 arm7tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, NULL
, 0);
252 /* nothing fetched, STR r0, [r0] in Execute (2) */
253 arm7tdmi_clock_data_in(jtag_info
, r0
);
255 /* MOV r0, r15 fetched, STR in Decode */
256 arm7tdmi_clock_out(jtag_info
, ARMV4_5_T_MOV(0, 15), NULL
, 0);
257 arm7tdmi_clock_out(jtag_info
, ARMV4_5_T_STR(0, 0), NULL
, 0);
258 arm7tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, NULL
, 0);
259 arm7tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, NULL
, 0);
260 /* nothing fetched, STR r0, [r0] in Execute (2) */
261 arm7tdmi_clock_data_in(jtag_info
, pc
);
263 /* use pc-relative LDR to clear r0[1:0] (for switch to ARM mode) */
264 arm7tdmi_clock_out(jtag_info
, ARMV4_5_T_LDR_PCREL(0), NULL
, 0);
265 arm7tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, NULL
, 0);
266 arm7tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, NULL
, 0);
267 /* nothing fetched, data for LDR r0, [PC, #0] */
268 arm7tdmi_clock_out(jtag_info
, 0x0, NULL
, 0);
269 /* nothing fetched, data from previous cycle is written to register */
270 arm7tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, NULL
, 0);
273 arm7tdmi_clock_out(jtag_info
, ARMV4_5_T_BX(0), NULL
, 0);
274 /* NOP fetched, BX in Decode, MOV in Execute */
275 arm7tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, NULL
, 0);
276 /* NOP fetched, BX in Execute (1) */
277 arm7tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, NULL
, 0);
279 jtag_execute_queue();
281 /* fix program counter:
282 * MOV r0, r15 was the 4th instruction (+6)
283 * reading PC in Thumb state gives address of instruction + 4
288 /* FIX!!! is this a potential performance bottleneck w.r.t. requiring too many
289 * roundtrips when jtag_execute_queue() has a large overhead(e.g. for USB)s?
291 * The solution is to arrange for a large out/in scan in this loop and
292 * and convert data afterwards.
294 static void arm7tdmi_read_core_regs(struct target
*target
,
295 uint32_t mask
, uint32_t *core_regs
[16])
298 struct arm7_9_common
*arm7_9
= target_to_arm7_9(target
);
299 struct arm_jtag
*jtag_info
= &arm7_9
->jtag_info
;
301 /* STMIA r0-15, [r0] at debug speed
302 * register values will start to appear on 4th DCLK
304 arm7tdmi_clock_out(jtag_info
, ARMV4_5_STMIA(0, mask
& 0xffff, 0, 0), NULL
, 0);
306 /* fetch NOP, STM in DECODE stage */
307 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
308 /* fetch NOP, STM in EXECUTE stage (1st cycle) */
309 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
311 for (i
= 0; i
<= 15; i
++) {
313 /* nothing fetched, STM still in EXECUTE (1 + i cycle) */
314 arm7tdmi_clock_data_in(jtag_info
, core_regs
[i
]);
318 static void arm7tdmi_read_core_regs_target_buffer(struct target
*target
,
319 uint32_t mask
, void *buffer
, int size
)
322 struct arm7_9_common
*arm7_9
= target_to_arm7_9(target
);
323 struct arm_jtag
*jtag_info
= &arm7_9
->jtag_info
;
324 int be
= (target
->endianness
== TARGET_BIG_ENDIAN
) ? 1 : 0;
325 uint32_t *buf_u32
= buffer
;
326 uint16_t *buf_u16
= buffer
;
327 uint8_t *buf_u8
= buffer
;
329 /* STMIA r0-15, [r0] at debug speed
330 * register values will start to appear on 4th DCLK
332 arm7tdmi_clock_out(jtag_info
, ARMV4_5_STMIA(0, mask
& 0xffff, 0, 0), NULL
, 0);
334 /* fetch NOP, STM in DECODE stage */
335 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
336 /* fetch NOP, STM in EXECUTE stage (1st cycle) */
337 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
339 for (i
= 0; i
<= 15; i
++) {
340 /* nothing fetched, STM still in EXECUTE (1 + i cycle), read databus */
341 if (mask
& (1 << i
)) {
344 arm7tdmi_clock_data_in_endianness(jtag_info
, buf_u32
++, 4, be
);
347 arm7tdmi_clock_data_in_endianness(jtag_info
, buf_u16
++, 2, be
);
350 arm7tdmi_clock_data_in_endianness(jtag_info
, buf_u8
++, 1, be
);
357 static void arm7tdmi_read_xpsr(struct target
*target
, uint32_t *xpsr
, int spsr
)
359 struct arm7_9_common
*arm7_9
= target_to_arm7_9(target
);
360 struct arm_jtag
*jtag_info
= &arm7_9
->jtag_info
;
363 arm7tdmi_clock_out(jtag_info
, ARMV4_5_MRS(0, spsr
& 1), NULL
, 0);
366 arm7tdmi_clock_out(jtag_info
, ARMV4_5_STR(0, 15), NULL
, 0);
367 /* fetch NOP, STR in DECODE stage */
368 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
369 /* fetch NOP, STR in EXECUTE stage (1st cycle) */
370 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
371 /* nothing fetched, STR still in EXECUTE (2nd cycle) */
372 arm7tdmi_clock_data_in(jtag_info
, xpsr
);
375 static void arm7tdmi_write_xpsr(struct target
*target
, uint32_t xpsr
, int spsr
)
377 struct arm7_9_common
*arm7_9
= target_to_arm7_9(target
);
378 struct arm_jtag
*jtag_info
= &arm7_9
->jtag_info
;
380 LOG_DEBUG("xpsr: %8.8" PRIx32
", spsr: %i", xpsr
, spsr
);
383 arm7tdmi_clock_out(jtag_info
, ARMV4_5_MSR_IM(xpsr
& 0xff, 0, 1, spsr
), NULL
, 0);
384 /* MSR2 fetched, MSR1 in DECODE */
385 arm7tdmi_clock_out(jtag_info
, ARMV4_5_MSR_IM((xpsr
& 0xff00) >> 8, 0xc, 2, spsr
), NULL
, 0);
386 /* MSR3 fetched, MSR1 in EXECUTE (1), MSR2 in DECODE */
387 arm7tdmi_clock_out(jtag_info
, ARMV4_5_MSR_IM((xpsr
& 0xff0000) >> 16, 0x8, 4, spsr
), NULL
, 0);
388 /* nothing fetched, MSR1 in EXECUTE (2) */
389 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
390 /* MSR4 fetched, MSR2 in EXECUTE (1), MSR3 in DECODE */
391 arm7tdmi_clock_out(jtag_info
, ARMV4_5_MSR_IM((xpsr
& 0xff000000) >> 24, 0x4, 8, spsr
), NULL
, 0);
392 /* nothing fetched, MSR2 in EXECUTE (2) */
393 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
394 /* NOP fetched, MSR3 in EXECUTE (1), MSR4 in DECODE */
395 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
396 /* nothing fetched, MSR3 in EXECUTE (2) */
397 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
398 /* NOP fetched, MSR4 in EXECUTE (1) */
399 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
400 /* nothing fetched, MSR4 in EXECUTE (2) */
401 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
404 static void arm7tdmi_write_xpsr_im8(struct target
*target
,
405 uint8_t xpsr_im
, int rot
, int spsr
)
407 struct arm7_9_common
*arm7_9
= target_to_arm7_9(target
);
408 struct arm_jtag
*jtag_info
= &arm7_9
->jtag_info
;
410 LOG_DEBUG("xpsr_im: %2.2x, rot: %i, spsr: %i", xpsr_im
, rot
, spsr
);
413 arm7tdmi_clock_out(jtag_info
, ARMV4_5_MSR_IM(xpsr_im
, rot
, 1, spsr
), NULL
, 0);
414 /* NOP fetched, MSR in DECODE */
415 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
416 /* NOP fetched, MSR in EXECUTE (1) */
417 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
418 /* nothing fetched, MSR in EXECUTE (2) */
419 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
422 static void arm7tdmi_write_core_regs(struct target
*target
,
423 uint32_t mask
, uint32_t core_regs
[16])
426 struct arm7_9_common
*arm7_9
= target_to_arm7_9(target
);
427 struct arm_jtag
*jtag_info
= &arm7_9
->jtag_info
;
429 /* LDMIA r0-15, [r0] at debug speed
430 * register values will start to appear on 4th DCLK
432 arm7tdmi_clock_out(jtag_info
, ARMV4_5_LDMIA(0, mask
& 0xffff, 0, 0), NULL
, 0);
434 /* fetch NOP, LDM in DECODE stage */
435 arm7tdmi_clock_out_inner(jtag_info
, ARMV4_5_NOP
, 0);
436 /* fetch NOP, LDM in EXECUTE stage (1st cycle) */
437 arm7tdmi_clock_out_inner(jtag_info
, ARMV4_5_NOP
, 0);
439 for (i
= 0; i
<= 15; i
++) {
441 /* nothing fetched, LDM still in EXECUTE (1 + i cycle) */
442 arm7tdmi_clock_out_inner(jtag_info
, core_regs
[i
], 0);
444 arm7tdmi_clock_out_inner(jtag_info
, ARMV4_5_NOP
, 0);
447 static void arm7tdmi_load_word_regs(struct target
*target
, uint32_t mask
)
449 struct arm7_9_common
*arm7_9
= target_to_arm7_9(target
);
450 struct arm_jtag
*jtag_info
= &arm7_9
->jtag_info
;
452 /* put system-speed load-multiple into the pipeline */
453 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
454 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 1);
455 arm7tdmi_clock_out(jtag_info
, ARMV4_5_LDMIA(0, mask
& 0xffff, 0, 1), NULL
, 0);
458 static void arm7tdmi_load_hword_reg(struct target
*target
, int num
)
460 struct arm7_9_common
*arm7_9
= target_to_arm7_9(target
);
461 struct arm_jtag
*jtag_info
= &arm7_9
->jtag_info
;
463 /* put system-speed load half-word into the pipeline */
464 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
465 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 1);
466 arm7tdmi_clock_out(jtag_info
, ARMV4_5_LDRH_IP(num
, 0), NULL
, 0);
469 static void arm7tdmi_load_byte_reg(struct target
*target
, int num
)
471 struct arm7_9_common
*arm7_9
= target_to_arm7_9(target
);
472 struct arm_jtag
*jtag_info
= &arm7_9
->jtag_info
;
474 /* put system-speed load byte into the pipeline */
475 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
476 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 1);
477 arm7tdmi_clock_out(jtag_info
, ARMV4_5_LDRB_IP(num
, 0), NULL
, 0);
480 static void arm7tdmi_store_word_regs(struct target
*target
, uint32_t mask
)
482 struct arm7_9_common
*arm7_9
= target_to_arm7_9(target
);
483 struct arm_jtag
*jtag_info
= &arm7_9
->jtag_info
;
485 /* put system-speed store-multiple into the pipeline */
486 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
487 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 1);
488 arm7tdmi_clock_out(jtag_info
, ARMV4_5_STMIA(0, mask
, 0, 1), NULL
, 0);
491 static void arm7tdmi_store_hword_reg(struct target
*target
, int num
)
493 struct arm7_9_common
*arm7_9
= target_to_arm7_9(target
);
494 struct arm_jtag
*jtag_info
= &arm7_9
->jtag_info
;
496 /* put system-speed store half-word into the pipeline */
497 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
498 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 1);
499 arm7tdmi_clock_out(jtag_info
, ARMV4_5_STRH_IP(num
, 0), NULL
, 0);
502 static void arm7tdmi_store_byte_reg(struct target
*target
, int num
)
504 struct arm7_9_common
*arm7_9
= target_to_arm7_9(target
);
505 struct arm_jtag
*jtag_info
= &arm7_9
->jtag_info
;
507 /* put system-speed store byte into the pipeline */
508 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
509 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 1);
510 arm7tdmi_clock_out(jtag_info
, ARMV4_5_STRB_IP(num
, 0), NULL
, 0);
513 static void arm7tdmi_write_pc(struct target
*target
, uint32_t pc
)
515 struct arm7_9_common
*arm7_9
= target_to_arm7_9(target
);
516 struct arm_jtag
*jtag_info
= &arm7_9
->jtag_info
;
518 /* LDMIA r0-15, [r0] at debug speed
519 * register values will start to appear on 4th DCLK
521 arm7tdmi_clock_out(jtag_info
, ARMV4_5_LDMIA(0, 0x8000, 0, 0), NULL
, 0);
522 /* fetch NOP, LDM in DECODE stage */
523 arm7tdmi_clock_out_inner(jtag_info
, ARMV4_5_NOP
, 0);
524 /* fetch NOP, LDM in EXECUTE stage (1st cycle) */
525 arm7tdmi_clock_out_inner(jtag_info
, ARMV4_5_NOP
, 0);
526 /* nothing fetched, LDM in EXECUTE stage (1st cycle) load register */
527 arm7tdmi_clock_out_inner(jtag_info
, pc
, 0);
528 /* nothing fetched, LDM in EXECUTE stage (2nd cycle) load register */
529 arm7tdmi_clock_out_inner(jtag_info
, ARMV4_5_NOP
, 0);
530 /* nothing fetched, LDM in EXECUTE stage (3rd cycle) load register */
531 arm7tdmi_clock_out_inner(jtag_info
, ARMV4_5_NOP
, 0);
532 /* fetch NOP, LDM in EXECUTE stage (4th cycle) */
533 arm7tdmi_clock_out_inner(jtag_info
, ARMV4_5_NOP
, 0);
534 /* fetch NOP, LDM in EXECUTE stage (5th cycle) */
535 arm7tdmi_clock_out_inner(jtag_info
, ARMV4_5_NOP
, 0);
538 static void arm7tdmi_branch_resume(struct target
*target
)
540 struct arm7_9_common
*arm7_9
= target_to_arm7_9(target
);
541 struct arm_jtag
*jtag_info
= &arm7_9
->jtag_info
;
543 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 1);
544 arm7tdmi_clock_out_inner(jtag_info
, ARMV4_5_B(0xfffffa, 0), 0);
547 static void arm7tdmi_branch_resume_thumb(struct target
*target
)
549 struct arm7_9_common
*arm7_9
= target_to_arm7_9(target
);
550 struct arm
*arm
= &arm7_9
->arm
;
551 struct arm_jtag
*jtag_info
= &arm7_9
->jtag_info
;
552 struct reg
*dbg_stat
= &arm7_9
->eice_cache
->reg_list
[EICE_DBG_STAT
];
556 /* LDMIA r0, [r0] at debug speed
557 * register values will start to appear on 4th DCLK
559 arm7tdmi_clock_out(jtag_info
, ARMV4_5_LDMIA(0, 0x1, 0, 0), NULL
, 0);
561 /* fetch NOP, LDM in DECODE stage */
562 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
563 /* fetch NOP, LDM in EXECUTE stage (1st cycle) */
564 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
565 /* nothing fetched, LDM in EXECUTE stage (2nd cycle) */
566 arm7tdmi_clock_out(jtag_info
,
567 buf_get_u32(arm
->pc
->value
, 0, 32) | 1, NULL
, 0);
568 /* nothing fetched, LDM in EXECUTE stage (3rd cycle) */
569 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
571 /* Branch and eXchange */
572 arm7tdmi_clock_out(jtag_info
, ARMV4_5_BX(0), NULL
, 0);
574 embeddedice_read_reg(dbg_stat
);
576 /* fetch NOP, BX in DECODE stage */
577 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
579 /* target is now in Thumb state */
580 embeddedice_read_reg(dbg_stat
);
582 /* fetch NOP, BX in EXECUTE stage (1st cycle) */
583 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
585 /* target is now in Thumb state */
586 embeddedice_read_reg(dbg_stat
);
589 arm7tdmi_clock_out(jtag_info
, ARMV4_5_T_LDR_PCREL(0), NULL
, 0);
590 /* fetch NOP, LDR in Decode */
591 arm7tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, NULL
, 0);
592 /* fetch NOP, LDR in Execute */
593 arm7tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, NULL
, 0);
594 /* nothing fetched, LDR in EXECUTE stage (2nd cycle) */
595 arm7tdmi_clock_out(jtag_info
, buf_get_u32(arm
->core_cache
->reg_list
[0].value
, 0, 32), NULL
, 0);
596 /* nothing fetched, LDR in EXECUTE stage (3rd cycle) */
597 arm7tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, NULL
, 0);
599 arm7tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, NULL
, 0);
600 arm7tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, NULL
, 0);
602 embeddedice_read_reg(dbg_stat
);
604 arm7tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, NULL
, 1);
605 arm7tdmi_clock_out(jtag_info
, ARMV4_5_T_B(0x7f8), NULL
, 0);
608 static void arm7tdmi_build_reg_cache(struct target
*target
)
610 struct reg_cache
**cache_p
= register_get_last_cache_p(&target
->reg_cache
);
611 struct arm
*arm
= target_to_arm(target
);
613 (*cache_p
) = arm_build_reg_cache(target
, arm
);
616 int arm7tdmi_init_target(struct command_context
*cmd_ctx
, struct target
*target
)
618 arm7tdmi_build_reg_cache(target
);
619 arm_semihosting_init(target
);
623 int arm7tdmi_init_arch_info(struct target
*target
,
624 struct arm7_9_common
*arm7_9
, struct jtag_tap
*tap
)
626 /* prepare JTAG information for the new target */
627 arm7_9
->jtag_info
.tap
= tap
;
628 arm7_9
->jtag_info
.scann_size
= 4;
630 /* register arch-specific functions */
631 arm7_9
->examine_debug_reason
= arm7tdmi_examine_debug_reason
;
632 arm7_9
->change_to_arm
= arm7tdmi_change_to_arm
;
633 arm7_9
->read_core_regs
= arm7tdmi_read_core_regs
;
634 arm7_9
->read_core_regs_target_buffer
= arm7tdmi_read_core_regs_target_buffer
;
635 arm7_9
->read_xpsr
= arm7tdmi_read_xpsr
;
637 arm7_9
->write_xpsr
= arm7tdmi_write_xpsr
;
638 arm7_9
->write_xpsr_im8
= arm7tdmi_write_xpsr_im8
;
639 arm7_9
->write_core_regs
= arm7tdmi_write_core_regs
;
641 arm7_9
->load_word_regs
= arm7tdmi_load_word_regs
;
642 arm7_9
->load_hword_reg
= arm7tdmi_load_hword_reg
;
643 arm7_9
->load_byte_reg
= arm7tdmi_load_byte_reg
;
645 arm7_9
->store_word_regs
= arm7tdmi_store_word_regs
;
646 arm7_9
->store_hword_reg
= arm7tdmi_store_hword_reg
;
647 arm7_9
->store_byte_reg
= arm7tdmi_store_byte_reg
;
649 arm7_9
->write_pc
= arm7tdmi_write_pc
;
650 arm7_9
->branch_resume
= arm7tdmi_branch_resume
;
651 arm7_9
->branch_resume_thumb
= arm7tdmi_branch_resume_thumb
;
653 arm7_9
->enable_single_step
= arm7_9_enable_eice_step
;
654 arm7_9
->disable_single_step
= arm7_9_disable_eice_step
;
656 arm7_9
->write_memory
= arm7_9_write_memory
;
657 arm7_9
->bulk_write_memory
= arm7_9_bulk_write_memory
;
659 arm7_9
->post_debug_entry
= NULL
;
661 arm7_9
->pre_restore_context
= NULL
;
663 /* initialize arch-specific breakpoint handling */
664 arm7_9
->arm_bkpt
= 0xdeeedeee;
665 arm7_9
->thumb_bkpt
= 0xdeee;
667 arm7_9
->dbgreq_adjust_pc
= 2;
669 arm7_9_init_arch_info(target
, arm7_9
);
674 static int arm7tdmi_target_create(struct target
*target
, Jim_Interp
*interp
)
676 struct arm7_9_common
*arm7_9
;
678 arm7_9
= calloc(1, sizeof(struct arm7_9_common
));
679 arm7tdmi_init_arch_info(target
, arm7_9
, target
->tap
);
680 arm7_9
->arm
.is_armv4
= true;
685 /** Holds methods for ARM7TDMI targets. */
686 struct target_type arm7tdmi_target
= {
690 .arch_state
= arm_arch_state
,
692 .target_request_data
= arm7_9_target_request_data
,
695 .resume
= arm7_9_resume
,
698 .assert_reset
= arm7_9_assert_reset
,
699 .deassert_reset
= arm7_9_deassert_reset
,
700 .soft_reset_halt
= arm7_9_soft_reset_halt
,
702 .get_gdb_reg_list
= arm_get_gdb_reg_list
,
704 .read_memory
= arm7_9_read_memory
,
705 .write_memory
= arm7_9_write_memory_opt
,
707 .checksum_memory
= arm_checksum_memory
,
708 .blank_check_memory
= arm_blank_check_memory
,
710 .run_algorithm
= armv4_5_run_algorithm
,
712 .add_breakpoint
= arm7_9_add_breakpoint
,
713 .remove_breakpoint
= arm7_9_remove_breakpoint
,
714 .add_watchpoint
= arm7_9_add_watchpoint
,
715 .remove_watchpoint
= arm7_9_remove_watchpoint
,
717 .commands
= arm7_9_command_handlers
,
718 .target_create
= arm7tdmi_target_create
,
719 .init_target
= arm7tdmi_init_target
,
720 .examine
= arm7_9_examine
,
721 .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)