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

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)