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

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)