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

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)