added template for removing in_handler
[openocd.git] / src / target / arm7tdmi.c
1 /***************************************************************************
2 * Copyright (C) 2005 by Dominic Rath *
3 * Dominic.Rath@gmx.de *
4 * *
5 * Copyright (C) 2008 by Spencer Oliver *
6 * spen@spen-soft.co.uk *
7 * *
8 * Copyright (C) 2007,2008 Øyvind Harboe *
9 * oyvind.harboe@zylin.com *
10 * *
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. *
15 * *
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. *
20 * *
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 ***************************************************************************/
26 #ifdef HAVE_CONFIG_H
27 #include "config.h"
28 #endif
29
30 #include "arm7tdmi.h"
31
32 #include "arm7_9_common.h"
33 #include "register.h"
34 #include "target.h"
35 #include "armv4_5.h"
36 #include "embeddedice.h"
37 #include "etm.h"
38 #include "log.h"
39 #include "jtag.h"
40 #include "arm_jtag.h"
41
42 #include <stdlib.h>
43 #include <string.h>
44
45 #if 0
46 #define _DEBUG_INSTRUCTION_EXECUTION_
47 #endif
48
49 /* forward declarations */
50
51 int arm7tdmi_target_create(struct target_s *target,Jim_Interp *interp);
52 int arm7tdmi_quit(void);
53
54 /* target function declarations */
55 int arm7tdmi_poll(struct target_s *target);
56 int arm7tdmi_halt(target_t *target);
57
58 target_type_t arm7tdmi_target =
59 {
60 .name = "arm7tdmi",
61
62 .poll = arm7_9_poll,
63 .arch_state = armv4_5_arch_state,
64
65 .target_request_data = arm7_9_target_request_data,
66
67 .halt = arm7_9_halt,
68 .resume = arm7_9_resume,
69 .step = arm7_9_step,
70
71 .assert_reset = arm7_9_assert_reset,
72 .deassert_reset = arm7_9_deassert_reset,
73 .soft_reset_halt = arm7_9_soft_reset_halt,
74
75 .get_gdb_reg_list = armv4_5_get_gdb_reg_list,
76
77 .read_memory = arm7_9_read_memory,
78 .write_memory = arm7_9_write_memory,
79 .bulk_write_memory = arm7_9_bulk_write_memory,
80 .checksum_memory = arm7_9_checksum_memory,
81 .blank_check_memory = arm7_9_blank_check_memory,
82
83 .run_algorithm = armv4_5_run_algorithm,
84
85 .add_breakpoint = arm7_9_add_breakpoint,
86 .remove_breakpoint = arm7_9_remove_breakpoint,
87 .add_watchpoint = arm7_9_add_watchpoint,
88 .remove_watchpoint = arm7_9_remove_watchpoint,
89
90 .register_commands = arm7tdmi_register_commands,
91 .target_create = arm7tdmi_target_create,
92 .init_target = arm7tdmi_init_target,
93 .examine = arm7tdmi_examine,
94 .quit = arm7tdmi_quit
95 };
96
97 int arm7tdmi_examine_debug_reason(target_t *target)
98 {
99 int retval = ERROR_OK;
100 /* get pointers to arch-specific information */
101 armv4_5_common_t *armv4_5 = target->arch_info;
102 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
103
104 /* only check the debug reason if we don't know it already */
105 if ((target->debug_reason != DBG_REASON_DBGRQ)
106 && (target->debug_reason != DBG_REASON_SINGLESTEP))
107 {
108 scan_field_t fields[2];
109 u8 databus[4];
110 u8 breakpoint;
111
112 jtag_add_end_state(TAP_DRPAUSE);
113
114 fields[0].tap = arm7_9->jtag_info.tap;
115 fields[0].num_bits = 1;
116 fields[0].out_value = NULL;
117 fields[0].in_value = &breakpoint;
118 fields[0].in_handler = NULL;
119
120 fields[1].tap = arm7_9->jtag_info.tap;
121 fields[1].num_bits = 32;
122 fields[1].out_value = NULL;
123 fields[1].in_value = databus;
124 fields[1].in_handler = NULL;
125
126 if((retval = arm_jtag_scann(&arm7_9->jtag_info, 0x1)) != ERROR_OK)
127 {
128 return retval;
129 }
130 arm_jtag_set_instr(&arm7_9->jtag_info, arm7_9->jtag_info.intest_instr, NULL);
131
132 jtag_add_dr_scan(2, fields, TAP_DRPAUSE);
133 if((retval = jtag_execute_queue()) != ERROR_OK)
134 {
135 return retval;
136 }
137
138 fields[0].in_value = NULL;
139 fields[0].out_value = &breakpoint;
140 fields[1].in_value = NULL;
141 fields[1].out_value = databus;
142
143 jtag_add_dr_scan(2, fields, TAP_DRPAUSE);
144
145 if (breakpoint & 1)
146 target->debug_reason = DBG_REASON_WATCHPOINT;
147 else
148 target->debug_reason = DBG_REASON_BREAKPOINT;
149 }
150
151 return ERROR_OK;
152 }
153
154 static int arm7tdmi_num_bits[]={1, 32};
155 static __inline int arm7tdmi_clock_out_inner(arm_jtag_t *jtag_info, u32 out, int breakpoint)
156 {
157 u32 values[2]={breakpoint, flip_u32(out, 32)};
158
159 jtag_add_dr_out(jtag_info->tap,
160 2,
161 arm7tdmi_num_bits,
162 values,
163 TAP_INVALID);
164
165 jtag_add_runtest(0, TAP_INVALID);
166
167 return ERROR_OK;
168 }
169
170 /* put an instruction in the ARM7TDMI pipeline or write the data bus, and optionally read data */
171 static __inline int arm7tdmi_clock_out(arm_jtag_t *jtag_info, u32 out, u32 *deprecated, int breakpoint)
172 {
173 jtag_add_end_state(TAP_DRPAUSE);
174 arm_jtag_scann(jtag_info, 0x1);
175 arm_jtag_set_instr(jtag_info, jtag_info->intest_instr, NULL);
176
177 return arm7tdmi_clock_out_inner(jtag_info, out, breakpoint);
178 }
179
180 /* clock the target, reading the databus */
181 int arm7tdmi_clock_data_in(arm_jtag_t *jtag_info, u32 *in)
182 {
183 int retval = ERROR_OK;
184 scan_field_t fields[2];
185
186 jtag_add_end_state(TAP_DRPAUSE);
187 if((retval = arm_jtag_scann(jtag_info, 0x1)) != ERROR_OK)
188 {
189 return retval;
190 }
191 arm_jtag_set_instr(jtag_info, jtag_info->intest_instr, NULL);
192
193 fields[0].tap = jtag_info->tap;
194 fields[0].num_bits = 1;
195 fields[0].out_value = NULL;
196 fields[0].in_value = NULL;
197 fields[0].in_handler = NULL;
198
199
200 fields[1].tap = jtag_info->tap;
201 fields[1].num_bits = 32;
202 fields[1].out_value = NULL;
203 u8 tmp[4];
204 fields[1].in_value = tmp;
205 fields[1].in_handler = NULL;
206
207 jtag_add_dr_scan_now(2, fields, TAP_INVALID);
208
209 if (jtag_error==ERROR_OK)
210 {
211 *in=flip_u32(le_to_h_u32(tmp), 32);
212 }
213
214 jtag_add_runtest(0, TAP_INVALID);
215
216 #ifdef _DEBUG_INSTRUCTION_EXECUTION_
217 {
218 if((retval = jtag_execute_queue()) != ERROR_OK)
219 {
220 return retval;
221 }
222
223 if (in)
224 {
225 LOG_DEBUG("in: 0x%8.8x", *in);
226 }
227 else
228 {
229 LOG_ERROR("BUG: called with in == NULL");
230 }
231 }
232 #endif
233
234 return ERROR_OK;
235 }
236
237 /* clock the target, and read the databus
238 * the *in pointer points to a buffer where elements of 'size' bytes
239 * are stored in big (be==1) or little (be==0) endianness
240 */
241 int arm7tdmi_clock_data_in_endianness(arm_jtag_t *jtag_info, void *in, int size, int be)
242 {
243 int retval = ERROR_OK;
244 scan_field_t fields[2];
245
246 jtag_add_end_state(TAP_DRPAUSE);
247 if((retval = arm_jtag_scann(jtag_info, 0x1)) != ERROR_OK)
248 {
249 return retval;
250 }
251 arm_jtag_set_instr(jtag_info, jtag_info->intest_instr, NULL);
252
253 fields[0].tap = jtag_info->tap;
254 fields[0].num_bits = 1;
255 fields[0].out_value = NULL;
256 fields[0].in_value = NULL;
257 fields[0].in_handler = NULL;
258
259
260 fields[1].tap = jtag_info->tap;
261 fields[1].num_bits = 32;
262 fields[1].out_value = NULL;
263 fields[1].in_value = NULL;
264 switch (size)
265 {
266 case 4:
267 fields[1].in_handler = (be) ? arm_jtag_buf_to_be32_flip : arm_jtag_buf_to_le32_flip; /* deprecated! invoke this from user code! */
268 break;
269 case 2:
270 fields[1].in_handler = (be) ? arm_jtag_buf_to_be16_flip : arm_jtag_buf_to_le16_flip; /* deprecated! invoke this from user code! */
271 break;
272 case 1:
273 fields[1].in_handler = arm_jtag_buf_to_8_flip; /* deprecated! invoke this from user code! */
274 break;
275 }
276 fields[1].in_handler_priv = in;
277
278
279
280 jtag_add_dr_scan(2, fields, TAP_INVALID);
281
282 jtag_add_runtest(0, TAP_INVALID);
283
284 #ifdef _DEBUG_INSTRUCTION_EXECUTION_
285 {
286 if((retval = jtag_execute_queue()) != ERROR_OK)
287 {
288 return retval;
289 }
290
291 if (in)
292 {
293 LOG_DEBUG("in: 0x%8.8x", *(u32*)in);
294 }
295 else
296 {
297 LOG_ERROR("BUG: called with in == NULL");
298 }
299 }
300 #endif
301
302 return ERROR_OK;
303 }
304
305 void arm7tdmi_change_to_arm(target_t *target, u32 *r0, u32 *pc)
306 {
307 /* get pointers to arch-specific information */
308 armv4_5_common_t *armv4_5 = target->arch_info;
309 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
310 arm_jtag_t *jtag_info = &arm7_9->jtag_info;
311
312 /* save r0 before using it and put system in ARM state
313 * to allow common handling of ARM and THUMB debugging */
314
315 /* fetch STR r0, [r0] */
316 arm7tdmi_clock_out(jtag_info, ARMV4_5_T_STR(0, 0), NULL, 0);
317 arm7tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, NULL, 0);
318 arm7tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, NULL, 0);
319 /* nothing fetched, STR r0, [r0] in Execute (2) */
320 arm7tdmi_clock_data_in(jtag_info, r0);
321
322 /* MOV r0, r15 fetched, STR in Decode */
323 arm7tdmi_clock_out(jtag_info, ARMV4_5_T_MOV(0, 15), NULL, 0);
324 arm7tdmi_clock_out(jtag_info, ARMV4_5_T_STR(0, 0), NULL, 0);
325 arm7tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, NULL, 0);
326 arm7tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, NULL, 0);
327 /* nothing fetched, STR r0, [r0] in Execute (2) */
328 arm7tdmi_clock_data_in(jtag_info, pc);
329
330 /* use pc-relative LDR to clear r0[1:0] (for switch to ARM mode) */
331 arm7tdmi_clock_out(jtag_info, ARMV4_5_T_LDR_PCREL(0), NULL, 0);
332 arm7tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, NULL, 0);
333 arm7tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, NULL, 0);
334 /* nothing fetched, data for LDR r0, [PC, #0] */
335 arm7tdmi_clock_out(jtag_info, 0x0, NULL, 0);
336 /* nothing fetched, data from previous cycle is written to register */
337 arm7tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, NULL, 0);
338
339 /* fetch BX */
340 arm7tdmi_clock_out(jtag_info, ARMV4_5_T_BX(0), NULL, 0);
341 /* NOP fetched, BX in Decode, MOV in Execute */
342 arm7tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, NULL, 0);
343 /* NOP fetched, BX in Execute (1) */
344 arm7tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, NULL, 0);
345
346 jtag_execute_queue();
347
348 /* fix program counter:
349 * MOV r0, r15 was the 4th instruction (+6)
350 * reading PC in Thumb state gives address of instruction + 4
351 */
352 *pc -= 0xa;
353 }
354
355 void arm7tdmi_read_core_regs(target_t *target, u32 mask, u32* core_regs[16])
356 {
357 int i;
358 /* get pointers to arch-specific information */
359 armv4_5_common_t *armv4_5 = target->arch_info;
360 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
361 arm_jtag_t *jtag_info = &arm7_9->jtag_info;
362
363 /* STMIA r0-15, [r0] at debug speed
364 * register values will start to appear on 4th DCLK
365 */
366 arm7tdmi_clock_out(jtag_info, ARMV4_5_STMIA(0, mask & 0xffff, 0, 0), NULL, 0);
367
368 /* fetch NOP, STM in DECODE stage */
369 arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
370 /* fetch NOP, STM in EXECUTE stage (1st cycle) */
371 arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
372
373 for (i = 0; i <= 15; i++)
374 {
375 if (mask & (1 << i))
376 /* nothing fetched, STM still in EXECUTE (1+i cycle) */
377 arm7tdmi_clock_data_in(jtag_info, core_regs[i]);
378 }
379 }
380
381 void arm7tdmi_read_core_regs_target_buffer(target_t *target, u32 mask, void* buffer, int size)
382 {
383 int i;
384 /* get pointers to arch-specific information */
385 armv4_5_common_t *armv4_5 = target->arch_info;
386 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
387 arm_jtag_t *jtag_info = &arm7_9->jtag_info;
388 int be = (target->endianness == TARGET_BIG_ENDIAN) ? 1 : 0;
389 u32 *buf_u32 = buffer;
390 u16 *buf_u16 = buffer;
391 u8 *buf_u8 = buffer;
392
393 /* STMIA r0-15, [r0] at debug speed
394 * register values will start to appear on 4th DCLK
395 */
396 arm7tdmi_clock_out(jtag_info, ARMV4_5_STMIA(0, mask & 0xffff, 0, 0), NULL, 0);
397
398 /* fetch NOP, STM in DECODE stage */
399 arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
400 /* fetch NOP, STM in EXECUTE stage (1st cycle) */
401 arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
402
403 for (i = 0; i <= 15; i++)
404 {
405 /* nothing fetched, STM still in EXECUTE (1+i cycle), read databus */
406 if (mask & (1 << i))
407 {
408 switch (size)
409 {
410 case 4:
411 arm7tdmi_clock_data_in_endianness(jtag_info, buf_u32++, 4, be);
412 break;
413 case 2:
414 arm7tdmi_clock_data_in_endianness(jtag_info, buf_u16++, 2, be);
415 break;
416 case 1:
417 arm7tdmi_clock_data_in_endianness(jtag_info, buf_u8++, 1, be);
418 break;
419 }
420 }
421 }
422 }
423
424 void arm7tdmi_read_xpsr(target_t *target, u32 *xpsr, int spsr)
425 {
426 /* get pointers to arch-specific information */
427 armv4_5_common_t *armv4_5 = target->arch_info;
428 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
429 arm_jtag_t *jtag_info = &arm7_9->jtag_info;
430
431 /* MRS r0, cpsr */
432 arm7tdmi_clock_out(jtag_info, ARMV4_5_MRS(0, spsr & 1), NULL, 0);
433
434 /* STR r0, [r15] */
435 arm7tdmi_clock_out(jtag_info, ARMV4_5_STR(0, 15), NULL, 0);
436 /* fetch NOP, STR in DECODE stage */
437 arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
438 /* fetch NOP, STR in EXECUTE stage (1st cycle) */
439 arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
440 /* nothing fetched, STR still in EXECUTE (2nd cycle) */
441 arm7tdmi_clock_data_in(jtag_info, xpsr);
442 }
443
444 void arm7tdmi_write_xpsr(target_t *target, u32 xpsr, int spsr)
445 {
446 /* get pointers to arch-specific information */
447 armv4_5_common_t *armv4_5 = target->arch_info;
448 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
449 arm_jtag_t *jtag_info = &arm7_9->jtag_info;
450
451 LOG_DEBUG("xpsr: %8.8x, spsr: %i", xpsr, spsr);
452
453 /* MSR1 fetched */
454 arm7tdmi_clock_out(jtag_info, ARMV4_5_MSR_IM(xpsr & 0xff, 0, 1, spsr), NULL, 0);
455 /* MSR2 fetched, MSR1 in DECODE */
456 arm7tdmi_clock_out(jtag_info, ARMV4_5_MSR_IM((xpsr & 0xff00) >> 8, 0xc, 2, spsr), NULL, 0);
457 /* MSR3 fetched, MSR1 in EXECUTE (1), MSR2 in DECODE */
458 arm7tdmi_clock_out(jtag_info, ARMV4_5_MSR_IM((xpsr & 0xff0000) >> 16, 0x8, 4, spsr), NULL, 0);
459 /* nothing fetched, MSR1 in EXECUTE (2) */
460 arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
461 /* MSR4 fetched, MSR2 in EXECUTE (1), MSR3 in DECODE */
462 arm7tdmi_clock_out(jtag_info, ARMV4_5_MSR_IM((xpsr & 0xff000000) >> 24, 0x4, 8, spsr), NULL, 0);
463 /* nothing fetched, MSR2 in EXECUTE (2) */
464 arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
465 /* NOP fetched, MSR3 in EXECUTE (1), MSR4 in DECODE */
466 arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
467 /* nothing fetched, MSR3 in EXECUTE (2) */
468 arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
469 /* NOP fetched, MSR4 in EXECUTE (1) */
470 arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
471 /* nothing fetched, MSR4 in EXECUTE (2) */
472 arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
473 }
474
475 void arm7tdmi_write_xpsr_im8(target_t *target, u8 xpsr_im, int rot, int spsr)
476 {
477 /* get pointers to arch-specific information */
478 armv4_5_common_t *armv4_5 = target->arch_info;
479 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
480 arm_jtag_t *jtag_info = &arm7_9->jtag_info;
481
482 LOG_DEBUG("xpsr_im: %2.2x, rot: %i, spsr: %i", xpsr_im, rot, spsr);
483
484 /* MSR fetched */
485 arm7tdmi_clock_out(jtag_info, ARMV4_5_MSR_IM(xpsr_im, rot, 1, spsr), NULL, 0);
486 /* NOP fetched, MSR in DECODE */
487 arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
488 /* NOP fetched, MSR in EXECUTE (1) */
489 arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
490 /* nothing fetched, MSR in EXECUTE (2) */
491 arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
492 }
493
494 void arm7tdmi_write_core_regs(target_t *target, u32 mask, u32 core_regs[16])
495 {
496 int i;
497 /* get pointers to arch-specific information */
498 armv4_5_common_t *armv4_5 = target->arch_info;
499 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
500 arm_jtag_t *jtag_info = &arm7_9->jtag_info;
501
502 /* LDMIA r0-15, [r0] at debug speed
503 * register values will start to appear on 4th DCLK
504 */
505 arm7tdmi_clock_out(jtag_info, ARMV4_5_LDMIA(0, mask & 0xffff, 0, 0), NULL, 0);
506
507 /* fetch NOP, LDM in DECODE stage */
508 arm7tdmi_clock_out_inner(jtag_info, ARMV4_5_NOP, 0);
509 /* fetch NOP, LDM in EXECUTE stage (1st cycle) */
510 arm7tdmi_clock_out_inner(jtag_info, ARMV4_5_NOP, 0);
511
512 for (i = 0; i <= 15; i++)
513 {
514 if (mask & (1 << i))
515 /* nothing fetched, LDM still in EXECUTE (1+i cycle) */
516 arm7tdmi_clock_out_inner(jtag_info, core_regs[i], 0);
517 }
518 arm7tdmi_clock_out_inner(jtag_info, ARMV4_5_NOP, 0);
519 }
520
521 void arm7tdmi_load_word_regs(target_t *target, u32 mask)
522 {
523 /* get pointers to arch-specific information */
524 armv4_5_common_t *armv4_5 = target->arch_info;
525 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
526 arm_jtag_t *jtag_info = &arm7_9->jtag_info;
527
528 /* put system-speed load-multiple into the pipeline */
529 arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
530 arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 1);
531 arm7tdmi_clock_out(jtag_info, ARMV4_5_LDMIA(0, mask & 0xffff, 0, 1), NULL, 0);
532 }
533
534 void arm7tdmi_load_hword_reg(target_t *target, int num)
535 {
536 /* get pointers to arch-specific information */
537 armv4_5_common_t *armv4_5 = target->arch_info;
538 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
539 arm_jtag_t *jtag_info = &arm7_9->jtag_info;
540
541 /* put system-speed load half-word into the pipeline */
542 arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
543 arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 1);
544 arm7tdmi_clock_out(jtag_info, ARMV4_5_LDRH_IP(num, 0), NULL, 0);
545 }
546
547 void arm7tdmi_load_byte_reg(target_t *target, int num)
548 {
549 /* get pointers to arch-specific information */
550 armv4_5_common_t *armv4_5 = target->arch_info;
551 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
552 arm_jtag_t *jtag_info = &arm7_9->jtag_info;
553
554 /* put system-speed load byte into the pipeline */
555 arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
556 arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 1);
557 arm7tdmi_clock_out(jtag_info, ARMV4_5_LDRB_IP(num, 0), NULL, 0);
558 }
559
560 void arm7tdmi_store_word_regs(target_t *target, u32 mask)
561 {
562 /* get pointers to arch-specific information */
563 armv4_5_common_t *armv4_5 = target->arch_info;
564 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
565 arm_jtag_t *jtag_info = &arm7_9->jtag_info;
566
567 /* put system-speed store-multiple into the pipeline */
568 arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
569 arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 1);
570 arm7tdmi_clock_out(jtag_info, ARMV4_5_STMIA(0, mask, 0, 1), NULL, 0);
571 }
572
573 void arm7tdmi_store_hword_reg(target_t *target, int num)
574 {
575 /* get pointers to arch-specific information */
576 armv4_5_common_t *armv4_5 = target->arch_info;
577 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
578 arm_jtag_t *jtag_info = &arm7_9->jtag_info;
579
580 /* put system-speed store half-word into the pipeline */
581 arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
582 arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 1);
583 arm7tdmi_clock_out(jtag_info, ARMV4_5_STRH_IP(num, 0), NULL, 0);
584 }
585
586 void arm7tdmi_store_byte_reg(target_t *target, int num)
587 {
588 /* get pointers to arch-specific information */
589 armv4_5_common_t *armv4_5 = target->arch_info;
590 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
591 arm_jtag_t *jtag_info = &arm7_9->jtag_info;
592
593 /* put system-speed store byte into the pipeline */
594 arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
595 arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 1);
596 arm7tdmi_clock_out(jtag_info, ARMV4_5_STRB_IP(num, 0), NULL, 0);
597 }
598
599 void arm7tdmi_write_pc(target_t *target, u32 pc)
600 {
601 /* get pointers to arch-specific information */
602 armv4_5_common_t *armv4_5 = target->arch_info;
603 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
604 arm_jtag_t *jtag_info = &arm7_9->jtag_info;
605
606 /* LDMIA r0-15, [r0] at debug speed
607 * register values will start to appear on 4th DCLK
608 */
609 arm7tdmi_clock_out(jtag_info, ARMV4_5_LDMIA(0, 0x8000, 0, 0), NULL, 0);
610 /* fetch NOP, LDM in DECODE stage */
611 arm7tdmi_clock_out_inner(jtag_info, ARMV4_5_NOP, 0);
612 /* fetch NOP, LDM in EXECUTE stage (1st cycle) */
613 arm7tdmi_clock_out_inner(jtag_info, ARMV4_5_NOP, 0);
614 /* nothing fetched, LDM in EXECUTE stage (1st cycle) load register */
615 arm7tdmi_clock_out_inner(jtag_info, pc, 0);
616 /* nothing fetched, LDM in EXECUTE stage (2nd cycle) load register */
617 arm7tdmi_clock_out_inner(jtag_info, ARMV4_5_NOP, 0);
618 /* nothing fetched, LDM in EXECUTE stage (3rd cycle) load register */
619 arm7tdmi_clock_out_inner(jtag_info, ARMV4_5_NOP, 0);
620 /* fetch NOP, LDM in EXECUTE stage (4th cycle) */
621 arm7tdmi_clock_out_inner(jtag_info, ARMV4_5_NOP, 0);
622 /* fetch NOP, LDM in EXECUTE stage (5th cycle) */
623 arm7tdmi_clock_out_inner(jtag_info, ARMV4_5_NOP, 0);
624 }
625
626 void arm7tdmi_branch_resume(target_t *target)
627 {
628 /* get pointers to arch-specific information */
629 armv4_5_common_t *armv4_5 = target->arch_info;
630 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
631 arm_jtag_t *jtag_info = &arm7_9->jtag_info;
632
633 arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 1);
634 arm7tdmi_clock_out_inner(jtag_info, ARMV4_5_B(0xfffffa, 0), 0);
635 }
636
637 void arm7tdmi_branch_resume_thumb(target_t *target)
638 {
639 LOG_DEBUG("-");
640
641 /* get pointers to arch-specific information */
642 armv4_5_common_t *armv4_5 = target->arch_info;
643 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
644 arm_jtag_t *jtag_info = &arm7_9->jtag_info;
645 reg_t *dbg_stat = &arm7_9->eice_cache->reg_list[EICE_DBG_STAT];
646
647 /* LDMIA r0, [r0] at debug speed
648 * register values will start to appear on 4th DCLK
649 */
650 arm7tdmi_clock_out(jtag_info, ARMV4_5_LDMIA(0, 0x1, 0, 0), NULL, 0);
651
652 /* fetch NOP, LDM in DECODE stage */
653 arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
654 /* fetch NOP, LDM in EXECUTE stage (1st cycle) */
655 arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
656 /* nothing fetched, LDM in EXECUTE stage (2nd cycle) */
657 arm7tdmi_clock_out(jtag_info, buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32) | 1, NULL, 0);
658 /* nothing fetched, LDM in EXECUTE stage (3rd cycle) */
659 arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
660
661 /* Branch and eXchange */
662 arm7tdmi_clock_out(jtag_info, ARMV4_5_BX(0), NULL, 0);
663
664 embeddedice_read_reg(dbg_stat);
665
666 /* fetch NOP, BX in DECODE stage */
667 arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
668
669 /* target is now in Thumb state */
670 embeddedice_read_reg(dbg_stat);
671
672 /* fetch NOP, BX in EXECUTE stage (1st cycle) */
673 arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
674
675 /* target is now in Thumb state */
676 embeddedice_read_reg(dbg_stat);
677
678 /* load r0 value */
679 arm7tdmi_clock_out(jtag_info, ARMV4_5_T_LDR_PCREL(0), NULL, 0);
680 /* fetch NOP, LDR in Decode */
681 arm7tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, NULL, 0);
682 /* fetch NOP, LDR in Execute */
683 arm7tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, NULL, 0);
684 /* nothing fetched, LDR in EXECUTE stage (2nd cycle) */
685 arm7tdmi_clock_out(jtag_info, buf_get_u32(armv4_5->core_cache->reg_list[0].value, 0, 32), NULL, 0);
686 /* nothing fetched, LDR in EXECUTE stage (3rd cycle) */
687 arm7tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, NULL, 0);
688
689 arm7tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, NULL, 0);
690 arm7tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, NULL, 0);
691
692 embeddedice_read_reg(dbg_stat);
693
694 arm7tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, NULL, 1);
695 arm7tdmi_clock_out(jtag_info, ARMV4_5_T_B(0x7f8), NULL, 0);
696 }
697
698 void arm7tdmi_build_reg_cache(target_t *target)
699 {
700 reg_cache_t **cache_p = register_get_last_cache_p(&target->reg_cache);
701 /* get pointers to arch-specific information */
702 armv4_5_common_t *armv4_5 = target->arch_info;
703
704 (*cache_p) = armv4_5_build_reg_cache(target, armv4_5);
705 armv4_5->core_cache = (*cache_p);
706 }
707
708 int arm7tdmi_examine(struct target_s *target)
709 {
710 int retval;
711 armv4_5_common_t *armv4_5 = target->arch_info;
712 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
713 if (!target->type->examined)
714 {
715 /* get pointers to arch-specific information */
716 reg_cache_t **cache_p = register_get_last_cache_p(&target->reg_cache);
717 reg_cache_t *t=embeddedice_build_reg_cache(target, arm7_9);
718 if (t==NULL)
719 return ERROR_FAIL;
720
721 (*cache_p) = t;
722 arm7_9->eice_cache = (*cache_p);
723
724 if (arm7_9->etm_ctx)
725 {
726 arm_jtag_t *jtag_info = &arm7_9->jtag_info;
727 (*cache_p)->next = etm_build_reg_cache(target, jtag_info, arm7_9->etm_ctx);
728 arm7_9->etm_ctx->reg_cache = (*cache_p)->next;
729 }
730 target->type->examined = 1;
731 }
732 if ((retval=embeddedice_setup(target))!=ERROR_OK)
733 return retval;
734 if ((retval=arm7_9_setup(target))!=ERROR_OK)
735 return retval;
736 if (arm7_9->etm_ctx)
737 {
738 if ((retval=etm_setup(target))!=ERROR_OK)
739 return retval;
740 }
741 return ERROR_OK;
742 }
743
744 int arm7tdmi_init_target(struct command_context_s *cmd_ctx, struct target_s *target)
745 {
746 arm7tdmi_build_reg_cache(target);
747
748 return ERROR_OK;
749 }
750
751 int arm7tdmi_quit(void)
752 {
753 return ERROR_OK;
754 }
755
756 int arm7tdmi_init_arch_info(target_t *target, arm7tdmi_common_t *arm7tdmi, jtag_tap_t *tap)
757 {
758 armv4_5_common_t *armv4_5;
759 arm7_9_common_t *arm7_9;
760
761 arm7_9 = &arm7tdmi->arm7_9_common;
762 armv4_5 = &arm7_9->armv4_5_common;
763
764 /* prepare JTAG information for the new target */
765 arm7_9->jtag_info.tap = tap;
766 arm7_9->jtag_info.scann_size = 4;
767
768 /* register arch-specific functions */
769 arm7_9->examine_debug_reason = arm7tdmi_examine_debug_reason;
770 arm7_9->change_to_arm = arm7tdmi_change_to_arm;
771 arm7_9->read_core_regs = arm7tdmi_read_core_regs;
772 arm7_9->read_core_regs_target_buffer = arm7tdmi_read_core_regs_target_buffer;
773 arm7_9->read_xpsr = arm7tdmi_read_xpsr;
774
775 arm7_9->write_xpsr = arm7tdmi_write_xpsr;
776 arm7_9->write_xpsr_im8 = arm7tdmi_write_xpsr_im8;
777 arm7_9->write_core_regs = arm7tdmi_write_core_regs;
778
779 arm7_9->load_word_regs = arm7tdmi_load_word_regs;
780 arm7_9->load_hword_reg = arm7tdmi_load_hword_reg;
781 arm7_9->load_byte_reg = arm7tdmi_load_byte_reg;
782
783 arm7_9->store_word_regs = arm7tdmi_store_word_regs;
784 arm7_9->store_hword_reg = arm7tdmi_store_hword_reg;
785 arm7_9->store_byte_reg = arm7tdmi_store_byte_reg;
786
787 arm7_9->write_pc = arm7tdmi_write_pc;
788 arm7_9->branch_resume = arm7tdmi_branch_resume;
789 arm7_9->branch_resume_thumb = arm7tdmi_branch_resume_thumb;
790
791 arm7_9->enable_single_step = arm7_9_enable_eice_step;
792 arm7_9->disable_single_step = arm7_9_disable_eice_step;
793
794 arm7_9->pre_debug_entry = NULL;
795 arm7_9->post_debug_entry = NULL;
796
797 arm7_9->pre_restore_context = NULL;
798 arm7_9->post_restore_context = NULL;
799
800 /* initialize arch-specific breakpoint handling */
801 arm7_9->arm_bkpt = 0xdeeedeee;
802 arm7_9->thumb_bkpt = 0xdeee;
803
804 arm7_9->dbgreq_adjust_pc = 2;
805 arm7_9->arch_info = arm7tdmi;
806
807 arm7tdmi->arch_info = NULL;
808 arm7tdmi->common_magic = ARM7TDMI_COMMON_MAGIC;
809
810 arm7_9_init_arch_info(target, arm7_9);
811
812 return ERROR_OK;
813 }
814
815 int arm7tdmi_target_create( struct target_s *target, Jim_Interp *interp )
816 {
817 arm7tdmi_common_t *arm7tdmi;
818
819 arm7tdmi = calloc(1,sizeof(arm7tdmi_common_t));
820 arm7tdmi_init_arch_info(target, arm7tdmi, target->tap);
821
822 return ERROR_OK;
823 }
824
825 int arm7tdmi_register_commands(struct command_context_s *cmd_ctx)
826 {
827 int retval;
828
829 retval = arm7_9_register_commands(cmd_ctx);
830
831 return retval;
832 }

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)