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

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)