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

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)