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

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)