remove TAP_INVALID as argument to jtag_add_xxx() fn's
[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 u8 databus[4];
99 u8 breakpoint;
100
101 jtag_add_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, 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, 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, u32 out, int breakpoint)
143 {
144 u32 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_add_end_state(TAP_INVALID));
151
152 jtag_add_runtest(0, jtag_add_end_state(TAP_INVALID));
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, u32 out, u32 *deprecated, int breakpoint)
159 {
160 jtag_add_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, u32 *in)
169 {
170 int retval = ERROR_OK;
171 scan_field_t fields[2];
172
173 jtag_add_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 = (u8 *)in;
189
190 jtag_add_dr_scan(2, fields, jtag_add_end_state(TAP_INVALID));
191
192 jtag_add_callback(arm7flip32, (u8 *)in);
193
194 jtag_add_runtest(0, jtag_add_end_state(TAP_INVALID));
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(u8 *tmp, void *in, int size, int be, int flip)
218 {
219 u32 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(((u8*)in), readback);
228 } else
229 {
230 h_u32_to_le(((u8*)in), readback);
231 }
232 break;
233 case 2:
234 if (be)
235 {
236 h_u16_to_be(((u8*)in), readback & 0xffff);
237 } else
238 {
239 h_u16_to_le(((u8*)in), readback & 0xffff);
240 }
241 break;
242 case 1:
243 *((u8 *)in)= readback & 0xff;
244 break;
245 }
246 }
247
248 static int arm7endianness(u8 *in, jtag_callback_data_t size, jtag_callback_data_t be, jtag_callback_data_t captured)
249 {
250 arm_endianness((u8 *)captured, in, (int)size, (int)be, 1);
251 return ERROR_OK;
252 }
253
254 /* clock the target, and read the databus
255 * the *in pointer points to a buffer where elements of 'size' bytes
256 * are stored in big (be==1) or little (be==0) endianness
257 */
258 int arm7tdmi_clock_data_in_endianness(arm_jtag_t *jtag_info, void *in, int size, int be)
259 {
260 int retval = ERROR_OK;
261 scan_field_t fields[2];
262
263 jtag_add_end_state(TAP_DRPAUSE);
264 if((retval = arm_jtag_scann(jtag_info, 0x1)) != ERROR_OK)
265 {
266 return retval;
267 }
268 arm_jtag_set_instr(jtag_info, jtag_info->intest_instr, NULL);
269
270 fields[0].tap = jtag_info->tap;
271 fields[0].num_bits = 1;
272 fields[0].out_value = NULL;
273 fields[0].in_value = NULL;
274
275 fields[1].tap = jtag_info->tap;
276 fields[1].num_bits = 32;
277 fields[1].out_value = NULL;
278 jtag_alloc_in_value32(&fields[1]);
279
280 jtag_add_dr_scan(2, fields, jtag_add_end_state(TAP_INVALID));
281
282 jtag_add_callback4(arm7endianness, in, (jtag_callback_data_t)size, (jtag_callback_data_t)be, (jtag_callback_data_t)fields[1].in_value);
283
284 jtag_add_runtest(0, jtag_add_end_state(TAP_INVALID));
285
286 #ifdef _DEBUG_INSTRUCTION_EXECUTION_
287 {
288 if((retval = jtag_execute_queue()) != ERROR_OK)
289 {
290 return retval;
291 }
292
293 if (in)
294 {
295 LOG_DEBUG("in: 0x%8.8x", *(u32*)in);
296 }
297 else
298 {
299 LOG_ERROR("BUG: called with in == NULL");
300 }
301 }
302 #endif
303
304 return ERROR_OK;
305 }
306
307 void arm7tdmi_change_to_arm(target_t *target, u32 *r0, u32 *pc)
308 {
309 /* get pointers to arch-specific information */
310 armv4_5_common_t *armv4_5 = target->arch_info;
311 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
312 arm_jtag_t *jtag_info = &arm7_9->jtag_info;
313
314 /* save r0 before using it and put system in ARM state
315 * to allow common handling of ARM and THUMB debugging */
316
317 /* fetch STR r0, [r0] */
318 arm7tdmi_clock_out(jtag_info, ARMV4_5_T_STR(0, 0), NULL, 0);
319 arm7tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, NULL, 0);
320 arm7tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, NULL, 0);
321 /* nothing fetched, STR r0, [r0] in Execute (2) */
322 arm7tdmi_clock_data_in(jtag_info, r0);
323
324 /* MOV r0, r15 fetched, STR in Decode */
325 arm7tdmi_clock_out(jtag_info, ARMV4_5_T_MOV(0, 15), NULL, 0);
326 arm7tdmi_clock_out(jtag_info, ARMV4_5_T_STR(0, 0), NULL, 0);
327 arm7tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, NULL, 0);
328 arm7tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, NULL, 0);
329 /* nothing fetched, STR r0, [r0] in Execute (2) */
330 arm7tdmi_clock_data_in(jtag_info, pc);
331
332 /* use pc-relative LDR to clear r0[1:0] (for switch to ARM mode) */
333 arm7tdmi_clock_out(jtag_info, ARMV4_5_T_LDR_PCREL(0), NULL, 0);
334 arm7tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, NULL, 0);
335 arm7tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, NULL, 0);
336 /* nothing fetched, data for LDR r0, [PC, #0] */
337 arm7tdmi_clock_out(jtag_info, 0x0, NULL, 0);
338 /* nothing fetched, data from previous cycle is written to register */
339 arm7tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, NULL, 0);
340
341 /* fetch BX */
342 arm7tdmi_clock_out(jtag_info, ARMV4_5_T_BX(0), NULL, 0);
343 /* NOP fetched, BX in Decode, MOV in Execute */
344 arm7tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, NULL, 0);
345 /* NOP fetched, BX in Execute (1) */
346 arm7tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, NULL, 0);
347
348 jtag_execute_queue();
349
350 /* fix program counter:
351 * MOV r0, r15 was the 4th instruction (+6)
352 * reading PC in Thumb state gives address of instruction + 4
353 */
354 *pc -= 0xa;
355 }
356
357
358 /* FIX!!! is this a potential performance bottleneck w.r.t. requiring too many
359 * roundtrips when jtag_execute_queue() has a large overhead(e.g. for USB)s?
360 *
361 * The solution is to arrange for a large out/in scan in this loop and
362 * and convert data afterwards.
363 */
364 void arm7tdmi_read_core_regs(target_t *target, u32 mask, u32* core_regs[16])
365 {
366 int i;
367 /* get pointers to arch-specific information */
368 armv4_5_common_t *armv4_5 = target->arch_info;
369 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
370 arm_jtag_t *jtag_info = &arm7_9->jtag_info;
371
372 /* STMIA r0-15, [r0] at debug speed
373 * register values will start to appear on 4th DCLK
374 */
375 arm7tdmi_clock_out(jtag_info, ARMV4_5_STMIA(0, mask & 0xffff, 0, 0), NULL, 0);
376
377 /* fetch NOP, STM in DECODE stage */
378 arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
379 /* fetch NOP, STM in EXECUTE stage (1st cycle) */
380 arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
381
382 for (i = 0; i <= 15; i++)
383 {
384 if (mask & (1 << i))
385 /* nothing fetched, STM still in EXECUTE (1+i cycle) */
386 arm7tdmi_clock_data_in(jtag_info, core_regs[i]);
387 }
388 }
389
390 void arm7tdmi_read_core_regs_target_buffer(target_t *target, u32 mask, void* buffer, int size)
391 {
392 int i;
393 /* get pointers to arch-specific information */
394 armv4_5_common_t *armv4_5 = target->arch_info;
395 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
396 arm_jtag_t *jtag_info = &arm7_9->jtag_info;
397 int be = (target->endianness == TARGET_BIG_ENDIAN) ? 1 : 0;
398 u32 *buf_u32 = buffer;
399 u16 *buf_u16 = buffer;
400 u8 *buf_u8 = buffer;
401
402 /* STMIA r0-15, [r0] at debug speed
403 * register values will start to appear on 4th DCLK
404 */
405 arm7tdmi_clock_out(jtag_info, ARMV4_5_STMIA(0, mask & 0xffff, 0, 0), NULL, 0);
406
407 /* fetch NOP, STM in DECODE stage */
408 arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
409 /* fetch NOP, STM in EXECUTE stage (1st cycle) */
410 arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
411
412 for (i = 0; i <= 15; i++)
413 {
414 /* nothing fetched, STM still in EXECUTE (1+i cycle), read databus */
415 if (mask & (1 << i))
416 {
417 switch (size)
418 {
419 case 4:
420 arm7tdmi_clock_data_in_endianness(jtag_info, buf_u32++, 4, be);
421 break;
422 case 2:
423 arm7tdmi_clock_data_in_endianness(jtag_info, buf_u16++, 2, be);
424 break;
425 case 1:
426 arm7tdmi_clock_data_in_endianness(jtag_info, buf_u8++, 1, be);
427 break;
428 }
429 }
430 }
431 }
432
433 void arm7tdmi_read_xpsr(target_t *target, u32 *xpsr, int spsr)
434 {
435 /* get pointers to arch-specific information */
436 armv4_5_common_t *armv4_5 = target->arch_info;
437 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
438 arm_jtag_t *jtag_info = &arm7_9->jtag_info;
439
440 /* MRS r0, cpsr */
441 arm7tdmi_clock_out(jtag_info, ARMV4_5_MRS(0, spsr & 1), NULL, 0);
442
443 /* STR r0, [r15] */
444 arm7tdmi_clock_out(jtag_info, ARMV4_5_STR(0, 15), NULL, 0);
445 /* fetch NOP, STR in DECODE stage */
446 arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
447 /* fetch NOP, STR in EXECUTE stage (1st cycle) */
448 arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
449 /* nothing fetched, STR still in EXECUTE (2nd cycle) */
450 arm7tdmi_clock_data_in(jtag_info, xpsr);
451 }
452
453 void arm7tdmi_write_xpsr(target_t *target, u32 xpsr, int spsr)
454 {
455 /* get pointers to arch-specific information */
456 armv4_5_common_t *armv4_5 = target->arch_info;
457 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
458 arm_jtag_t *jtag_info = &arm7_9->jtag_info;
459
460 LOG_DEBUG("xpsr: %8.8x, spsr: %i", xpsr, spsr);
461
462 /* MSR1 fetched */
463 arm7tdmi_clock_out(jtag_info, ARMV4_5_MSR_IM(xpsr & 0xff, 0, 1, spsr), NULL, 0);
464 /* MSR2 fetched, MSR1 in DECODE */
465 arm7tdmi_clock_out(jtag_info, ARMV4_5_MSR_IM((xpsr & 0xff00) >> 8, 0xc, 2, spsr), NULL, 0);
466 /* MSR3 fetched, MSR1 in EXECUTE (1), MSR2 in DECODE */
467 arm7tdmi_clock_out(jtag_info, ARMV4_5_MSR_IM((xpsr & 0xff0000) >> 16, 0x8, 4, spsr), NULL, 0);
468 /* nothing fetched, MSR1 in EXECUTE (2) */
469 arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
470 /* MSR4 fetched, MSR2 in EXECUTE (1), MSR3 in DECODE */
471 arm7tdmi_clock_out(jtag_info, ARMV4_5_MSR_IM((xpsr & 0xff000000) >> 24, 0x4, 8, spsr), NULL, 0);
472 /* nothing fetched, MSR2 in EXECUTE (2) */
473 arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
474 /* NOP fetched, MSR3 in EXECUTE (1), MSR4 in DECODE */
475 arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
476 /* nothing fetched, MSR3 in EXECUTE (2) */
477 arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
478 /* NOP fetched, MSR4 in EXECUTE (1) */
479 arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
480 /* nothing fetched, MSR4 in EXECUTE (2) */
481 arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
482 }
483
484 void arm7tdmi_write_xpsr_im8(target_t *target, u8 xpsr_im, int rot, int spsr)
485 {
486 /* get pointers to arch-specific information */
487 armv4_5_common_t *armv4_5 = target->arch_info;
488 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
489 arm_jtag_t *jtag_info = &arm7_9->jtag_info;
490
491 LOG_DEBUG("xpsr_im: %2.2x, rot: %i, spsr: %i", xpsr_im, rot, spsr);
492
493 /* MSR fetched */
494 arm7tdmi_clock_out(jtag_info, ARMV4_5_MSR_IM(xpsr_im, rot, 1, spsr), NULL, 0);
495 /* NOP fetched, MSR in DECODE */
496 arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
497 /* NOP fetched, MSR in EXECUTE (1) */
498 arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
499 /* nothing fetched, MSR in EXECUTE (2) */
500 arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
501 }
502
503 void arm7tdmi_write_core_regs(target_t *target, u32 mask, u32 core_regs[16])
504 {
505 int i;
506 /* get pointers to arch-specific information */
507 armv4_5_common_t *armv4_5 = target->arch_info;
508 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
509 arm_jtag_t *jtag_info = &arm7_9->jtag_info;
510
511 /* LDMIA r0-15, [r0] at debug speed
512 * register values will start to appear on 4th DCLK
513 */
514 arm7tdmi_clock_out(jtag_info, ARMV4_5_LDMIA(0, mask & 0xffff, 0, 0), NULL, 0);
515
516 /* fetch NOP, LDM in DECODE stage */
517 arm7tdmi_clock_out_inner(jtag_info, ARMV4_5_NOP, 0);
518 /* fetch NOP, LDM in EXECUTE stage (1st cycle) */
519 arm7tdmi_clock_out_inner(jtag_info, ARMV4_5_NOP, 0);
520
521 for (i = 0; i <= 15; i++)
522 {
523 if (mask & (1 << i))
524 /* nothing fetched, LDM still in EXECUTE (1+i cycle) */
525 arm7tdmi_clock_out_inner(jtag_info, core_regs[i], 0);
526 }
527 arm7tdmi_clock_out_inner(jtag_info, ARMV4_5_NOP, 0);
528 }
529
530 void arm7tdmi_load_word_regs(target_t *target, u32 mask)
531 {
532 /* get pointers to arch-specific information */
533 armv4_5_common_t *armv4_5 = target->arch_info;
534 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
535 arm_jtag_t *jtag_info = &arm7_9->jtag_info;
536
537 /* put system-speed load-multiple into the pipeline */
538 arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
539 arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 1);
540 arm7tdmi_clock_out(jtag_info, ARMV4_5_LDMIA(0, mask & 0xffff, 0, 1), NULL, 0);
541 }
542
543 void arm7tdmi_load_hword_reg(target_t *target, int num)
544 {
545 /* get pointers to arch-specific information */
546 armv4_5_common_t *armv4_5 = target->arch_info;
547 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
548 arm_jtag_t *jtag_info = &arm7_9->jtag_info;
549
550 /* put system-speed load half-word into the pipeline */
551 arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
552 arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 1);
553 arm7tdmi_clock_out(jtag_info, ARMV4_5_LDRH_IP(num, 0), NULL, 0);
554 }
555
556 void arm7tdmi_load_byte_reg(target_t *target, int num)
557 {
558 /* get pointers to arch-specific information */
559 armv4_5_common_t *armv4_5 = target->arch_info;
560 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
561 arm_jtag_t *jtag_info = &arm7_9->jtag_info;
562
563 /* put system-speed load byte into the pipeline */
564 arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
565 arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 1);
566 arm7tdmi_clock_out(jtag_info, ARMV4_5_LDRB_IP(num, 0), NULL, 0);
567 }
568
569 void arm7tdmi_store_word_regs(target_t *target, u32 mask)
570 {
571 /* get pointers to arch-specific information */
572 armv4_5_common_t *armv4_5 = target->arch_info;
573 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
574 arm_jtag_t *jtag_info = &arm7_9->jtag_info;
575
576 /* put system-speed store-multiple into the pipeline */
577 arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
578 arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 1);
579 arm7tdmi_clock_out(jtag_info, ARMV4_5_STMIA(0, mask, 0, 1), NULL, 0);
580 }
581
582 void arm7tdmi_store_hword_reg(target_t *target, int num)
583 {
584 /* get pointers to arch-specific information */
585 armv4_5_common_t *armv4_5 = target->arch_info;
586 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
587 arm_jtag_t *jtag_info = &arm7_9->jtag_info;
588
589 /* put system-speed store half-word into the pipeline */
590 arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
591 arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 1);
592 arm7tdmi_clock_out(jtag_info, ARMV4_5_STRH_IP(num, 0), NULL, 0);
593 }
594
595 void arm7tdmi_store_byte_reg(target_t *target, int num)
596 {
597 /* get pointers to arch-specific information */
598 armv4_5_common_t *armv4_5 = target->arch_info;
599 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
600 arm_jtag_t *jtag_info = &arm7_9->jtag_info;
601
602 /* put system-speed store byte into the pipeline */
603 arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
604 arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 1);
605 arm7tdmi_clock_out(jtag_info, ARMV4_5_STRB_IP(num, 0), NULL, 0);
606 }
607
608 void arm7tdmi_write_pc(target_t *target, u32 pc)
609 {
610 /* get pointers to arch-specific information */
611 armv4_5_common_t *armv4_5 = target->arch_info;
612 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
613 arm_jtag_t *jtag_info = &arm7_9->jtag_info;
614
615 /* LDMIA r0-15, [r0] at debug speed
616 * register values will start to appear on 4th DCLK
617 */
618 arm7tdmi_clock_out(jtag_info, ARMV4_5_LDMIA(0, 0x8000, 0, 0), NULL, 0);
619 /* fetch NOP, LDM in DECODE stage */
620 arm7tdmi_clock_out_inner(jtag_info, ARMV4_5_NOP, 0);
621 /* fetch NOP, LDM in EXECUTE stage (1st cycle) */
622 arm7tdmi_clock_out_inner(jtag_info, ARMV4_5_NOP, 0);
623 /* nothing fetched, LDM in EXECUTE stage (1st cycle) load register */
624 arm7tdmi_clock_out_inner(jtag_info, pc, 0);
625 /* nothing fetched, LDM in EXECUTE stage (2nd cycle) load register */
626 arm7tdmi_clock_out_inner(jtag_info, ARMV4_5_NOP, 0);
627 /* nothing fetched, LDM in EXECUTE stage (3rd cycle) load register */
628 arm7tdmi_clock_out_inner(jtag_info, ARMV4_5_NOP, 0);
629 /* fetch NOP, LDM in EXECUTE stage (4th cycle) */
630 arm7tdmi_clock_out_inner(jtag_info, ARMV4_5_NOP, 0);
631 /* fetch NOP, LDM in EXECUTE stage (5th cycle) */
632 arm7tdmi_clock_out_inner(jtag_info, ARMV4_5_NOP, 0);
633 }
634
635 void arm7tdmi_branch_resume(target_t *target)
636 {
637 /* get pointers to arch-specific information */
638 armv4_5_common_t *armv4_5 = target->arch_info;
639 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
640 arm_jtag_t *jtag_info = &arm7_9->jtag_info;
641
642 arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 1);
643 arm7tdmi_clock_out_inner(jtag_info, ARMV4_5_B(0xfffffa, 0), 0);
644 }
645
646 void arm7tdmi_branch_resume_thumb(target_t *target)
647 {
648 LOG_DEBUG("-");
649
650 /* get pointers to arch-specific information */
651 armv4_5_common_t *armv4_5 = target->arch_info;
652 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
653 arm_jtag_t *jtag_info = &arm7_9->jtag_info;
654 reg_t *dbg_stat = &arm7_9->eice_cache->reg_list[EICE_DBG_STAT];
655
656 /* LDMIA r0, [r0] at debug speed
657 * register values will start to appear on 4th DCLK
658 */
659 arm7tdmi_clock_out(jtag_info, ARMV4_5_LDMIA(0, 0x1, 0, 0), NULL, 0);
660
661 /* fetch NOP, LDM in DECODE stage */
662 arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
663 /* fetch NOP, LDM in EXECUTE stage (1st cycle) */
664 arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
665 /* nothing fetched, LDM in EXECUTE stage (2nd cycle) */
666 arm7tdmi_clock_out(jtag_info, buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32) | 1, NULL, 0);
667 /* nothing fetched, LDM in EXECUTE stage (3rd cycle) */
668 arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
669
670 /* Branch and eXchange */
671 arm7tdmi_clock_out(jtag_info, ARMV4_5_BX(0), NULL, 0);
672
673 embeddedice_read_reg(dbg_stat);
674
675 /* fetch NOP, BX in DECODE stage */
676 arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
677
678 /* target is now in Thumb state */
679 embeddedice_read_reg(dbg_stat);
680
681 /* fetch NOP, BX in EXECUTE stage (1st cycle) */
682 arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
683
684 /* target is now in Thumb state */
685 embeddedice_read_reg(dbg_stat);
686
687 /* load r0 value */
688 arm7tdmi_clock_out(jtag_info, ARMV4_5_T_LDR_PCREL(0), NULL, 0);
689 /* fetch NOP, LDR in Decode */
690 arm7tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, NULL, 0);
691 /* fetch NOP, LDR in Execute */
692 arm7tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, NULL, 0);
693 /* nothing fetched, LDR in EXECUTE stage (2nd cycle) */
694 arm7tdmi_clock_out(jtag_info, buf_get_u32(armv4_5->core_cache->reg_list[0].value, 0, 32), NULL, 0);
695 /* nothing fetched, LDR in EXECUTE stage (3rd cycle) */
696 arm7tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, NULL, 0);
697
698 arm7tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, NULL, 0);
699 arm7tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, NULL, 0);
700
701 embeddedice_read_reg(dbg_stat);
702
703 arm7tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, NULL, 1);
704 arm7tdmi_clock_out(jtag_info, ARMV4_5_T_B(0x7f8), NULL, 0);
705 }
706
707 void arm7tdmi_build_reg_cache(target_t *target)
708 {
709 reg_cache_t **cache_p = register_get_last_cache_p(&target->reg_cache);
710 /* get pointers to arch-specific information */
711 armv4_5_common_t *armv4_5 = target->arch_info;
712
713 (*cache_p) = armv4_5_build_reg_cache(target, armv4_5);
714 armv4_5->core_cache = (*cache_p);
715 }
716
717 int arm7tdmi_examine(struct target_s *target)
718 {
719 int retval;
720 armv4_5_common_t *armv4_5 = target->arch_info;
721 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
722 if (!target_was_examined(target))
723 {
724 /* get pointers to arch-specific information */
725 reg_cache_t **cache_p = register_get_last_cache_p(&target->reg_cache);
726 reg_cache_t *t=embeddedice_build_reg_cache(target, arm7_9);
727 if (t==NULL)
728 return ERROR_FAIL;
729
730 (*cache_p) = t;
731 arm7_9->eice_cache = (*cache_p);
732
733 if (arm7_9->etm_ctx)
734 {
735 arm_jtag_t *jtag_info = &arm7_9->jtag_info;
736 (*cache_p)->next = etm_build_reg_cache(target, jtag_info, arm7_9->etm_ctx);
737 arm7_9->etm_ctx->reg_cache = (*cache_p)->next;
738 }
739 target_set_examined(target);
740 }
741 if ((retval=embeddedice_setup(target))!=ERROR_OK)
742 return retval;
743 if ((retval=arm7_9_setup(target))!=ERROR_OK)
744 return retval;
745 if (arm7_9->etm_ctx)
746 {
747 if ((retval=etm_setup(target))!=ERROR_OK)
748 return retval;
749 }
750 return ERROR_OK;
751 }
752
753 int arm7tdmi_init_target(struct command_context_s *cmd_ctx, struct target_s *target)
754 {
755 arm7tdmi_build_reg_cache(target);
756
757 return ERROR_OK;
758 }
759
760 int arm7tdmi_quit(void)
761 {
762 return ERROR_OK;
763 }
764
765 int arm7tdmi_init_arch_info(target_t *target, arm7tdmi_common_t *arm7tdmi, jtag_tap_t *tap)
766 {
767 armv4_5_common_t *armv4_5;
768 arm7_9_common_t *arm7_9;
769
770 arm7_9 = &arm7tdmi->arm7_9_common;
771 armv4_5 = &arm7_9->armv4_5_common;
772
773 /* prepare JTAG information for the new target */
774 arm7_9->jtag_info.tap = tap;
775 arm7_9->jtag_info.scann_size = 4;
776
777 /* register arch-specific functions */
778 arm7_9->examine_debug_reason = arm7tdmi_examine_debug_reason;
779 arm7_9->change_to_arm = arm7tdmi_change_to_arm;
780 arm7_9->read_core_regs = arm7tdmi_read_core_regs;
781 arm7_9->read_core_regs_target_buffer = arm7tdmi_read_core_regs_target_buffer;
782 arm7_9->read_xpsr = arm7tdmi_read_xpsr;
783
784 arm7_9->write_xpsr = arm7tdmi_write_xpsr;
785 arm7_9->write_xpsr_im8 = arm7tdmi_write_xpsr_im8;
786 arm7_9->write_core_regs = arm7tdmi_write_core_regs;
787
788 arm7_9->load_word_regs = arm7tdmi_load_word_regs;
789 arm7_9->load_hword_reg = arm7tdmi_load_hword_reg;
790 arm7_9->load_byte_reg = arm7tdmi_load_byte_reg;
791
792 arm7_9->store_word_regs = arm7tdmi_store_word_regs;
793 arm7_9->store_hword_reg = arm7tdmi_store_hword_reg;
794 arm7_9->store_byte_reg = arm7tdmi_store_byte_reg;
795
796 arm7_9->write_pc = arm7tdmi_write_pc;
797 arm7_9->branch_resume = arm7tdmi_branch_resume;
798 arm7_9->branch_resume_thumb = arm7tdmi_branch_resume_thumb;
799
800 arm7_9->enable_single_step = arm7_9_enable_eice_step;
801 arm7_9->disable_single_step = arm7_9_disable_eice_step;
802
803 arm7_9->pre_debug_entry = NULL;
804 arm7_9->post_debug_entry = NULL;
805
806 arm7_9->pre_restore_context = NULL;
807 arm7_9->post_restore_context = NULL;
808
809 /* initialize arch-specific breakpoint handling */
810 arm7_9->arm_bkpt = 0xdeeedeee;
811 arm7_9->thumb_bkpt = 0xdeee;
812
813 arm7_9->dbgreq_adjust_pc = 2;
814 arm7_9->arch_info = arm7tdmi;
815
816 arm7tdmi->arch_info = NULL;
817 arm7tdmi->common_magic = ARM7TDMI_COMMON_MAGIC;
818
819 arm7_9_init_arch_info(target, arm7_9);
820
821 return ERROR_OK;
822 }
823
824 int arm7tdmi_target_create( struct target_s *target, Jim_Interp *interp )
825 {
826 arm7tdmi_common_t *arm7tdmi;
827
828 arm7tdmi = calloc(1,sizeof(arm7tdmi_common_t));
829 arm7tdmi_init_arch_info(target, arm7tdmi, target->tap);
830
831 return ERROR_OK;
832 }
833
834 int arm7tdmi_register_commands(struct command_context_s *cmd_ctx)
835 {
836 int retval;
837
838 retval = arm7_9_register_commands(cmd_ctx);
839
840 return retval;
841 }

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)