OpenOCD
arm7tdmi.c
Go to the documentation of this file.
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 
3 /***************************************************************************
4  * Copyright (C) 2005 by Dominic Rath *
5  * Dominic.Rath@gmx.de *
6  * *
7  * Copyright (C) 2008 by Spencer Oliver *
8  * spen@spen-soft.co.uk *
9  * *
10  * Copyright (C) 2007,2008 Øyvind Harboe *
11  * oyvind.harboe@zylin.com *
12  ***************************************************************************/
13 
14 #ifdef HAVE_CONFIG_H
15 #include "config.h"
16 #endif
17 
18 #include "arm7tdmi.h"
19 #include "target_type.h"
20 #include "register.h"
21 #include "arm_opcodes.h"
22 #include "arm_semihosting.h"
23 
24 /*
25  * For information about ARM7TDMI, see ARM DDI 0210C (r4p1)
26  * or ARM DDI 0029G (r3). "Debug In Depth", Appendix B,
27  * covers JTAG support.
28  */
29 
30 #if 0
31 #define _DEBUG_INSTRUCTION_EXECUTION_
32 #endif
33 
35 {
36  int retval = ERROR_OK;
37  struct arm7_9_common *arm7_9 = target_to_arm7_9(target);
38 
39  /* only check the debug reason if we don't know it already */
42  struct scan_field fields[2];
43  uint8_t databus[4];
44  uint8_t breakpoint;
45 
46  fields[0].num_bits = 1;
47  fields[0].out_value = NULL;
48  fields[0].in_value = &breakpoint;
49 
50  fields[1].num_bits = 32;
51  fields[1].out_value = NULL;
52  fields[1].in_value = databus;
53 
54  retval = arm_jtag_scann(&arm7_9->jtag_info, 0x1, TAP_DRPAUSE);
55  if (retval != ERROR_OK)
56  return retval;
58  if (retval != ERROR_OK)
59  return retval;
60 
61  jtag_add_dr_scan(arm7_9->jtag_info.tap, 2, fields, TAP_DRPAUSE);
62  retval = jtag_execute_queue();
63  if (retval != ERROR_OK)
64  return retval;
65 
66  fields[0].in_value = NULL;
67  fields[0].out_value = &breakpoint;
68  fields[1].in_value = NULL;
69  fields[1].out_value = databus;
70 
71  jtag_add_dr_scan(arm7_9->jtag_info.tap, 2, fields, TAP_DRPAUSE);
72 
73  if (breakpoint & 1)
75  else
77  }
78 
79  return ERROR_OK;
80 }
81 
82 static const int arm7tdmi_num_bits[] = {1, 32};
83 
84 static inline int arm7tdmi_clock_out_inner(struct arm_jtag *jtag_info, uint32_t out, int breakpoint)
85 {
86  uint8_t bp = breakpoint ? 1 : 0;
87  uint8_t out_value[4];
88  buf_set_u32(out_value, 0, 32, flip_u32(out, 32));
89 
90  struct scan_field fields[2] = {
91  { .num_bits = arm7tdmi_num_bits[0], .out_value = &bp },
92  { .num_bits = arm7tdmi_num_bits[1], .out_value = out_value },
93  };
94 
95  jtag_add_dr_scan(jtag_info->tap,
96  2,
97  fields,
98  TAP_DRPAUSE);
99 
101 
102  return ERROR_OK;
103 }
104 
105 /* put an instruction in the ARM7TDMI pipeline or write the data bus,
106  * and optionally read data
107  */
108 static inline int arm7tdmi_clock_out(struct arm_jtag *jtag_info,
109  uint32_t out, int breakpoint)
110 {
111  int retval;
112  retval = arm_jtag_scann(jtag_info, 0x1, TAP_DRPAUSE);
113  if (retval != ERROR_OK)
114  return retval;
115  retval = arm_jtag_set_instr(jtag_info->tap, jtag_info->intest_instr, NULL, TAP_DRPAUSE);
116  if (retval != ERROR_OK)
117  return retval;
118 
119  return arm7tdmi_clock_out_inner(jtag_info, out, breakpoint);
120 }
121 
122 /* clock the target, reading the databus */
123 static int arm7tdmi_clock_data_in(struct arm_jtag *jtag_info, uint32_t *in)
124 {
125  int retval = ERROR_OK;
126  struct scan_field fields[2];
127 
128  retval = arm_jtag_scann(jtag_info, 0x1, TAP_DRPAUSE);
129  if (retval != ERROR_OK)
130  return retval;
131  retval = arm_jtag_set_instr(jtag_info->tap, jtag_info->intest_instr, NULL, TAP_DRPAUSE);
132  if (retval != ERROR_OK)
133  return retval;
134 
135  fields[0].num_bits = 1;
136  fields[0].out_value = NULL;
137  fields[0].in_value = NULL;
138 
139  fields[1].num_bits = 32;
140  fields[1].out_value = NULL;
141  fields[1].in_value = (uint8_t *)in;
142 
143  jtag_add_dr_scan(jtag_info->tap, 2, fields, TAP_DRPAUSE);
144 
146 
148 
149 #ifdef _DEBUG_INSTRUCTION_EXECUTION_
150  retval = jtag_execute_queue();
151  if (retval != ERROR_OK)
152  return retval;
153 
154  if (in)
155  LOG_DEBUG("in: 0x%8.8x", *in);
156  else
157  LOG_ERROR("BUG: called with in == NULL");
158 #endif
159 
160  return ERROR_OK;
161 }
162 
163 /* clock the target, and read the databus
164  * the *in pointer points to a buffer where elements of 'size' bytes
165  * are stored in big (be == 1) or little (be == 0) endianness
166  */
167 static int arm7tdmi_clock_data_in_endianness(struct arm_jtag *jtag_info,
168  void *in, int size, int be)
169 {
170  int retval = ERROR_OK;
171  struct scan_field fields[3];
172 
173  retval = arm_jtag_scann(jtag_info, 0x1, TAP_DRPAUSE);
174  if (retval != ERROR_OK)
175  return retval;
176  retval = arm_jtag_set_instr(jtag_info->tap, jtag_info->intest_instr, NULL, TAP_DRPAUSE);
177  if (retval != ERROR_OK)
178  return retval;
179 
180  fields[0].num_bits = 1;
181  fields[0].out_value = NULL;
182  fields[0].in_value = NULL;
183 
184  if (size == 4) {
185  fields[1].num_bits = 32;
186  fields[1].out_value = NULL;
187  fields[1].in_value = in;
188  } else {
189  /* Discard irrelevant bits of the scan, making sure we don't write more
190  * than size bytes to in */
191  fields[1].num_bits = 32 - size * 8;
192  fields[1].out_value = NULL;
193  fields[1].in_value = NULL;
194 
195  fields[2].num_bits = size * 8;
196  fields[2].out_value = NULL;
197  fields[2].in_value = in;
198  }
199 
200  jtag_add_dr_scan(jtag_info->tap, size == 4 ? 2 : 3, fields, TAP_DRPAUSE);
201 
207 
209 
210 #ifdef _DEBUG_INSTRUCTION_EXECUTION_
211 {
212  retval = jtag_execute_queue();
213  if (retval != ERROR_OK)
214  return retval;
215 
216  if (in)
217  LOG_DEBUG("in: 0x%8.8x", *(uint32_t *)in);
218  else
219  LOG_ERROR("BUG: called with in == NULL");
220 }
221 #endif
222 
223  return ERROR_OK;
224 }
225 
227  uint32_t *r0, uint32_t *pc)
228 {
229  struct arm7_9_common *arm7_9 = target_to_arm7_9(target);
230  struct arm_jtag *jtag_info = &arm7_9->jtag_info;
231 
232  /* save r0 before using it and put system in ARM state
233  * to allow common handling of ARM and THUMB debugging */
234 
235  /* fetch STR r0, [r0] */
236  arm7tdmi_clock_out(jtag_info, ARMV4_5_T_STR(0, 0), 0);
237  arm7tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0);
238  arm7tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0);
239  /* nothing fetched, STR r0, [r0] in Execute (2) */
240  arm7tdmi_clock_data_in(jtag_info, r0);
241 
242  /* MOV r0, r15 fetched, STR in Decode */
243  arm7tdmi_clock_out(jtag_info, ARMV4_5_T_MOV(0, 15), 0);
244  arm7tdmi_clock_out(jtag_info, ARMV4_5_T_STR(0, 0), 0);
245  arm7tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0);
246  arm7tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0);
247  /* nothing fetched, STR r0, [r0] in Execute (2) */
248  arm7tdmi_clock_data_in(jtag_info, pc);
249 
250  /* use pc-relative LDR to clear r0[1:0] (for switch to ARM mode) */
251  arm7tdmi_clock_out(jtag_info, ARMV4_5_T_LDR_PCREL(0), 0);
252  arm7tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0);
253  arm7tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0);
254  /* nothing fetched, data for LDR r0, [PC, #0] */
255  arm7tdmi_clock_out(jtag_info, 0x0, 0);
256  /* nothing fetched, data from previous cycle is written to register */
257  arm7tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0);
258 
259  /* fetch BX */
260  arm7tdmi_clock_out(jtag_info, ARMV4_5_T_BX(0), 0);
261  /* NOP fetched, BX in Decode, MOV in Execute */
262  arm7tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0);
263  /* NOP fetched, BX in Execute (1) */
264  arm7tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0);
265 
267 
268  /* fix program counter:
269  * MOV r0, r15 was the 4th instruction (+6)
270  * reading PC in Thumb state gives address of instruction + 4
271  */
272  *pc -= 0xa;
273 }
274 
275 /* FIX!!! is this a potential performance bottleneck w.r.t. requiring too many
276  * roundtrips when jtag_execute_queue() has a large overhead(e.g. for USB)s?
277  *
278  * The solution is to arrange for a large out/in scan in this loop and
279  * and convert data afterwards.
280  */
282  uint32_t mask, uint32_t *core_regs[16])
283 {
284  int i;
285  struct arm7_9_common *arm7_9 = target_to_arm7_9(target);
286  struct arm_jtag *jtag_info = &arm7_9->jtag_info;
287 
288  /* STMIA r0-15, [r0] at debug speed
289  * register values will start to appear on 4th DCLK
290  */
291  arm7tdmi_clock_out(jtag_info, ARMV4_5_STMIA(0, mask & 0xffff, 0, 0), 0);
292 
293  /* fetch NOP, STM in DECODE stage */
294  arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0);
295  /* fetch NOP, STM in EXECUTE stage (1st cycle) */
296  arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0);
297 
298  for (i = 0; i <= 15; i++) {
299  if (mask & (1 << i))
300  /* nothing fetched, STM still in EXECUTE (1 + i cycle) */
301  arm7tdmi_clock_data_in(jtag_info, core_regs[i]);
302  }
303 }
304 
306  uint32_t mask, void *buffer, int size)
307 {
308  int i;
309  struct arm7_9_common *arm7_9 = target_to_arm7_9(target);
310  struct arm_jtag *jtag_info = &arm7_9->jtag_info;
311  int be = (target->endianness == TARGET_BIG_ENDIAN) ? 1 : 0;
312  uint32_t *buf_u32 = buffer;
313  uint16_t *buf_u16 = buffer;
314  uint8_t *buf_u8 = buffer;
315 
316  /* STMIA r0-15, [r0] at debug speed
317  * register values will start to appear on 4th DCLK
318  */
319  arm7tdmi_clock_out(jtag_info, ARMV4_5_STMIA(0, mask & 0xffff, 0, 0), 0);
320 
321  /* fetch NOP, STM in DECODE stage */
322  arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0);
323  /* fetch NOP, STM in EXECUTE stage (1st cycle) */
324  arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0);
325 
326  for (i = 0; i <= 15; i++) {
327  /* nothing fetched, STM still in EXECUTE (1 + i cycle), read databus */
328  if (mask & (1 << i)) {
329  switch (size) {
330  case 4:
331  arm7tdmi_clock_data_in_endianness(jtag_info, buf_u32++, 4, be);
332  break;
333  case 2:
334  arm7tdmi_clock_data_in_endianness(jtag_info, buf_u16++, 2, be);
335  break;
336  case 1:
337  arm7tdmi_clock_data_in_endianness(jtag_info, buf_u8++, 1, be);
338  break;
339  }
340  }
341  }
342 }
343 
344 static void arm7tdmi_read_xpsr(struct target *target, uint32_t *xpsr, int spsr)
345 {
346  struct arm7_9_common *arm7_9 = target_to_arm7_9(target);
347  struct arm_jtag *jtag_info = &arm7_9->jtag_info;
348 
349  /* MRS r0, cpsr */
350  arm7tdmi_clock_out(jtag_info, ARMV4_5_MRS(0, spsr & 1), 0);
351 
352  /* STR r0, [r15] */
353  arm7tdmi_clock_out(jtag_info, ARMV4_5_STR(0, 15), 0);
354  /* fetch NOP, STR in DECODE stage */
355  arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0);
356  /* fetch NOP, STR in EXECUTE stage (1st cycle) */
357  arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0);
358  /* nothing fetched, STR still in EXECUTE (2nd cycle) */
359  arm7tdmi_clock_data_in(jtag_info, xpsr);
360 }
361 
362 static void arm7tdmi_write_xpsr(struct target *target, uint32_t xpsr, int spsr)
363 {
364  struct arm7_9_common *arm7_9 = target_to_arm7_9(target);
365  struct arm_jtag *jtag_info = &arm7_9->jtag_info;
366 
367  LOG_DEBUG("xpsr: %8.8" PRIx32 ", spsr: %i", xpsr, spsr);
368 
369  /* MSR1 fetched */
370  arm7tdmi_clock_out(jtag_info, ARMV4_5_MSR_IM(xpsr & 0xff, 0, 1, spsr), 0);
371  /* MSR2 fetched, MSR1 in DECODE */
372  arm7tdmi_clock_out(jtag_info, ARMV4_5_MSR_IM((xpsr & 0xff00) >> 8, 0xc, 2, spsr), 0);
373  /* MSR3 fetched, MSR1 in EXECUTE (1), MSR2 in DECODE */
374  arm7tdmi_clock_out(jtag_info, ARMV4_5_MSR_IM((xpsr & 0xff0000) >> 16, 0x8, 4, spsr), 0);
375  /* nothing fetched, MSR1 in EXECUTE (2) */
376  arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0);
377  /* MSR4 fetched, MSR2 in EXECUTE (1), MSR3 in DECODE */
378  arm7tdmi_clock_out(jtag_info, ARMV4_5_MSR_IM((xpsr & 0xff000000) >> 24, 0x4, 8, spsr), 0);
379  /* nothing fetched, MSR2 in EXECUTE (2) */
380  arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0);
381  /* NOP fetched, MSR3 in EXECUTE (1), MSR4 in DECODE */
382  arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0);
383  /* nothing fetched, MSR3 in EXECUTE (2) */
384  arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0);
385  /* NOP fetched, MSR4 in EXECUTE (1) */
386  arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0);
387  /* nothing fetched, MSR4 in EXECUTE (2) */
388  arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0);
389 }
390 
392  uint8_t xpsr_im, int rot, int spsr)
393 {
394  struct arm7_9_common *arm7_9 = target_to_arm7_9(target);
395  struct arm_jtag *jtag_info = &arm7_9->jtag_info;
396 
397  LOG_DEBUG("xpsr_im: %2.2x, rot: %i, spsr: %i", xpsr_im, rot, spsr);
398 
399  /* MSR fetched */
400  arm7tdmi_clock_out(jtag_info, ARMV4_5_MSR_IM(xpsr_im, rot, 1, spsr), 0);
401  /* NOP fetched, MSR in DECODE */
402  arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0);
403  /* NOP fetched, MSR in EXECUTE (1) */
404  arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0);
405  /* nothing fetched, MSR in EXECUTE (2) */
406  arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0);
407 }
408 
410  uint32_t mask, uint32_t core_regs[16])
411 {
412  int i;
413  struct arm7_9_common *arm7_9 = target_to_arm7_9(target);
414  struct arm_jtag *jtag_info = &arm7_9->jtag_info;
415 
416  /* LDMIA r0-15, [r0] at debug speed
417  * register values will start to appear on 4th DCLK
418  */
419  arm7tdmi_clock_out(jtag_info, ARMV4_5_LDMIA(0, mask & 0xffff, 0, 0), 0);
420 
421  /* fetch NOP, LDM in DECODE stage */
422  arm7tdmi_clock_out_inner(jtag_info, ARMV4_5_NOP, 0);
423  /* fetch NOP, LDM in EXECUTE stage (1st cycle) */
424  arm7tdmi_clock_out_inner(jtag_info, ARMV4_5_NOP, 0);
425 
426  for (i = 0; i <= 15; i++) {
427  if (mask & (1 << i))
428  /* nothing fetched, LDM still in EXECUTE (1 + i cycle) */
429  arm7tdmi_clock_out_inner(jtag_info, core_regs[i], 0);
430  }
431  arm7tdmi_clock_out_inner(jtag_info, ARMV4_5_NOP, 0);
432 }
433 
434 static void arm7tdmi_load_word_regs(struct target *target, uint32_t mask)
435 {
436  struct arm7_9_common *arm7_9 = target_to_arm7_9(target);
437  struct arm_jtag *jtag_info = &arm7_9->jtag_info;
438 
439  /* put system-speed load-multiple into the pipeline */
440  arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0);
441  arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, 1);
442  arm7tdmi_clock_out(jtag_info, ARMV4_5_LDMIA(0, mask & 0xffff, 0, 1), 0);
443 }
444 
445 static void arm7tdmi_load_hword_reg(struct target *target, int num)
446 {
447  struct arm7_9_common *arm7_9 = target_to_arm7_9(target);
448  struct arm_jtag *jtag_info = &arm7_9->jtag_info;
449 
450  /* put system-speed load half-word into the pipeline */
451  arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0);
452  arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, 1);
453  arm7tdmi_clock_out(jtag_info, ARMV4_5_LDRH_IP(num, 0), 0);
454 }
455 
456 static void arm7tdmi_load_byte_reg(struct target *target, int num)
457 {
458  struct arm7_9_common *arm7_9 = target_to_arm7_9(target);
459  struct arm_jtag *jtag_info = &arm7_9->jtag_info;
460 
461  /* put system-speed load byte into the pipeline */
462  arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0);
463  arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, 1);
464  arm7tdmi_clock_out(jtag_info, ARMV4_5_LDRB_IP(num, 0), 0);
465 }
466 
467 static void arm7tdmi_store_word_regs(struct target *target, uint32_t mask)
468 {
469  struct arm7_9_common *arm7_9 = target_to_arm7_9(target);
470  struct arm_jtag *jtag_info = &arm7_9->jtag_info;
471 
472  /* put system-speed store-multiple into the pipeline */
473  arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0);
474  arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, 1);
475  arm7tdmi_clock_out(jtag_info, ARMV4_5_STMIA(0, mask, 0, 1), 0);
476 }
477 
478 static void arm7tdmi_store_hword_reg(struct target *target, int num)
479 {
480  struct arm7_9_common *arm7_9 = target_to_arm7_9(target);
481  struct arm_jtag *jtag_info = &arm7_9->jtag_info;
482 
483  /* put system-speed store half-word into the pipeline */
484  arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0);
485  arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, 1);
486  arm7tdmi_clock_out(jtag_info, ARMV4_5_STRH_IP(num, 0), 0);
487 }
488 
489 static void arm7tdmi_store_byte_reg(struct target *target, int num)
490 {
491  struct arm7_9_common *arm7_9 = target_to_arm7_9(target);
492  struct arm_jtag *jtag_info = &arm7_9->jtag_info;
493 
494  /* put system-speed store byte into the pipeline */
495  arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0);
496  arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, 1);
497  arm7tdmi_clock_out(jtag_info, ARMV4_5_STRB_IP(num, 0), 0);
498 }
499 
500 static void arm7tdmi_write_pc(struct target *target, uint32_t pc)
501 {
502  struct arm7_9_common *arm7_9 = target_to_arm7_9(target);
503  struct arm_jtag *jtag_info = &arm7_9->jtag_info;
504 
505  /* LDMIA r0-15, [r0] at debug speed
506  * register values will start to appear on 4th DCLK
507  */
508  arm7tdmi_clock_out(jtag_info, ARMV4_5_LDMIA(0, 0x8000, 0, 0), 0);
509  /* fetch NOP, LDM in DECODE stage */
510  arm7tdmi_clock_out_inner(jtag_info, ARMV4_5_NOP, 0);
511  /* fetch NOP, LDM in EXECUTE stage (1st cycle) */
512  arm7tdmi_clock_out_inner(jtag_info, ARMV4_5_NOP, 0);
513  /* nothing fetched, LDM in EXECUTE stage (1st cycle) load register */
514  arm7tdmi_clock_out_inner(jtag_info, pc, 0);
515  /* nothing fetched, LDM in EXECUTE stage (2nd cycle) load register */
516  arm7tdmi_clock_out_inner(jtag_info, ARMV4_5_NOP, 0);
517  /* nothing fetched, LDM in EXECUTE stage (3rd cycle) load register */
518  arm7tdmi_clock_out_inner(jtag_info, ARMV4_5_NOP, 0);
519  /* fetch NOP, LDM in EXECUTE stage (4th cycle) */
520  arm7tdmi_clock_out_inner(jtag_info, ARMV4_5_NOP, 0);
521  /* fetch NOP, LDM in EXECUTE stage (5th cycle) */
522  arm7tdmi_clock_out_inner(jtag_info, ARMV4_5_NOP, 0);
523 }
524 
526 {
527  struct arm7_9_common *arm7_9 = target_to_arm7_9(target);
528  struct arm_jtag *jtag_info = &arm7_9->jtag_info;
529 
530  arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, 1);
531  arm7tdmi_clock_out_inner(jtag_info, ARMV4_5_B(0xfffffa, 0), 0);
532 }
533 
535 {
536  struct arm7_9_common *arm7_9 = target_to_arm7_9(target);
537  struct arm *arm = &arm7_9->arm;
538  struct arm_jtag *jtag_info = &arm7_9->jtag_info;
539  struct reg *dbg_stat = &arm7_9->eice_cache->reg_list[EICE_DBG_STAT];
540 
541  LOG_DEBUG("-");
542 
543  /* LDMIA r0, [r0] at debug speed
544  * register values will start to appear on 4th DCLK
545  */
546  arm7tdmi_clock_out(jtag_info, ARMV4_5_LDMIA(0, 0x1, 0, 0), 0);
547 
548  /* fetch NOP, LDM in DECODE stage */
549  arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0);
550  /* fetch NOP, LDM in EXECUTE stage (1st cycle) */
551  arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0);
552  /* nothing fetched, LDM in EXECUTE stage (2nd cycle) */
553  arm7tdmi_clock_out(jtag_info, buf_get_u32(arm->pc->value, 0, 32) | 1, 0);
554  /* nothing fetched, LDM in EXECUTE stage (3rd cycle) */
555  arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0);
556 
557  /* Branch and eXchange */
558  arm7tdmi_clock_out(jtag_info, ARMV4_5_BX(0), 0);
559 
560  embeddedice_read_reg(dbg_stat);
561 
562  /* fetch NOP, BX in DECODE stage */
563  arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0);
564 
565  /* target is now in Thumb state */
566  embeddedice_read_reg(dbg_stat);
567 
568  /* fetch NOP, BX in EXECUTE stage (1st cycle) */
569  arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0);
570 
571  /* target is now in Thumb state */
572  embeddedice_read_reg(dbg_stat);
573 
574  /* load r0 value */
575  arm7tdmi_clock_out(jtag_info, ARMV4_5_T_LDR_PCREL(0), 0);
576  /* fetch NOP, LDR in Decode */
577  arm7tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0);
578  /* fetch NOP, LDR in Execute */
579  arm7tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0);
580  /* nothing fetched, LDR in EXECUTE stage (2nd cycle) */
581  arm7tdmi_clock_out(jtag_info, buf_get_u32(arm->core_cache->reg_list[0].value, 0, 32), 0);
582  /* nothing fetched, LDR in EXECUTE stage (3rd cycle) */
583  arm7tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0);
584 
585  arm7tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0);
586  arm7tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0);
587 
588  embeddedice_read_reg(dbg_stat);
589 
590  arm7tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 1);
591  arm7tdmi_clock_out(jtag_info, ARMV4_5_T_B(0x7f8), 0);
592 }
593 
595 {
596  struct reg_cache **cache_p = register_get_last_cache_p(&target->reg_cache);
597  struct arm *arm = target_to_arm(target);
598 
599  (*cache_p) = arm_build_reg_cache(target, arm);
600 }
601 
603 {
604  struct arm *arm = target_to_arm(target);
605 
607 }
608 
609 int arm7tdmi_init_target(struct command_context *cmd_ctx, struct target *target)
610 {
613  return ERROR_OK;
614 }
615 
617 {
619 }
620 
622  struct arm7_9_common *arm7_9, struct jtag_tap *tap)
623 {
624  /* prepare JTAG information for the new target */
625  arm7_9->jtag_info.tap = tap;
626  arm7_9->jtag_info.scann_size = 4;
627 
628  /* register arch-specific functions */
633  arm7_9->read_xpsr = arm7tdmi_read_xpsr;
634 
638 
642 
646 
647  arm7_9->write_pc = arm7tdmi_write_pc;
650 
653 
656 
657  arm7_9->post_debug_entry = NULL;
658 
659  arm7_9->pre_restore_context = NULL;
660 
661  /* initialize arch-specific breakpoint handling */
662  arm7_9->arm_bkpt = 0xdeeedeee;
663  arm7_9->thumb_bkpt = 0xdeee;
664 
665  arm7_9->dbgreq_adjust_pc = 2;
666 
667  arm7_9_init_arch_info(target, arm7_9);
668 
669  return ERROR_OK;
670 }
671 
672 static int arm7tdmi_target_create(struct target *target, Jim_Interp *interp)
673 {
674  struct arm7_9_common *arm7_9;
675 
676  arm7_9 = calloc(1, sizeof(struct arm7_9_common));
678  arm7_9->arm.arch = ARM_ARCH_V4;
679 
680  return ERROR_OK;
681 }
682 
684 struct target_type arm7tdmi_target = {
685  .name = "arm7tdmi",
686 
687  .poll = arm7_9_poll,
688  .arch_state = arm_arch_state,
689 
690  .target_request_data = arm7_9_target_request_data,
691 
692  .halt = arm7_9_halt,
693  .resume = arm7_9_resume,
694  .step = arm7_9_step,
695 
696  .assert_reset = arm7_9_assert_reset,
697  .deassert_reset = arm7_9_deassert_reset,
698  .soft_reset_halt = arm7_9_soft_reset_halt,
699 
700  .get_gdb_arch = arm_get_gdb_arch,
701  .get_gdb_reg_list = arm_get_gdb_reg_list,
702 
703  .read_memory = arm7_9_read_memory,
704  .write_memory = arm7_9_write_memory_opt,
705 
706  .checksum_memory = arm_checksum_memory,
707  .blank_check_memory = arm_blank_check_memory,
708 
709  .run_algorithm = armv4_5_run_algorithm,
710 
711  .add_breakpoint = arm7_9_add_breakpoint,
712  .remove_breakpoint = arm7_9_remove_breakpoint,
713  .add_watchpoint = arm7_9_add_watchpoint,
714  .remove_watchpoint = arm7_9_remove_watchpoint,
715 
716  .commands = arm7_9_command_handlers,
717  .target_create = arm7tdmi_target_create,
718  .init_target = arm7tdmi_init_target,
719  .deinit_target = arm7tdmi_deinit_target,
720  .examine = arm7_9_examine,
721  .check_reset = arm7_9_check_reset,
722 };
int arm7_9_endianness_callback(jtag_callback_data_t pu8_in, jtag_callback_data_t i_size, jtag_callback_data_t i_be, jtag_callback_data_t i_flip)
int arm7_9_write_memory_opt(struct target *target, target_addr_t address, uint32_t size, uint32_t count, const uint8_t *buffer)
int arm7_9_examine(struct target *target)
Perform per-target setup that requires JTAG access.
void arm7_9_disable_eice_step(struct target *target)
int arm7_9_read_memory(struct target *target, target_addr_t address, uint32_t size, uint32_t count, uint8_t *buffer)
int arm7_9_add_breakpoint(struct target *target, struct breakpoint *breakpoint)
Add a breakpoint to an ARM7/9 target.
int arm7_9_soft_reset_halt(struct target *target)
Issue a software reset and halt to an ARM7/9 target.
const struct command_registration arm7_9_command_handlers[]
int arm7_9_assert_reset(struct target *target)
Asserts the reset (SRST) on an ARM7/9 target.
int arm7_9_poll(struct target *target)
Polls an ARM7/9 target for its current status.
int arm7_9_halt(struct target *target)
Halt an ARM7/9 target.
int arm7_9_remove_breakpoint(struct target *target, struct breakpoint *breakpoint)
Removes a breakpoint from an ARM7/9 target.
int arm7_9_remove_watchpoint(struct target *target, struct watchpoint *watchpoint)
Remove a watchpoint from an ARM7/9 target.
int arm7_9_deassert_reset(struct target *target)
Deassert the reset (SRST) signal on an ARM7/9 target.
int arm7_9_write_memory(struct target *target, target_addr_t address, uint32_t size, uint32_t count, const uint8_t *buffer)
void arm7_9_enable_eice_step(struct target *target, uint32_t next_pc)
int arm7_9_bulk_write_memory(struct target *target, target_addr_t address, uint32_t count, const uint8_t *buffer)
int arm7_9_step(struct target *target, int current, target_addr_t address, int handle_breakpoints)
int arm7_9_target_request_data(struct target *target, uint32_t size, uint8_t *buffer)
Get some data from the ARM7/9 target.
int arm7_9_add_watchpoint(struct target *target, struct watchpoint *watchpoint)
Add a watchpoint to an ARM7/9 target.
int arm7_9_check_reset(struct target *target)
int arm7_9_init_arch_info(struct target *target, struct arm7_9_common *arm7_9)
int arm7_9_resume(struct target *target, int current, target_addr_t address, int handle_breakpoints, int debug_execution)
static struct arm7_9_common * target_to_arm7_9(struct target *target)
static void arm7tdmi_store_byte_reg(struct target *target, int num)
Definition: arm7tdmi.c:489
static int arm7tdmi_clock_out_inner(struct arm_jtag *jtag_info, uint32_t out, int breakpoint)
Definition: arm7tdmi.c:84
static int arm7tdmi_target_create(struct target *target, Jim_Interp *interp)
Definition: arm7tdmi.c:672
static int arm7tdmi_examine_debug_reason(struct target *target)
Definition: arm7tdmi.c:34
static void arm7tdmi_read_core_regs(struct target *target, uint32_t mask, uint32_t *core_regs[16])
Definition: arm7tdmi.c:281
static void arm7tdmi_store_hword_reg(struct target *target, int num)
Definition: arm7tdmi.c:478
static int arm7tdmi_clock_out(struct arm_jtag *jtag_info, uint32_t out, int breakpoint)
Definition: arm7tdmi.c:108
int arm7tdmi_init_arch_info(struct target *target, struct arm7_9_common *arm7_9, struct jtag_tap *tap)
Definition: arm7tdmi.c:621
static void arm7tdmi_branch_resume(struct target *target)
Definition: arm7tdmi.c:525
static void arm7tdmi_write_xpsr(struct target *target, uint32_t xpsr, int spsr)
Definition: arm7tdmi.c:362
static void arm7tdmi_read_xpsr(struct target *target, uint32_t *xpsr, int spsr)
Definition: arm7tdmi.c:344
static void arm7tdmi_build_reg_cache(struct target *target)
Definition: arm7tdmi.c:594
static void arm7tdmi_load_word_regs(struct target *target, uint32_t mask)
Definition: arm7tdmi.c:434
static void arm7tdmi_load_hword_reg(struct target *target, int num)
Definition: arm7tdmi.c:445
static void arm7tdmi_write_pc(struct target *target, uint32_t pc)
Definition: arm7tdmi.c:500
static int arm7tdmi_clock_data_in(struct arm_jtag *jtag_info, uint32_t *in)
Definition: arm7tdmi.c:123
static void arm7tdmi_branch_resume_thumb(struct target *target)
Definition: arm7tdmi.c:534
static void arm7tdmi_free_reg_cache(struct target *target)
Definition: arm7tdmi.c:602
static void arm7tdmi_store_word_regs(struct target *target, uint32_t mask)
Definition: arm7tdmi.c:467
static void arm7tdmi_load_byte_reg(struct target *target, int num)
Definition: arm7tdmi.c:456
struct target_type arm7tdmi_target
Holds methods for ARM7TDMI targets.
Definition: arm7tdmi.c:684
static void arm7tdmi_write_xpsr_im8(struct target *target, uint8_t xpsr_im, int rot, int spsr)
Definition: arm7tdmi.c:391
void arm7tdmi_deinit_target(struct target *target)
Definition: arm7tdmi.c:616
static void arm7tdmi_read_core_regs_target_buffer(struct target *target, uint32_t mask, void *buffer, int size)
Definition: arm7tdmi.c:305
static void arm7tdmi_write_core_regs(struct target *target, uint32_t mask, uint32_t core_regs[16])
Definition: arm7tdmi.c:409
static int arm7tdmi_clock_data_in_endianness(struct arm_jtag *jtag_info, void *in, int size, int be)
Definition: arm7tdmi.c:167
static const int arm7tdmi_num_bits[]
Definition: arm7tdmi.c:82
static void arm7tdmi_change_to_arm(struct target *target, uint32_t *r0, uint32_t *pc)
Definition: arm7tdmi.c:226
int arm7tdmi_init_target(struct command_context *cmd_ctx, struct target *target)
Definition: arm7tdmi.c:609
int arm_blank_check_memory(struct target *target, struct target_memory_check_block *blocks, int num_blocks, uint8_t erased_value)
Runs ARM code in the target to check whether a memory block holds all ones.
Definition: armv4_5.c:1673
int arm_arch_state(struct target *target)
Definition: armv4_5.c:782
int arm_checksum_memory(struct target *target, target_addr_t address, uint32_t count, uint32_t *checksum)
Runs ARM code in the target to calculate a CRC32 checksum.
Definition: armv4_5.c:1600
@ ARM_ARCH_V4
Definition: arm.h:55
struct reg_cache * arm_build_reg_cache(struct target *target, struct arm *arm)
Definition: armv4_5.c:646
const char * arm_get_gdb_arch(const struct target *target)
Definition: armv4_5.c:1267
int arm_get_gdb_reg_list(struct target *target, struct reg **reg_list[], int *reg_list_size, enum target_register_class reg_class)
Definition: armv4_5.c:1272
void arm_free_reg_cache(struct arm *arm)
Definition: armv4_5.c:761
static struct arm * target_to_arm(const struct target *target)
Convert target handle to generic ARM target state handle.
Definition: arm.h:261
int armv4_5_run_algorithm(struct target *target, int num_mem_params, struct mem_param *mem_params, int num_reg_params, struct reg_param *reg_params, target_addr_t entry_point, target_addr_t exit_point, unsigned int timeout_ms, void *arch_info)
Definition: armv4_5.c:1574
static int arm_jtag_scann(struct arm_jtag *jtag_info, uint32_t new_scan_chain, tap_state_t end_state)
Definition: arm_jtag.h:43
static int arm_jtag_set_instr(struct jtag_tap *tap, uint32_t new_instr, void *no_verify_capture, tap_state_t end_state)
Definition: arm_jtag.h:31
static void arm7flip32(jtag_callback_data_t arg)
Definition: arm_jtag.h:57
Macros used to generate various ARM or Thumb opcodes.
#define ARMV4_5_T_BX(rm)
Definition: arm_opcodes.h:299
#define ARMV4_5_BX(rm)
Definition: arm_opcodes.h:122
#define ARMV4_5_T_NOP
Definition: arm_opcodes.h:286
#define ARMV4_5_LDMIA(rn, list, s, w)
Definition: arm_opcodes.h:42
#define ARMV4_5_T_B(imm)
Definition: arm_opcodes.h:306
#define ARMV4_5_MRS(rn, r)
Definition: arm_opcodes.h:52
#define ARMV4_5_STRH_IP(rd, rn)
Definition: arm_opcodes.h:105
#define ARMV4_5_T_MOV(rd, rm)
Definition: arm_opcodes.h:276
#define ARMV4_5_LDRH_IP(rd, rn)
Definition: arm_opcodes.h:87
#define ARMV4_5_LDRB_IP(rd, rn)
Definition: arm_opcodes.h:93
#define ARMV4_5_T_LDR_PCREL(rd)
Definition: arm_opcodes.h:268
#define ARMV4_5_B(im, l)
Definition: arm_opcodes.h:117
#define ARMV4_5_STR(rd, rn)
Definition: arm_opcodes.h:58
#define ARMV4_5_NOP
Definition: arm_opcodes.h:46
#define ARMV4_5_STMIA(rn, list, s, w)
Definition: arm_opcodes.h:33
#define ARMV4_5_MSR_IM(im, rotate, field, r)
Definition: arm_opcodes.h:74
#define ARMV4_5_STRB_IP(rd, rn)
Definition: arm_opcodes.h:111
#define ARMV4_5_T_STR(rd, rn)
Definition: arm_opcodes.h:245
int arm_semihosting_init(struct target *target)
Initialize ARM semihosting support.
uint32_t flip_u32(uint32_t value, unsigned int num)
Inverts the ordering of bits inside a 32-bit word (e.g.
Definition: binarybuffer.c:165
static uint32_t buf_get_u32(const uint8_t *_buffer, unsigned int first, unsigned int num)
Retrieves num bits from _buffer, starting at the first bit, returning the bits in a 32-bit word.
Definition: binarybuffer.h:104
static void buf_set_u32(uint8_t *_buffer, unsigned int first, unsigned int num, uint32_t value)
Sets num bits in _buffer, starting at the first bit, using the bits in value.
Definition: binarybuffer.h:34
int embeddedice_read_reg(struct reg *reg)
Queue a read for an EmbeddedICE register into the register cache, not checking the value read.
Definition: embeddedice.c:464
@ EICE_DBG_STAT
Definition: embeddedice.h:21
int mask
Definition: esirisc.c:1741
void jtag_add_runtest(unsigned int num_cycles, tap_state_t state)
Goes to TAP_IDLE (if we're not already there), cycle precisely num_cycles in the TAP_IDLE state,...
Definition: jtag/core.c:592
int jtag_execute_queue(void)
For software FIFO implementations, the queued commands can be executed during this call or earlier.
Definition: jtag/core.c:1037
void jtag_add_dr_scan(struct jtag_tap *active, int in_num_fields, const struct scan_field *in_fields, tap_state_t state)
Generate a DR SCAN using the fields passed to the function.
Definition: jtag/core.c:451
void jtag_add_callback4(jtag_callback_t f, jtag_callback_data_t data0, jtag_callback_data_t data1, jtag_callback_data_t data2, jtag_callback_data_t data3)
void jtag_add_callback(jtag_callback1_t f, jtag_callback_data_t data0)
A simpler version of jtag_add_callback4().
@ TAP_DRPAUSE
Definition: jtag.h:44
intptr_t jtag_callback_data_t
Defines the type of data passed to the jtag_callback_t interface.
Definition: jtag.h:337
#define LOG_ERROR(expr ...)
Definition: log.h:132
#define LOG_DEBUG(expr ...)
Definition: log.h:109
#define ERROR_OK
Definition: log.h:164
struct reg_cache ** register_get_last_cache_p(struct reg_cache **first)
Definition: register.c:72
size_t size
Size of the control block search area.
Definition: rtt/rtt.c:30
Structure for items that are common between both ARM7 and ARM9 targets.
Definition: arm7_9_common.h:28
void(* enable_single_step)(struct target *target, uint32_t next_pc)
Definition: arm7_9_common.h:98
struct arm arm
Definition: arm7_9_common.h:31
void(* read_xpsr)(struct target *target, uint32_t *xpsr, int spsr)
Function for reading CPSR or SPSR.
Definition: arm7_9_common.h:73
void(* store_hword_reg)(struct target *target, int num)
Definition: arm7_9_common.h:89
void(* write_xpsr_im8)(struct target *target, uint8_t xpsr_im, int rot, int spsr)
Function for writing an immediate value to CPSR or SPSR.
Definition: arm7_9_common.h:79
void(* write_core_regs)(struct target *target, uint32_t mask, uint32_t core_regs[16])
Definition: arm7_9_common.h:82
uint32_t arm_bkpt
ARM breakpoint instruction.
Definition: arm7_9_common.h:36
int(* bulk_write_memory)(struct target *target, target_addr_t address, uint32_t count, const uint8_t *buffer)
Write target memory in multiples of 4 bytes, optimized for writing large quantities of data.
void(* branch_resume)(struct target *target)
Definition: arm7_9_common.h:95
int(* write_memory)(struct target *target, target_addr_t address, uint32_t size, uint32_t count, const uint8_t *buffer)
Variant specific memory write function that does not dispatch to bulk_write_memory.
struct arm_jtag jtag_info
JTAG information for target.
Definition: arm7_9_common.h:33
void(* read_core_regs_target_buffer)(struct target *target, uint32_t mask, void *buffer, int size)
Definition: arm7_9_common.h:71
void(* store_byte_reg)(struct target *target, int num)
Definition: arm7_9_common.h:90
struct reg_cache * eice_cache
Embedded ICE register cache.
Definition: arm7_9_common.h:34
int(* post_debug_entry)(struct target *target)
Callback function called after entering debug mode.
void(* load_word_regs)(struct target *target, uint32_t mask)
Definition: arm7_9_common.h:84
void(* load_byte_reg)(struct target *target, int num)
Definition: arm7_9_common.h:86
void(* read_core_regs)(struct target *target, uint32_t mask, uint32_t *core_regs[16])
Function for reading the core registers.
Definition: arm7_9_common.h:68
void(* load_hword_reg)(struct target *target, int num)
Definition: arm7_9_common.h:85
void(* disable_single_step)(struct target *target)
Definition: arm7_9_common.h:99
void(* write_pc)(struct target *target, uint32_t pc)
Function for writing to the program counter.
Definition: arm7_9_common.h:92
uint16_t thumb_bkpt
Thumb breakpoint instruction.
Definition: arm7_9_common.h:37
void(* store_word_regs)(struct target *target, uint32_t mask)
Definition: arm7_9_common.h:88
void(* pre_restore_context)(struct target *target)
Callback function called before restoring the processor context.
int dbgreq_adjust_pc
Amount of PC adjustment caused by a DBGREQ.
Definition: arm7_9_common.h:47
int(* examine_debug_reason)(struct target *target)
Function for determining why debug state was entered.
Definition: arm7_9_common.h:62
void(* branch_resume_thumb)(struct target *target)
Definition: arm7_9_common.h:96
void(* change_to_arm)(struct target *target, uint32_t *r0, uint32_t *pc)
Function for changing from Thumb to ARM mode.
Definition: arm7_9_common.h:65
void(* write_xpsr)(struct target *target, uint32_t xpsr, int spsr)
Function for writing to CPSR or SPSR.
Definition: arm7_9_common.h:76
uint32_t scann_size
Definition: arm_jtag.h:20
uint32_t intest_instr
Definition: arm_jtag.h:24
struct jtag_tap * tap
Definition: arm_jtag.h:18
Represents a generic ARM core, with standard application registers.
Definition: arm.h:175
enum arm_arch arch
ARM architecture version.
Definition: arm.h:202
struct reg * pc
Handle to the PC; valid in all core modes.
Definition: arm.h:181
struct reg_cache * core_cache
Definition: arm.h:178
Definition: jtag.h:101
struct reg * reg_list
Definition: register.h:147
Definition: register.h:111
uint8_t * value
Definition: register.h:122
This structure defines a single scan field in the scan.
Definition: jtag.h:87
uint8_t * in_value
A pointer to a 32-bit memory location for data scanned out.
Definition: jtag.h:93
const uint8_t * out_value
A pointer to value to be scanned into the device.
Definition: jtag.h:91
unsigned int num_bits
The number of bits this field specifies.
Definition: jtag.h:89
This holds methods shared between all instances of a given target type.
Definition: target_type.h:26
const char * name
Name of this type of target.
Definition: target_type.h:31
Definition: target.h:116
struct jtag_tap * tap
Definition: target.h:119
enum target_debug_reason debug_reason
Definition: target.h:154
enum target_endianness endianness
Definition: target.h:155
struct reg_cache * reg_cache
Definition: target.h:158
@ DBG_REASON_DBGRQ
Definition: target.h:69
@ DBG_REASON_SINGLESTEP
Definition: target.h:73
@ DBG_REASON_WATCHPOINT
Definition: target.h:71
@ DBG_REASON_BREAKPOINT
Definition: target.h:70
@ TARGET_BIG_ENDIAN
Definition: target.h:82
#define NULL
Definition: usb.h:16