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