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

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)