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

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)