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

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)