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_PD
);
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_PD
);
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_PD
);
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, -1);
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_PD
);
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_PD
);
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
, -1);
224 jtag_add_runtest(0, -1);
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_PD
);
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
, -1);
296 jtag_add_runtest(0, -1);
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
370 void arm7tdmi_read_core_regs(target_t
*target
, u32 mask
, u32
* core_regs
[16])
373 /* get pointers to arch-specific information */
374 armv4_5_common_t
*armv4_5
= target
->arch_info
;
375 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
376 arm_jtag_t
*jtag_info
= &arm7_9
->jtag_info
;
378 /* STMIA r0-15, [r0] at debug speed
379 * register values will start to appear on 4th DCLK
381 arm7tdmi_clock_out(jtag_info
, ARMV4_5_STMIA(0, mask
& 0xffff, 0, 0), NULL
, 0);
383 /* fetch NOP, STM in DECODE stage */
384 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
385 /* fetch NOP, STM in EXECUTE stage (1st cycle) */
386 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
388 for (i
= 0; i
<= 15; i
++)
391 /* nothing fetched, STM still in EXECUTE (1+i cycle) */
392 arm7tdmi_clock_data_in(jtag_info
, core_regs
[i
]);
397 void arm7tdmi_read_core_regs_target_buffer(target_t
*target
, u32 mask
, void* buffer
, int size
)
400 /* get pointers to arch-specific information */
401 armv4_5_common_t
*armv4_5
= target
->arch_info
;
402 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
403 arm_jtag_t
*jtag_info
= &arm7_9
->jtag_info
;
404 int be
= (target
->endianness
== TARGET_BIG_ENDIAN
) ? 1 : 0;
405 u32
*buf_u32
= buffer
;
406 u16
*buf_u16
= buffer
;
409 /* STMIA r0-15, [r0] at debug speed
410 * register values will start to appear on 4th DCLK
412 arm7tdmi_clock_out(jtag_info
, ARMV4_5_STMIA(0, mask
& 0xffff, 0, 0), NULL
, 0);
414 /* fetch NOP, STM in DECODE stage */
415 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
416 /* fetch NOP, STM in EXECUTE stage (1st cycle) */
417 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
419 for (i
= 0; i
<= 15; i
++)
421 /* nothing fetched, STM still in EXECUTE (1+i cycle), read databus */
427 arm7tdmi_clock_data_in_endianness(jtag_info
, buf_u32
++, 4, be
);
430 arm7tdmi_clock_data_in_endianness(jtag_info
, buf_u16
++, 2, be
);
433 arm7tdmi_clock_data_in_endianness(jtag_info
, buf_u8
++, 1, be
);
441 void arm7tdmi_read_xpsr(target_t
*target
, u32
*xpsr
, int spsr
)
443 /* get pointers to arch-specific information */
444 armv4_5_common_t
*armv4_5
= target
->arch_info
;
445 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
446 arm_jtag_t
*jtag_info
= &arm7_9
->jtag_info
;
449 arm7tdmi_clock_out(jtag_info
, ARMV4_5_MRS(0, spsr
& 1), NULL
, 0);
452 arm7tdmi_clock_out(jtag_info
, ARMV4_5_STR(0, 15), NULL
, 0);
453 /* fetch NOP, STR in DECODE stage */
454 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
455 /* fetch NOP, STR in EXECUTE stage (1st cycle) */
456 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
457 /* nothing fetched, STR still in EXECUTE (2nd cycle) */
458 arm7tdmi_clock_data_in(jtag_info
, xpsr
);
462 void arm7tdmi_write_xpsr(target_t
*target
, u32 xpsr
, int spsr
)
464 /* get pointers to arch-specific information */
465 armv4_5_common_t
*armv4_5
= target
->arch_info
;
466 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
467 arm_jtag_t
*jtag_info
= &arm7_9
->jtag_info
;
469 LOG_DEBUG("xpsr: %8.8x, spsr: %i", xpsr
, spsr
);
472 arm7tdmi_clock_out(jtag_info
, ARMV4_5_MSR_IM(xpsr
& 0xff, 0, 1, spsr
), NULL
, 0);
473 /* MSR2 fetched, MSR1 in DECODE */
474 arm7tdmi_clock_out(jtag_info
, ARMV4_5_MSR_IM((xpsr
& 0xff00) >> 8, 0xc, 2, spsr
), NULL
, 0);
475 /* MSR3 fetched, MSR1 in EXECUTE (1), MSR2 in DECODE */
476 arm7tdmi_clock_out(jtag_info
, ARMV4_5_MSR_IM((xpsr
& 0xff0000) >> 16, 0x8, 4, spsr
), NULL
, 0);
477 /* nothing fetched, MSR1 in EXECUTE (2) */
478 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
479 /* MSR4 fetched, MSR2 in EXECUTE (1), MSR3 in DECODE */
480 arm7tdmi_clock_out(jtag_info
, ARMV4_5_MSR_IM((xpsr
& 0xff000000) >> 24, 0x4, 8, spsr
), NULL
, 0);
481 /* nothing fetched, MSR2 in EXECUTE (2) */
482 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
483 /* NOP fetched, MSR3 in EXECUTE (1), MSR4 in DECODE */
484 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
485 /* nothing fetched, MSR3 in EXECUTE (2) */
486 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
487 /* NOP fetched, MSR4 in EXECUTE (1) */
488 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
489 /* nothing fetched, MSR4 in EXECUTE (2) */
490 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
493 void arm7tdmi_write_xpsr_im8(target_t
*target
, u8 xpsr_im
, int rot
, int spsr
)
495 /* get pointers to arch-specific information */
496 armv4_5_common_t
*armv4_5
= target
->arch_info
;
497 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
498 arm_jtag_t
*jtag_info
= &arm7_9
->jtag_info
;
500 LOG_DEBUG("xpsr_im: %2.2x, rot: %i, spsr: %i", xpsr_im
, rot
, spsr
);
503 arm7tdmi_clock_out(jtag_info
, ARMV4_5_MSR_IM(xpsr_im
, rot
, 1, spsr
), NULL
, 0);
504 /* NOP fetched, MSR in DECODE */
505 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
506 /* NOP fetched, MSR in EXECUTE (1) */
507 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
508 /* nothing fetched, MSR in EXECUTE (2) */
509 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
513 void arm7tdmi_write_core_regs(target_t
*target
, u32 mask
, u32 core_regs
[16])
516 /* get pointers to arch-specific information */
517 armv4_5_common_t
*armv4_5
= target
->arch_info
;
518 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
519 arm_jtag_t
*jtag_info
= &arm7_9
->jtag_info
;
521 /* LDMIA r0-15, [r0] at debug speed
522 * register values will start to appear on 4th DCLK
524 arm7tdmi_clock_out(jtag_info
, ARMV4_5_LDMIA(0, mask
& 0xffff, 0, 0), NULL
, 0);
526 /* fetch NOP, LDM in DECODE stage */
527 arm7tdmi_clock_out_inner(jtag_info
, ARMV4_5_NOP
, 0);
528 /* fetch NOP, LDM in EXECUTE stage (1st cycle) */
529 arm7tdmi_clock_out_inner(jtag_info
, ARMV4_5_NOP
, 0);
531 for (i
= 0; i
<= 15; i
++)
534 /* nothing fetched, LDM still in EXECUTE (1+i cycle) */
535 arm7tdmi_clock_out_inner(jtag_info
, core_regs
[i
], 0);
537 arm7tdmi_clock_out_inner(jtag_info
, ARMV4_5_NOP
, 0);
541 void arm7tdmi_load_word_regs(target_t
*target
, u32 mask
)
543 /* get pointers to arch-specific information */
544 armv4_5_common_t
*armv4_5
= target
->arch_info
;
545 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
546 arm_jtag_t
*jtag_info
= &arm7_9
->jtag_info
;
548 /* put system-speed load-multiple into the pipeline */
549 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
550 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 1);
551 arm7tdmi_clock_out(jtag_info
, ARMV4_5_LDMIA(0, mask
& 0xffff, 0, 1), NULL
, 0);
555 void arm7tdmi_load_hword_reg(target_t
*target
, int num
)
557 /* get pointers to arch-specific information */
558 armv4_5_common_t
*armv4_5
= target
->arch_info
;
559 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
560 arm_jtag_t
*jtag_info
= &arm7_9
->jtag_info
;
562 /* put system-speed load half-word into the pipeline */
563 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
564 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 1);
565 arm7tdmi_clock_out(jtag_info
, ARMV4_5_LDRH_IP(num
, 0), NULL
, 0);
569 void arm7tdmi_load_byte_reg(target_t
*target
, int num
)
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 load byte 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_LDRB_IP(num
, 0), NULL
, 0);
583 void arm7tdmi_store_word_regs(target_t
*target
, u32 mask
)
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-multiple 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_STMIA(0, mask
, 0, 1), NULL
, 0);
597 void arm7tdmi_store_hword_reg(target_t
*target
, int num
)
599 /* get pointers to arch-specific information */
600 armv4_5_common_t
*armv4_5
= target
->arch_info
;
601 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
602 arm_jtag_t
*jtag_info
= &arm7_9
->jtag_info
;
604 /* put system-speed store half-word into the pipeline */
605 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
606 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 1);
607 arm7tdmi_clock_out(jtag_info
, ARMV4_5_STRH_IP(num
, 0), NULL
, 0);
611 void arm7tdmi_store_byte_reg(target_t
*target
, int num
)
613 /* get pointers to arch-specific information */
614 armv4_5_common_t
*armv4_5
= target
->arch_info
;
615 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
616 arm_jtag_t
*jtag_info
= &arm7_9
->jtag_info
;
618 /* put system-speed store byte into the pipeline */
619 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
620 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 1);
621 arm7tdmi_clock_out(jtag_info
, ARMV4_5_STRB_IP(num
, 0), NULL
, 0);
625 void arm7tdmi_write_pc(target_t
*target
, u32 pc
)
627 /* get pointers to arch-specific information */
628 armv4_5_common_t
*armv4_5
= target
->arch_info
;
629 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
630 arm_jtag_t
*jtag_info
= &arm7_9
->jtag_info
;
632 /* LDMIA r0-15, [r0] at debug speed
633 * register values will start to appear on 4th DCLK
635 arm7tdmi_clock_out(jtag_info
, ARMV4_5_LDMIA(0, 0x8000, 0, 0), NULL
, 0);
636 /* fetch NOP, LDM in DECODE stage */
637 arm7tdmi_clock_out_inner(jtag_info
, ARMV4_5_NOP
, 0);
638 /* fetch NOP, LDM in EXECUTE stage (1st cycle) */
639 arm7tdmi_clock_out_inner(jtag_info
, ARMV4_5_NOP
, 0);
640 /* nothing fetched, LDM in EXECUTE stage (1st cycle) load register */
641 arm7tdmi_clock_out_inner(jtag_info
, pc
, 0);
642 /* nothing fetched, LDM in EXECUTE stage (2nd cycle) load register */
643 arm7tdmi_clock_out_inner(jtag_info
, ARMV4_5_NOP
, 0);
644 /* nothing fetched, LDM in EXECUTE stage (3rd cycle) load register */
645 arm7tdmi_clock_out_inner(jtag_info
, ARMV4_5_NOP
, 0);
646 /* fetch NOP, LDM in EXECUTE stage (4th cycle) */
647 arm7tdmi_clock_out_inner(jtag_info
, ARMV4_5_NOP
, 0);
648 /* fetch NOP, LDM in EXECUTE stage (5th cycle) */
649 arm7tdmi_clock_out_inner(jtag_info
, ARMV4_5_NOP
, 0);
652 void arm7tdmi_branch_resume(target_t
*target
)
654 /* get pointers to arch-specific information */
655 armv4_5_common_t
*armv4_5
= target
->arch_info
;
656 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
657 arm_jtag_t
*jtag_info
= &arm7_9
->jtag_info
;
659 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 1);
660 arm7tdmi_clock_out_inner(jtag_info
, ARMV4_5_B(0xfffffa, 0), 0);
664 void arm7tdmi_branch_resume_thumb(target_t
*target
)
668 /* get pointers to arch-specific information */
669 armv4_5_common_t
*armv4_5
= target
->arch_info
;
670 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
671 arm_jtag_t
*jtag_info
= &arm7_9
->jtag_info
;
672 reg_t
*dbg_stat
= &arm7_9
->eice_cache
->reg_list
[EICE_DBG_STAT
];
674 /* LDMIA r0, [r0] at debug speed
675 * register values will start to appear on 4th DCLK
677 arm7tdmi_clock_out(jtag_info
, ARMV4_5_LDMIA(0, 0x1, 0, 0), NULL
, 0);
679 /* fetch NOP, LDM in DECODE stage */
680 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
681 /* fetch NOP, LDM in EXECUTE stage (1st cycle) */
682 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
683 /* nothing fetched, LDM in EXECUTE stage (2nd cycle) */
684 arm7tdmi_clock_out(jtag_info
, buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32) | 1, NULL
, 0);
685 /* nothing fetched, LDM in EXECUTE stage (3rd cycle) */
686 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
688 /* Branch and eXchange */
689 arm7tdmi_clock_out(jtag_info
, ARMV4_5_BX(0), NULL
, 0);
691 embeddedice_read_reg(dbg_stat
);
693 /* fetch NOP, BX in DECODE stage */
694 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
696 /* target is now in Thumb state */
697 embeddedice_read_reg(dbg_stat
);
699 /* fetch NOP, BX in EXECUTE stage (1st cycle) */
700 arm7tdmi_clock_out(jtag_info
, ARMV4_5_NOP
, NULL
, 0);
702 /* target is now in Thumb state */
703 embeddedice_read_reg(dbg_stat
);
706 arm7tdmi_clock_out(jtag_info
, ARMV4_5_T_LDR_PCREL(0), NULL
, 0);
707 /* fetch NOP, LDR in Decode */
708 arm7tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, NULL
, 0);
709 /* fetch NOP, LDR in Execute */
710 arm7tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, NULL
, 0);
711 /* nothing fetched, LDR in EXECUTE stage (2nd cycle) */
712 arm7tdmi_clock_out(jtag_info
, buf_get_u32(armv4_5
->core_cache
->reg_list
[0].value
, 0, 32), NULL
, 0);
713 /* nothing fetched, LDR in EXECUTE stage (3rd cycle) */
714 arm7tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, NULL
, 0);
716 arm7tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, NULL
, 0);
717 arm7tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, NULL
, 0);
719 embeddedice_read_reg(dbg_stat
);
721 arm7tdmi_clock_out(jtag_info
, ARMV4_5_T_NOP
, NULL
, 1);
722 arm7tdmi_clock_out(jtag_info
, ARMV4_5_T_B(0x7f8), NULL
, 0);
726 void arm7tdmi_build_reg_cache(target_t
*target
)
728 reg_cache_t
**cache_p
= register_get_last_cache_p(&target
->reg_cache
);
729 /* get pointers to arch-specific information */
730 armv4_5_common_t
*armv4_5
= target
->arch_info
;
732 (*cache_p
) = armv4_5_build_reg_cache(target
, armv4_5
);
733 armv4_5
->core_cache
= (*cache_p
);
736 int arm7tdmi_examine(struct target_s
*target
)
739 armv4_5_common_t
*armv4_5
= target
->arch_info
;
740 arm7_9_common_t
*arm7_9
= armv4_5
->arch_info
;
741 if (!target
->type
->examined
)
743 /* get pointers to arch-specific information */
744 reg_cache_t
**cache_p
= register_get_last_cache_p(&target
->reg_cache
);
745 reg_cache_t
*t
=embeddedice_build_reg_cache(target
, arm7_9
);
750 arm7_9
->eice_cache
= (*cache_p
);
754 arm_jtag_t
*jtag_info
= &arm7_9
->jtag_info
;
755 (*cache_p
)->next
= etm_build_reg_cache(target
, jtag_info
, arm7_9
->etm_ctx
);
756 arm7_9
->etm_ctx
->reg_cache
= (*cache_p
)->next
;
758 target
->type
->examined
= 1;
760 if ((retval
=embeddedice_setup(target
))!=ERROR_OK
)
762 if ((retval
=arm7_9_setup(target
))!=ERROR_OK
)
766 if ((retval
=etm_setup(target
))!=ERROR_OK
)
772 int arm7tdmi_init_target(struct command_context_s
*cmd_ctx
, struct target_s
*target
)
775 arm7tdmi_build_reg_cache(target
);
781 int arm7tdmi_quit(void)
787 int arm7tdmi_init_arch_info(target_t
*target
, arm7tdmi_common_t
*arm7tdmi
, jtag_tap_t
*tap
, const char *variant
)
789 armv4_5_common_t
*armv4_5
;
790 arm7_9_common_t
*arm7_9
;
792 arm7_9
= &arm7tdmi
->arm7_9_common
;
793 armv4_5
= &arm7_9
->armv4_5_common
;
795 /* prepare JTAG information for the new target */
796 arm7_9
->jtag_info
.tap
= tap
;
797 arm7_9
->jtag_info
.scann_size
= 4;
799 /* register arch-specific functions */
800 arm7_9
->examine_debug_reason
= arm7tdmi_examine_debug_reason
;
801 arm7_9
->change_to_arm
= arm7tdmi_change_to_arm
;
802 arm7_9
->read_core_regs
= arm7tdmi_read_core_regs
;
803 arm7_9
->read_core_regs_target_buffer
= arm7tdmi_read_core_regs_target_buffer
;
804 arm7_9
->read_xpsr
= arm7tdmi_read_xpsr
;
806 arm7_9
->write_xpsr
= arm7tdmi_write_xpsr
;
807 arm7_9
->write_xpsr_im8
= arm7tdmi_write_xpsr_im8
;
808 arm7_9
->write_core_regs
= arm7tdmi_write_core_regs
;
810 arm7_9
->load_word_regs
= arm7tdmi_load_word_regs
;
811 arm7_9
->load_hword_reg
= arm7tdmi_load_hword_reg
;
812 arm7_9
->load_byte_reg
= arm7tdmi_load_byte_reg
;
814 arm7_9
->store_word_regs
= arm7tdmi_store_word_regs
;
815 arm7_9
->store_hword_reg
= arm7tdmi_store_hword_reg
;
816 arm7_9
->store_byte_reg
= arm7tdmi_store_byte_reg
;
818 arm7_9
->write_pc
= arm7tdmi_write_pc
;
819 arm7_9
->branch_resume
= arm7tdmi_branch_resume
;
820 arm7_9
->branch_resume_thumb
= arm7tdmi_branch_resume_thumb
;
822 arm7_9
->enable_single_step
= arm7_9_enable_eice_step
;
823 arm7_9
->disable_single_step
= arm7_9_disable_eice_step
;
825 arm7_9
->pre_debug_entry
= NULL
;
826 arm7_9
->post_debug_entry
= NULL
;
828 arm7_9
->pre_restore_context
= NULL
;
829 arm7_9
->post_restore_context
= NULL
;
831 /* initialize arch-specific breakpoint handling */
832 arm7_9
->arm_bkpt
= 0xdeeedeee;
833 arm7_9
->thumb_bkpt
= 0xdeee;
835 arm7_9
->dbgreq_adjust_pc
= 2;
836 arm7_9
->arch_info
= arm7tdmi
;
838 arm7tdmi
->arch_info
= NULL
;
839 arm7tdmi
->common_magic
= ARM7TDMI_COMMON_MAGIC
;
843 arm7tdmi
->variant
= strdup(variant
);
847 arm7tdmi
->variant
= strdup("");
850 arm7_9_init_arch_info(target
, arm7_9
);
857 int arm7tdmi_target_create( struct target_s
*target
, Jim_Interp
*interp
)
859 arm7tdmi_common_t
*arm7tdmi
;
861 arm7tdmi
= calloc(1,sizeof(arm7tdmi_common_t
));
863 arm7tdmi_init_arch_info(target
, arm7tdmi
, target
->tap
, target
->variant
);
869 int arm7tdmi_register_commands(struct command_context_s
*cmd_ctx
)
873 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)