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

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)