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

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)