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

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)