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_set_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
, jtag_set_end_state(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
, jtag_set_end_state(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
, uint32_t out
, int breakpoint
)
144 uint32_t values
[2]={breakpoint
, flip_u32(out
, 32)};
146 jtag_add_dr_out(jtag_info
->tap
,
150 jtag_get_end_state());
152 jtag_add_runtest(0, jtag_get_end_state());
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
, uint32_t out
, uint32_t *deprecated
, int breakpoint
)
160 jtag_set_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
, uint32_t *in
)
170 int retval
= ERROR_OK
;
171 scan_field_t fields
[2];
173 jtag_set_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
= (uint8_t *)in
;
190 jtag_add_dr_scan(2, fields
, jtag_get_end_state());
192 jtag_add_callback(arm7flip32
, (jtag_callback_data_t
)in
);
194 jtag_add_runtest(0, jtag_get_end_state());
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(uint8_t *tmp
, void *in
, int size
, int be
, int flip
)
219 uint32_t readback
= le_to_h_u32(tmp
);
221 readback
= flip_u32(readback
, 32);
227 h_u32_to_be(((uint8_t*)in
), readback
);
230 h_u32_to_le(((uint8_t*)in
), readback
);
236 h_u16_to_be(((uint8_t*)in
), readback
& 0xffff);
239 h_u16_to_le(((uint8_t*)in
), readback
& 0xffff);
243 *((uint8_t *)in
)= readback
& 0xff;
248 static int arm7endianness(jtag_callback_data_t arg
, jtag_callback_data_t size
, jtag_callback_data_t be
, jtag_callback_data_t captured
)
250 uint8_t *in
= (uint8_t *)arg
;
251 arm_endianness((uint8_t *)captured
, in
, (int)size
, (int)be
, 1);
255 /* clock the target, and read the databus
256 * the *in pointer points to a buffer where elements of 'size' bytes
257 * are stored in big (be == 1) or little (be == 0) endianness
259 int arm7tdmi_clock_data_in_endianness(arm_jtag_t
*jtag_info
, void *in
, int size
, int be
)
261 int retval
= ERROR_OK
;
262 scan_field_t fields
[2];
264 jtag_set_end_state(TAP_DRPAUSE
);
265 if ((retval
= arm_jtag_scann(jtag_info
, 0x1)) != ERROR_OK
)
269 arm_jtag_set_instr(jtag_info
, jtag_info
->intest_instr
, NULL
);
271 fields
[0].tap
= jtag_info
->tap
;
272 fields
[0].num_bits
= 1;
273 fields
[0].out_value
= NULL
;
274 fields
[0].in_value
= NULL
;
276 fields
[1].tap
= jtag_info
->tap
;
277 fields
[1].num_bits
= 32;
278 fields
[1].out_value
= NULL
;
279 jtag_alloc_in_value32(&fields
[1]);
281 jtag_add_dr_scan(2, fields
, jtag_get_end_state());
283 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
);
285 jtag_add_runtest(0, jtag_get_end_state());
287 #ifdef _DEBUG_INSTRUCTION_EXECUTION_
289 if ((retval
= jtag_execute_queue()) != ERROR_OK
)
296 LOG_DEBUG("in: 0x%8.8x", *(uint32_t*)in
);
300 LOG_ERROR("BUG: called with in == NULL");
308 void arm7tdmi_change_to_arm(target_t
*target
, uint32_t *r0
, uint32_t *pc
)
310 /* get pointers to arch-specific information */
311 armv4_5_common_t
*armv4_5
= target
->arch_info
;
312 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
313 arm_jtag_t
*jtag_info
= &arm7_9
->jtag_info
;
315 /* save r0 before using it and put system in ARM state
316 * to allow common handling of ARM and THUMB debugging */
318 /* fetch STR r0, [r0] */
319 arm7tdmi_clock_out(jtag_info
, ARMV4_5_T_STR(0, 0), NULL
, 0);
320 arm7tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, NULL
, 0);
321 arm7tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, NULL
, 0);
322 /* nothing fetched, STR r0, [r0] in Execute (2) */
323 arm7tdmi_clock_data_in(jtag_info
, r0
);
325 /* MOV r0, r15 fetched, STR in Decode */
326 arm7tdmi_clock_out(jtag_info
, ARMV4_5_T_MOV(0, 15), NULL
, 0);
327 arm7tdmi_clock_out(jtag_info
, ARMV4_5_T_STR(0, 0), NULL
, 0);
328 arm7tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, NULL
, 0);
329 arm7tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, NULL
, 0);
330 /* nothing fetched, STR r0, [r0] in Execute (2) */
331 arm7tdmi_clock_data_in(jtag_info
, pc
);
333 /* use pc-relative LDR to clear r0[1:0] (for switch to ARM mode) */
334 arm7tdmi_clock_out(jtag_info
, ARMV4_5_T_LDR_PCREL(0), NULL
, 0);
335 arm7tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, NULL
, 0);
336 arm7tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, NULL
, 0);
337 /* nothing fetched, data for LDR r0, [PC, #0] */
338 arm7tdmi_clock_out(jtag_info
, 0x0, NULL
, 0);
339 /* nothing fetched, data from previous cycle is written to register */
340 arm7tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, NULL
, 0);
343 arm7tdmi_clock_out(jtag_info
, ARMV4_5_T_BX(0), NULL
, 0);
344 /* NOP fetched, BX in Decode, MOV in Execute */
345 arm7tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, NULL
, 0);
346 /* NOP fetched, BX in Execute (1) */
347 arm7tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, NULL
, 0);
349 jtag_execute_queue();
351 /* fix program counter:
352 * MOV r0, r15 was the 4th instruction (+6)
353 * reading PC in Thumb state gives address of instruction + 4
359 /* FIX!!! is this a potential performance bottleneck w.r.t. requiring too many
360 * roundtrips when jtag_execute_queue() has a large overhead(e.g. for USB)s?
362 * The solution is to arrange for a large out/in scan in this loop and
363 * and convert data afterwards.
365 void arm7tdmi_read_core_regs(target_t
*target
, uint32_t mask
, uint32_t* core_regs
[16])
368 /* get pointers to arch-specific information */
369 armv4_5_common_t
*armv4_5
= target
->arch_info
;
370 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
371 arm_jtag_t
*jtag_info
= &arm7_9
->jtag_info
;
373 /* STMIA r0-15, [r0] at debug speed
374 * register values will start to appear on 4th DCLK
376 arm7tdmi_clock_out(jtag_info
, ARMV4_5_STMIA(0, mask
& 0xffff, 0, 0), NULL
, 0);
378 /* fetch NOP, STM in DECODE stage */
379 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
380 /* fetch NOP, STM in EXECUTE stage (1st cycle) */
381 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
383 for (i
= 0; i
<= 15; i
++)
386 /* nothing fetched, STM still in EXECUTE (1 + i cycle) */
387 arm7tdmi_clock_data_in(jtag_info
, core_regs
[i
]);
391 void arm7tdmi_read_core_regs_target_buffer(target_t
*target
, uint32_t mask
, void* buffer
, int size
)
394 /* get pointers to arch-specific information */
395 armv4_5_common_t
*armv4_5
= target
->arch_info
;
396 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
397 arm_jtag_t
*jtag_info
= &arm7_9
->jtag_info
;
398 int be
= (target
->endianness
== TARGET_BIG_ENDIAN
) ? 1 : 0;
399 uint32_t *buf_u32
= buffer
;
400 uint16_t *buf_u16
= buffer
;
401 uint8_t *buf_u8
= buffer
;
403 /* STMIA r0-15, [r0] at debug speed
404 * register values will start to appear on 4th DCLK
406 arm7tdmi_clock_out(jtag_info
, ARMV4_5_STMIA(0, mask
& 0xffff, 0, 0), NULL
, 0);
408 /* fetch NOP, STM in DECODE stage */
409 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
410 /* fetch NOP, STM in EXECUTE stage (1st cycle) */
411 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
413 for (i
= 0; i
<= 15; i
++)
415 /* nothing fetched, STM still in EXECUTE (1 + i cycle), read databus */
421 arm7tdmi_clock_data_in_endianness(jtag_info
, buf_u32
++, 4, be
);
424 arm7tdmi_clock_data_in_endianness(jtag_info
, buf_u16
++, 2, be
);
427 arm7tdmi_clock_data_in_endianness(jtag_info
, buf_u8
++, 1, be
);
434 void arm7tdmi_read_xpsr(target_t
*target
, uint32_t *xpsr
, int spsr
)
436 /* get pointers to arch-specific information */
437 armv4_5_common_t
*armv4_5
= target
->arch_info
;
438 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
439 arm_jtag_t
*jtag_info
= &arm7_9
->jtag_info
;
442 arm7tdmi_clock_out(jtag_info
, ARMV4_5_MRS(0, spsr
& 1), NULL
, 0);
445 arm7tdmi_clock_out(jtag_info
, ARMV4_5_STR(0, 15), NULL
, 0);
446 /* fetch NOP, STR in DECODE stage */
447 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
448 /* fetch NOP, STR in EXECUTE stage (1st cycle) */
449 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
450 /* nothing fetched, STR still in EXECUTE (2nd cycle) */
451 arm7tdmi_clock_data_in(jtag_info
, xpsr
);
454 void arm7tdmi_write_xpsr(target_t
*target
, uint32_t xpsr
, int spsr
)
456 /* get pointers to arch-specific information */
457 armv4_5_common_t
*armv4_5
= target
->arch_info
;
458 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
459 arm_jtag_t
*jtag_info
= &arm7_9
->jtag_info
;
461 LOG_DEBUG("xpsr: %8.8" PRIx32
", spsr: %i", xpsr
, spsr
);
464 arm7tdmi_clock_out(jtag_info
, ARMV4_5_MSR_IM(xpsr
& 0xff, 0, 1, spsr
), NULL
, 0);
465 /* MSR2 fetched, MSR1 in DECODE */
466 arm7tdmi_clock_out(jtag_info
, ARMV4_5_MSR_IM((xpsr
& 0xff00) >> 8, 0xc, 2, spsr
), NULL
, 0);
467 /* MSR3 fetched, MSR1 in EXECUTE (1), MSR2 in DECODE */
468 arm7tdmi_clock_out(jtag_info
, ARMV4_5_MSR_IM((xpsr
& 0xff0000) >> 16, 0x8, 4, spsr
), NULL
, 0);
469 /* nothing fetched, MSR1 in EXECUTE (2) */
470 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
471 /* MSR4 fetched, MSR2 in EXECUTE (1), MSR3 in DECODE */
472 arm7tdmi_clock_out(jtag_info
, ARMV4_5_MSR_IM((xpsr
& 0xff000000) >> 24, 0x4, 8, spsr
), NULL
, 0);
473 /* nothing fetched, MSR2 in EXECUTE (2) */
474 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
475 /* NOP fetched, MSR3 in EXECUTE (1), MSR4 in DECODE */
476 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
477 /* nothing fetched, MSR3 in EXECUTE (2) */
478 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
479 /* NOP fetched, MSR4 in EXECUTE (1) */
480 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
481 /* nothing fetched, MSR4 in EXECUTE (2) */
482 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
485 void arm7tdmi_write_xpsr_im8(target_t
*target
, uint8_t xpsr_im
, int rot
, int spsr
)
487 /* get pointers to arch-specific information */
488 armv4_5_common_t
*armv4_5
= target
->arch_info
;
489 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
490 arm_jtag_t
*jtag_info
= &arm7_9
->jtag_info
;
492 LOG_DEBUG("xpsr_im: %2.2x, rot: %i, spsr: %i", xpsr_im
, rot
, spsr
);
495 arm7tdmi_clock_out(jtag_info
, ARMV4_5_MSR_IM(xpsr_im
, rot
, 1, spsr
), NULL
, 0);
496 /* NOP fetched, MSR in DECODE */
497 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
498 /* NOP fetched, MSR in EXECUTE (1) */
499 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
500 /* nothing fetched, MSR in EXECUTE (2) */
501 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
504 void arm7tdmi_write_core_regs(target_t
*target
, uint32_t mask
, uint32_t core_regs
[16])
507 /* get pointers to arch-specific information */
508 armv4_5_common_t
*armv4_5
= target
->arch_info
;
509 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
510 arm_jtag_t
*jtag_info
= &arm7_9
->jtag_info
;
512 /* LDMIA r0-15, [r0] at debug speed
513 * register values will start to appear on 4th DCLK
515 arm7tdmi_clock_out(jtag_info
, ARMV4_5_LDMIA(0, mask
& 0xffff, 0, 0), NULL
, 0);
517 /* fetch NOP, LDM in DECODE stage */
518 arm7tdmi_clock_out_inner(jtag_info
, ARMV4_5_NOP
, 0);
519 /* fetch NOP, LDM in EXECUTE stage (1st cycle) */
520 arm7tdmi_clock_out_inner(jtag_info
, ARMV4_5_NOP
, 0);
522 for (i
= 0; i
<= 15; i
++)
525 /* nothing fetched, LDM still in EXECUTE (1 + i cycle) */
526 arm7tdmi_clock_out_inner(jtag_info
, core_regs
[i
], 0);
528 arm7tdmi_clock_out_inner(jtag_info
, ARMV4_5_NOP
, 0);
531 void arm7tdmi_load_word_regs(target_t
*target
, uint32_t mask
)
533 /* get pointers to arch-specific information */
534 armv4_5_common_t
*armv4_5
= target
->arch_info
;
535 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
536 arm_jtag_t
*jtag_info
= &arm7_9
->jtag_info
;
538 /* put system-speed load-multiple into the pipeline */
539 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
540 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 1);
541 arm7tdmi_clock_out(jtag_info
, ARMV4_5_LDMIA(0, mask
& 0xffff, 0, 1), NULL
, 0);
544 void arm7tdmi_load_hword_reg(target_t
*target
, int num
)
546 /* get pointers to arch-specific information */
547 armv4_5_common_t
*armv4_5
= target
->arch_info
;
548 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
549 arm_jtag_t
*jtag_info
= &arm7_9
->jtag_info
;
551 /* put system-speed load half-word into the pipeline */
552 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
553 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 1);
554 arm7tdmi_clock_out(jtag_info
, ARMV4_5_LDRH_IP(num
, 0), NULL
, 0);
557 void arm7tdmi_load_byte_reg(target_t
*target
, int num
)
559 /* get pointers to arch-specific information */
560 armv4_5_common_t
*armv4_5
= target
->arch_info
;
561 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
562 arm_jtag_t
*jtag_info
= &arm7_9
->jtag_info
;
564 /* put system-speed load byte into the pipeline */
565 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
566 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 1);
567 arm7tdmi_clock_out(jtag_info
, ARMV4_5_LDRB_IP(num
, 0), NULL
, 0);
570 void arm7tdmi_store_word_regs(target_t
*target
, uint32_t mask
)
572 /* get pointers to arch-specific information */
573 armv4_5_common_t
*armv4_5
= target
->arch_info
;
574 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
575 arm_jtag_t
*jtag_info
= &arm7_9
->jtag_info
;
577 /* put system-speed store-multiple into the pipeline */
578 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
579 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 1);
580 arm7tdmi_clock_out(jtag_info
, ARMV4_5_STMIA(0, mask
, 0, 1), NULL
, 0);
583 void arm7tdmi_store_hword_reg(target_t
*target
, int num
)
585 /* get pointers to arch-specific information */
586 armv4_5_common_t
*armv4_5
= target
->arch_info
;
587 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
588 arm_jtag_t
*jtag_info
= &arm7_9
->jtag_info
;
590 /* put system-speed store half-word into the pipeline */
591 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
592 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 1);
593 arm7tdmi_clock_out(jtag_info
, ARMV4_5_STRH_IP(num
, 0), NULL
, 0);
596 void arm7tdmi_store_byte_reg(target_t
*target
, int num
)
598 /* get pointers to arch-specific information */
599 armv4_5_common_t
*armv4_5
= target
->arch_info
;
600 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
601 arm_jtag_t
*jtag_info
= &arm7_9
->jtag_info
;
603 /* put system-speed store byte into the pipeline */
604 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
605 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 1);
606 arm7tdmi_clock_out(jtag_info
, ARMV4_5_STRB_IP(num
, 0), NULL
, 0);
609 void arm7tdmi_write_pc(target_t
*target
, uint32_t pc
)
611 /* get pointers to arch-specific information */
612 armv4_5_common_t
*armv4_5
= target
->arch_info
;
613 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
614 arm_jtag_t
*jtag_info
= &arm7_9
->jtag_info
;
616 /* LDMIA r0-15, [r0] at debug speed
617 * register values will start to appear on 4th DCLK
619 arm7tdmi_clock_out(jtag_info
, ARMV4_5_LDMIA(0, 0x8000, 0, 0), NULL
, 0);
620 /* fetch NOP, LDM in DECODE stage */
621 arm7tdmi_clock_out_inner(jtag_info
, ARMV4_5_NOP
, 0);
622 /* fetch NOP, LDM in EXECUTE stage (1st cycle) */
623 arm7tdmi_clock_out_inner(jtag_info
, ARMV4_5_NOP
, 0);
624 /* nothing fetched, LDM in EXECUTE stage (1st cycle) load register */
625 arm7tdmi_clock_out_inner(jtag_info
, pc
, 0);
626 /* nothing fetched, LDM in EXECUTE stage (2nd cycle) load register */
627 arm7tdmi_clock_out_inner(jtag_info
, ARMV4_5_NOP
, 0);
628 /* nothing fetched, LDM in EXECUTE stage (3rd cycle) load register */
629 arm7tdmi_clock_out_inner(jtag_info
, ARMV4_5_NOP
, 0);
630 /* fetch NOP, LDM in EXECUTE stage (4th cycle) */
631 arm7tdmi_clock_out_inner(jtag_info
, ARMV4_5_NOP
, 0);
632 /* fetch NOP, LDM in EXECUTE stage (5th cycle) */
633 arm7tdmi_clock_out_inner(jtag_info
, ARMV4_5_NOP
, 0);
636 void arm7tdmi_branch_resume(target_t
*target
)
638 /* get pointers to arch-specific information */
639 armv4_5_common_t
*armv4_5
= target
->arch_info
;
640 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
641 arm_jtag_t
*jtag_info
= &arm7_9
->jtag_info
;
643 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 1);
644 arm7tdmi_clock_out_inner(jtag_info
, ARMV4_5_B(0xfffffa, 0), 0);
647 void arm7tdmi_branch_resume_thumb(target_t
*target
)
651 /* get pointers to arch-specific information */
652 armv4_5_common_t
*armv4_5
= target
->arch_info
;
653 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
654 arm_jtag_t
*jtag_info
= &arm7_9
->jtag_info
;
655 reg_t
*dbg_stat
= &arm7_9
->eice_cache
->reg_list
[EICE_DBG_STAT
];
657 /* LDMIA r0, [r0] at debug speed
658 * register values will start to appear on 4th DCLK
660 arm7tdmi_clock_out(jtag_info
, ARMV4_5_LDMIA(0, 0x1, 0, 0), NULL
, 0);
662 /* fetch NOP, LDM in DECODE stage */
663 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
664 /* fetch NOP, LDM in EXECUTE stage (1st cycle) */
665 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
666 /* nothing fetched, LDM in EXECUTE stage (2nd cycle) */
667 arm7tdmi_clock_out(jtag_info
, buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32) | 1, NULL
, 0);
668 /* nothing fetched, LDM in EXECUTE stage (3rd cycle) */
669 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
671 /* Branch and eXchange */
672 arm7tdmi_clock_out(jtag_info
, ARMV4_5_BX(0), NULL
, 0);
674 embeddedice_read_reg(dbg_stat
);
676 /* fetch NOP, BX in DECODE stage */
677 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
679 /* target is now in Thumb state */
680 embeddedice_read_reg(dbg_stat
);
682 /* fetch NOP, BX in EXECUTE stage (1st cycle) */
683 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
685 /* target is now in Thumb state */
686 embeddedice_read_reg(dbg_stat
);
689 arm7tdmi_clock_out(jtag_info
, ARMV4_5_T_LDR_PCREL(0), NULL
, 0);
690 /* fetch NOP, LDR in Decode */
691 arm7tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, NULL
, 0);
692 /* fetch NOP, LDR in Execute */
693 arm7tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, NULL
, 0);
694 /* nothing fetched, LDR in EXECUTE stage (2nd cycle) */
695 arm7tdmi_clock_out(jtag_info
, buf_get_u32(armv4_5
->core_cache
->reg_list
[0].value
, 0, 32), NULL
, 0);
696 /* nothing fetched, LDR in EXECUTE stage (3rd cycle) */
697 arm7tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, NULL
, 0);
699 arm7tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, NULL
, 0);
700 arm7tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, NULL
, 0);
702 embeddedice_read_reg(dbg_stat
);
704 arm7tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, NULL
, 1);
705 arm7tdmi_clock_out(jtag_info
, ARMV4_5_T_B(0x7f8), NULL
, 0);
708 void arm7tdmi_build_reg_cache(target_t
*target
)
710 reg_cache_t
**cache_p
= register_get_last_cache_p(&target
->reg_cache
);
711 /* get pointers to arch-specific information */
712 armv4_5_common_t
*armv4_5
= target
->arch_info
;
714 (*cache_p
) = armv4_5_build_reg_cache(target
, armv4_5
);
715 armv4_5
->core_cache
= (*cache_p
);
718 int arm7tdmi_examine(struct target_s
*target
)
721 armv4_5_common_t
*armv4_5
= target
->arch_info
;
722 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
723 if (!target_was_examined(target
))
725 /* get pointers to arch-specific information */
726 reg_cache_t
**cache_p
= register_get_last_cache_p(&target
->reg_cache
);
727 reg_cache_t
*t
= embeddedice_build_reg_cache(target
, arm7_9
);
732 arm7_9
->eice_cache
= (*cache_p
);
736 arm_jtag_t
*jtag_info
= &arm7_9
->jtag_info
;
737 (*cache_p
)->next
= etm_build_reg_cache(target
, jtag_info
, arm7_9
->etm_ctx
);
738 arm7_9
->etm_ctx
->reg_cache
= (*cache_p
)->next
;
740 target_set_examined(target
);
742 if ((retval
= embeddedice_setup(target
)) != ERROR_OK
)
744 if ((retval
= arm7_9_setup(target
)) != ERROR_OK
)
748 if ((retval
= etm_setup(target
)) != ERROR_OK
)
754 int arm7tdmi_init_target(struct command_context_s
*cmd_ctx
, struct target_s
*target
)
756 arm7tdmi_build_reg_cache(target
);
761 int arm7tdmi_quit(void)
766 int arm7tdmi_init_arch_info(target_t
*target
, arm7tdmi_common_t
*arm7tdmi
, jtag_tap_t
*tap
)
768 armv4_5_common_t
*armv4_5
;
769 arm7_9_common_t
*arm7_9
;
771 arm7_9
= &arm7tdmi
->arm7_9_common
;
772 armv4_5
= &arm7_9
->armv4_5_common
;
774 /* prepare JTAG information for the new target */
775 arm7_9
->jtag_info
.tap
= tap
;
776 arm7_9
->jtag_info
.scann_size
= 4;
778 /* register arch-specific functions */
779 arm7_9
->examine_debug_reason
= arm7tdmi_examine_debug_reason
;
780 arm7_9
->change_to_arm
= arm7tdmi_change_to_arm
;
781 arm7_9
->read_core_regs
= arm7tdmi_read_core_regs
;
782 arm7_9
->read_core_regs_target_buffer
= arm7tdmi_read_core_regs_target_buffer
;
783 arm7_9
->read_xpsr
= arm7tdmi_read_xpsr
;
785 arm7_9
->write_xpsr
= arm7tdmi_write_xpsr
;
786 arm7_9
->write_xpsr_im8
= arm7tdmi_write_xpsr_im8
;
787 arm7_9
->write_core_regs
= arm7tdmi_write_core_regs
;
789 arm7_9
->load_word_regs
= arm7tdmi_load_word_regs
;
790 arm7_9
->load_hword_reg
= arm7tdmi_load_hword_reg
;
791 arm7_9
->load_byte_reg
= arm7tdmi_load_byte_reg
;
793 arm7_9
->store_word_regs
= arm7tdmi_store_word_regs
;
794 arm7_9
->store_hword_reg
= arm7tdmi_store_hword_reg
;
795 arm7_9
->store_byte_reg
= arm7tdmi_store_byte_reg
;
797 arm7_9
->write_pc
= arm7tdmi_write_pc
;
798 arm7_9
->branch_resume
= arm7tdmi_branch_resume
;
799 arm7_9
->branch_resume_thumb
= arm7tdmi_branch_resume_thumb
;
801 arm7_9
->enable_single_step
= arm7_9_enable_eice_step
;
802 arm7_9
->disable_single_step
= arm7_9_disable_eice_step
;
804 arm7_9
->pre_debug_entry
= NULL
;
805 arm7_9
->post_debug_entry
= NULL
;
807 arm7_9
->pre_restore_context
= NULL
;
808 arm7_9
->post_restore_context
= NULL
;
810 /* initialize arch-specific breakpoint handling */
811 arm7_9
->arm_bkpt
= 0xdeeedeee;
812 arm7_9
->thumb_bkpt
= 0xdeee;
814 arm7_9
->dbgreq_adjust_pc
= 2;
815 arm7_9
->arch_info
= arm7tdmi
;
817 arm7tdmi
->arch_info
= NULL
;
818 arm7tdmi
->common_magic
= ARM7TDMI_COMMON_MAGIC
;
820 arm7_9_init_arch_info(target
, arm7_9
);
825 int arm7tdmi_target_create(struct target_s
*target
, Jim_Interp
*interp
)
827 arm7tdmi_common_t
*arm7tdmi
;
829 arm7tdmi
= calloc(1,sizeof(arm7tdmi_common_t
));
830 arm7tdmi_init_arch_info(target
, arm7tdmi
, target
->tap
);
831 arm7tdmi
->arm7_9_common
.armv4_5_common
.is_armv4
= true;
836 int arm7tdmi_register_commands(struct command_context_s
*cmd_ctx
)
840 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)