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 #define _DEBUG_INSTRUCTION_EXECUTION_
38 /* forward declarations */
40 int arm7tdmi_target_create(struct target_s
*target
,Jim_Interp
*interp
);
41 int arm7tdmi_quit(void);
43 /* target function declarations */
44 int arm7tdmi_poll(struct target_s
*target
);
45 int arm7tdmi_halt(target_t
*target
);
47 target_type_t arm7tdmi_target
=
52 .arch_state
= armv4_5_arch_state
,
54 .target_request_data
= arm7_9_target_request_data
,
57 .resume
= arm7_9_resume
,
60 .assert_reset
= arm7_9_assert_reset
,
61 .deassert_reset
= arm7_9_deassert_reset
,
62 .soft_reset_halt
= arm7_9_soft_reset_halt
,
64 .get_gdb_reg_list
= armv4_5_get_gdb_reg_list
,
66 .read_memory
= arm7_9_read_memory
,
67 .write_memory
= arm7_9_write_memory
,
68 .bulk_write_memory
= arm7_9_bulk_write_memory
,
69 .checksum_memory
= arm7_9_checksum_memory
,
70 .blank_check_memory
= arm7_9_blank_check_memory
,
72 .run_algorithm
= armv4_5_run_algorithm
,
74 .add_breakpoint
= arm7_9_add_breakpoint
,
75 .remove_breakpoint
= arm7_9_remove_breakpoint
,
76 .add_watchpoint
= arm7_9_add_watchpoint
,
77 .remove_watchpoint
= arm7_9_remove_watchpoint
,
79 .register_commands
= arm7tdmi_register_commands
,
80 .target_create
= arm7tdmi_target_create
,
81 .init_target
= arm7tdmi_init_target
,
82 .examine
= arm7tdmi_examine
,
86 int arm7tdmi_examine_debug_reason(target_t
*target
)
88 int retval
= ERROR_OK
;
89 /* get pointers to arch-specific information */
90 armv4_5_common_t
*armv4_5
= target
->arch_info
;
91 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
93 /* only check the debug reason if we don't know it already */
94 if ((target
->debug_reason
!= DBG_REASON_DBGRQ
)
95 && (target
->debug_reason
!= DBG_REASON_SINGLESTEP
))
97 scan_field_t fields
[2];
101 jtag_add_end_state(TAP_DRPAUSE
);
103 fields
[0].tap
= arm7_9
->jtag_info
.tap
;
104 fields
[0].num_bits
= 1;
105 fields
[0].out_value
= NULL
;
106 fields
[0].in_value
= &breakpoint
;
108 fields
[1].tap
= arm7_9
->jtag_info
.tap
;
109 fields
[1].num_bits
= 32;
110 fields
[1].out_value
= NULL
;
111 fields
[1].in_value
= databus
;
113 if((retval
= arm_jtag_scann(&arm7_9
->jtag_info
, 0x1)) != ERROR_OK
)
117 arm_jtag_set_instr(&arm7_9
->jtag_info
, arm7_9
->jtag_info
.intest_instr
, NULL
);
119 jtag_add_dr_scan(2, fields
, TAP_DRPAUSE
);
120 if((retval
= jtag_execute_queue()) != ERROR_OK
)
125 fields
[0].in_value
= NULL
;
126 fields
[0].out_value
= &breakpoint
;
127 fields
[1].in_value
= NULL
;
128 fields
[1].out_value
= databus
;
130 jtag_add_dr_scan(2, fields
, TAP_DRPAUSE
);
133 target
->debug_reason
= DBG_REASON_WATCHPOINT
;
135 target
->debug_reason
= DBG_REASON_BREAKPOINT
;
141 static int arm7tdmi_num_bits
[]={1, 32};
142 static __inline
int arm7tdmi_clock_out_inner(arm_jtag_t
*jtag_info
, u32 out
, int breakpoint
)
144 u32 values
[2]={breakpoint
, flip_u32(out
, 32)};
146 jtag_add_dr_out(jtag_info
->tap
,
150 jtag_add_end_state(TAP_INVALID
));
152 jtag_add_runtest(0, jtag_add_end_state(TAP_INVALID
));
157 /* put an instruction in the ARM7TDMI pipeline or write the data bus, and optionally read data */
158 static __inline
int arm7tdmi_clock_out(arm_jtag_t
*jtag_info
, u32 out
, u32
*deprecated
, int breakpoint
)
160 jtag_add_end_state(TAP_DRPAUSE
);
161 arm_jtag_scann(jtag_info
, 0x1);
162 arm_jtag_set_instr(jtag_info
, jtag_info
->intest_instr
, NULL
);
164 return arm7tdmi_clock_out_inner(jtag_info
, out
, breakpoint
);
167 /* clock the target, reading the databus */
168 int arm7tdmi_clock_data_in(arm_jtag_t
*jtag_info
, u32
*in
)
170 int retval
= ERROR_OK
;
171 scan_field_t fields
[2];
173 jtag_add_end_state(TAP_DRPAUSE
);
174 if((retval
= arm_jtag_scann(jtag_info
, 0x1)) != ERROR_OK
)
178 arm_jtag_set_instr(jtag_info
, jtag_info
->intest_instr
, NULL
);
180 fields
[0].tap
= jtag_info
->tap
;
181 fields
[0].num_bits
= 1;
182 fields
[0].out_value
= NULL
;
183 fields
[0].in_value
= NULL
;
185 fields
[1].tap
= jtag_info
->tap
;
186 fields
[1].num_bits
= 32;
187 fields
[1].out_value
= NULL
;
188 fields
[1].in_value
= (u8
*)in
;
190 jtag_add_dr_scan(2, fields
, jtag_add_end_state(TAP_INVALID
));
192 jtag_add_callback(arm7flip32
, (u8
*)in
);
194 jtag_add_runtest(0, jtag_add_end_state(TAP_INVALID
));
196 #ifdef _DEBUG_INSTRUCTION_EXECUTION_
198 if((retval
= jtag_execute_queue()) != ERROR_OK
)
205 LOG_DEBUG("in: 0x%8.8x", *in
);
209 LOG_ERROR("BUG: called with in == NULL");
217 void arm_endianness(u8
*tmp
, void *in
, int size
, int be
, int flip
)
219 u32 readback
=le_to_h_u32(tmp
);
221 readback
=flip_u32(readback
, 32);
227 h_u32_to_be(((u8
*)in
), readback
);
230 h_u32_to_le(((u8
*)in
), readback
);
236 h_u16_to_be(((u8
*)in
), readback
& 0xffff);
239 h_u16_to_le(((u8
*)in
), readback
& 0xffff);
243 *((u8
*)in
)= readback
& 0xff;
248 static int arm7endianness(u8
*in
, jtag_callback_data_t size
, jtag_callback_data_t be
, jtag_callback_data_t captured
)
250 arm_endianness((u8
*)captured
, in
, (int)size
, (int)be
, 1);
254 /* clock the target, and read the databus
255 * the *in pointer points to a buffer where elements of 'size' bytes
256 * are stored in big (be==1) or little (be==0) endianness
258 int arm7tdmi_clock_data_in_endianness(arm_jtag_t
*jtag_info
, void *in
, int size
, int be
)
260 int retval
= ERROR_OK
;
261 scan_field_t fields
[2];
263 jtag_add_end_state(TAP_DRPAUSE
);
264 if((retval
= arm_jtag_scann(jtag_info
, 0x1)) != ERROR_OK
)
268 arm_jtag_set_instr(jtag_info
, jtag_info
->intest_instr
, NULL
);
270 fields
[0].tap
= jtag_info
->tap
;
271 fields
[0].num_bits
= 1;
272 fields
[0].out_value
= NULL
;
273 fields
[0].in_value
= NULL
;
275 fields
[1].tap
= jtag_info
->tap
;
276 fields
[1].num_bits
= 32;
277 fields
[1].out_value
= NULL
;
278 jtag_alloc_in_value32(&fields
[1]);
280 jtag_add_dr_scan(2, fields
, jtag_add_end_state(TAP_INVALID
));
282 jtag_add_callback4(arm7endianness
, in
, (jtag_callback_data_t
)size
, (jtag_callback_data_t
)be
, (jtag_callback_data_t
)fields
[1].in_value
);
284 jtag_add_runtest(0, jtag_add_end_state(TAP_INVALID
));
286 #ifdef _DEBUG_INSTRUCTION_EXECUTION_
288 if((retval
= jtag_execute_queue()) != ERROR_OK
)
295 LOG_DEBUG("in: 0x%8.8x", *(u32
*)in
);
299 LOG_ERROR("BUG: called with in == NULL");
307 void arm7tdmi_change_to_arm(target_t
*target
, u32
*r0
, u32
*pc
)
309 /* get pointers to arch-specific information */
310 armv4_5_common_t
*armv4_5
= target
->arch_info
;
311 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
312 arm_jtag_t
*jtag_info
= &arm7_9
->jtag_info
;
314 /* save r0 before using it and put system in ARM state
315 * to allow common handling of ARM and THUMB debugging */
317 /* fetch STR r0, [r0] */
318 arm7tdmi_clock_out(jtag_info
, ARMV4_5_T_STR(0, 0), NULL
, 0);
319 arm7tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, NULL
, 0);
320 arm7tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, NULL
, 0);
321 /* nothing fetched, STR r0, [r0] in Execute (2) */
322 arm7tdmi_clock_data_in(jtag_info
, r0
);
324 /* MOV r0, r15 fetched, STR in Decode */
325 arm7tdmi_clock_out(jtag_info
, ARMV4_5_T_MOV(0, 15), NULL
, 0);
326 arm7tdmi_clock_out(jtag_info
, ARMV4_5_T_STR(0, 0), NULL
, 0);
327 arm7tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, NULL
, 0);
328 arm7tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, NULL
, 0);
329 /* nothing fetched, STR r0, [r0] in Execute (2) */
330 arm7tdmi_clock_data_in(jtag_info
, pc
);
332 /* use pc-relative LDR to clear r0[1:0] (for switch to ARM mode) */
333 arm7tdmi_clock_out(jtag_info
, ARMV4_5_T_LDR_PCREL(0), NULL
, 0);
334 arm7tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, NULL
, 0);
335 arm7tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, NULL
, 0);
336 /* nothing fetched, data for LDR r0, [PC, #0] */
337 arm7tdmi_clock_out(jtag_info
, 0x0, NULL
, 0);
338 /* nothing fetched, data from previous cycle is written to register */
339 arm7tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, NULL
, 0);
342 arm7tdmi_clock_out(jtag_info
, ARMV4_5_T_BX(0), NULL
, 0);
343 /* NOP fetched, BX in Decode, MOV in Execute */
344 arm7tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, NULL
, 0);
345 /* NOP fetched, BX in Execute (1) */
346 arm7tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, NULL
, 0);
348 jtag_execute_queue();
350 /* fix program counter:
351 * MOV r0, r15 was the 4th instruction (+6)
352 * reading PC in Thumb state gives address of instruction + 4
358 /* FIX!!! is this a potential performance bottleneck w.r.t. requiring too many
359 * roundtrips when jtag_execute_queue() has a large overhead(e.g. for USB)s?
361 * The solution is to arrange for a large out/in scan in this loop and
362 * and convert data afterwards.
364 void arm7tdmi_read_core_regs(target_t
*target
, u32 mask
, u32
* core_regs
[16])
367 /* get pointers to arch-specific information */
368 armv4_5_common_t
*armv4_5
= target
->arch_info
;
369 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
370 arm_jtag_t
*jtag_info
= &arm7_9
->jtag_info
;
372 /* STMIA r0-15, [r0] at debug speed
373 * register values will start to appear on 4th DCLK
375 arm7tdmi_clock_out(jtag_info
, ARMV4_5_STMIA(0, mask
& 0xffff, 0, 0), NULL
, 0);
377 /* fetch NOP, STM in DECODE stage */
378 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
379 /* fetch NOP, STM in EXECUTE stage (1st cycle) */
380 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
382 for (i
= 0; i
<= 15; i
++)
385 /* nothing fetched, STM still in EXECUTE (1+i cycle) */
386 arm7tdmi_clock_data_in(jtag_info
, core_regs
[i
]);
390 void arm7tdmi_read_core_regs_target_buffer(target_t
*target
, u32 mask
, void* buffer
, int size
)
393 /* get pointers to arch-specific information */
394 armv4_5_common_t
*armv4_5
= target
->arch_info
;
395 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
396 arm_jtag_t
*jtag_info
= &arm7_9
->jtag_info
;
397 int be
= (target
->endianness
== TARGET_BIG_ENDIAN
) ? 1 : 0;
398 u32
*buf_u32
= buffer
;
399 u16
*buf_u16
= buffer
;
402 /* STMIA r0-15, [r0] at debug speed
403 * register values will start to appear on 4th DCLK
405 arm7tdmi_clock_out(jtag_info
, ARMV4_5_STMIA(0, mask
& 0xffff, 0, 0), NULL
, 0);
407 /* fetch NOP, STM in DECODE stage */
408 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
409 /* fetch NOP, STM in EXECUTE stage (1st cycle) */
410 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
412 for (i
= 0; i
<= 15; i
++)
414 /* nothing fetched, STM still in EXECUTE (1+i cycle), read databus */
420 arm7tdmi_clock_data_in_endianness(jtag_info
, buf_u32
++, 4, be
);
423 arm7tdmi_clock_data_in_endianness(jtag_info
, buf_u16
++, 2, be
);
426 arm7tdmi_clock_data_in_endianness(jtag_info
, buf_u8
++, 1, be
);
433 void arm7tdmi_read_xpsr(target_t
*target
, u32
*xpsr
, int spsr
)
435 /* get pointers to arch-specific information */
436 armv4_5_common_t
*armv4_5
= target
->arch_info
;
437 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
438 arm_jtag_t
*jtag_info
= &arm7_9
->jtag_info
;
441 arm7tdmi_clock_out(jtag_info
, ARMV4_5_MRS(0, spsr
& 1), NULL
, 0);
444 arm7tdmi_clock_out(jtag_info
, ARMV4_5_STR(0, 15), NULL
, 0);
445 /* fetch NOP, STR in DECODE stage */
446 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
447 /* fetch NOP, STR in EXECUTE stage (1st cycle) */
448 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
449 /* nothing fetched, STR still in EXECUTE (2nd cycle) */
450 arm7tdmi_clock_data_in(jtag_info
, xpsr
);
453 void arm7tdmi_write_xpsr(target_t
*target
, u32 xpsr
, int spsr
)
455 /* get pointers to arch-specific information */
456 armv4_5_common_t
*armv4_5
= target
->arch_info
;
457 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
458 arm_jtag_t
*jtag_info
= &arm7_9
->jtag_info
;
460 LOG_DEBUG("xpsr: %8.8x, spsr: %i", xpsr
, spsr
);
463 arm7tdmi_clock_out(jtag_info
, ARMV4_5_MSR_IM(xpsr
& 0xff, 0, 1, spsr
), NULL
, 0);
464 /* MSR2 fetched, MSR1 in DECODE */
465 arm7tdmi_clock_out(jtag_info
, ARMV4_5_MSR_IM((xpsr
& 0xff00) >> 8, 0xc, 2, spsr
), NULL
, 0);
466 /* MSR3 fetched, MSR1 in EXECUTE (1), MSR2 in DECODE */
467 arm7tdmi_clock_out(jtag_info
, ARMV4_5_MSR_IM((xpsr
& 0xff0000) >> 16, 0x8, 4, spsr
), NULL
, 0);
468 /* nothing fetched, MSR1 in EXECUTE (2) */
469 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
470 /* MSR4 fetched, MSR2 in EXECUTE (1), MSR3 in DECODE */
471 arm7tdmi_clock_out(jtag_info
, ARMV4_5_MSR_IM((xpsr
& 0xff000000) >> 24, 0x4, 8, spsr
), NULL
, 0);
472 /* nothing fetched, MSR2 in EXECUTE (2) */
473 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
474 /* NOP fetched, MSR3 in EXECUTE (1), MSR4 in DECODE */
475 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
476 /* nothing fetched, MSR3 in EXECUTE (2) */
477 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
478 /* NOP fetched, MSR4 in EXECUTE (1) */
479 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
480 /* nothing fetched, MSR4 in EXECUTE (2) */
481 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
484 void arm7tdmi_write_xpsr_im8(target_t
*target
, u8 xpsr_im
, int rot
, int spsr
)
486 /* get pointers to arch-specific information */
487 armv4_5_common_t
*armv4_5
= target
->arch_info
;
488 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
489 arm_jtag_t
*jtag_info
= &arm7_9
->jtag_info
;
491 LOG_DEBUG("xpsr_im: %2.2x, rot: %i, spsr: %i", xpsr_im
, rot
, spsr
);
494 arm7tdmi_clock_out(jtag_info
, ARMV4_5_MSR_IM(xpsr_im
, rot
, 1, spsr
), NULL
, 0);
495 /* NOP fetched, MSR in DECODE */
496 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
497 /* NOP fetched, MSR in EXECUTE (1) */
498 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
499 /* nothing fetched, MSR in EXECUTE (2) */
500 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
503 void arm7tdmi_write_core_regs(target_t
*target
, u32 mask
, u32 core_regs
[16])
506 /* get pointers to arch-specific information */
507 armv4_5_common_t
*armv4_5
= target
->arch_info
;
508 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
509 arm_jtag_t
*jtag_info
= &arm7_9
->jtag_info
;
511 /* LDMIA r0-15, [r0] at debug speed
512 * register values will start to appear on 4th DCLK
514 arm7tdmi_clock_out(jtag_info
, ARMV4_5_LDMIA(0, mask
& 0xffff, 0, 0), NULL
, 0);
516 /* fetch NOP, LDM in DECODE stage */
517 arm7tdmi_clock_out_inner(jtag_info
, ARMV4_5_NOP
, 0);
518 /* fetch NOP, LDM in EXECUTE stage (1st cycle) */
519 arm7tdmi_clock_out_inner(jtag_info
, ARMV4_5_NOP
, 0);
521 for (i
= 0; i
<= 15; i
++)
524 /* nothing fetched, LDM still in EXECUTE (1+i cycle) */
525 arm7tdmi_clock_out_inner(jtag_info
, core_regs
[i
], 0);
527 arm7tdmi_clock_out_inner(jtag_info
, ARMV4_5_NOP
, 0);
530 void arm7tdmi_load_word_regs(target_t
*target
, u32 mask
)
532 /* get pointers to arch-specific information */
533 armv4_5_common_t
*armv4_5
= target
->arch_info
;
534 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
535 arm_jtag_t
*jtag_info
= &arm7_9
->jtag_info
;
537 /* put system-speed load-multiple into the pipeline */
538 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
539 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 1);
540 arm7tdmi_clock_out(jtag_info
, ARMV4_5_LDMIA(0, mask
& 0xffff, 0, 1), NULL
, 0);
543 void arm7tdmi_load_hword_reg(target_t
*target
, int num
)
545 /* get pointers to arch-specific information */
546 armv4_5_common_t
*armv4_5
= target
->arch_info
;
547 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
548 arm_jtag_t
*jtag_info
= &arm7_9
->jtag_info
;
550 /* put system-speed load half-word into the pipeline */
551 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
552 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 1);
553 arm7tdmi_clock_out(jtag_info
, ARMV4_5_LDRH_IP(num
, 0), NULL
, 0);
556 void arm7tdmi_load_byte_reg(target_t
*target
, int num
)
558 /* get pointers to arch-specific information */
559 armv4_5_common_t
*armv4_5
= target
->arch_info
;
560 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
561 arm_jtag_t
*jtag_info
= &arm7_9
->jtag_info
;
563 /* put system-speed load byte into the pipeline */
564 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
565 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 1);
566 arm7tdmi_clock_out(jtag_info
, ARMV4_5_LDRB_IP(num
, 0), NULL
, 0);
569 void arm7tdmi_store_word_regs(target_t
*target
, u32 mask
)
571 /* get pointers to arch-specific information */
572 armv4_5_common_t
*armv4_5
= target
->arch_info
;
573 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
574 arm_jtag_t
*jtag_info
= &arm7_9
->jtag_info
;
576 /* put system-speed store-multiple into the pipeline */
577 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
578 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 1);
579 arm7tdmi_clock_out(jtag_info
, ARMV4_5_STMIA(0, mask
, 0, 1), NULL
, 0);
582 void arm7tdmi_store_hword_reg(target_t
*target
, int num
)
584 /* get pointers to arch-specific information */
585 armv4_5_common_t
*armv4_5
= target
->arch_info
;
586 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
587 arm_jtag_t
*jtag_info
= &arm7_9
->jtag_info
;
589 /* put system-speed store half-word into the pipeline */
590 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
591 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 1);
592 arm7tdmi_clock_out(jtag_info
, ARMV4_5_STRH_IP(num
, 0), NULL
, 0);
595 void arm7tdmi_store_byte_reg(target_t
*target
, int num
)
597 /* get pointers to arch-specific information */
598 armv4_5_common_t
*armv4_5
= target
->arch_info
;
599 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
600 arm_jtag_t
*jtag_info
= &arm7_9
->jtag_info
;
602 /* put system-speed store byte into the pipeline */
603 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
604 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 1);
605 arm7tdmi_clock_out(jtag_info
, ARMV4_5_STRB_IP(num
, 0), NULL
, 0);
608 void arm7tdmi_write_pc(target_t
*target
, u32 pc
)
610 /* get pointers to arch-specific information */
611 armv4_5_common_t
*armv4_5
= target
->arch_info
;
612 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
613 arm_jtag_t
*jtag_info
= &arm7_9
->jtag_info
;
615 /* LDMIA r0-15, [r0] at debug speed
616 * register values will start to appear on 4th DCLK
618 arm7tdmi_clock_out(jtag_info
, ARMV4_5_LDMIA(0, 0x8000, 0, 0), NULL
, 0);
619 /* fetch NOP, LDM in DECODE stage */
620 arm7tdmi_clock_out_inner(jtag_info
, ARMV4_5_NOP
, 0);
621 /* fetch NOP, LDM in EXECUTE stage (1st cycle) */
622 arm7tdmi_clock_out_inner(jtag_info
, ARMV4_5_NOP
, 0);
623 /* nothing fetched, LDM in EXECUTE stage (1st cycle) load register */
624 arm7tdmi_clock_out_inner(jtag_info
, pc
, 0);
625 /* nothing fetched, LDM in EXECUTE stage (2nd cycle) load register */
626 arm7tdmi_clock_out_inner(jtag_info
, ARMV4_5_NOP
, 0);
627 /* nothing fetched, LDM in EXECUTE stage (3rd cycle) load register */
628 arm7tdmi_clock_out_inner(jtag_info
, ARMV4_5_NOP
, 0);
629 /* fetch NOP, LDM in EXECUTE stage (4th cycle) */
630 arm7tdmi_clock_out_inner(jtag_info
, ARMV4_5_NOP
, 0);
631 /* fetch NOP, LDM in EXECUTE stage (5th cycle) */
632 arm7tdmi_clock_out_inner(jtag_info
, ARMV4_5_NOP
, 0);
635 void arm7tdmi_branch_resume(target_t
*target
)
637 /* get pointers to arch-specific information */
638 armv4_5_common_t
*armv4_5
= target
->arch_info
;
639 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
640 arm_jtag_t
*jtag_info
= &arm7_9
->jtag_info
;
642 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 1);
643 arm7tdmi_clock_out_inner(jtag_info
, ARMV4_5_B(0xfffffa, 0), 0);
646 void arm7tdmi_branch_resume_thumb(target_t
*target
)
650 /* get pointers to arch-specific information */
651 armv4_5_common_t
*armv4_5
= target
->arch_info
;
652 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
653 arm_jtag_t
*jtag_info
= &arm7_9
->jtag_info
;
654 reg_t
*dbg_stat
= &arm7_9
->eice_cache
->reg_list
[EICE_DBG_STAT
];
656 /* LDMIA r0, [r0] at debug speed
657 * register values will start to appear on 4th DCLK
659 arm7tdmi_clock_out(jtag_info
, ARMV4_5_LDMIA(0, 0x1, 0, 0), NULL
, 0);
661 /* fetch NOP, LDM in DECODE stage */
662 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
663 /* fetch NOP, LDM in EXECUTE stage (1st cycle) */
664 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
665 /* nothing fetched, LDM in EXECUTE stage (2nd cycle) */
666 arm7tdmi_clock_out(jtag_info
, buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32) | 1, NULL
, 0);
667 /* nothing fetched, LDM in EXECUTE stage (3rd cycle) */
668 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
670 /* Branch and eXchange */
671 arm7tdmi_clock_out(jtag_info
, ARMV4_5_BX(0), NULL
, 0);
673 embeddedice_read_reg(dbg_stat
);
675 /* fetch NOP, BX in DECODE stage */
676 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
678 /* target is now in Thumb state */
679 embeddedice_read_reg(dbg_stat
);
681 /* fetch NOP, BX in EXECUTE stage (1st cycle) */
682 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
684 /* target is now in Thumb state */
685 embeddedice_read_reg(dbg_stat
);
688 arm7tdmi_clock_out(jtag_info
, ARMV4_5_T_LDR_PCREL(0), NULL
, 0);
689 /* fetch NOP, LDR in Decode */
690 arm7tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, NULL
, 0);
691 /* fetch NOP, LDR in Execute */
692 arm7tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, NULL
, 0);
693 /* nothing fetched, LDR in EXECUTE stage (2nd cycle) */
694 arm7tdmi_clock_out(jtag_info
, buf_get_u32(armv4_5
->core_cache
->reg_list
[0].value
, 0, 32), NULL
, 0);
695 /* nothing fetched, LDR in EXECUTE stage (3rd cycle) */
696 arm7tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, NULL
, 0);
698 arm7tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, NULL
, 0);
699 arm7tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, NULL
, 0);
701 embeddedice_read_reg(dbg_stat
);
703 arm7tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, NULL
, 1);
704 arm7tdmi_clock_out(jtag_info
, ARMV4_5_T_B(0x7f8), NULL
, 0);
707 void arm7tdmi_build_reg_cache(target_t
*target
)
709 reg_cache_t
**cache_p
= register_get_last_cache_p(&target
->reg_cache
);
710 /* get pointers to arch-specific information */
711 armv4_5_common_t
*armv4_5
= target
->arch_info
;
713 (*cache_p
) = armv4_5_build_reg_cache(target
, armv4_5
);
714 armv4_5
->core_cache
= (*cache_p
);
717 int arm7tdmi_examine(struct target_s
*target
)
720 armv4_5_common_t
*armv4_5
= target
->arch_info
;
721 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
722 if (!target_was_examined(target
))
724 /* get pointers to arch-specific information */
725 reg_cache_t
**cache_p
= register_get_last_cache_p(&target
->reg_cache
);
726 reg_cache_t
*t
=embeddedice_build_reg_cache(target
, arm7_9
);
731 arm7_9
->eice_cache
= (*cache_p
);
735 arm_jtag_t
*jtag_info
= &arm7_9
->jtag_info
;
736 (*cache_p
)->next
= etm_build_reg_cache(target
, jtag_info
, arm7_9
->etm_ctx
);
737 arm7_9
->etm_ctx
->reg_cache
= (*cache_p
)->next
;
739 target_set_examined(target
);
741 if ((retval
=embeddedice_setup(target
))!=ERROR_OK
)
743 if ((retval
=arm7_9_setup(target
))!=ERROR_OK
)
747 if ((retval
=etm_setup(target
))!=ERROR_OK
)
753 int arm7tdmi_init_target(struct command_context_s
*cmd_ctx
, struct target_s
*target
)
755 arm7tdmi_build_reg_cache(target
);
760 int arm7tdmi_quit(void)
765 int arm7tdmi_init_arch_info(target_t
*target
, arm7tdmi_common_t
*arm7tdmi
, jtag_tap_t
*tap
)
767 armv4_5_common_t
*armv4_5
;
768 arm7_9_common_t
*arm7_9
;
770 arm7_9
= &arm7tdmi
->arm7_9_common
;
771 armv4_5
= &arm7_9
->armv4_5_common
;
773 /* prepare JTAG information for the new target */
774 arm7_9
->jtag_info
.tap
= tap
;
775 arm7_9
->jtag_info
.scann_size
= 4;
777 /* register arch-specific functions */
778 arm7_9
->examine_debug_reason
= arm7tdmi_examine_debug_reason
;
779 arm7_9
->change_to_arm
= arm7tdmi_change_to_arm
;
780 arm7_9
->read_core_regs
= arm7tdmi_read_core_regs
;
781 arm7_9
->read_core_regs_target_buffer
= arm7tdmi_read_core_regs_target_buffer
;
782 arm7_9
->read_xpsr
= arm7tdmi_read_xpsr
;
784 arm7_9
->write_xpsr
= arm7tdmi_write_xpsr
;
785 arm7_9
->write_xpsr_im8
= arm7tdmi_write_xpsr_im8
;
786 arm7_9
->write_core_regs
= arm7tdmi_write_core_regs
;
788 arm7_9
->load_word_regs
= arm7tdmi_load_word_regs
;
789 arm7_9
->load_hword_reg
= arm7tdmi_load_hword_reg
;
790 arm7_9
->load_byte_reg
= arm7tdmi_load_byte_reg
;
792 arm7_9
->store_word_regs
= arm7tdmi_store_word_regs
;
793 arm7_9
->store_hword_reg
= arm7tdmi_store_hword_reg
;
794 arm7_9
->store_byte_reg
= arm7tdmi_store_byte_reg
;
796 arm7_9
->write_pc
= arm7tdmi_write_pc
;
797 arm7_9
->branch_resume
= arm7tdmi_branch_resume
;
798 arm7_9
->branch_resume_thumb
= arm7tdmi_branch_resume_thumb
;
800 arm7_9
->enable_single_step
= arm7_9_enable_eice_step
;
801 arm7_9
->disable_single_step
= arm7_9_disable_eice_step
;
803 arm7_9
->pre_debug_entry
= NULL
;
804 arm7_9
->post_debug_entry
= NULL
;
806 arm7_9
->pre_restore_context
= NULL
;
807 arm7_9
->post_restore_context
= NULL
;
809 /* initialize arch-specific breakpoint handling */
810 arm7_9
->arm_bkpt
= 0xdeeedeee;
811 arm7_9
->thumb_bkpt
= 0xdeee;
813 arm7_9
->dbgreq_adjust_pc
= 2;
814 arm7_9
->arch_info
= arm7tdmi
;
816 arm7tdmi
->arch_info
= NULL
;
817 arm7tdmi
->common_magic
= ARM7TDMI_COMMON_MAGIC
;
819 arm7_9_init_arch_info(target
, arm7_9
);
824 int arm7tdmi_target_create( struct target_s
*target
, Jim_Interp
*interp
)
826 arm7tdmi_common_t
*arm7tdmi
;
828 arm7tdmi
= calloc(1,sizeof(arm7tdmi_common_t
));
829 arm7tdmi_init_arch_info(target
, arm7tdmi
, target
->tap
);
834 int arm7tdmi_register_commands(struct command_context_s
*cmd_ctx
)
838 retval
= arm7_9_register_commands(cmd_ctx
);
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)