use COMMAND_REGISTER macro
[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 arm *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 arm *armv4_5 = target_to_armv4_5(target);
755
756 (*cache_p) = armv4_5_build_reg_cache(target, armv4_5);
757 }
758
759 int arm9tdmi_init_target(struct command_context *cmd_ctx,
760 struct target *target)
761 {
762 arm9tdmi_build_reg_cache(target);
763 return ERROR_OK;
764 }
765
766 int arm9tdmi_init_arch_info(struct target *target,
767 struct arm7_9_common *arm7_9, struct jtag_tap *tap)
768 {
769 /* prepare JTAG information for the new target */
770 arm7_9->jtag_info.tap = tap;
771 arm7_9->jtag_info.scann_size = 5;
772
773 /* register arch-specific functions */
774 arm7_9->examine_debug_reason = arm9tdmi_examine_debug_reason;
775 arm7_9->change_to_arm = arm9tdmi_change_to_arm;
776 arm7_9->read_core_regs = arm9tdmi_read_core_regs;
777 arm7_9->read_core_regs_target_buffer = arm9tdmi_read_core_regs_target_buffer;
778 arm7_9->read_xpsr = arm9tdmi_read_xpsr;
779
780 arm7_9->write_xpsr = arm9tdmi_write_xpsr;
781 arm7_9->write_xpsr_im8 = arm9tdmi_write_xpsr_im8;
782 arm7_9->write_core_regs = arm9tdmi_write_core_regs;
783
784 arm7_9->load_word_regs = arm9tdmi_load_word_regs;
785 arm7_9->load_hword_reg = arm9tdmi_load_hword_reg;
786 arm7_9->load_byte_reg = arm9tdmi_load_byte_reg;
787
788 arm7_9->store_word_regs = arm9tdmi_store_word_regs;
789 arm7_9->store_hword_reg = arm9tdmi_store_hword_reg;
790 arm7_9->store_byte_reg = arm9tdmi_store_byte_reg;
791
792 arm7_9->write_pc = arm9tdmi_write_pc;
793 arm7_9->branch_resume = arm9tdmi_branch_resume;
794 arm7_9->branch_resume_thumb = arm9tdmi_branch_resume_thumb;
795
796 arm7_9->enable_single_step = arm9tdmi_enable_single_step;
797 arm7_9->disable_single_step = arm9tdmi_disable_single_step;
798
799 arm7_9->post_debug_entry = NULL;
800
801 arm7_9->pre_restore_context = NULL;
802 arm7_9->post_restore_context = NULL;
803
804 /* initialize arch-specific breakpoint handling */
805 arm7_9->arm_bkpt = 0xdeeedeee;
806 arm7_9->thumb_bkpt = 0xdeee;
807
808 arm7_9->dbgreq_adjust_pc = 3;
809
810 arm7_9_init_arch_info(target, arm7_9);
811
812 /* override use of DBGRQ, this is safe on ARM9TDMI */
813 arm7_9->use_dbgrq = 1;
814
815 /* all ARM9s have the vector catch register */
816 arm7_9->has_vector_catch = 1;
817
818 return ERROR_OK;
819 }
820
821 static int arm9tdmi_target_create(struct target *target, Jim_Interp *interp)
822 {
823 struct arm7_9_common *arm7_9 = calloc(1,sizeof(struct arm7_9_common));
824
825 arm9tdmi_init_arch_info(target, arm7_9, target->tap);
826 arm7_9->armv4_5_common.is_armv4 = true;
827
828 return ERROR_OK;
829 }
830
831 COMMAND_HANDLER(handle_arm9tdmi_catch_vectors_command)
832 {
833 struct target *target = get_current_target(CMD_CTX);
834 struct arm7_9_common *arm7_9 = target_to_arm7_9(target);
835 struct reg *vector_catch;
836 uint32_t vector_catch_value;
837
838 /* it's uncommon, but some ARM7 chips can support this */
839 if (arm7_9->common_magic != ARM7_9_COMMON_MAGIC
840 || !arm7_9->has_vector_catch) {
841 command_print(CMD_CTX, "target doesn't have EmbeddedICE "
842 "with vector_catch");
843 return ERROR_TARGET_INVALID;
844 }
845
846 vector_catch = &arm7_9->eice_cache->reg_list[EICE_VEC_CATCH];
847
848 /* read the vector catch register if necessary */
849 if (!vector_catch->valid)
850 embeddedice_read_reg(vector_catch);
851
852 /* get the current setting */
853 vector_catch_value = buf_get_u32(vector_catch->value, 0, 8);
854
855 if (CMD_ARGC > 0)
856 {
857 vector_catch_value = 0x0;
858 if (strcmp(CMD_ARGV[0], "all") == 0)
859 {
860 vector_catch_value = 0xdf;
861 }
862 else if (strcmp(CMD_ARGV[0], "none") == 0)
863 {
864 /* do nothing */
865 }
866 else
867 {
868 for (unsigned i = 0; i < CMD_ARGC; i++)
869 {
870 /* go through list of vectors */
871 unsigned j;
872 for (j = 0; arm9tdmi_vectors[j].name; j++)
873 {
874 if (strcmp(CMD_ARGV[i], arm9tdmi_vectors[j].name) == 0)
875 {
876 vector_catch_value |= arm9tdmi_vectors[j].value;
877 break;
878 }
879 }
880
881 /* complain if vector wasn't found */
882 if (!arm9tdmi_vectors[j].name)
883 {
884 command_print(CMD_CTX, "vector '%s' not found, leaving current setting unchanged", CMD_ARGV[i]);
885
886 /* reread current setting */
887 vector_catch_value = buf_get_u32(
888 vector_catch->value,
889 0, 8);
890
891 break;
892 }
893 }
894 }
895
896 /* store new settings */
897 buf_set_u32(vector_catch->value, 0, 8, vector_catch_value);
898 embeddedice_store_reg(vector_catch);
899 }
900
901 /* output current settings */
902 for (unsigned i = 0; arm9tdmi_vectors[i].name; i++) {
903 command_print(CMD_CTX, "%s: %s", arm9tdmi_vectors[i].name,
904 (vector_catch_value & arm9tdmi_vectors[i].value)
905 ? "catch" : "don't catch");
906 }
907
908 return ERROR_OK;
909 }
910
911 int arm9tdmi_register_commands(struct command_context *cmd_ctx)
912 {
913 int retval;
914 struct command *arm9tdmi_cmd;
915
916 retval = arm7_9_register_commands(cmd_ctx);
917 arm9tdmi_cmd = COMMAND_REGISTER(cmd_ctx, NULL, "arm9",
918 NULL, COMMAND_ANY,
919 "arm9 specific commands");
920 COMMAND_REGISTER(cmd_ctx, arm9tdmi_cmd, "vector_catch",
921 handle_arm9tdmi_catch_vectors_command, COMMAND_EXEC,
922 "arm9 vector_catch [all|none|reset|undef|swi|pabt|dabt|irq|fiq] ...");
923
924 return retval;
925 }
926
927 /** Holds methods for ARM9TDMI targets. */
928 struct target_type arm9tdmi_target =
929 {
930 .name = "arm9tdmi",
931
932 .poll = arm7_9_poll,
933 .arch_state = armv4_5_arch_state,
934
935 .target_request_data = arm7_9_target_request_data,
936
937 .halt = arm7_9_halt,
938 .resume = arm7_9_resume,
939 .step = arm7_9_step,
940
941 .assert_reset = arm7_9_assert_reset,
942 .deassert_reset = arm7_9_deassert_reset,
943 .soft_reset_halt = arm7_9_soft_reset_halt,
944
945 .get_gdb_reg_list = armv4_5_get_gdb_reg_list,
946
947 .read_memory = arm7_9_read_memory,
948 .write_memory = arm7_9_write_memory,
949 .bulk_write_memory = arm7_9_bulk_write_memory,
950
951 .checksum_memory = arm_checksum_memory,
952 .blank_check_memory = arm_blank_check_memory,
953
954 .run_algorithm = armv4_5_run_algorithm,
955
956 .add_breakpoint = arm7_9_add_breakpoint,
957 .remove_breakpoint = arm7_9_remove_breakpoint,
958 .add_watchpoint = arm7_9_add_watchpoint,
959 .remove_watchpoint = arm7_9_remove_watchpoint,
960
961 .register_commands = arm9tdmi_register_commands,
962 .target_create = arm9tdmi_target_create,
963 .init_target = arm9tdmi_init_target,
964 .examine = arm7_9_examine,
965 };

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)