25151ff4b9a94d0f8cd72a7bf785c29a484e716c
[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 #include "target_type.h"
32 #include "register.h"
33 #include "arm_opcodes.h"
34
35
36 /*
37 * For information about ARM7TDMI, see ARM DDI 0210C (r4p1)
38 * or ARM DDI 0029G (r3). "Debug In Depth", Appendix B,
39 * covers JTAG support.
40 */
41
42 #if 0
43 #define _DEBUG_INSTRUCTION_EXECUTION_
44 #endif
45
46 static int arm7tdmi_examine_debug_reason(struct target *target)
47 {
48 int retval = ERROR_OK;
49 struct arm7_9_common *arm7_9 = target_to_arm7_9(target);
50
51 /* only check the debug reason if we don't know it already */
52 if ((target->debug_reason != DBG_REASON_DBGRQ)
53 && (target->debug_reason != DBG_REASON_SINGLESTEP))
54 {
55 struct scan_field fields[2];
56 uint8_t databus[4];
57 uint8_t breakpoint;
58
59 jtag_set_end_state(TAP_DRPAUSE);
60
61 fields[0].num_bits = 1;
62 fields[0].out_value = NULL;
63 fields[0].in_value = &breakpoint;
64
65 fields[1].num_bits = 32;
66 fields[1].out_value = NULL;
67 fields[1].in_value = databus;
68
69 if ((retval = arm_jtag_scann(&arm7_9->jtag_info, 0x1, TAP_DRPAUSE)) != ERROR_OK)
70 {
71 return retval;
72 }
73 arm_jtag_set_instr(&arm7_9->jtag_info, arm7_9->jtag_info.intest_instr, NULL, TAP_DRPAUSE);
74
75 jtag_add_dr_scan(arm7_9->jtag_info.tap, 2, fields, TAP_DRPAUSE);
76 if ((retval = jtag_execute_queue()) != ERROR_OK)
77 {
78 return retval;
79 }
80
81 fields[0].in_value = NULL;
82 fields[0].out_value = &breakpoint;
83 fields[1].in_value = NULL;
84 fields[1].out_value = databus;
85
86 jtag_add_dr_scan(arm7_9->jtag_info.tap, 2, fields, TAP_DRPAUSE);
87
88 if (breakpoint & 1)
89 target->debug_reason = DBG_REASON_WATCHPOINT;
90 else
91 target->debug_reason = DBG_REASON_BREAKPOINT;
92 }
93
94 return ERROR_OK;
95 }
96
97 static const int arm7tdmi_num_bits[] = {1, 32};
98
99 static __inline int arm7tdmi_clock_out_inner(struct arm_jtag *jtag_info, uint32_t out, int breakpoint)
100 {
101 uint32_t values[2]={breakpoint, flip_u32(out, 32)};
102
103 jtag_add_dr_out(jtag_info->tap,
104 2,
105 arm7tdmi_num_bits,
106 values,
107 jtag_get_end_state());
108
109 jtag_add_runtest(0, jtag_get_end_state());
110
111 return ERROR_OK;
112 }
113
114 /* put an instruction in the ARM7TDMI pipeline or write the data bus,
115 * and optionally read data
116 *
117 * FIXME remove the unused "deprecated" parameter
118 */
119 static __inline int arm7tdmi_clock_out(struct arm_jtag *jtag_info,
120 uint32_t out, uint32_t *deprecated, int breakpoint)
121 {
122 jtag_set_end_state(TAP_DRPAUSE);
123 arm_jtag_scann(jtag_info, 0x1, TAP_DRPAUSE);
124 arm_jtag_set_instr(jtag_info, jtag_info->intest_instr, NULL, TAP_DRPAUSE);
125
126 return arm7tdmi_clock_out_inner(jtag_info, out, breakpoint);
127 }
128
129 /* clock the target, reading the databus */
130 static int arm7tdmi_clock_data_in(struct arm_jtag *jtag_info, uint32_t *in)
131 {
132 int retval = ERROR_OK;
133 struct scan_field fields[2];
134
135 jtag_set_end_state(TAP_DRPAUSE);
136 if ((retval = arm_jtag_scann(jtag_info, 0x1, TAP_DRPAUSE)) != ERROR_OK)
137 {
138 return retval;
139 }
140 arm_jtag_set_instr(jtag_info, jtag_info->intest_instr, NULL, TAP_DRPAUSE);
141
142 fields[0].num_bits = 1;
143 fields[0].out_value = NULL;
144 fields[0].in_value = NULL;
145
146 fields[1].num_bits = 32;
147 fields[1].out_value = NULL;
148 fields[1].in_value = (uint8_t *)in;
149
150 jtag_add_dr_scan(jtag_info->tap, 2, fields, TAP_DRPAUSE);
151
152 jtag_add_callback(arm7flip32, (jtag_callback_data_t)in);
153
154 jtag_add_runtest(0, TAP_DRPAUSE);
155
156 #ifdef _DEBUG_INSTRUCTION_EXECUTION_
157 if ((retval = jtag_execute_queue()) != ERROR_OK)
158 return retval;
159
160 if (in)
161 LOG_DEBUG("in: 0x%8.8x", *in);
162 else
163 LOG_ERROR("BUG: called with in == NULL");
164 #endif
165
166 return ERROR_OK;
167 }
168
169 void arm_endianness(uint8_t *tmp, void *in, int size, int be, int flip)
170 {
171 uint32_t readback = le_to_h_u32(tmp);
172 if (flip)
173 readback = flip_u32(readback, 32);
174 switch (size)
175 {
176 case 4:
177 if (be)
178 {
179 h_u32_to_be(((uint8_t*)in), readback);
180 } else
181 {
182 h_u32_to_le(((uint8_t*)in), readback);
183 }
184 break;
185 case 2:
186 if (be)
187 {
188 h_u16_to_be(((uint8_t*)in), readback & 0xffff);
189 } else
190 {
191 h_u16_to_le(((uint8_t*)in), readback & 0xffff);
192 }
193 break;
194 case 1:
195 *((uint8_t *)in)= readback & 0xff;
196 break;
197 }
198 }
199
200 static int arm7endianness(jtag_callback_data_t arg,
201 jtag_callback_data_t size, jtag_callback_data_t be,
202 jtag_callback_data_t captured)
203 {
204 uint8_t *in = (uint8_t *)arg;
205
206 arm_endianness((uint8_t *)captured, in, (int)size, (int)be, 1);
207 return ERROR_OK;
208 }
209
210 /* clock the target, and read the databus
211 * the *in pointer points to a buffer where elements of 'size' bytes
212 * are stored in big (be == 1) or little (be == 0) endianness
213 */
214 static int arm7tdmi_clock_data_in_endianness(struct arm_jtag *jtag_info,
215 void *in, int size, int be)
216 {
217 int retval = ERROR_OK;
218 struct scan_field fields[2];
219
220 jtag_set_end_state(TAP_DRPAUSE);
221 if ((retval = arm_jtag_scann(jtag_info, 0x1, TAP_DRPAUSE)) != ERROR_OK)
222 {
223 return retval;
224 }
225 arm_jtag_set_instr(jtag_info, jtag_info->intest_instr, NULL, TAP_DRPAUSE);
226
227 fields[0].num_bits = 1;
228 fields[0].out_value = NULL;
229 fields[0].in_value = NULL;
230
231 fields[1].num_bits = 32;
232 fields[1].out_value = NULL;
233 jtag_alloc_in_value32(&fields[1]);
234
235 jtag_add_dr_scan(jtag_info->tap, 2, fields, TAP_DRPAUSE);
236
237 jtag_add_callback4(arm7endianness, (jtag_callback_data_t)in, (jtag_callback_data_t)size, (jtag_callback_data_t)be, (jtag_callback_data_t)fields[1].in_value);
238
239 jtag_add_runtest(0, TAP_DRPAUSE);
240
241 #ifdef _DEBUG_INSTRUCTION_EXECUTION_
242 {
243 if ((retval = jtag_execute_queue()) != ERROR_OK)
244 {
245 return retval;
246 }
247
248 if (in)
249 {
250 LOG_DEBUG("in: 0x%8.8x", *(uint32_t*)in);
251 }
252 else
253 {
254 LOG_ERROR("BUG: called with in == NULL");
255 }
256 }
257 #endif
258
259 return ERROR_OK;
260 }
261
262 static void arm7tdmi_change_to_arm(struct target *target,
263 uint32_t *r0, uint32_t *pc)
264 {
265 struct arm7_9_common *arm7_9 = target_to_arm7_9(target);
266 struct arm_jtag *jtag_info = &arm7_9->jtag_info;
267
268 /* save r0 before using it and put system in ARM state
269 * to allow common handling of ARM and THUMB debugging */
270
271 /* fetch STR r0, [r0] */
272 arm7tdmi_clock_out(jtag_info, ARMV4_5_T_STR(0, 0), NULL, 0);
273 arm7tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, NULL, 0);
274 arm7tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, NULL, 0);
275 /* nothing fetched, STR r0, [r0] in Execute (2) */
276 arm7tdmi_clock_data_in(jtag_info, r0);
277
278 /* MOV r0, r15 fetched, STR in Decode */
279 arm7tdmi_clock_out(jtag_info, ARMV4_5_T_MOV(0, 15), NULL, 0);
280 arm7tdmi_clock_out(jtag_info, ARMV4_5_T_STR(0, 0), NULL, 0);
281 arm7tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, NULL, 0);
282 arm7tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, NULL, 0);
283 /* nothing fetched, STR r0, [r0] in Execute (2) */
284 arm7tdmi_clock_data_in(jtag_info, pc);
285
286 /* use pc-relative LDR to clear r0[1:0] (for switch to ARM mode) */
287 arm7tdmi_clock_out(jtag_info, ARMV4_5_T_LDR_PCREL(0), NULL, 0);
288 arm7tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, NULL, 0);
289 arm7tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, NULL, 0);
290 /* nothing fetched, data for LDR r0, [PC, #0] */
291 arm7tdmi_clock_out(jtag_info, 0x0, NULL, 0);
292 /* nothing fetched, data from previous cycle is written to register */
293 arm7tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, NULL, 0);
294
295 /* fetch BX */
296 arm7tdmi_clock_out(jtag_info, ARMV4_5_T_BX(0), NULL, 0);
297 /* NOP fetched, BX in Decode, MOV in Execute */
298 arm7tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, NULL, 0);
299 /* NOP fetched, BX in Execute (1) */
300 arm7tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, NULL, 0);
301
302 jtag_execute_queue();
303
304 /* fix program counter:
305 * MOV r0, r15 was the 4th instruction (+6)
306 * reading PC in Thumb state gives address of instruction + 4
307 */
308 *pc -= 0xa;
309 }
310
311
312 /* FIX!!! is this a potential performance bottleneck w.r.t. requiring too many
313 * roundtrips when jtag_execute_queue() has a large overhead(e.g. for USB)s?
314 *
315 * The solution is to arrange for a large out/in scan in this loop and
316 * and convert data afterwards.
317 */
318 static void arm7tdmi_read_core_regs(struct target *target,
319 uint32_t mask, uint32_t* core_regs[16])
320 {
321 int i;
322 struct arm7_9_common *arm7_9 = target_to_arm7_9(target);
323 struct arm_jtag *jtag_info = &arm7_9->jtag_info;
324
325 /* STMIA r0-15, [r0] at debug speed
326 * register values will start to appear on 4th DCLK
327 */
328 arm7tdmi_clock_out(jtag_info, ARMV4_5_STMIA(0, mask & 0xffff, 0, 0), NULL, 0);
329
330 /* fetch NOP, STM in DECODE stage */
331 arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
332 /* fetch NOP, STM in EXECUTE stage (1st cycle) */
333 arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
334
335 for (i = 0; i <= 15; i++)
336 {
337 if (mask & (1 << i))
338 /* nothing fetched, STM still in EXECUTE (1 + i cycle) */
339 arm7tdmi_clock_data_in(jtag_info, core_regs[i]);
340 }
341 }
342
343 static void arm7tdmi_read_core_regs_target_buffer(struct target *target,
344 uint32_t mask, void* buffer, int size)
345 {
346 int i;
347 struct arm7_9_common *arm7_9 = target_to_arm7_9(target);
348 struct arm_jtag *jtag_info = &arm7_9->jtag_info;
349 int be = (target->endianness == TARGET_BIG_ENDIAN) ? 1 : 0;
350 uint32_t *buf_u32 = buffer;
351 uint16_t *buf_u16 = buffer;
352 uint8_t *buf_u8 = buffer;
353
354 /* STMIA r0-15, [r0] at debug speed
355 * register values will start to appear on 4th DCLK
356 */
357 arm7tdmi_clock_out(jtag_info, ARMV4_5_STMIA(0, mask & 0xffff, 0, 0), NULL, 0);
358
359 /* fetch NOP, STM in DECODE stage */
360 arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
361 /* fetch NOP, STM in EXECUTE stage (1st cycle) */
362 arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
363
364 for (i = 0; i <= 15; i++)
365 {
366 /* nothing fetched, STM still in EXECUTE (1 + i cycle), read databus */
367 if (mask & (1 << i))
368 {
369 switch (size)
370 {
371 case 4:
372 arm7tdmi_clock_data_in_endianness(jtag_info, buf_u32++, 4, be);
373 break;
374 case 2:
375 arm7tdmi_clock_data_in_endianness(jtag_info, buf_u16++, 2, be);
376 break;
377 case 1:
378 arm7tdmi_clock_data_in_endianness(jtag_info, buf_u8++, 1, be);
379 break;
380 }
381 }
382 }
383 }
384
385 static void arm7tdmi_read_xpsr(struct target *target, uint32_t *xpsr, int spsr)
386 {
387 struct arm7_9_common *arm7_9 = target_to_arm7_9(target);
388 struct arm_jtag *jtag_info = &arm7_9->jtag_info;
389
390 /* MRS r0, cpsr */
391 arm7tdmi_clock_out(jtag_info, ARMV4_5_MRS(0, spsr & 1), NULL, 0);
392
393 /* STR r0, [r15] */
394 arm7tdmi_clock_out(jtag_info, ARMV4_5_STR(0, 15), NULL, 0);
395 /* fetch NOP, STR in DECODE stage */
396 arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
397 /* fetch NOP, STR in EXECUTE stage (1st cycle) */
398 arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
399 /* nothing fetched, STR still in EXECUTE (2nd cycle) */
400 arm7tdmi_clock_data_in(jtag_info, xpsr);
401 }
402
403 static void arm7tdmi_write_xpsr(struct target *target, uint32_t xpsr, int spsr)
404 {
405 struct arm7_9_common *arm7_9 = target_to_arm7_9(target);
406 struct arm_jtag *jtag_info = &arm7_9->jtag_info;
407
408 LOG_DEBUG("xpsr: %8.8" PRIx32 ", spsr: %i", xpsr, spsr);
409
410 /* MSR1 fetched */
411 arm7tdmi_clock_out(jtag_info, ARMV4_5_MSR_IM(xpsr & 0xff, 0, 1, spsr), NULL, 0);
412 /* MSR2 fetched, MSR1 in DECODE */
413 arm7tdmi_clock_out(jtag_info, ARMV4_5_MSR_IM((xpsr & 0xff00) >> 8, 0xc, 2, spsr), NULL, 0);
414 /* MSR3 fetched, MSR1 in EXECUTE (1), MSR2 in DECODE */
415 arm7tdmi_clock_out(jtag_info, ARMV4_5_MSR_IM((xpsr & 0xff0000) >> 16, 0x8, 4, spsr), NULL, 0);
416 /* nothing fetched, MSR1 in EXECUTE (2) */
417 arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
418 /* MSR4 fetched, MSR2 in EXECUTE (1), MSR3 in DECODE */
419 arm7tdmi_clock_out(jtag_info, ARMV4_5_MSR_IM((xpsr & 0xff000000) >> 24, 0x4, 8, spsr), NULL, 0);
420 /* nothing fetched, MSR2 in EXECUTE (2) */
421 arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
422 /* NOP fetched, MSR3 in EXECUTE (1), MSR4 in DECODE */
423 arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
424 /* nothing fetched, MSR3 in EXECUTE (2) */
425 arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
426 /* NOP fetched, MSR4 in EXECUTE (1) */
427 arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
428 /* nothing fetched, MSR4 in EXECUTE (2) */
429 arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
430 }
431
432 static void arm7tdmi_write_xpsr_im8(struct target *target,
433 uint8_t xpsr_im, int rot, int spsr)
434 {
435 struct arm7_9_common *arm7_9 = target_to_arm7_9(target);
436 struct arm_jtag *jtag_info = &arm7_9->jtag_info;
437
438 LOG_DEBUG("xpsr_im: %2.2x, rot: %i, spsr: %i", xpsr_im, rot, spsr);
439
440 /* MSR fetched */
441 arm7tdmi_clock_out(jtag_info, ARMV4_5_MSR_IM(xpsr_im, rot, 1, spsr), NULL, 0);
442 /* NOP fetched, MSR in DECODE */
443 arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
444 /* NOP fetched, MSR in EXECUTE (1) */
445 arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
446 /* nothing fetched, MSR in EXECUTE (2) */
447 arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
448 }
449
450 static void arm7tdmi_write_core_regs(struct target *target,
451 uint32_t mask, uint32_t core_regs[16])
452 {
453 int i;
454 struct arm7_9_common *arm7_9 = target_to_arm7_9(target);
455 struct arm_jtag *jtag_info = &arm7_9->jtag_info;
456
457 /* LDMIA r0-15, [r0] at debug speed
458 * register values will start to appear on 4th DCLK
459 */
460 arm7tdmi_clock_out(jtag_info, ARMV4_5_LDMIA(0, mask & 0xffff, 0, 0), NULL, 0);
461
462 /* fetch NOP, LDM in DECODE stage */
463 arm7tdmi_clock_out_inner(jtag_info, ARMV4_5_NOP, 0);
464 /* fetch NOP, LDM in EXECUTE stage (1st cycle) */
465 arm7tdmi_clock_out_inner(jtag_info, ARMV4_5_NOP, 0);
466
467 for (i = 0; i <= 15; i++)
468 {
469 if (mask & (1 << i))
470 /* nothing fetched, LDM still in EXECUTE (1 + i cycle) */
471 arm7tdmi_clock_out_inner(jtag_info, core_regs[i], 0);
472 }
473 arm7tdmi_clock_out_inner(jtag_info, ARMV4_5_NOP, 0);
474 }
475
476 static void arm7tdmi_load_word_regs(struct target *target, uint32_t mask)
477 {
478 struct arm7_9_common *arm7_9 = target_to_arm7_9(target);
479 struct arm_jtag *jtag_info = &arm7_9->jtag_info;
480
481 /* put system-speed load-multiple into the pipeline */
482 arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
483 arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 1);
484 arm7tdmi_clock_out(jtag_info, ARMV4_5_LDMIA(0, mask & 0xffff, 0, 1), NULL, 0);
485 }
486
487 static void arm7tdmi_load_hword_reg(struct target *target, int num)
488 {
489 struct arm7_9_common *arm7_9 = target_to_arm7_9(target);
490 struct arm_jtag *jtag_info = &arm7_9->jtag_info;
491
492 /* put system-speed load half-word into the pipeline */
493 arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
494 arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 1);
495 arm7tdmi_clock_out(jtag_info, ARMV4_5_LDRH_IP(num, 0), NULL, 0);
496 }
497
498 static void arm7tdmi_load_byte_reg(struct target *target, int num)
499 {
500 struct arm7_9_common *arm7_9 = target_to_arm7_9(target);
501 struct arm_jtag *jtag_info = &arm7_9->jtag_info;
502
503 /* put system-speed load byte into the pipeline */
504 arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
505 arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 1);
506 arm7tdmi_clock_out(jtag_info, ARMV4_5_LDRB_IP(num, 0), NULL, 0);
507 }
508
509 static void arm7tdmi_store_word_regs(struct target *target, uint32_t mask)
510 {
511 struct arm7_9_common *arm7_9 = target_to_arm7_9(target);
512 struct arm_jtag *jtag_info = &arm7_9->jtag_info;
513
514 /* put system-speed store-multiple into the pipeline */
515 arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
516 arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 1);
517 arm7tdmi_clock_out(jtag_info, ARMV4_5_STMIA(0, mask, 0, 1), NULL, 0);
518 }
519
520 static void arm7tdmi_store_hword_reg(struct target *target, int num)
521 {
522 struct arm7_9_common *arm7_9 = target_to_arm7_9(target);
523 struct arm_jtag *jtag_info = &arm7_9->jtag_info;
524
525 /* put system-speed store half-word into the pipeline */
526 arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
527 arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 1);
528 arm7tdmi_clock_out(jtag_info, ARMV4_5_STRH_IP(num, 0), NULL, 0);
529 }
530
531 static void arm7tdmi_store_byte_reg(struct target *target, int num)
532 {
533 struct arm7_9_common *arm7_9 = target_to_arm7_9(target);
534 struct arm_jtag *jtag_info = &arm7_9->jtag_info;
535
536 /* put system-speed store byte into the pipeline */
537 arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
538 arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 1);
539 arm7tdmi_clock_out(jtag_info, ARMV4_5_STRB_IP(num, 0), NULL, 0);
540 }
541
542 static void arm7tdmi_write_pc(struct target *target, uint32_t pc)
543 {
544 struct arm7_9_common *arm7_9 = target_to_arm7_9(target);
545 struct arm_jtag *jtag_info = &arm7_9->jtag_info;
546
547 /* LDMIA r0-15, [r0] at debug speed
548 * register values will start to appear on 4th DCLK
549 */
550 arm7tdmi_clock_out(jtag_info, ARMV4_5_LDMIA(0, 0x8000, 0, 0), NULL, 0);
551 /* fetch NOP, LDM in DECODE stage */
552 arm7tdmi_clock_out_inner(jtag_info, ARMV4_5_NOP, 0);
553 /* fetch NOP, LDM in EXECUTE stage (1st cycle) */
554 arm7tdmi_clock_out_inner(jtag_info, ARMV4_5_NOP, 0);
555 /* nothing fetched, LDM in EXECUTE stage (1st cycle) load register */
556 arm7tdmi_clock_out_inner(jtag_info, pc, 0);
557 /* nothing fetched, LDM in EXECUTE stage (2nd cycle) load register */
558 arm7tdmi_clock_out_inner(jtag_info, ARMV4_5_NOP, 0);
559 /* nothing fetched, LDM in EXECUTE stage (3rd cycle) load register */
560 arm7tdmi_clock_out_inner(jtag_info, ARMV4_5_NOP, 0);
561 /* fetch NOP, LDM in EXECUTE stage (4th cycle) */
562 arm7tdmi_clock_out_inner(jtag_info, ARMV4_5_NOP, 0);
563 /* fetch NOP, LDM in EXECUTE stage (5th cycle) */
564 arm7tdmi_clock_out_inner(jtag_info, ARMV4_5_NOP, 0);
565 }
566
567 static void arm7tdmi_branch_resume(struct target *target)
568 {
569 struct arm7_9_common *arm7_9 = target_to_arm7_9(target);
570 struct arm_jtag *jtag_info = &arm7_9->jtag_info;
571
572 arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 1);
573 arm7tdmi_clock_out_inner(jtag_info, ARMV4_5_B(0xfffffa, 0), 0);
574 }
575
576 static void arm7tdmi_branch_resume_thumb(struct target *target)
577 {
578 struct arm7_9_common *arm7_9 = target_to_arm7_9(target);
579 struct arm *armv4_5 = &arm7_9->armv4_5_common;
580 struct arm_jtag *jtag_info = &arm7_9->jtag_info;
581 struct reg *dbg_stat = &arm7_9->eice_cache->reg_list[EICE_DBG_STAT];
582
583 LOG_DEBUG("-");
584
585 /* LDMIA r0, [r0] at debug speed
586 * register values will start to appear on 4th DCLK
587 */
588 arm7tdmi_clock_out(jtag_info, ARMV4_5_LDMIA(0, 0x1, 0, 0), NULL, 0);
589
590 /* fetch NOP, LDM in DECODE stage */
591 arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
592 /* fetch NOP, LDM in EXECUTE stage (1st cycle) */
593 arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
594 /* nothing fetched, LDM in EXECUTE stage (2nd cycle) */
595 arm7tdmi_clock_out(jtag_info,
596 buf_get_u32(armv4_5->pc->value, 0, 32) | 1, NULL, 0);
597 /* nothing fetched, LDM in EXECUTE stage (3rd cycle) */
598 arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
599
600 /* Branch and eXchange */
601 arm7tdmi_clock_out(jtag_info, ARMV4_5_BX(0), NULL, 0);
602
603 embeddedice_read_reg(dbg_stat);
604
605 /* fetch NOP, BX in DECODE stage */
606 arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
607
608 /* target is now in Thumb state */
609 embeddedice_read_reg(dbg_stat);
610
611 /* fetch NOP, BX in EXECUTE stage (1st cycle) */
612 arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
613
614 /* target is now in Thumb state */
615 embeddedice_read_reg(dbg_stat);
616
617 /* load r0 value */
618 arm7tdmi_clock_out(jtag_info, ARMV4_5_T_LDR_PCREL(0), NULL, 0);
619 /* fetch NOP, LDR in Decode */
620 arm7tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, NULL, 0);
621 /* fetch NOP, LDR in Execute */
622 arm7tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, NULL, 0);
623 /* nothing fetched, LDR in EXECUTE stage (2nd cycle) */
624 arm7tdmi_clock_out(jtag_info, buf_get_u32(armv4_5->core_cache->reg_list[0].value, 0, 32), NULL, 0);
625 /* nothing fetched, LDR in EXECUTE stage (3rd cycle) */
626 arm7tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, NULL, 0);
627
628 arm7tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, NULL, 0);
629 arm7tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, NULL, 0);
630
631 embeddedice_read_reg(dbg_stat);
632
633 arm7tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, NULL, 1);
634 arm7tdmi_clock_out(jtag_info, ARMV4_5_T_B(0x7f8), NULL, 0);
635 }
636
637 static void arm7tdmi_build_reg_cache(struct target *target)
638 {
639 struct reg_cache **cache_p = register_get_last_cache_p(&target->reg_cache);
640 struct arm *armv4_5 = target_to_arm(target);
641
642 (*cache_p) = arm_build_reg_cache(target, armv4_5);
643 }
644
645 int arm7tdmi_init_target(struct command_context *cmd_ctx, struct target *target)
646 {
647 arm7tdmi_build_reg_cache(target);
648
649 return ERROR_OK;
650 }
651
652 int arm7tdmi_init_arch_info(struct target *target,
653 struct arm7_9_common *arm7_9, struct jtag_tap *tap)
654 {
655 /* prepare JTAG information for the new target */
656 arm7_9->jtag_info.tap = tap;
657 arm7_9->jtag_info.scann_size = 4;
658
659 /* register arch-specific functions */
660 arm7_9->examine_debug_reason = arm7tdmi_examine_debug_reason;
661 arm7_9->change_to_arm = arm7tdmi_change_to_arm;
662 arm7_9->read_core_regs = arm7tdmi_read_core_regs;
663 arm7_9->read_core_regs_target_buffer = arm7tdmi_read_core_regs_target_buffer;
664 arm7_9->read_xpsr = arm7tdmi_read_xpsr;
665
666 arm7_9->write_xpsr = arm7tdmi_write_xpsr;
667 arm7_9->write_xpsr_im8 = arm7tdmi_write_xpsr_im8;
668 arm7_9->write_core_regs = arm7tdmi_write_core_regs;
669
670 arm7_9->load_word_regs = arm7tdmi_load_word_regs;
671 arm7_9->load_hword_reg = arm7tdmi_load_hword_reg;
672 arm7_9->load_byte_reg = arm7tdmi_load_byte_reg;
673
674 arm7_9->store_word_regs = arm7tdmi_store_word_regs;
675 arm7_9->store_hword_reg = arm7tdmi_store_hword_reg;
676 arm7_9->store_byte_reg = arm7tdmi_store_byte_reg;
677
678 arm7_9->write_pc = arm7tdmi_write_pc;
679 arm7_9->branch_resume = arm7tdmi_branch_resume;
680 arm7_9->branch_resume_thumb = arm7tdmi_branch_resume_thumb;
681
682 arm7_9->enable_single_step = arm7_9_enable_eice_step;
683 arm7_9->disable_single_step = arm7_9_disable_eice_step;
684
685 arm7_9->post_debug_entry = NULL;
686
687 arm7_9->pre_restore_context = NULL;
688
689 /* initialize arch-specific breakpoint handling */
690 arm7_9->arm_bkpt = 0xdeeedeee;
691 arm7_9->thumb_bkpt = 0xdeee;
692
693 arm7_9->dbgreq_adjust_pc = 2;
694
695 arm7_9_init_arch_info(target, arm7_9);
696
697 return ERROR_OK;
698 }
699
700 static int arm7tdmi_target_create(struct target *target, Jim_Interp *interp)
701 {
702 struct arm7_9_common *arm7_9;
703
704 arm7_9 = calloc(1,sizeof(struct arm7_9_common));
705 arm7tdmi_init_arch_info(target, arm7_9, target->tap);
706 arm7_9->armv4_5_common.is_armv4 = true;
707
708 return ERROR_OK;
709 }
710
711 /** Holds methods for ARM7TDMI targets. */
712 struct target_type arm7tdmi_target =
713 {
714 .name = "arm7tdmi",
715
716 .poll = arm7_9_poll,
717 .arch_state = arm_arch_state,
718
719 .target_request_data = arm7_9_target_request_data,
720
721 .halt = arm7_9_halt,
722 .resume = arm7_9_resume,
723 .step = arm7_9_step,
724
725 .assert_reset = arm7_9_assert_reset,
726 .deassert_reset = arm7_9_deassert_reset,
727 .soft_reset_halt = arm7_9_soft_reset_halt,
728
729 .get_gdb_reg_list = arm_get_gdb_reg_list,
730
731 .read_memory = arm7_9_read_memory,
732 .write_memory = arm7_9_write_memory,
733 .bulk_write_memory = arm7_9_bulk_write_memory,
734
735 .checksum_memory = arm_checksum_memory,
736 .blank_check_memory = arm_blank_check_memory,
737
738 .run_algorithm = armv4_5_run_algorithm,
739
740 .add_breakpoint = arm7_9_add_breakpoint,
741 .remove_breakpoint = arm7_9_remove_breakpoint,
742 .add_watchpoint = arm7_9_add_watchpoint,
743 .remove_watchpoint = arm7_9_remove_watchpoint,
744
745 .commands = arm7_9_command_handlers,
746 .target_create = arm7tdmi_target_create,
747 .init_target = arm7tdmi_init_target,
748 .examine = arm7_9_examine,
749 .check_reset = arm7_9_check_reset,
750 };

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)