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

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)