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

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)