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 * This program is free software; you can redistribute it and/or modify *
9 * it under the terms of the GNU General Public License as published by *
10 * the Free Software Foundation; either version 2 of the License, or *
11 * (at your option) any later version. *
13 * This program is distributed in the hope that it will be useful, *
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
16 * GNU General Public License for more details. *
18 * You should have received a copy of the GNU General Public License *
19 * along with this program; if not, write to the *
20 * Free Software Foundation, Inc., *
21 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
22 ***************************************************************************/
29 #include "arm7_9_common.h"
33 #include "embeddedice.h"
43 #define _DEBUG_INSTRUCTION_EXECUTION_
47 int arm7tdmi_register_commands(struct command_context_s
*cmd_ctx
);
49 /* forward declarations */
51 int arm7tdmi_target_create(struct target_s
*target
,Jim_Interp
*interp
);
52 int arm7tdmi_init_target(struct command_context_s
*cmd_ctx
, struct target_s
*target
);
53 int arm7tdmi_quit(void);
55 /* target function declarations */
56 int arm7tdmi_poll(struct target_s
*target
);
57 int arm7tdmi_halt(target_t
*target
);
59 target_type_t arm7tdmi_target
=
64 .arch_state
= armv4_5_arch_state
,
66 .target_request_data
= arm7_9_target_request_data
,
69 .resume
= arm7_9_resume
,
72 .assert_reset
= arm7_9_assert_reset
,
73 .deassert_reset
= arm7_9_deassert_reset
,
74 .soft_reset_halt
= arm7_9_soft_reset_halt
,
76 .get_gdb_reg_list
= armv4_5_get_gdb_reg_list
,
78 .read_memory
= arm7_9_read_memory
,
79 .write_memory
= arm7_9_write_memory
,
80 .bulk_write_memory
= arm7_9_bulk_write_memory
,
81 .checksum_memory
= arm7_9_checksum_memory
,
82 .blank_check_memory
= arm7_9_blank_check_memory
,
84 .run_algorithm
= armv4_5_run_algorithm
,
86 .add_breakpoint
= arm7_9_add_breakpoint
,
87 .remove_breakpoint
= arm7_9_remove_breakpoint
,
88 .add_watchpoint
= arm7_9_add_watchpoint
,
89 .remove_watchpoint
= arm7_9_remove_watchpoint
,
91 .register_commands
= arm7tdmi_register_commands
,
92 .target_create
= arm7tdmi_target_create
,
93 .init_target
= arm7tdmi_init_target
,
94 .examine
= arm7tdmi_examine
,
98 int arm7tdmi_examine_debug_reason(target_t
*target
)
100 int retval
= ERROR_OK
;
101 /* get pointers to arch-specific information */
102 armv4_5_common_t
*armv4_5
= target
->arch_info
;
103 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
105 /* only check the debug reason if we don't know it already */
106 if ((target
->debug_reason
!= DBG_REASON_DBGRQ
)
107 && (target
->debug_reason
!= DBG_REASON_SINGLESTEP
))
109 scan_field_t fields
[2];
113 jtag_add_end_state(TAP_DRPAUSE
);
115 fields
[0].tap
= arm7_9
->jtag_info
.tap
;
116 fields
[0].num_bits
= 1;
117 fields
[0].out_value
= NULL
;
118 fields
[0].out_mask
= NULL
;
119 fields
[0].in_value
= &breakpoint
;
120 fields
[0].in_check_value
= NULL
;
121 fields
[0].in_check_mask
= NULL
;
122 fields
[0].in_handler
= NULL
;
123 fields
[0].in_handler_priv
= NULL
;
125 fields
[1].tap
= arm7_9
->jtag_info
.tap
;
126 fields
[1].num_bits
= 32;
127 fields
[1].out_value
= NULL
;
128 fields
[1].out_mask
= NULL
;
129 fields
[1].in_value
= databus
;
130 fields
[1].in_check_value
= NULL
;
131 fields
[1].in_check_mask
= NULL
;
132 fields
[1].in_handler
= NULL
;
133 fields
[1].in_handler_priv
= NULL
;
135 if((retval
= arm_jtag_scann(&arm7_9
->jtag_info
, 0x1)) != ERROR_OK
)
139 arm_jtag_set_instr(&arm7_9
->jtag_info
, arm7_9
->jtag_info
.intest_instr
, NULL
);
141 jtag_add_dr_scan(2, fields
, TAP_DRPAUSE
);
142 if((retval
= jtag_execute_queue()) != ERROR_OK
)
147 fields
[0].in_value
= NULL
;
148 fields
[0].out_value
= &breakpoint
;
149 fields
[1].in_value
= NULL
;
150 fields
[1].out_value
= databus
;
152 jtag_add_dr_scan(2, fields
, TAP_DRPAUSE
);
155 target
->debug_reason
= DBG_REASON_WATCHPOINT
;
157 target
->debug_reason
= DBG_REASON_BREAKPOINT
;
163 static int arm7tdmi_num_bits
[]={1, 32};
164 static __inline
int arm7tdmi_clock_out_inner(arm_jtag_t
*jtag_info
, u32 out
, int breakpoint
)
166 u32 values
[2]={breakpoint
, flip_u32(out
, 32)};
168 jtag_add_dr_out(jtag_info
->tap
,
174 jtag_add_runtest(0, TAP_INVALID
);
179 /* put an instruction in the ARM7TDMI pipeline or write the data bus, and optionally read data */
180 static __inline
int arm7tdmi_clock_out(arm_jtag_t
*jtag_info
, u32 out
, u32
*deprecated
, int breakpoint
)
182 jtag_add_end_state(TAP_DRPAUSE
);
183 arm_jtag_scann(jtag_info
, 0x1);
184 arm_jtag_set_instr(jtag_info
, jtag_info
->intest_instr
, NULL
);
186 return arm7tdmi_clock_out_inner(jtag_info
, out
, breakpoint
);
189 /* clock the target, reading the databus */
190 int arm7tdmi_clock_data_in(arm_jtag_t
*jtag_info
, u32
*in
)
192 int retval
= ERROR_OK
;
193 scan_field_t fields
[2];
195 jtag_add_end_state(TAP_DRPAUSE
);
196 if((retval
= arm_jtag_scann(jtag_info
, 0x1)) != ERROR_OK
)
200 arm_jtag_set_instr(jtag_info
, jtag_info
->intest_instr
, NULL
);
202 fields
[0].tap
= jtag_info
->tap
;
203 fields
[0].num_bits
= 1;
204 fields
[0].out_value
= NULL
;
205 fields
[0].out_mask
= NULL
;
206 fields
[0].in_value
= NULL
;
207 fields
[0].in_check_value
= NULL
;
208 fields
[0].in_check_mask
= NULL
;
209 fields
[0].in_handler
= NULL
;
210 fields
[0].in_handler_priv
= NULL
;
212 fields
[1].tap
= jtag_info
->tap
;
213 fields
[1].num_bits
= 32;
214 fields
[1].out_value
= NULL
;
215 fields
[1].out_mask
= NULL
;
216 fields
[1].in_value
= NULL
;
217 fields
[1].in_handler
= arm_jtag_buf_to_u32_flip
;
218 fields
[1].in_handler_priv
= in
;
219 fields
[1].in_check_value
= NULL
;
220 fields
[1].in_check_mask
= NULL
;
222 jtag_add_dr_scan(2, fields
, TAP_INVALID
);
224 jtag_add_runtest(0, TAP_INVALID
);
226 #ifdef _DEBUG_INSTRUCTION_EXECUTION_
228 if((retval
= jtag_execute_queue()) != ERROR_OK
)
235 LOG_DEBUG("in: 0x%8.8x", *in
);
239 LOG_ERROR("BUG: called with in == NULL");
247 /* clock the target, and read the databus
248 * the *in pointer points to a buffer where elements of 'size' bytes
249 * are stored in big (be==1) or little (be==0) endianness
251 int arm7tdmi_clock_data_in_endianness(arm_jtag_t
*jtag_info
, void *in
, int size
, int be
)
253 int retval
= ERROR_OK
;
254 scan_field_t fields
[2];
256 jtag_add_end_state(TAP_DRPAUSE
);
257 if((retval
= arm_jtag_scann(jtag_info
, 0x1)) != ERROR_OK
)
261 arm_jtag_set_instr(jtag_info
, jtag_info
->intest_instr
, NULL
);
263 fields
[0].tap
= jtag_info
->tap
;
264 fields
[0].num_bits
= 1;
265 fields
[0].out_value
= NULL
;
266 fields
[0].out_mask
= NULL
;
267 fields
[0].in_value
= NULL
;
268 fields
[0].in_check_value
= NULL
;
269 fields
[0].in_check_mask
= NULL
;
270 fields
[0].in_handler
= NULL
;
271 fields
[0].in_handler_priv
= NULL
;
273 fields
[1].tap
= jtag_info
->tap
;
274 fields
[1].num_bits
= 32;
275 fields
[1].out_value
= NULL
;
276 fields
[1].out_mask
= NULL
;
277 fields
[1].in_value
= NULL
;
281 fields
[1].in_handler
= (be
) ? arm_jtag_buf_to_be32_flip
: arm_jtag_buf_to_le32_flip
;
284 fields
[1].in_handler
= (be
) ? arm_jtag_buf_to_be16_flip
: arm_jtag_buf_to_le16_flip
;
287 fields
[1].in_handler
= arm_jtag_buf_to_8_flip
;
290 fields
[1].in_handler_priv
= in
;
291 fields
[1].in_check_value
= NULL
;
292 fields
[1].in_check_mask
= NULL
;
294 jtag_add_dr_scan(2, fields
, TAP_INVALID
);
296 jtag_add_runtest(0, TAP_INVALID
);
298 #ifdef _DEBUG_INSTRUCTION_EXECUTION_
300 if((retval
= jtag_execute_queue()) != ERROR_OK
)
307 LOG_DEBUG("in: 0x%8.8x", *(u32
*)in
);
311 LOG_ERROR("BUG: called with in == NULL");
319 void arm7tdmi_change_to_arm(target_t
*target
, u32
*r0
, u32
*pc
)
321 /* get pointers to arch-specific information */
322 armv4_5_common_t
*armv4_5
= target
->arch_info
;
323 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
324 arm_jtag_t
*jtag_info
= &arm7_9
->jtag_info
;
326 /* save r0 before using it and put system in ARM state
327 * to allow common handling of ARM and THUMB debugging */
329 /* fetch STR r0, [r0] */
330 arm7tdmi_clock_out(jtag_info
, ARMV4_5_T_STR(0, 0), NULL
, 0);
331 arm7tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, NULL
, 0);
332 arm7tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, NULL
, 0);
333 /* nothing fetched, STR r0, [r0] in Execute (2) */
334 arm7tdmi_clock_data_in(jtag_info
, r0
);
336 /* MOV r0, r15 fetched, STR in Decode */
337 arm7tdmi_clock_out(jtag_info
, ARMV4_5_T_MOV(0, 15), NULL
, 0);
338 arm7tdmi_clock_out(jtag_info
, ARMV4_5_T_STR(0, 0), NULL
, 0);
339 arm7tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, NULL
, 0);
340 arm7tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, NULL
, 0);
341 /* nothing fetched, STR r0, [r0] in Execute (2) */
342 arm7tdmi_clock_data_in(jtag_info
, pc
);
344 /* use pc-relative LDR to clear r0[1:0] (for switch to ARM mode) */
345 arm7tdmi_clock_out(jtag_info
, ARMV4_5_T_LDR_PCREL(0), NULL
, 0);
346 arm7tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, NULL
, 0);
347 arm7tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, NULL
, 0);
348 /* nothing fetched, data for LDR r0, [PC, #0] */
349 arm7tdmi_clock_out(jtag_info
, 0x0, NULL
, 0);
350 /* nothing fetched, data from previous cycle is written to register */
351 arm7tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, NULL
, 0);
354 arm7tdmi_clock_out(jtag_info
, ARMV4_5_T_BX(0), NULL
, 0);
355 /* NOP fetched, BX in Decode, MOV in Execute */
356 arm7tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, NULL
, 0);
357 /* NOP fetched, BX in Execute (1) */
358 arm7tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, NULL
, 0);
360 jtag_execute_queue();
362 /* fix program counter:
363 * MOV r0, r15 was the 4th instruction (+6)
364 * reading PC in Thumb state gives address of instruction + 4
369 void arm7tdmi_read_core_regs(target_t
*target
, u32 mask
, u32
* core_regs
[16])
372 /* get pointers to arch-specific information */
373 armv4_5_common_t
*armv4_5
= target
->arch_info
;
374 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
375 arm_jtag_t
*jtag_info
= &arm7_9
->jtag_info
;
377 /* STMIA r0-15, [r0] at debug speed
378 * register values will start to appear on 4th DCLK
380 arm7tdmi_clock_out(jtag_info
, ARMV4_5_STMIA(0, mask
& 0xffff, 0, 0), NULL
, 0);
382 /* fetch NOP, STM in DECODE stage */
383 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
384 /* fetch NOP, STM in EXECUTE stage (1st cycle) */
385 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
387 for (i
= 0; i
<= 15; i
++)
390 /* nothing fetched, STM still in EXECUTE (1+i cycle) */
391 arm7tdmi_clock_data_in(jtag_info
, core_regs
[i
]);
395 void arm7tdmi_read_core_regs_target_buffer(target_t
*target
, u32 mask
, void* buffer
, int size
)
398 /* get pointers to arch-specific information */
399 armv4_5_common_t
*armv4_5
= target
->arch_info
;
400 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
401 arm_jtag_t
*jtag_info
= &arm7_9
->jtag_info
;
402 int be
= (target
->endianness
== TARGET_BIG_ENDIAN
) ? 1 : 0;
403 u32
*buf_u32
= buffer
;
404 u16
*buf_u16
= buffer
;
407 /* STMIA r0-15, [r0] at debug speed
408 * register values will start to appear on 4th DCLK
410 arm7tdmi_clock_out(jtag_info
, ARMV4_5_STMIA(0, mask
& 0xffff, 0, 0), NULL
, 0);
412 /* fetch NOP, STM in DECODE stage */
413 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
414 /* fetch NOP, STM in EXECUTE stage (1st cycle) */
415 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
417 for (i
= 0; i
<= 15; i
++)
419 /* nothing fetched, STM still in EXECUTE (1+i cycle), read databus */
425 arm7tdmi_clock_data_in_endianness(jtag_info
, buf_u32
++, 4, be
);
428 arm7tdmi_clock_data_in_endianness(jtag_info
, buf_u16
++, 2, be
);
431 arm7tdmi_clock_data_in_endianness(jtag_info
, buf_u8
++, 1, be
);
438 void arm7tdmi_read_xpsr(target_t
*target
, u32
*xpsr
, int spsr
)
440 /* get pointers to arch-specific information */
441 armv4_5_common_t
*armv4_5
= target
->arch_info
;
442 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
443 arm_jtag_t
*jtag_info
= &arm7_9
->jtag_info
;
446 arm7tdmi_clock_out(jtag_info
, ARMV4_5_MRS(0, spsr
& 1), NULL
, 0);
449 arm7tdmi_clock_out(jtag_info
, ARMV4_5_STR(0, 15), NULL
, 0);
450 /* fetch NOP, STR in DECODE stage */
451 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
452 /* fetch NOP, STR in EXECUTE stage (1st cycle) */
453 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
454 /* nothing fetched, STR still in EXECUTE (2nd cycle) */
455 arm7tdmi_clock_data_in(jtag_info
, xpsr
);
458 void arm7tdmi_write_xpsr(target_t
*target
, u32 xpsr
, int spsr
)
460 /* get pointers to arch-specific information */
461 armv4_5_common_t
*armv4_5
= target
->arch_info
;
462 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
463 arm_jtag_t
*jtag_info
= &arm7_9
->jtag_info
;
465 LOG_DEBUG("xpsr: %8.8x, spsr: %i", xpsr
, spsr
);
468 arm7tdmi_clock_out(jtag_info
, ARMV4_5_MSR_IM(xpsr
& 0xff, 0, 1, spsr
), NULL
, 0);
469 /* MSR2 fetched, MSR1 in DECODE */
470 arm7tdmi_clock_out(jtag_info
, ARMV4_5_MSR_IM((xpsr
& 0xff00) >> 8, 0xc, 2, spsr
), NULL
, 0);
471 /* MSR3 fetched, MSR1 in EXECUTE (1), MSR2 in DECODE */
472 arm7tdmi_clock_out(jtag_info
, ARMV4_5_MSR_IM((xpsr
& 0xff0000) >> 16, 0x8, 4, spsr
), NULL
, 0);
473 /* nothing fetched, MSR1 in EXECUTE (2) */
474 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
475 /* MSR4 fetched, MSR2 in EXECUTE (1), MSR3 in DECODE */
476 arm7tdmi_clock_out(jtag_info
, ARMV4_5_MSR_IM((xpsr
& 0xff000000) >> 24, 0x4, 8, spsr
), NULL
, 0);
477 /* nothing fetched, MSR2 in EXECUTE (2) */
478 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
479 /* NOP fetched, MSR3 in EXECUTE (1), MSR4 in DECODE */
480 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
481 /* nothing fetched, MSR3 in EXECUTE (2) */
482 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
483 /* NOP fetched, MSR4 in EXECUTE (1) */
484 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
485 /* nothing fetched, MSR4 in EXECUTE (2) */
486 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
489 void arm7tdmi_write_xpsr_im8(target_t
*target
, u8 xpsr_im
, int rot
, int spsr
)
491 /* get pointers to arch-specific information */
492 armv4_5_common_t
*armv4_5
= target
->arch_info
;
493 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
494 arm_jtag_t
*jtag_info
= &arm7_9
->jtag_info
;
496 LOG_DEBUG("xpsr_im: %2.2x, rot: %i, spsr: %i", xpsr_im
, rot
, spsr
);
499 arm7tdmi_clock_out(jtag_info
, ARMV4_5_MSR_IM(xpsr_im
, rot
, 1, spsr
), NULL
, 0);
500 /* NOP fetched, MSR in DECODE */
501 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
502 /* NOP fetched, MSR in EXECUTE (1) */
503 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
504 /* nothing fetched, MSR in EXECUTE (2) */
505 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
508 void arm7tdmi_write_core_regs(target_t
*target
, u32 mask
, u32 core_regs
[16])
511 /* get pointers to arch-specific information */
512 armv4_5_common_t
*armv4_5
= target
->arch_info
;
513 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
514 arm_jtag_t
*jtag_info
= &arm7_9
->jtag_info
;
516 /* LDMIA r0-15, [r0] at debug speed
517 * register values will start to appear on 4th DCLK
519 arm7tdmi_clock_out(jtag_info
, ARMV4_5_LDMIA(0, mask
& 0xffff, 0, 0), NULL
, 0);
521 /* fetch NOP, LDM in DECODE stage */
522 arm7tdmi_clock_out_inner(jtag_info
, ARMV4_5_NOP
, 0);
523 /* fetch NOP, LDM in EXECUTE stage (1st cycle) */
524 arm7tdmi_clock_out_inner(jtag_info
, ARMV4_5_NOP
, 0);
526 for (i
= 0; i
<= 15; i
++)
529 /* nothing fetched, LDM still in EXECUTE (1+i cycle) */
530 arm7tdmi_clock_out_inner(jtag_info
, core_regs
[i
], 0);
532 arm7tdmi_clock_out_inner(jtag_info
, ARMV4_5_NOP
, 0);
535 void arm7tdmi_load_word_regs(target_t
*target
, u32 mask
)
537 /* get pointers to arch-specific information */
538 armv4_5_common_t
*armv4_5
= target
->arch_info
;
539 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
540 arm_jtag_t
*jtag_info
= &arm7_9
->jtag_info
;
542 /* put system-speed load-multiple into the pipeline */
543 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
544 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 1);
545 arm7tdmi_clock_out(jtag_info
, ARMV4_5_LDMIA(0, mask
& 0xffff, 0, 1), NULL
, 0);
548 void arm7tdmi_load_hword_reg(target_t
*target
, int num
)
550 /* get pointers to arch-specific information */
551 armv4_5_common_t
*armv4_5
= target
->arch_info
;
552 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
553 arm_jtag_t
*jtag_info
= &arm7_9
->jtag_info
;
555 /* put system-speed load half-word into the pipeline */
556 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
557 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 1);
558 arm7tdmi_clock_out(jtag_info
, ARMV4_5_LDRH_IP(num
, 0), NULL
, 0);
561 void arm7tdmi_load_byte_reg(target_t
*target
, int num
)
563 /* get pointers to arch-specific information */
564 armv4_5_common_t
*armv4_5
= target
->arch_info
;
565 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
566 arm_jtag_t
*jtag_info
= &arm7_9
->jtag_info
;
568 /* put system-speed load byte into the pipeline */
569 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
570 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 1);
571 arm7tdmi_clock_out(jtag_info
, ARMV4_5_LDRB_IP(num
, 0), NULL
, 0);
574 void arm7tdmi_store_word_regs(target_t
*target
, u32 mask
)
576 /* get pointers to arch-specific information */
577 armv4_5_common_t
*armv4_5
= target
->arch_info
;
578 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
579 arm_jtag_t
*jtag_info
= &arm7_9
->jtag_info
;
581 /* put system-speed store-multiple into the pipeline */
582 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
583 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 1);
584 arm7tdmi_clock_out(jtag_info
, ARMV4_5_STMIA(0, mask
, 0, 1), NULL
, 0);
587 void arm7tdmi_store_hword_reg(target_t
*target
, int num
)
589 /* get pointers to arch-specific information */
590 armv4_5_common_t
*armv4_5
= target
->arch_info
;
591 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
592 arm_jtag_t
*jtag_info
= &arm7_9
->jtag_info
;
594 /* put system-speed store half-word into the pipeline */
595 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
596 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 1);
597 arm7tdmi_clock_out(jtag_info
, ARMV4_5_STRH_IP(num
, 0), NULL
, 0);
600 void arm7tdmi_store_byte_reg(target_t
*target
, int num
)
602 /* get pointers to arch-specific information */
603 armv4_5_common_t
*armv4_5
= target
->arch_info
;
604 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
605 arm_jtag_t
*jtag_info
= &arm7_9
->jtag_info
;
607 /* put system-speed store byte into the pipeline */
608 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
609 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 1);
610 arm7tdmi_clock_out(jtag_info
, ARMV4_5_STRB_IP(num
, 0), NULL
, 0);
613 void arm7tdmi_write_pc(target_t
*target
, u32 pc
)
615 /* get pointers to arch-specific information */
616 armv4_5_common_t
*armv4_5
= target
->arch_info
;
617 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
618 arm_jtag_t
*jtag_info
= &arm7_9
->jtag_info
;
620 /* LDMIA r0-15, [r0] at debug speed
621 * register values will start to appear on 4th DCLK
623 arm7tdmi_clock_out(jtag_info
, ARMV4_5_LDMIA(0, 0x8000, 0, 0), NULL
, 0);
624 /* fetch NOP, LDM in DECODE stage */
625 arm7tdmi_clock_out_inner(jtag_info
, ARMV4_5_NOP
, 0);
626 /* fetch NOP, LDM in EXECUTE stage (1st cycle) */
627 arm7tdmi_clock_out_inner(jtag_info
, ARMV4_5_NOP
, 0);
628 /* nothing fetched, LDM in EXECUTE stage (1st cycle) load register */
629 arm7tdmi_clock_out_inner(jtag_info
, pc
, 0);
630 /* nothing fetched, LDM in EXECUTE stage (2nd cycle) load register */
631 arm7tdmi_clock_out_inner(jtag_info
, ARMV4_5_NOP
, 0);
632 /* nothing fetched, LDM in EXECUTE stage (3rd cycle) load register */
633 arm7tdmi_clock_out_inner(jtag_info
, ARMV4_5_NOP
, 0);
634 /* fetch NOP, LDM in EXECUTE stage (4th cycle) */
635 arm7tdmi_clock_out_inner(jtag_info
, ARMV4_5_NOP
, 0);
636 /* fetch NOP, LDM in EXECUTE stage (5th cycle) */
637 arm7tdmi_clock_out_inner(jtag_info
, ARMV4_5_NOP
, 0);
640 void arm7tdmi_branch_resume(target_t
*target
)
642 /* get pointers to arch-specific information */
643 armv4_5_common_t
*armv4_5
= target
->arch_info
;
644 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
645 arm_jtag_t
*jtag_info
= &arm7_9
->jtag_info
;
647 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 1);
648 arm7tdmi_clock_out_inner(jtag_info
, ARMV4_5_B(0xfffffa, 0), 0);
651 void arm7tdmi_branch_resume_thumb(target_t
*target
)
655 /* get pointers to arch-specific information */
656 armv4_5_common_t
*armv4_5
= target
->arch_info
;
657 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
658 arm_jtag_t
*jtag_info
= &arm7_9
->jtag_info
;
659 reg_t
*dbg_stat
= &arm7_9
->eice_cache
->reg_list
[EICE_DBG_STAT
];
661 /* LDMIA r0, [r0] at debug speed
662 * register values will start to appear on 4th DCLK
664 arm7tdmi_clock_out(jtag_info
, ARMV4_5_LDMIA(0, 0x1, 0, 0), NULL
, 0);
666 /* fetch NOP, LDM in DECODE stage */
667 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
668 /* fetch NOP, LDM in EXECUTE stage (1st cycle) */
669 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
670 /* nothing fetched, LDM in EXECUTE stage (2nd cycle) */
671 arm7tdmi_clock_out(jtag_info
, buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32) | 1, NULL
, 0);
672 /* nothing fetched, LDM in EXECUTE stage (3rd cycle) */
673 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
675 /* Branch and eXchange */
676 arm7tdmi_clock_out(jtag_info
, ARMV4_5_BX(0), NULL
, 0);
678 embeddedice_read_reg(dbg_stat
);
680 /* fetch NOP, BX in DECODE stage */
681 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
683 /* target is now in Thumb state */
684 embeddedice_read_reg(dbg_stat
);
686 /* fetch NOP, BX in EXECUTE stage (1st cycle) */
687 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
689 /* target is now in Thumb state */
690 embeddedice_read_reg(dbg_stat
);
693 arm7tdmi_clock_out(jtag_info
, ARMV4_5_T_LDR_PCREL(0), NULL
, 0);
694 /* fetch NOP, LDR in Decode */
695 arm7tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, NULL
, 0);
696 /* fetch NOP, LDR in Execute */
697 arm7tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, NULL
, 0);
698 /* nothing fetched, LDR in EXECUTE stage (2nd cycle) */
699 arm7tdmi_clock_out(jtag_info
, buf_get_u32(armv4_5
->core_cache
->reg_list
[0].value
, 0, 32), NULL
, 0);
700 /* nothing fetched, LDR in EXECUTE stage (3rd cycle) */
701 arm7tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, NULL
, 0);
703 arm7tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, NULL
, 0);
704 arm7tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, NULL
, 0);
706 embeddedice_read_reg(dbg_stat
);
708 arm7tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, NULL
, 1);
709 arm7tdmi_clock_out(jtag_info
, ARMV4_5_T_B(0x7f8), NULL
, 0);
712 void arm7tdmi_build_reg_cache(target_t
*target
)
714 reg_cache_t
**cache_p
= register_get_last_cache_p(&target
->reg_cache
);
715 /* get pointers to arch-specific information */
716 armv4_5_common_t
*armv4_5
= target
->arch_info
;
718 (*cache_p
) = armv4_5_build_reg_cache(target
, armv4_5
);
719 armv4_5
->core_cache
= (*cache_p
);
722 int arm7tdmi_examine(struct target_s
*target
)
725 armv4_5_common_t
*armv4_5
= target
->arch_info
;
726 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
727 if (!target
->type
->examined
)
729 /* get pointers to arch-specific information */
730 reg_cache_t
**cache_p
= register_get_last_cache_p(&target
->reg_cache
);
731 reg_cache_t
*t
=embeddedice_build_reg_cache(target
, arm7_9
);
736 arm7_9
->eice_cache
= (*cache_p
);
740 arm_jtag_t
*jtag_info
= &arm7_9
->jtag_info
;
741 (*cache_p
)->next
= etm_build_reg_cache(target
, jtag_info
, arm7_9
->etm_ctx
);
742 arm7_9
->etm_ctx
->reg_cache
= (*cache_p
)->next
;
744 target
->type
->examined
= 1;
746 if ((retval
=embeddedice_setup(target
))!=ERROR_OK
)
748 if ((retval
=arm7_9_setup(target
))!=ERROR_OK
)
752 if ((retval
=etm_setup(target
))!=ERROR_OK
)
758 int arm7tdmi_init_target(struct command_context_s
*cmd_ctx
, struct target_s
*target
)
760 arm7tdmi_build_reg_cache(target
);
765 int arm7tdmi_quit(void)
770 int arm7tdmi_init_arch_info(target_t
*target
, arm7tdmi_common_t
*arm7tdmi
, jtag_tap_t
*tap
)
772 armv4_5_common_t
*armv4_5
;
773 arm7_9_common_t
*arm7_9
;
775 arm7_9
= &arm7tdmi
->arm7_9_common
;
776 armv4_5
= &arm7_9
->armv4_5_common
;
778 /* prepare JTAG information for the new target */
779 arm7_9
->jtag_info
.tap
= tap
;
780 arm7_9
->jtag_info
.scann_size
= 4;
782 /* register arch-specific functions */
783 arm7_9
->examine_debug_reason
= arm7tdmi_examine_debug_reason
;
784 arm7_9
->change_to_arm
= arm7tdmi_change_to_arm
;
785 arm7_9
->read_core_regs
= arm7tdmi_read_core_regs
;
786 arm7_9
->read_core_regs_target_buffer
= arm7tdmi_read_core_regs_target_buffer
;
787 arm7_9
->read_xpsr
= arm7tdmi_read_xpsr
;
789 arm7_9
->write_xpsr
= arm7tdmi_write_xpsr
;
790 arm7_9
->write_xpsr_im8
= arm7tdmi_write_xpsr_im8
;
791 arm7_9
->write_core_regs
= arm7tdmi_write_core_regs
;
793 arm7_9
->load_word_regs
= arm7tdmi_load_word_regs
;
794 arm7_9
->load_hword_reg
= arm7tdmi_load_hword_reg
;
795 arm7_9
->load_byte_reg
= arm7tdmi_load_byte_reg
;
797 arm7_9
->store_word_regs
= arm7tdmi_store_word_regs
;
798 arm7_9
->store_hword_reg
= arm7tdmi_store_hword_reg
;
799 arm7_9
->store_byte_reg
= arm7tdmi_store_byte_reg
;
801 arm7_9
->write_pc
= arm7tdmi_write_pc
;
802 arm7_9
->branch_resume
= arm7tdmi_branch_resume
;
803 arm7_9
->branch_resume_thumb
= arm7tdmi_branch_resume_thumb
;
805 arm7_9
->enable_single_step
= arm7_9_enable_eice_step
;
806 arm7_9
->disable_single_step
= arm7_9_disable_eice_step
;
808 arm7_9
->pre_debug_entry
= NULL
;
809 arm7_9
->post_debug_entry
= NULL
;
811 arm7_9
->pre_restore_context
= NULL
;
812 arm7_9
->post_restore_context
= NULL
;
814 /* initialize arch-specific breakpoint handling */
815 arm7_9
->arm_bkpt
= 0xdeeedeee;
816 arm7_9
->thumb_bkpt
= 0xdeee;
818 arm7_9
->dbgreq_adjust_pc
= 2;
819 arm7_9
->arch_info
= arm7tdmi
;
821 arm7tdmi
->arch_info
= NULL
;
822 arm7tdmi
->common_magic
= ARM7TDMI_COMMON_MAGIC
;
824 arm7_9_init_arch_info(target
, arm7_9
);
829 int arm7tdmi_target_create( struct target_s
*target
, Jim_Interp
*interp
)
831 arm7tdmi_common_t
*arm7tdmi
;
833 arm7tdmi
= calloc(1,sizeof(arm7tdmi_common_t
));
834 arm7tdmi_init_arch_info(target
, arm7tdmi
, target
->tap
);
839 int arm7tdmi_register_commands(struct command_context_s
*cmd_ctx
)
843 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)