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

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)