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