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

Linking to existing account procedure

If you already have an account and want to add another login method you MUST first sign in with your existing account and then change URL to read https://review.openocd.org/login/?link to get to this page again but this time it'll work for linking. Thank you.

SSH host keys fingerprints

1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=..              |
|+o..   .         |
|*.o   . .        |
|+B . . .         |
|Bo. = o S        |
|Oo.+ + =         |
|oB=.* = . o      |
| =+=.+   + E     |
|. .=o   . o      |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)