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

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)