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

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)