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

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)