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

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)