Audit and eliminate redundant #include directives in arm target files.
[openocd.git] / src / target / arm9tdmi.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) 2008 by Hongtao Zheng *
9 * hontor@126.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 "arm9tdmi.h"
31
32
33 #if 0
34 #define _DEBUG_INSTRUCTION_EXECUTION_
35 #endif
36
37 /* cli handling */
38 int handle_arm9tdmi_catch_vectors_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
39
40 /* forward declarations */
41 int arm9tdmi_target_create( struct target_s *target, Jim_Interp *interp );
42
43 int arm9tdmi_quit(void);
44
45 target_type_t arm9tdmi_target =
46 {
47 .name = "arm9tdmi",
48
49 .poll = arm7_9_poll,
50 .arch_state = armv4_5_arch_state,
51
52 .target_request_data = arm7_9_target_request_data,
53
54 .halt = arm7_9_halt,
55 .resume = arm7_9_resume,
56 .step = arm7_9_step,
57
58 .assert_reset = arm7_9_assert_reset,
59 .deassert_reset = arm7_9_deassert_reset,
60 .soft_reset_halt = arm7_9_soft_reset_halt,
61
62 .get_gdb_reg_list = armv4_5_get_gdb_reg_list,
63
64 .read_memory = arm7_9_read_memory,
65 .write_memory = arm7_9_write_memory,
66 .bulk_write_memory = arm7_9_bulk_write_memory,
67 .checksum_memory = arm7_9_checksum_memory,
68 .blank_check_memory = arm7_9_blank_check_memory,
69
70 .run_algorithm = armv4_5_run_algorithm,
71
72 .add_breakpoint = arm7_9_add_breakpoint,
73 .remove_breakpoint = arm7_9_remove_breakpoint,
74 .add_watchpoint = arm7_9_add_watchpoint,
75 .remove_watchpoint = arm7_9_remove_watchpoint,
76
77 .register_commands = arm9tdmi_register_commands,
78 .target_create = arm9tdmi_target_create,
79 .init_target = arm9tdmi_init_target,
80 .examine = arm9tdmi_examine,
81 .quit = arm9tdmi_quit
82 };
83
84 arm9tdmi_vector_t arm9tdmi_vectors[] =
85 {
86 {"reset", ARM9TDMI_RESET_VECTOR},
87 {"undef", ARM9TDMI_UNDEF_VECTOR},
88 {"swi", ARM9TDMI_SWI_VECTOR},
89 {"pabt", ARM9TDMI_PABT_VECTOR},
90 {"dabt", ARM9TDMI_DABT_VECTOR},
91 {"reserved", ARM9TDMI_RESERVED_VECTOR},
92 {"irq", ARM9TDMI_IRQ_VECTOR},
93 {"fiq", ARM9TDMI_FIQ_VECTOR},
94 {0, 0},
95 };
96
97 int arm9tdmi_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[3];
109 u8 databus[4];
110 u8 instructionbus[4];
111 u8 debug_reason;
112
113 jtag_add_end_state(TAP_DRPAUSE);
114
115 fields[0].tap = arm7_9->jtag_info.tap;
116 fields[0].num_bits = 32;
117 fields[0].out_value = NULL;
118 fields[0].in_value = databus;
119
120 fields[1].tap = arm7_9->jtag_info.tap;
121 fields[1].num_bits = 3;
122 fields[1].out_value = NULL;
123 fields[1].in_value = &debug_reason;
124
125 fields[2].tap = arm7_9->jtag_info.tap;
126 fields[2].num_bits = 32;
127 fields[2].out_value = NULL;
128 fields[2].in_value = instructionbus;
129
130 if ((retval = arm_jtag_scann(&arm7_9->jtag_info, 0x1)) != ERROR_OK)
131 {
132 return retval;
133 }
134 arm_jtag_set_instr(&arm7_9->jtag_info, arm7_9->jtag_info.intest_instr, NULL);
135
136 jtag_add_dr_scan(3, fields, TAP_DRPAUSE);
137 if ((retval = jtag_execute_queue()) != ERROR_OK)
138 {
139 return retval;
140 }
141
142 fields[0].in_value = NULL;
143 fields[0].out_value = databus;
144 fields[1].in_value = NULL;
145 fields[1].out_value = &debug_reason;
146 fields[2].in_value = NULL;
147 fields[2].out_value = instructionbus;
148
149 jtag_add_dr_scan(3, fields, TAP_DRPAUSE);
150
151 if (debug_reason & 0x4)
152 if (debug_reason & 0x2)
153 target->debug_reason = DBG_REASON_WPTANDBKPT;
154 else
155 target->debug_reason = DBG_REASON_WATCHPOINT;
156 else
157 target->debug_reason = DBG_REASON_BREAKPOINT;
158 }
159
160 return ERROR_OK;
161 }
162
163 /* put an instruction in the ARM9TDMI pipeline or write the data bus, and optionally read data */
164 int arm9tdmi_clock_out(arm_jtag_t *jtag_info, u32 instr, u32 out, u32 *in, int sysspeed)
165 {
166 int retval = ERROR_OK;
167 scan_field_t fields[3];
168 u8 out_buf[4];
169 u8 instr_buf[4];
170 u8 sysspeed_buf = 0x0;
171
172 /* prepare buffer */
173 buf_set_u32(out_buf, 0, 32, out);
174
175 buf_set_u32(instr_buf, 0, 32, flip_u32(instr, 32));
176
177 if (sysspeed)
178 buf_set_u32(&sysspeed_buf, 2, 1, 1);
179
180 jtag_add_end_state(TAP_DRPAUSE);
181 if ((retval = arm_jtag_scann(jtag_info, 0x1)) != ERROR_OK)
182 {
183 return retval;
184 }
185
186 arm_jtag_set_instr(jtag_info, jtag_info->intest_instr, NULL);
187
188 fields[0].tap = jtag_info->tap;
189 fields[0].num_bits = 32;
190 fields[0].out_value = out_buf;
191 fields[0].in_value = NULL;
192
193 fields[1].tap = jtag_info->tap;
194 fields[1].num_bits = 3;
195 fields[1].out_value = &sysspeed_buf;
196 fields[1].in_value = NULL;
197
198 fields[2].tap = jtag_info->tap;
199 fields[2].num_bits = 32;
200 fields[2].out_value = instr_buf;
201 fields[2].in_value = NULL;
202
203 if (in)
204 {
205 u8 tmp[4];
206 fields[0].in_value=tmp;
207 jtag_add_dr_scan_now(3, fields, TAP_INVALID);
208
209 *in=le_to_h_u32(tmp);
210 }
211 else
212 {
213 jtag_add_dr_scan(3, fields, TAP_INVALID);
214 }
215
216 jtag_add_runtest(0, TAP_INVALID);
217
218 #ifdef _DEBUG_INSTRUCTION_EXECUTION_
219 {
220 if ((retval = jtag_execute_queue()) != ERROR_OK)
221 {
222 return retval;
223 }
224
225 if (in)
226 {
227 LOG_DEBUG("instr: 0x%8.8x, out: 0x%8.8x, in: 0x%8.8x", instr, out, *in);
228 }
229 else
230 LOG_DEBUG("instr: 0x%8.8x, out: 0x%8.8x", instr, out);
231 }
232 #endif
233
234 return ERROR_OK;
235 }
236
237 /* just read data (instruction and data-out = don't care) */
238 int arm9tdmi_clock_data_in(arm_jtag_t *jtag_info, u32 *in)
239 {
240 int retval = ERROR_OK;;
241 scan_field_t fields[3];
242
243 jtag_add_end_state(TAP_DRPAUSE);
244 if ((retval = arm_jtag_scann(jtag_info, 0x1)) != ERROR_OK)
245 {
246 return retval;
247 }
248
249 arm_jtag_set_instr(jtag_info, jtag_info->intest_instr, NULL);
250
251 fields[0].tap = jtag_info->tap;
252 fields[0].num_bits = 32;
253 fields[0].out_value = NULL;
254 u8 tmp[4];
255 fields[0].in_value = tmp;
256
257 fields[1].tap = jtag_info->tap;
258 fields[1].num_bits = 3;
259 fields[1].out_value = NULL;
260 fields[1].in_value = NULL;
261
262 fields[2].tap = jtag_info->tap;
263 fields[2].num_bits = 32;
264 fields[2].out_value = NULL;
265 fields[2].in_value = NULL;
266
267 jtag_add_dr_scan_now(3, fields, TAP_INVALID);
268
269 *in=le_to_h_u32(tmp);
270
271 jtag_add_runtest(0, TAP_INVALID);
272
273 #ifdef _DEBUG_INSTRUCTION_EXECUTION_
274 {
275 if ((retval = jtag_execute_queue()) != ERROR_OK)
276 {
277 return retval;
278 }
279
280 if (in)
281 {
282 LOG_DEBUG("in: 0x%8.8x", *in);
283 }
284 else
285 {
286 LOG_ERROR("BUG: called with in == NULL");
287 }
288 }
289 #endif
290
291 return ERROR_OK;
292 }
293
294 extern void arm_endianness(u8 *tmp, void *in, int size, int be, int flip);
295
296 /* clock the target, and read the databus
297 * the *in pointer points to a buffer where elements of 'size' bytes
298 * are stored in big (be==1) or little (be==0) endianness
299 */
300 int arm9tdmi_clock_data_in_endianness(arm_jtag_t *jtag_info, void *in, int size, int be)
301 {
302 int retval = ERROR_OK;
303 scan_field_t fields[3];
304
305 jtag_add_end_state(TAP_DRPAUSE);
306 if ((retval = arm_jtag_scann(jtag_info, 0x1)) != ERROR_OK)
307 {
308 return retval;
309 }
310
311 arm_jtag_set_instr(jtag_info, jtag_info->intest_instr, NULL);
312
313 fields[0].tap = jtag_info->tap;
314 fields[0].num_bits = 32;
315 fields[0].out_value = NULL;
316 u8 tmp[4];
317 fields[0].in_value = tmp;
318
319 fields[1].tap = jtag_info->tap;
320 fields[1].num_bits = 3;
321 fields[1].out_value = NULL;
322 fields[1].in_value = NULL;
323
324 fields[2].tap = jtag_info->tap;
325 fields[2].num_bits = 32;
326 fields[2].out_value = NULL;
327 fields[2].in_value = NULL;
328
329 jtag_add_dr_scan_now(3, fields, TAP_INVALID);
330
331 arm_endianness(tmp, in, size, be, 0);
332
333
334 jtag_add_runtest(0, TAP_INVALID);
335
336 #ifdef _DEBUG_INSTRUCTION_EXECUTION_
337 {
338 if ((retval = jtag_execute_queue()) != ERROR_OK)
339 {
340 return retval;
341 }
342
343 if (in)
344 {
345 LOG_DEBUG("in: 0x%8.8x", *(u32*)in);
346 }
347 else
348 {
349 LOG_ERROR("BUG: called with in == NULL");
350 }
351 }
352 #endif
353
354 return ERROR_OK;
355 }
356
357 void arm9tdmi_change_to_arm(target_t *target, u32 *r0, u32 *pc)
358 {
359 int retval = ERROR_OK;
360 /* get pointers to arch-specific information */
361 armv4_5_common_t *armv4_5 = target->arch_info;
362 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
363 arm_jtag_t *jtag_info = &arm7_9->jtag_info;
364
365 /* save r0 before using it and put system in ARM state
366 * to allow common handling of ARM and THUMB debugging */
367
368 /* fetch STR r0, [r0] */
369 arm9tdmi_clock_out(jtag_info, ARMV4_5_T_STR(0, 0), 0, NULL, 0);
370 arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0);
371 arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0);
372 /* STR r0, [r0] in Memory */
373 arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, r0, 0);
374
375 /* MOV r0, r15 fetched, STR in Decode */
376 arm9tdmi_clock_out(jtag_info, ARMV4_5_T_MOV(0, 15), 0, NULL, 0);
377 arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0);
378 arm9tdmi_clock_out(jtag_info, ARMV4_5_T_STR(0, 0), 0, NULL, 0);
379 arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0);
380 arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0);
381 /* nothing fetched, STR r0, [r0] in Memory */
382 arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, pc, 0);
383
384 /* use pc-relative LDR to clear r0[1:0] (for switch to ARM mode) */
385 arm9tdmi_clock_out(jtag_info, ARMV4_5_T_LDR_PCREL(0), 0, NULL, 0);
386 /* LDR in Decode */
387 arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0);
388 /* LDR in Execute */
389 arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0);
390 /* LDR in Memory (to account for interlock) */
391 arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0);
392
393 /* fetch BX */
394 arm9tdmi_clock_out(jtag_info, ARMV4_5_T_BX(0), 0, NULL, 0);
395 /* NOP fetched, BX in Decode, MOV in Execute */
396 arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0);
397 /* NOP fetched, BX in Execute (1) */
398 arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0);
399
400 if ((retval = jtag_execute_queue()) != ERROR_OK)
401 {
402 return;
403 }
404
405 /* fix program counter:
406 * MOV r0, r15 was the 5th instruction (+8)
407 * reading PC in Thumb state gives address of instruction + 4
408 */
409 *pc -= 0xc;
410 }
411
412 void arm9tdmi_read_core_regs(target_t *target, u32 mask, u32* core_regs[16])
413 {
414 int i;
415 /* get pointers to arch-specific information */
416 armv4_5_common_t *armv4_5 = target->arch_info;
417 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
418 arm_jtag_t *jtag_info = &arm7_9->jtag_info;
419
420 /* STMIA r0-15, [r0] at debug speed
421 * register values will start to appear on 4th DCLK
422 */
423 arm9tdmi_clock_out(jtag_info, ARMV4_5_STMIA(0, mask & 0xffff, 0, 0), 0, NULL, 0);
424
425 /* fetch NOP, STM in DECODE stage */
426 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
427 /* fetch NOP, STM in EXECUTE stage (1st cycle) */
428 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
429
430 for (i = 0; i <= 15; i++)
431 {
432 if (mask & (1 << i))
433 /* nothing fetched, STM in MEMORY (i'th cycle) */
434 arm9tdmi_clock_data_in(jtag_info, core_regs[i]);
435 }
436 }
437
438 void arm9tdmi_read_core_regs_target_buffer(target_t *target, u32 mask, void* buffer, int size)
439 {
440 int i;
441 /* get pointers to arch-specific information */
442 armv4_5_common_t *armv4_5 = target->arch_info;
443 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
444 arm_jtag_t *jtag_info = &arm7_9->jtag_info;
445 int be = (target->endianness == TARGET_BIG_ENDIAN) ? 1 : 0;
446 u32 *buf_u32 = buffer;
447 u16 *buf_u16 = buffer;
448 u8 *buf_u8 = buffer;
449
450 /* STMIA r0-15, [r0] at debug speed
451 * register values will start to appear on 4th DCLK
452 */
453 arm9tdmi_clock_out(jtag_info, ARMV4_5_STMIA(0, mask & 0xffff, 0, 0), 0, NULL, 0);
454
455 /* fetch NOP, STM in DECODE stage */
456 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
457 /* fetch NOP, STM in EXECUTE stage (1st cycle) */
458 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
459
460 for (i = 0; i <= 15; i++)
461 {
462 if (mask & (1 << i))
463 /* nothing fetched, STM in MEMORY (i'th cycle) */
464 switch (size)
465 {
466 case 4:
467 arm9tdmi_clock_data_in_endianness(jtag_info, buf_u32++, 4, be);
468 break;
469 case 2:
470 arm9tdmi_clock_data_in_endianness(jtag_info, buf_u16++, 2, be);
471 break;
472 case 1:
473 arm9tdmi_clock_data_in_endianness(jtag_info, buf_u8++, 1, be);
474 break;
475 }
476 }
477 }
478
479 void arm9tdmi_read_xpsr(target_t *target, u32 *xpsr, int spsr)
480 {
481 /* get pointers to arch-specific information */
482 armv4_5_common_t *armv4_5 = target->arch_info;
483 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
484 arm_jtag_t *jtag_info = &arm7_9->jtag_info;
485
486 /* MRS r0, cpsr */
487 arm9tdmi_clock_out(jtag_info, ARMV4_5_MRS(0, spsr & 1), 0, NULL, 0);
488 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
489 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
490 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
491 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
492
493 /* STR r0, [r15] */
494 arm9tdmi_clock_out(jtag_info, ARMV4_5_STR(0, 15), 0, NULL, 0);
495 /* fetch NOP, STR in DECODE stage */
496 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
497 /* fetch NOP, STR in EXECUTE stage (1st cycle) */
498 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
499 /* nothing fetched, STR in MEMORY */
500 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, xpsr, 0);
501 }
502
503 void arm9tdmi_write_xpsr(target_t *target, u32 xpsr, int spsr)
504 {
505 /* get pointers to arch-specific information */
506 armv4_5_common_t *armv4_5 = target->arch_info;
507 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
508 arm_jtag_t *jtag_info = &arm7_9->jtag_info;
509
510 LOG_DEBUG("xpsr: %8.8x, spsr: %i", xpsr, spsr);
511
512 /* MSR1 fetched */
513 arm9tdmi_clock_out(jtag_info, ARMV4_5_MSR_IM(xpsr & 0xff, 0, 1, spsr), 0, NULL, 0);
514 /* MSR2 fetched, MSR1 in DECODE */
515 arm9tdmi_clock_out(jtag_info, ARMV4_5_MSR_IM((xpsr & 0xff00) >> 8, 0xc, 2, spsr), 0, NULL, 0);
516 /* MSR3 fetched, MSR1 in EXECUTE (1), MSR2 in DECODE */
517 arm9tdmi_clock_out(jtag_info, ARMV4_5_MSR_IM((xpsr & 0xff0000) >> 16, 0x8, 4, spsr), 0, NULL, 0);
518 /* nothing fetched, MSR1 in EXECUTE (2) */
519 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
520 /* nothing fetched, MSR1 in EXECUTE (3) */
521 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
522 /* MSR4 fetched, MSR2 in EXECUTE (1), MSR3 in DECODE */
523 arm9tdmi_clock_out(jtag_info, ARMV4_5_MSR_IM((xpsr & 0xff000000) >> 24, 0x4, 8, spsr), 0, NULL, 0);
524 /* nothing fetched, MSR2 in EXECUTE (2) */
525 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
526 /* nothing fetched, MSR2 in EXECUTE (3) */
527 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
528 /* NOP fetched, MSR3 in EXECUTE (1), MSR4 in DECODE */
529 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
530 /* nothing fetched, MSR3 in EXECUTE (2) */
531 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
532 /* nothing fetched, MSR3 in EXECUTE (3) */
533 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
534 /* NOP fetched, MSR4 in EXECUTE (1) */
535 /* last MSR writes flags, which takes only one cycle */
536 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
537 }
538
539 void arm9tdmi_write_xpsr_im8(target_t *target, u8 xpsr_im, int rot, int spsr)
540 {
541 /* get pointers to arch-specific information */
542 armv4_5_common_t *armv4_5 = target->arch_info;
543 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
544 arm_jtag_t *jtag_info = &arm7_9->jtag_info;
545
546 LOG_DEBUG("xpsr_im: %2.2x, rot: %i, spsr: %i", xpsr_im, rot, spsr);
547
548 /* MSR fetched */
549 arm9tdmi_clock_out(jtag_info, ARMV4_5_MSR_IM(xpsr_im, rot, 1, spsr), 0, NULL, 0);
550 /* NOP fetched, MSR in DECODE */
551 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
552 /* NOP fetched, MSR in EXECUTE (1) */
553 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
554
555 /* rot == 4 writes flags, which takes only one cycle */
556 if (rot != 4)
557 {
558 /* nothing fetched, MSR in EXECUTE (2) */
559 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
560 /* nothing fetched, MSR in EXECUTE (3) */
561 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
562 }
563 }
564
565 void arm9tdmi_write_core_regs(target_t *target, u32 mask, u32 core_regs[16])
566 {
567 int i;
568 /* get pointers to arch-specific information */
569 armv4_5_common_t *armv4_5 = target->arch_info;
570 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
571 arm_jtag_t *jtag_info = &arm7_9->jtag_info;
572
573 /* LDMIA r0-15, [r0] at debug speed
574 * register values will start to appear on 4th DCLK
575 */
576 arm9tdmi_clock_out(jtag_info, ARMV4_5_LDMIA(0, mask & 0xffff, 0, 0), 0, NULL, 0);
577
578 /* fetch NOP, LDM in DECODE stage */
579 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
580 /* fetch NOP, LDM in EXECUTE stage (1st cycle) */
581 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
582
583 for (i = 0; i <= 15; i++)
584 {
585 if (mask & (1 << i))
586 /* nothing fetched, LDM still in EXECUTE (1+i cycle) */
587 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, core_regs[i], NULL, 0);
588 }
589 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
590 }
591
592 void arm9tdmi_load_word_regs(target_t *target, u32 mask)
593 {
594 /* get pointers to arch-specific information */
595 armv4_5_common_t *armv4_5 = target->arch_info;
596 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
597 arm_jtag_t *jtag_info = &arm7_9->jtag_info;
598
599 /* put system-speed load-multiple into the pipeline */
600 arm9tdmi_clock_out(jtag_info, ARMV4_5_LDMIA(0, mask & 0xffff, 0, 1), 0, NULL, 0);
601 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 1);
602 }
603
604 void arm9tdmi_load_hword_reg(target_t *target, int num)
605 {
606 /* get pointers to arch-specific information */
607 armv4_5_common_t *armv4_5 = target->arch_info;
608 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
609 arm_jtag_t *jtag_info = &arm7_9->jtag_info;
610
611 /* put system-speed load half-word into the pipeline */
612 arm9tdmi_clock_out(jtag_info, ARMV4_5_LDRH_IP(num, 0), 0, NULL, 0);
613 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 1);
614 }
615
616 void arm9tdmi_load_byte_reg(target_t *target, int num)
617 {
618 /* get pointers to arch-specific information */
619 armv4_5_common_t *armv4_5 = target->arch_info;
620 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
621 arm_jtag_t *jtag_info = &arm7_9->jtag_info;
622
623 /* put system-speed load byte into the pipeline */
624 arm9tdmi_clock_out(jtag_info, ARMV4_5_LDRB_IP(num, 0), 0, NULL, 0);
625 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 1);
626 }
627
628 void arm9tdmi_store_word_regs(target_t *target, u32 mask)
629 {
630 /* get pointers to arch-specific information */
631 armv4_5_common_t *armv4_5 = target->arch_info;
632 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
633 arm_jtag_t *jtag_info = &arm7_9->jtag_info;
634
635 /* put system-speed store-multiple into the pipeline */
636 arm9tdmi_clock_out(jtag_info, ARMV4_5_STMIA(0, mask, 0, 1), 0, NULL, 0);
637 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 1);
638 }
639
640 void arm9tdmi_store_hword_reg(target_t *target, int num)
641 {
642 /* get pointers to arch-specific information */
643 armv4_5_common_t *armv4_5 = target->arch_info;
644 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
645 arm_jtag_t *jtag_info = &arm7_9->jtag_info;
646
647 /* put system-speed store half-word into the pipeline */
648 arm9tdmi_clock_out(jtag_info, ARMV4_5_STRH_IP(num, 0), 0, NULL, 0);
649 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 1);
650 }
651
652 void arm9tdmi_store_byte_reg(target_t *target, int num)
653 {
654 /* get pointers to arch-specific information */
655 armv4_5_common_t *armv4_5 = target->arch_info;
656 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
657 arm_jtag_t *jtag_info = &arm7_9->jtag_info;
658
659 /* put system-speed store byte into the pipeline */
660 arm9tdmi_clock_out(jtag_info, ARMV4_5_STRB_IP(num, 0), 0, NULL, 0);
661 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 1);
662 }
663
664 void arm9tdmi_write_pc(target_t *target, u32 pc)
665 {
666 /* get pointers to arch-specific information */
667 armv4_5_common_t *armv4_5 = target->arch_info;
668 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
669 arm_jtag_t *jtag_info = &arm7_9->jtag_info;
670
671 /* LDMIA r0-15, [r0] at debug speed
672 * register values will start to appear on 4th DCLK
673 */
674 arm9tdmi_clock_out(jtag_info, ARMV4_5_LDMIA(0, 0x8000, 0, 0), 0, NULL, 0);
675
676 /* fetch NOP, LDM in DECODE stage */
677 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
678 /* fetch NOP, LDM in EXECUTE stage (1st cycle) */
679 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
680 /* nothing fetched, LDM in EXECUTE stage (2nd cycle) (output data) */
681 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, pc, NULL, 0);
682 /* nothing fetched, LDM in EXECUTE stage (3rd cycle) */
683 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
684 /* fetch NOP, LDM in EXECUTE stage (4th cycle) */
685 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
686 /* fetch NOP, LDM in EXECUTE stage (5th cycle) */
687 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
688 }
689
690 void arm9tdmi_branch_resume(target_t *target)
691 {
692 /* get pointers to arch-specific information */
693 armv4_5_common_t *armv4_5 = target->arch_info;
694 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
695 arm_jtag_t *jtag_info = &arm7_9->jtag_info;
696
697 arm9tdmi_clock_out(jtag_info, ARMV4_5_B(0xfffffc, 0), 0, NULL, 0);
698 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 1);
699 }
700
701 void arm9tdmi_branch_resume_thumb(target_t *target)
702 {
703 LOG_DEBUG("-");
704
705 /* get pointers to arch-specific information */
706 armv4_5_common_t *armv4_5 = target->arch_info;
707 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
708 arm_jtag_t *jtag_info = &arm7_9->jtag_info;
709 reg_t *dbg_stat = &arm7_9->eice_cache->reg_list[EICE_DBG_STAT];
710
711 /* LDMIA r0-15, [r0] at debug speed
712 * register values will start to appear on 4th DCLK
713 */
714 arm9tdmi_clock_out(jtag_info, ARMV4_5_LDMIA(0, 0x1, 0, 0), 0, NULL, 0);
715
716 /* fetch NOP, LDM in DECODE stage */
717 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
718 /* fetch NOP, LDM in EXECUTE stage (1st cycle) */
719 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
720 /* nothing fetched, LDM in EXECUTE stage (2nd cycle) */
721 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32) | 1, NULL, 0);
722 /* nothing fetched, LDM in EXECUTE stage (3rd cycle) */
723 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
724
725 /* Branch and eXchange */
726 arm9tdmi_clock_out(jtag_info, ARMV4_5_BX(0), 0, NULL, 0);
727
728 embeddedice_read_reg(dbg_stat);
729
730 /* fetch NOP, BX in DECODE stage */
731 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
732
733 embeddedice_read_reg(dbg_stat);
734
735 /* fetch NOP, BX in EXECUTE stage (1st cycle) */
736 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
737
738 /* target is now in Thumb state */
739 embeddedice_read_reg(dbg_stat);
740
741 /* load r0 value, MOV_IM in Decode*/
742 arm9tdmi_clock_out(jtag_info, ARMV4_5_T_LDR_PCREL(0), 0, NULL, 0);
743 /* fetch NOP, LDR in Decode, MOV_IM in Execute */
744 arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0);
745 /* fetch NOP, LDR in Execute */
746 arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0);
747 /* nothing fetched, LDR in EXECUTE stage (2nd cycle) */
748 arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, buf_get_u32(armv4_5->core_cache->reg_list[0].value, 0, 32), NULL, 0);
749 /* nothing fetched, LDR in EXECUTE stage (3rd cycle) */
750 arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0);
751
752 arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0);
753 arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0);
754
755 embeddedice_read_reg(dbg_stat);
756
757 arm9tdmi_clock_out(jtag_info, ARMV4_5_T_B(0x7f7), 0, NULL, 1);
758 arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0);
759 }
760
761 void arm9tdmi_enable_single_step(target_t *target, u32 next_pc)
762 {
763 /* get pointers to arch-specific information */
764 armv4_5_common_t *armv4_5 = target->arch_info;
765 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
766
767 if (arm7_9->has_single_step)
768 {
769 buf_set_u32(arm7_9->eice_cache->reg_list[EICE_DBG_CTRL].value, 3, 1, 1);
770 embeddedice_store_reg(&arm7_9->eice_cache->reg_list[EICE_DBG_CTRL]);
771 }
772 else
773 {
774 arm7_9_enable_eice_step(target, next_pc);
775 }
776 }
777
778 void arm9tdmi_disable_single_step(target_t *target)
779 {
780 /* get pointers to arch-specific information */
781 armv4_5_common_t *armv4_5 = target->arch_info;
782 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
783
784 if (arm7_9->has_single_step)
785 {
786 buf_set_u32(arm7_9->eice_cache->reg_list[EICE_DBG_CTRL].value, 3, 1, 0);
787 embeddedice_store_reg(&arm7_9->eice_cache->reg_list[EICE_DBG_CTRL]);
788 }
789 else
790 {
791 arm7_9_disable_eice_step(target);
792 }
793 }
794
795 void arm9tdmi_build_reg_cache(target_t *target)
796 {
797 reg_cache_t **cache_p = register_get_last_cache_p(&target->reg_cache);
798 /* get pointers to arch-specific information */
799 armv4_5_common_t *armv4_5 = target->arch_info;
800
801 (*cache_p) = armv4_5_build_reg_cache(target, armv4_5);
802 armv4_5->core_cache = (*cache_p);
803 }
804
805 int arm9tdmi_examine(struct target_s *target)
806 {
807 /* get pointers to arch-specific information */
808 int retval;
809 armv4_5_common_t *armv4_5 = target->arch_info;
810 arm7_9_common_t *arm7_9 = armv4_5->arch_info;
811 if (!target->type->examined)
812 {
813 reg_cache_t **cache_p = register_get_last_cache_p(&target->reg_cache);
814 reg_cache_t *t;
815 /* one extra register (vector catch) */
816 t=embeddedice_build_reg_cache(target, arm7_9);
817 if (t==NULL)
818 return ERROR_FAIL;
819 (*cache_p) = t;
820 arm7_9->eice_cache = (*cache_p);
821
822 if (arm7_9->etm_ctx)
823 {
824 arm_jtag_t *jtag_info = &arm7_9->jtag_info;
825 (*cache_p)->next = etm_build_reg_cache(target, jtag_info, arm7_9->etm_ctx);
826 arm7_9->etm_ctx->reg_cache = (*cache_p)->next;
827 }
828 target->type->examined = 1;
829 }
830 if ((retval=embeddedice_setup(target))!=ERROR_OK)
831 return retval;
832 if ((retval=arm7_9_setup(target))!=ERROR_OK)
833 return retval;
834 if (arm7_9->etm_ctx)
835 {
836 if ((retval=etm_setup(target))!=ERROR_OK)
837 return retval;
838 }
839 return ERROR_OK;
840 }
841
842 int arm9tdmi_init_target(struct command_context_s *cmd_ctx, struct target_s *target)
843 {
844
845 arm9tdmi_build_reg_cache(target);
846
847 return ERROR_OK;
848 }
849
850 int arm9tdmi_quit(void)
851 {
852 return ERROR_OK;
853 }
854
855 int arm9tdmi_init_arch_info(target_t *target, arm9tdmi_common_t *arm9tdmi, jtag_tap_t *tap)
856 {
857 armv4_5_common_t *armv4_5;
858 arm7_9_common_t *arm7_9;
859
860 arm7_9 = &arm9tdmi->arm7_9_common;
861 armv4_5 = &arm7_9->armv4_5_common;
862
863 /* prepare JTAG information for the new target */
864 arm7_9->jtag_info.tap = tap;
865 arm7_9->jtag_info.scann_size = 5;
866
867 /* register arch-specific functions */
868 arm7_9->examine_debug_reason = arm9tdmi_examine_debug_reason;
869 arm7_9->change_to_arm = arm9tdmi_change_to_arm;
870 arm7_9->read_core_regs = arm9tdmi_read_core_regs;
871 arm7_9->read_core_regs_target_buffer = arm9tdmi_read_core_regs_target_buffer;
872 arm7_9->read_xpsr = arm9tdmi_read_xpsr;
873
874 arm7_9->write_xpsr = arm9tdmi_write_xpsr;
875 arm7_9->write_xpsr_im8 = arm9tdmi_write_xpsr_im8;
876 arm7_9->write_core_regs = arm9tdmi_write_core_regs;
877
878 arm7_9->load_word_regs = arm9tdmi_load_word_regs;
879 arm7_9->load_hword_reg = arm9tdmi_load_hword_reg;
880 arm7_9->load_byte_reg = arm9tdmi_load_byte_reg;
881
882 arm7_9->store_word_regs = arm9tdmi_store_word_regs;
883 arm7_9->store_hword_reg = arm9tdmi_store_hword_reg;
884 arm7_9->store_byte_reg = arm9tdmi_store_byte_reg;
885
886 arm7_9->write_pc = arm9tdmi_write_pc;
887 arm7_9->branch_resume = arm9tdmi_branch_resume;
888 arm7_9->branch_resume_thumb = arm9tdmi_branch_resume_thumb;
889
890 arm7_9->enable_single_step = arm9tdmi_enable_single_step;
891 arm7_9->disable_single_step = arm9tdmi_disable_single_step;
892
893 arm7_9->pre_debug_entry = NULL;
894 arm7_9->post_debug_entry = NULL;
895
896 arm7_9->pre_restore_context = NULL;
897 arm7_9->post_restore_context = NULL;
898
899 /* initialize arch-specific breakpoint handling */
900 arm7_9->arm_bkpt = 0xdeeedeee;
901 arm7_9->thumb_bkpt = 0xdeee;
902
903 arm7_9->dbgreq_adjust_pc = 3;
904 arm7_9->arch_info = arm9tdmi;
905
906 arm9tdmi->common_magic = ARM9TDMI_COMMON_MAGIC;
907 arm9tdmi->arch_info = NULL;
908
909 arm7_9_init_arch_info(target, arm7_9);
910
911 /* override use of DBGRQ, this is safe on ARM9TDMI */
912 arm7_9->use_dbgrq = 1;
913
914 /* all ARM9s have the vector catch register */
915 arm7_9->has_vector_catch = 1;
916
917 return ERROR_OK;
918 }
919
920 int arm9tdmi_get_arch_pointers(target_t *target, armv4_5_common_t **armv4_5_p, arm7_9_common_t **arm7_9_p, arm9tdmi_common_t **arm9tdmi_p)
921 {
922 armv4_5_common_t *armv4_5 = target->arch_info;
923 arm7_9_common_t *arm7_9;
924 arm9tdmi_common_t *arm9tdmi;
925
926 if (armv4_5->common_magic != ARMV4_5_COMMON_MAGIC)
927 {
928 return -1;
929 }
930
931 arm7_9 = armv4_5->arch_info;
932 if (arm7_9->common_magic != ARM7_9_COMMON_MAGIC)
933 {
934 return -1;
935 }
936
937 arm9tdmi = arm7_9->arch_info;
938 if (arm9tdmi->common_magic != ARM9TDMI_COMMON_MAGIC)
939 {
940 return -1;
941 }
942
943 *armv4_5_p = armv4_5;
944 *arm7_9_p = arm7_9;
945 *arm9tdmi_p = arm9tdmi;
946
947 return ERROR_OK;
948 }
949
950 int arm9tdmi_target_create(struct target_s *target, Jim_Interp *interp)
951 {
952 arm9tdmi_common_t *arm9tdmi = calloc(1,sizeof(arm9tdmi_common_t));
953
954 arm9tdmi_init_arch_info(target, arm9tdmi, target->tap);
955
956 return ERROR_OK;
957 }
958
959 int arm9tdmi_register_commands(struct command_context_s *cmd_ctx)
960 {
961 int retval;
962 command_t *arm9tdmi_cmd;
963
964 retval = arm7_9_register_commands(cmd_ctx);
965 arm9tdmi_cmd = register_command(cmd_ctx, NULL, "arm9tdmi", NULL, COMMAND_ANY, "arm9tdmi specific commands");
966 register_command(cmd_ctx, arm9tdmi_cmd, "vector_catch", handle_arm9tdmi_catch_vectors_command, COMMAND_EXEC, "catch arm920t vectors ['all'|'none'|'<vec1 vec2 ...>']");
967
968 return retval;
969 }
970
971 int handle_arm9tdmi_catch_vectors_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
972 {
973 target_t *target = get_current_target(cmd_ctx);
974 armv4_5_common_t *armv4_5;
975 arm7_9_common_t *arm7_9;
976 arm9tdmi_common_t *arm9tdmi;
977 reg_t *vector_catch;
978 u32 vector_catch_value;
979 int i, j;
980
981 if (arm9tdmi_get_arch_pointers(target, &armv4_5, &arm7_9, &arm9tdmi) != ERROR_OK)
982 {
983 command_print(cmd_ctx, "current target isn't an ARM9TDMI based target");
984 return ERROR_OK;
985 }
986
987 vector_catch = &arm7_9->eice_cache->reg_list[EICE_VEC_CATCH];
988
989 /* read the vector catch register if necessary */
990 if (!vector_catch->valid)
991 embeddedice_read_reg(vector_catch);
992
993 /* get the current setting */
994 vector_catch_value = buf_get_u32(vector_catch->value, 0, 32);
995
996 if (argc > 0)
997 {
998 vector_catch_value = 0x0;
999 if (strcmp(args[0], "all") == 0)
1000 {
1001 vector_catch_value = 0xdf;
1002 }
1003 else if (strcmp(args[0], "none") == 0)
1004 {
1005 /* do nothing */
1006 }
1007 else
1008 {
1009 for (i = 0; i < argc; i++)
1010 {
1011 /* go through list of vectors */
1012 for (j = 0; arm9tdmi_vectors[j].name; j++)
1013 {
1014 if (strcmp(args[i], arm9tdmi_vectors[j].name) == 0)
1015 {
1016 vector_catch_value |= arm9tdmi_vectors[j].value;
1017 break;
1018 }
1019 }
1020
1021 /* complain if vector wasn't found */
1022 if (!arm9tdmi_vectors[j].name)
1023 {
1024 command_print(cmd_ctx, "vector '%s' not found, leaving current setting unchanged", args[i]);
1025
1026 /* reread current setting */
1027 vector_catch_value = buf_get_u32(vector_catch->value, 0, 32);
1028
1029 break;
1030 }
1031 }
1032 }
1033
1034 /* store new settings */
1035 buf_set_u32(vector_catch->value, 0, 32, vector_catch_value);
1036 embeddedice_store_reg(vector_catch);
1037 }
1038
1039 /* output current settings (skip RESERVED vector) */
1040 for (i = 0; i < 8; i++)
1041 {
1042 if (i != 5)
1043 {
1044 command_print(cmd_ctx, "%s: %s", arm9tdmi_vectors[i].name,
1045 (vector_catch_value & (1 << i)) ? "catch" : "don't catch");
1046 }
1047 }
1048
1049 return ERROR_OK;
1050 }

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)