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

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)