3f074be86bee15d45cd272cbe23ffa2c27b452dd
[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
34
35 /*
36 * NOTE: this holds code that's used with multiple ARM9 processors:
37 * - ARM9TDMI (ARMv4T) ... in ARM920, ARM922, and ARM940 cores
38 * - ARM9E-S (ARMv5TE) ... in ARM946, ARM966, and ARM968 cores
39 * - ARM9EJS (ARMv5TEJ) ... in ARM926 core
40 *
41 * In short, the file name is a misnomer ... it is NOT specific to
42 * that first generation ARM9 processor, or cores using it.
43 */
44
45 #if 0
46 #define _DEBUG_INSTRUCTION_EXECUTION_
47 #endif
48
49 enum arm9tdmi_vector_bit
50 {
51 ARM9TDMI_RESET_VECTOR = 0x01,
52 ARM9TDMI_UNDEF_VECTOR = 0x02,
53 ARM9TDMI_SWI_VECTOR = 0x04,
54 ARM9TDMI_PABT_VECTOR = 0x08,
55 ARM9TDMI_DABT_VECTOR = 0x10,
56 /* BIT(5) reserved -- must be zero */
57 ARM9TDMI_IRQ_VECTOR = 0x40,
58 ARM9TDMI_FIQ_VECTOR = 0x80,
59 };
60
61 static const struct arm9tdmi_vector {
62 char *name;
63 uint32_t value;
64 } arm9tdmi_vectors[] = {
65 {"reset", ARM9TDMI_RESET_VECTOR},
66 {"undef", ARM9TDMI_UNDEF_VECTOR},
67 {"swi", ARM9TDMI_SWI_VECTOR},
68 {"pabt", ARM9TDMI_PABT_VECTOR},
69 {"dabt", ARM9TDMI_DABT_VECTOR},
70 {"irq", ARM9TDMI_IRQ_VECTOR},
71 {"fiq", ARM9TDMI_FIQ_VECTOR},
72 {0, 0},
73 };
74
75 int arm9tdmi_examine_debug_reason(struct target *target)
76 {
77 int retval = ERROR_OK;
78 struct arm7_9_common *arm7_9 = target_to_arm7_9(target);
79
80 /* only check the debug reason if we don't know it already */
81 if ((target->debug_reason != DBG_REASON_DBGRQ)
82 && (target->debug_reason != DBG_REASON_SINGLESTEP))
83 {
84 struct scan_field fields[3];
85 uint8_t databus[4];
86 uint8_t instructionbus[4];
87 uint8_t debug_reason;
88
89 jtag_set_end_state(TAP_DRPAUSE);
90
91 fields[0].tap = arm7_9->jtag_info.tap;
92 fields[0].num_bits = 32;
93 fields[0].out_value = NULL;
94 fields[0].in_value = databus;
95
96 fields[1].tap = arm7_9->jtag_info.tap;
97 fields[1].num_bits = 3;
98 fields[1].out_value = NULL;
99 fields[1].in_value = &debug_reason;
100
101 fields[2].tap = arm7_9->jtag_info.tap;
102 fields[2].num_bits = 32;
103 fields[2].out_value = NULL;
104 fields[2].in_value = instructionbus;
105
106 if ((retval = arm_jtag_scann(&arm7_9->jtag_info, 0x1)) != ERROR_OK)
107 {
108 return retval;
109 }
110 arm_jtag_set_instr(&arm7_9->jtag_info, arm7_9->jtag_info.intest_instr, NULL);
111
112 jtag_add_dr_scan(3, fields, jtag_set_end_state(TAP_DRPAUSE));
113 if ((retval = jtag_execute_queue()) != ERROR_OK)
114 {
115 return retval;
116 }
117
118 fields[0].in_value = NULL;
119 fields[0].out_value = databus;
120 fields[1].in_value = NULL;
121 fields[1].out_value = &debug_reason;
122 fields[2].in_value = NULL;
123 fields[2].out_value = instructionbus;
124
125 jtag_add_dr_scan(3, fields, jtag_set_end_state(TAP_DRPAUSE));
126
127 if (debug_reason & 0x4)
128 if (debug_reason & 0x2)
129 target->debug_reason = DBG_REASON_WPTANDBKPT;
130 else
131 target->debug_reason = DBG_REASON_WATCHPOINT;
132 else
133 target->debug_reason = DBG_REASON_BREAKPOINT;
134 }
135
136 return ERROR_OK;
137 }
138
139 /* put an instruction in the ARM9TDMI pipeline or write the data bus,
140 * and optionally read data
141 */
142 int arm9tdmi_clock_out(struct arm_jtag *jtag_info, uint32_t instr,
143 uint32_t out, uint32_t *in, int sysspeed)
144 {
145 int retval = ERROR_OK;
146 struct scan_field fields[3];
147 uint8_t out_buf[4];
148 uint8_t instr_buf[4];
149 uint8_t sysspeed_buf = 0x0;
150
151 /* prepare buffer */
152 buf_set_u32(out_buf, 0, 32, out);
153
154 buf_set_u32(instr_buf, 0, 32, flip_u32(instr, 32));
155
156 if (sysspeed)
157 buf_set_u32(&sysspeed_buf, 2, 1, 1);
158
159 jtag_set_end_state(TAP_DRPAUSE);
160 if ((retval = arm_jtag_scann(jtag_info, 0x1)) != ERROR_OK)
161 {
162 return retval;
163 }
164
165 arm_jtag_set_instr(jtag_info, jtag_info->intest_instr, NULL);
166
167 fields[0].tap = jtag_info->tap;
168 fields[0].num_bits = 32;
169 fields[0].out_value = out_buf;
170 fields[0].in_value = NULL;
171
172 fields[1].tap = jtag_info->tap;
173 fields[1].num_bits = 3;
174 fields[1].out_value = &sysspeed_buf;
175 fields[1].in_value = NULL;
176
177 fields[2].tap = jtag_info->tap;
178 fields[2].num_bits = 32;
179 fields[2].out_value = instr_buf;
180 fields[2].in_value = NULL;
181
182 if (in)
183 {
184 fields[0].in_value = (uint8_t *)in;
185 jtag_add_dr_scan(3, fields, jtag_get_end_state());
186
187 jtag_add_callback(arm_le_to_h_u32, (jtag_callback_data_t)in);
188 }
189 else
190 {
191 jtag_add_dr_scan(3, fields, jtag_get_end_state());
192 }
193
194 jtag_add_runtest(0, jtag_get_end_state());
195
196 #ifdef _DEBUG_INSTRUCTION_EXECUTION_
197 {
198 if ((retval = jtag_execute_queue()) != ERROR_OK)
199 {
200 return retval;
201 }
202
203 if (in)
204 {
205 LOG_DEBUG("instr: 0x%8.8x, out: 0x%8.8x, in: 0x%8.8x", instr, out, *in);
206 }
207 else
208 LOG_DEBUG("instr: 0x%8.8x, out: 0x%8.8x", instr, out);
209 }
210 #endif
211
212 return ERROR_OK;
213 }
214
215 /* just read data (instruction and data-out = don't care) */
216 int arm9tdmi_clock_data_in(struct arm_jtag *jtag_info, uint32_t *in)
217 {
218 int retval = ERROR_OK;;
219 struct scan_field fields[3];
220
221 jtag_set_end_state(TAP_DRPAUSE);
222 if ((retval = arm_jtag_scann(jtag_info, 0x1)) != ERROR_OK)
223 {
224 return retval;
225 }
226
227 arm_jtag_set_instr(jtag_info, jtag_info->intest_instr, NULL);
228
229 fields[0].tap = jtag_info->tap;
230 fields[0].num_bits = 32;
231 fields[0].out_value = NULL;
232 fields[0].in_value = (uint8_t *)in;
233
234 fields[1].tap = jtag_info->tap;
235 fields[1].num_bits = 3;
236 fields[1].out_value = NULL;
237 fields[1].in_value = NULL;
238
239 fields[2].tap = jtag_info->tap;
240 fields[2].num_bits = 32;
241 fields[2].out_value = NULL;
242 fields[2].in_value = NULL;
243
244 jtag_add_dr_scan(3, fields, jtag_get_end_state());
245
246 jtag_add_callback(arm_le_to_h_u32, (jtag_callback_data_t)in);
247
248 jtag_add_runtest(0, jtag_get_end_state());
249
250 #ifdef _DEBUG_INSTRUCTION_EXECUTION_
251 {
252 if ((retval = jtag_execute_queue()) != ERROR_OK)
253 {
254 return retval;
255 }
256
257 if (in)
258 {
259 LOG_DEBUG("in: 0x%8.8x", *in);
260 }
261 else
262 {
263 LOG_ERROR("BUG: called with in == NULL");
264 }
265 }
266 #endif
267
268 return ERROR_OK;
269 }
270
271 extern void arm_endianness(uint8_t *tmp, void *in, int size, int be, int flip);
272
273 static int arm9endianness(jtag_callback_data_t arg,
274 jtag_callback_data_t size, jtag_callback_data_t be,
275 jtag_callback_data_t captured)
276 {
277 uint8_t *in = (uint8_t *)arg;
278
279 arm_endianness((uint8_t *)captured, in, (int)size, (int)be, 0);
280 return ERROR_OK;
281 }
282
283 /* clock the target, and read the databus
284 * the *in pointer points to a buffer where elements of 'size' bytes
285 * are stored in big (be == 1) or little (be == 0) endianness
286 */
287 int arm9tdmi_clock_data_in_endianness(struct arm_jtag *jtag_info,
288 void *in, int size, int be)
289 {
290 int retval = ERROR_OK;
291 struct scan_field fields[3];
292
293 jtag_set_end_state(TAP_DRPAUSE);
294 if ((retval = arm_jtag_scann(jtag_info, 0x1)) != ERROR_OK)
295 {
296 return retval;
297 }
298
299 arm_jtag_set_instr(jtag_info, jtag_info->intest_instr, NULL);
300
301 fields[0].tap = jtag_info->tap;
302 fields[0].num_bits = 32;
303 fields[0].out_value = NULL;
304 jtag_alloc_in_value32(&fields[0]);
305
306 fields[1].tap = jtag_info->tap;
307 fields[1].num_bits = 3;
308 fields[1].out_value = NULL;
309 fields[1].in_value = NULL;
310
311 fields[2].tap = jtag_info->tap;
312 fields[2].num_bits = 32;
313 fields[2].out_value = NULL;
314 fields[2].in_value = NULL;
315
316 jtag_add_dr_scan(3, fields, jtag_get_end_state());
317
318 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);
319
320 jtag_add_runtest(0, jtag_get_end_state());
321
322 #ifdef _DEBUG_INSTRUCTION_EXECUTION_
323 {
324 if ((retval = jtag_execute_queue()) != ERROR_OK)
325 {
326 return retval;
327 }
328
329 if (in)
330 {
331 LOG_DEBUG("in: 0x%8.8x", *(uint32_t*)in);
332 }
333 else
334 {
335 LOG_ERROR("BUG: called with in == NULL");
336 }
337 }
338 #endif
339
340 return ERROR_OK;
341 }
342
343 static void arm9tdmi_change_to_arm(struct target *target,
344 uint32_t *r0, uint32_t *pc)
345 {
346 int retval = ERROR_OK;
347 struct arm7_9_common *arm7_9 = target_to_arm7_9(target);
348 struct arm_jtag *jtag_info = &arm7_9->jtag_info;
349
350 /* save r0 before using it and put system in ARM state
351 * to allow common handling of ARM and THUMB debugging */
352
353 /* fetch STR r0, [r0] */
354 arm9tdmi_clock_out(jtag_info, ARMV4_5_T_STR(0, 0), 0, NULL, 0);
355 arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0);
356 arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0);
357 /* STR r0, [r0] in Memory */
358 arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, r0, 0);
359
360 /* MOV r0, r15 fetched, STR in Decode */
361 arm9tdmi_clock_out(jtag_info, ARMV4_5_T_MOV(0, 15), 0, NULL, 0);
362 arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0);
363 arm9tdmi_clock_out(jtag_info, ARMV4_5_T_STR(0, 0), 0, NULL, 0);
364 arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0);
365 arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0);
366 /* nothing fetched, STR r0, [r0] in Memory */
367 arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, pc, 0);
368
369 /* use pc-relative LDR to clear r0[1:0] (for switch to ARM mode) */
370 arm9tdmi_clock_out(jtag_info, ARMV4_5_T_LDR_PCREL(0), 0, NULL, 0);
371 /* LDR in Decode */
372 arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0);
373 /* LDR in Execute */
374 arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0);
375 /* LDR in Memory (to account for interlock) */
376 arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0);
377
378 /* fetch BX */
379 arm9tdmi_clock_out(jtag_info, ARMV4_5_T_BX(0), 0, NULL, 0);
380 /* NOP fetched, BX in Decode, MOV in Execute */
381 arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0);
382 /* NOP fetched, BX in Execute (1) */
383 arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0);
384
385 if ((retval = jtag_execute_queue()) != ERROR_OK)
386 {
387 return;
388 }
389
390 /* fix program counter:
391 * MOV r0, r15 was the 5th instruction (+8)
392 * reading PC in Thumb state gives address of instruction + 4
393 */
394 *pc -= 0xc;
395 }
396
397 void arm9tdmi_read_core_regs(struct target *target,
398 uint32_t mask, uint32_t* core_regs[16])
399 {
400 int i;
401 struct arm7_9_common *arm7_9 = target_to_arm7_9(target);
402 struct arm_jtag *jtag_info = &arm7_9->jtag_info;
403
404 /* STMIA r0-15, [r0] at debug speed
405 * register values will start to appear on 4th DCLK
406 */
407 arm9tdmi_clock_out(jtag_info, ARMV4_5_STMIA(0, mask & 0xffff, 0, 0), 0, NULL, 0);
408
409 /* fetch NOP, STM in DECODE stage */
410 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
411 /* fetch NOP, STM in EXECUTE stage (1st cycle) */
412 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
413
414 for (i = 0; i <= 15; i++)
415 {
416 if (mask & (1 << i))
417 /* nothing fetched, STM in MEMORY (i'th cycle) */
418 arm9tdmi_clock_data_in(jtag_info, core_regs[i]);
419 }
420 }
421
422 static void arm9tdmi_read_core_regs_target_buffer(struct target *target,
423 uint32_t mask, void* buffer, int size)
424 {
425 int i;
426 struct arm7_9_common *arm7_9 = target_to_arm7_9(target);
427 struct arm_jtag *jtag_info = &arm7_9->jtag_info;
428 int be = (target->endianness == TARGET_BIG_ENDIAN) ? 1 : 0;
429 uint32_t *buf_u32 = buffer;
430 uint16_t *buf_u16 = buffer;
431 uint8_t *buf_u8 = buffer;
432
433 /* STMIA r0-15, [r0] at debug speed
434 * register values will start to appear on 4th DCLK
435 */
436 arm9tdmi_clock_out(jtag_info, ARMV4_5_STMIA(0, mask & 0xffff, 0, 0), 0, NULL, 0);
437
438 /* fetch NOP, STM in DECODE stage */
439 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
440 /* fetch NOP, STM in EXECUTE stage (1st cycle) */
441 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
442
443 for (i = 0; i <= 15; i++)
444 {
445 if (mask & (1 << i))
446 /* nothing fetched, STM in MEMORY (i'th cycle) */
447 switch (size)
448 {
449 case 4:
450 arm9tdmi_clock_data_in_endianness(jtag_info, buf_u32++, 4, be);
451 break;
452 case 2:
453 arm9tdmi_clock_data_in_endianness(jtag_info, buf_u16++, 2, be);
454 break;
455 case 1:
456 arm9tdmi_clock_data_in_endianness(jtag_info, buf_u8++, 1, be);
457 break;
458 }
459 }
460 }
461
462 static void arm9tdmi_read_xpsr(struct target *target, uint32_t *xpsr, int spsr)
463 {
464 struct arm7_9_common *arm7_9 = target_to_arm7_9(target);
465 struct arm_jtag *jtag_info = &arm7_9->jtag_info;
466
467 /* MRS r0, cpsr */
468 arm9tdmi_clock_out(jtag_info, ARMV4_5_MRS(0, spsr & 1), 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 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
473
474 /* STR r0, [r15] */
475 arm9tdmi_clock_out(jtag_info, ARMV4_5_STR(0, 15), 0, NULL, 0);
476 /* fetch NOP, STR in DECODE stage */
477 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
478 /* fetch NOP, STR in EXECUTE stage (1st cycle) */
479 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
480 /* nothing fetched, STR in MEMORY */
481 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, xpsr, 0);
482 }
483
484 static void arm9tdmi_write_xpsr(struct target *target, uint32_t xpsr, int spsr)
485 {
486 struct arm7_9_common *arm7_9 = target_to_arm7_9(target);
487 struct arm_jtag *jtag_info = &arm7_9->jtag_info;
488
489 LOG_DEBUG("xpsr: %8.8" PRIx32 ", spsr: %i", xpsr, spsr);
490
491 /* MSR1 fetched */
492 arm9tdmi_clock_out(jtag_info, ARMV4_5_MSR_IM(xpsr & 0xff, 0, 1, spsr), 0, NULL, 0);
493 /* MSR2 fetched, MSR1 in DECODE */
494 arm9tdmi_clock_out(jtag_info, ARMV4_5_MSR_IM((xpsr & 0xff00) >> 8, 0xc, 2, spsr), 0, NULL, 0);
495 /* MSR3 fetched, MSR1 in EXECUTE (1), MSR2 in DECODE */
496 arm9tdmi_clock_out(jtag_info, ARMV4_5_MSR_IM((xpsr & 0xff0000) >> 16, 0x8, 4, spsr), 0, NULL, 0);
497 /* nothing fetched, MSR1 in EXECUTE (2) */
498 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
499 /* nothing fetched, MSR1 in EXECUTE (3) */
500 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
501 /* MSR4 fetched, MSR2 in EXECUTE (1), MSR3 in DECODE */
502 arm9tdmi_clock_out(jtag_info, ARMV4_5_MSR_IM((xpsr & 0xff000000) >> 24, 0x4, 8, spsr), 0, NULL, 0);
503 /* nothing fetched, MSR2 in EXECUTE (2) */
504 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
505 /* nothing fetched, MSR2 in EXECUTE (3) */
506 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
507 /* NOP fetched, MSR3 in EXECUTE (1), MSR4 in DECODE */
508 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
509 /* nothing fetched, MSR3 in EXECUTE (2) */
510 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
511 /* nothing fetched, MSR3 in EXECUTE (3) */
512 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
513 /* NOP fetched, MSR4 in EXECUTE (1) */
514 /* last MSR writes flags, which takes only one cycle */
515 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
516 }
517
518 static void arm9tdmi_write_xpsr_im8(struct target *target,
519 uint8_t xpsr_im, int rot, int spsr)
520 {
521 struct arm7_9_common *arm7_9 = target_to_arm7_9(target);
522 struct arm_jtag *jtag_info = &arm7_9->jtag_info;
523
524 LOG_DEBUG("xpsr_im: %2.2x, rot: %i, spsr: %i", xpsr_im, rot, spsr);
525
526 /* MSR fetched */
527 arm9tdmi_clock_out(jtag_info, ARMV4_5_MSR_IM(xpsr_im, rot, 1, spsr), 0, NULL, 0);
528 /* NOP fetched, MSR in DECODE */
529 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
530 /* NOP fetched, MSR in EXECUTE (1) */
531 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
532
533 /* rot == 4 writes flags, which takes only one cycle */
534 if (rot != 4)
535 {
536 /* nothing fetched, MSR in EXECUTE (2) */
537 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
538 /* nothing fetched, MSR in EXECUTE (3) */
539 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
540 }
541 }
542
543 void arm9tdmi_write_core_regs(struct target *target,
544 uint32_t mask, uint32_t core_regs[16])
545 {
546 int i;
547 struct arm7_9_common *arm7_9 = target_to_arm7_9(target);
548 struct arm_jtag *jtag_info = &arm7_9->jtag_info;
549
550 /* LDMIA r0-15, [r0] at debug speed
551 * register values will start to appear on 4th DCLK
552 */
553 arm9tdmi_clock_out(jtag_info, ARMV4_5_LDMIA(0, mask & 0xffff, 0, 0), 0, NULL, 0);
554
555 /* fetch NOP, LDM in DECODE stage */
556 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
557 /* fetch NOP, LDM in EXECUTE stage (1st cycle) */
558 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
559
560 for (i = 0; i <= 15; i++)
561 {
562 if (mask & (1 << i))
563 /* nothing fetched, LDM still in EXECUTE (1 + i cycle) */
564 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, core_regs[i], NULL, 0);
565 }
566 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
567 }
568
569 void arm9tdmi_load_word_regs(struct target *target, uint32_t mask)
570 {
571 struct arm7_9_common *arm7_9 = target_to_arm7_9(target);
572 struct arm_jtag *jtag_info = &arm7_9->jtag_info;
573
574 /* put system-speed load-multiple into the pipeline */
575 arm9tdmi_clock_out(jtag_info, ARMV4_5_LDMIA(0, mask & 0xffff, 0, 1), 0, NULL, 0);
576 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 1);
577 }
578
579 void arm9tdmi_load_hword_reg(struct target *target, int num)
580 {
581 struct arm7_9_common *arm7_9 = target_to_arm7_9(target);
582 struct arm_jtag *jtag_info = &arm7_9->jtag_info;
583
584 /* put system-speed load half-word into the pipeline */
585 arm9tdmi_clock_out(jtag_info, ARMV4_5_LDRH_IP(num, 0), 0, NULL, 0);
586 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 1);
587 }
588
589 void arm9tdmi_load_byte_reg(struct target *target, int num)
590 {
591 struct arm7_9_common *arm7_9 = target_to_arm7_9(target);
592 struct arm_jtag *jtag_info = &arm7_9->jtag_info;
593
594 /* put system-speed load byte into the pipeline */
595 arm9tdmi_clock_out(jtag_info, ARMV4_5_LDRB_IP(num, 0), 0, NULL, 0);
596 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 1);
597 }
598
599 void arm9tdmi_store_word_regs(struct target *target, uint32_t mask)
600 {
601 struct arm7_9_common *arm7_9 = target_to_arm7_9(target);
602 struct arm_jtag *jtag_info = &arm7_9->jtag_info;
603
604 /* put system-speed store-multiple into the pipeline */
605 arm9tdmi_clock_out(jtag_info, ARMV4_5_STMIA(0, mask, 0, 1), 0, NULL, 0);
606 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 1);
607 }
608
609 void arm9tdmi_store_hword_reg(struct target *target, int num)
610 {
611 struct arm7_9_common *arm7_9 = target_to_arm7_9(target);
612 struct arm_jtag *jtag_info = &arm7_9->jtag_info;
613
614 /* put system-speed store half-word into the pipeline */
615 arm9tdmi_clock_out(jtag_info, ARMV4_5_STRH_IP(num, 0), 0, NULL, 0);
616 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 1);
617 }
618
619 void arm9tdmi_store_byte_reg(struct target *target, int num)
620 {
621 struct arm7_9_common *arm7_9 = target_to_arm7_9(target);
622 struct arm_jtag *jtag_info = &arm7_9->jtag_info;
623
624 /* put system-speed store byte into the pipeline */
625 arm9tdmi_clock_out(jtag_info, ARMV4_5_STRB_IP(num, 0), 0, NULL, 0);
626 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 1);
627 }
628
629 static void arm9tdmi_write_pc(struct target *target, uint32_t pc)
630 {
631 struct arm7_9_common *arm7_9 = target_to_arm7_9(target);
632 struct arm_jtag *jtag_info = &arm7_9->jtag_info;
633
634 /* LDMIA r0-15, [r0] at debug speed
635 * register values will start to appear on 4th DCLK
636 */
637 arm9tdmi_clock_out(jtag_info, ARMV4_5_LDMIA(0, 0x8000, 0, 0), 0, NULL, 0);
638
639 /* fetch NOP, LDM in DECODE stage */
640 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
641 /* fetch NOP, LDM in EXECUTE stage (1st cycle) */
642 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
643 /* nothing fetched, LDM in EXECUTE stage (2nd cycle) (output data) */
644 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, pc, NULL, 0);
645 /* nothing fetched, LDM in EXECUTE stage (3rd cycle) */
646 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
647 /* fetch NOP, LDM in EXECUTE stage (4th cycle) */
648 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
649 /* fetch NOP, LDM in EXECUTE stage (5th cycle) */
650 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
651 }
652
653 void arm9tdmi_branch_resume(struct target *target)
654 {
655 struct arm7_9_common *arm7_9 = target_to_arm7_9(target);
656 struct arm_jtag *jtag_info = &arm7_9->jtag_info;
657
658 arm9tdmi_clock_out(jtag_info, ARMV4_5_B(0xfffffc, 0), 0, NULL, 0);
659 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 1);
660 }
661
662 static void arm9tdmi_branch_resume_thumb(struct target *target)
663 {
664 LOG_DEBUG("-");
665
666 struct arm7_9_common *arm7_9 = target_to_arm7_9(target);
667 struct armv4_5_common_s *armv4_5 = &arm7_9->armv4_5_common;
668 struct arm_jtag *jtag_info = &arm7_9->jtag_info;
669 struct reg *dbg_stat = &arm7_9->eice_cache->reg_list[EICE_DBG_STAT];
670
671 /* LDMIA r0-15, [r0] at debug speed
672 * register values will start to appear on 4th DCLK
673 */
674 arm9tdmi_clock_out(jtag_info, ARMV4_5_LDMIA(0, 0x1, 0, 0), 0, NULL, 0);
675
676 /* fetch NOP, LDM in DECODE stage */
677 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
678 /* fetch NOP, LDM in EXECUTE stage (1st cycle) */
679 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
680 /* nothing fetched, LDM in EXECUTE stage (2nd cycle) */
681 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32) | 1, NULL, 0);
682 /* nothing fetched, LDM in EXECUTE stage (3rd cycle) */
683 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
684
685 /* Branch and eXchange */
686 arm9tdmi_clock_out(jtag_info, ARMV4_5_BX(0), 0, NULL, 0);
687
688 embeddedice_read_reg(dbg_stat);
689
690 /* fetch NOP, BX in DECODE stage */
691 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
692
693 embeddedice_read_reg(dbg_stat);
694
695 /* fetch NOP, BX in EXECUTE stage (1st cycle) */
696 arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
697
698 /* target is now in Thumb state */
699 embeddedice_read_reg(dbg_stat);
700
701 /* load r0 value, MOV_IM in Decode*/
702 arm9tdmi_clock_out(jtag_info, ARMV4_5_T_LDR_PCREL(0), 0, NULL, 0);
703 /* fetch NOP, LDR in Decode, MOV_IM in Execute */
704 arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0);
705 /* fetch NOP, LDR in Execute */
706 arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0);
707 /* nothing fetched, LDR in EXECUTE stage (2nd cycle) */
708 arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, buf_get_u32(armv4_5->core_cache->reg_list[0].value, 0, 32), NULL, 0);
709 /* nothing fetched, LDR in EXECUTE stage (3rd cycle) */
710 arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0);
711
712 arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0);
713 arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0);
714
715 embeddedice_read_reg(dbg_stat);
716
717 arm9tdmi_clock_out(jtag_info, ARMV4_5_T_B(0x7f7), 0, NULL, 1);
718 arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0);
719 }
720
721 void arm9tdmi_enable_single_step(struct target *target, uint32_t next_pc)
722 {
723 struct arm7_9_common *arm7_9 = target_to_arm7_9(target);
724
725 if (arm7_9->has_single_step)
726 {
727 buf_set_u32(arm7_9->eice_cache->reg_list[EICE_DBG_CTRL].value, 3, 1, 1);
728 embeddedice_store_reg(&arm7_9->eice_cache->reg_list[EICE_DBG_CTRL]);
729 }
730 else
731 {
732 arm7_9_enable_eice_step(target, next_pc);
733 }
734 }
735
736 void arm9tdmi_disable_single_step(struct target *target)
737 {
738 struct arm7_9_common *arm7_9 = target_to_arm7_9(target);
739
740 if (arm7_9->has_single_step)
741 {
742 buf_set_u32(arm7_9->eice_cache->reg_list[EICE_DBG_CTRL].value, 3, 1, 0);
743 embeddedice_store_reg(&arm7_9->eice_cache->reg_list[EICE_DBG_CTRL]);
744 }
745 else
746 {
747 arm7_9_disable_eice_step(target);
748 }
749 }
750
751 static void arm9tdmi_build_reg_cache(struct target *target)
752 {
753 struct reg_cache **cache_p = register_get_last_cache_p(&target->reg_cache);
754 struct armv4_5_common_s *armv4_5 = target_to_armv4_5(target);
755
756 (*cache_p) = armv4_5_build_reg_cache(target, armv4_5);
757 armv4_5->core_cache = (*cache_p);
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 int arm9tdmi_register_commands(struct command_context *cmd_ctx)
913 {
914 int retval;
915 struct command *arm9tdmi_cmd;
916
917 retval = arm7_9_register_commands(cmd_ctx);
918 arm9tdmi_cmd = register_command(cmd_ctx, NULL, "arm9",
919 NULL, COMMAND_ANY,
920 "arm9 specific commands");
921 register_command(cmd_ctx, arm9tdmi_cmd, "vector_catch",
922 handle_arm9tdmi_catch_vectors_command, COMMAND_EXEC,
923 "arm9 vector_catch [all|none|reset|undef|swi|pabt|dabt|irq|fiq] ...");
924
925 return retval;
926 }
927
928 /** Holds methods for ARM9TDMI targets. */
929 struct target_type arm9tdmi_target =
930 {
931 .name = "arm9tdmi",
932
933 .poll = arm7_9_poll,
934 .arch_state = armv4_5_arch_state,
935
936 .target_request_data = arm7_9_target_request_data,
937
938 .halt = arm7_9_halt,
939 .resume = arm7_9_resume,
940 .step = arm7_9_step,
941
942 .assert_reset = arm7_9_assert_reset,
943 .deassert_reset = arm7_9_deassert_reset,
944 .soft_reset_halt = arm7_9_soft_reset_halt,
945
946 .get_gdb_reg_list = armv4_5_get_gdb_reg_list,
947
948 .read_memory = arm7_9_read_memory,
949 .write_memory = arm7_9_write_memory,
950 .bulk_write_memory = arm7_9_bulk_write_memory,
951
952 .checksum_memory = arm_checksum_memory,
953 .blank_check_memory = arm_blank_check_memory,
954
955 .run_algorithm = armv4_5_run_algorithm,
956
957 .add_breakpoint = arm7_9_add_breakpoint,
958 .remove_breakpoint = arm7_9_remove_breakpoint,
959 .add_watchpoint = arm7_9_add_watchpoint,
960 .remove_watchpoint = arm7_9_remove_watchpoint,
961
962 .register_commands = arm9tdmi_register_commands,
963 .target_create = arm9tdmi_target_create,
964 .init_target = arm9tdmi_init_target,
965 .examine = arm7_9_examine,
966 };

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)