ARM: add a default full_context() method
[openocd.git] / src / target / armv4_5.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 Oyvind Harboe *
9 * oyvind.harboe@zylin.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 "armv4_5.h"
31 #include "arm_jtag.h"
32 #include "breakpoints.h"
33 #include "arm_disassembler.h"
34 #include "binarybuffer.h"
35 #include "algorithm.h"
36 #include "register.h"
37
38
39 static const char *armv4_5_core_reg_list[] =
40 {
41 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
42 "r8", "r9", "r10", "r11", "r12", "r13_usr", "lr_usr", "pc",
43
44 "r8_fiq", "r9_fiq", "r10_fiq", "r11_fiq", "r12_fiq", "r13_fiq", "lr_fiq",
45
46 "r13_irq", "lr_irq",
47
48 "r13_svc", "lr_svc",
49
50 "r13_abt", "lr_abt",
51
52 "r13_und", "lr_und",
53
54 "cpsr", "spsr_fiq", "spsr_irq", "spsr_svc", "spsr_abt", "spsr_und",
55
56 "r13_mon", "lr_mon", "spsr_mon",
57 };
58
59 static const struct {
60 const char *name;
61 unsigned psr;
62 } arm_mode_data[] = {
63 /* Seven modes are standard from ARM7 on. "System" and "User" share
64 * the same registers; other modes shadow from 3 to 8 registers.
65 */
66 {
67 .name = "User",
68 .psr = ARMV4_5_MODE_USR,
69 },
70 {
71 .name = "FIQ",
72 .psr = ARMV4_5_MODE_FIQ,
73 },
74 {
75 .name = "Supervisor",
76 .psr = ARMV4_5_MODE_SVC,
77 },
78 {
79 .name = "Abort",
80 .psr = ARMV4_5_MODE_ABT,
81 },
82 {
83 .name = "IRQ",
84 .psr = ARMV4_5_MODE_IRQ,
85 },
86 {
87 .name = "Undefined" /* instruction */,
88 .psr = ARMV4_5_MODE_UND,
89 },
90 {
91 .name = "System",
92 .psr = ARMV4_5_MODE_SYS,
93 },
94 /* TrustZone "Security Extensions" add a secure monitor mode.
95 * This is distinct from a "debug monitor" which can support
96 * non-halting debug, in conjunction with some debuggers.
97 */
98 {
99 .name = "Secure Monitor",
100 .psr = ARM_MODE_MON,
101 },
102 };
103
104 /** Map PSR mode bits to the name of an ARM processor operating mode. */
105 const char *arm_mode_name(unsigned psr_mode)
106 {
107 for (unsigned i = 0; i < ARRAY_SIZE(arm_mode_data); i++) {
108 if (arm_mode_data[i].psr == psr_mode)
109 return arm_mode_data[i].name;
110 }
111 LOG_ERROR("unrecognized psr mode: %#02x", psr_mode);
112 return "UNRECOGNIZED";
113 }
114
115 /** Return true iff the parameter denotes a valid ARM processor mode. */
116 bool is_arm_mode(unsigned psr_mode)
117 {
118 for (unsigned i = 0; i < ARRAY_SIZE(arm_mode_data); i++) {
119 if (arm_mode_data[i].psr == psr_mode)
120 return true;
121 }
122 return false;
123 }
124
125 /** Map PSR mode bits to linear number indexing armv4_5_core_reg_map */
126 int armv4_5_mode_to_number(enum armv4_5_mode mode)
127 {
128 switch (mode) {
129 case ARMV4_5_MODE_ANY:
130 /* map MODE_ANY to user mode */
131 case ARMV4_5_MODE_USR:
132 return 0;
133 case ARMV4_5_MODE_FIQ:
134 return 1;
135 case ARMV4_5_MODE_IRQ:
136 return 2;
137 case ARMV4_5_MODE_SVC:
138 return 3;
139 case ARMV4_5_MODE_ABT:
140 return 4;
141 case ARMV4_5_MODE_UND:
142 return 5;
143 case ARMV4_5_MODE_SYS:
144 return 6;
145 case ARM_MODE_MON:
146 return 7;
147 default:
148 LOG_ERROR("invalid mode value encountered %d", mode);
149 return -1;
150 }
151 }
152
153 /** Map linear number indexing armv4_5_core_reg_map to PSR mode bits. */
154 enum armv4_5_mode armv4_5_number_to_mode(int number)
155 {
156 switch (number) {
157 case 0:
158 return ARMV4_5_MODE_USR;
159 case 1:
160 return ARMV4_5_MODE_FIQ;
161 case 2:
162 return ARMV4_5_MODE_IRQ;
163 case 3:
164 return ARMV4_5_MODE_SVC;
165 case 4:
166 return ARMV4_5_MODE_ABT;
167 case 5:
168 return ARMV4_5_MODE_UND;
169 case 6:
170 return ARMV4_5_MODE_SYS;
171 case 7:
172 return ARM_MODE_MON;
173 default:
174 LOG_ERROR("mode index out of bounds %d", number);
175 return ARMV4_5_MODE_ANY;
176 }
177 }
178
179 char* armv4_5_state_strings[] =
180 {
181 "ARM", "Thumb", "Jazelle"
182 };
183
184 static const struct armv4_5_core_reg armv4_5_core_reg_list_arch_info[] =
185 {
186 {0, ARMV4_5_MODE_ANY, NULL, NULL},
187 {1, ARMV4_5_MODE_ANY, NULL, NULL},
188 {2, ARMV4_5_MODE_ANY, NULL, NULL},
189 {3, ARMV4_5_MODE_ANY, NULL, NULL},
190 {4, ARMV4_5_MODE_ANY, NULL, NULL},
191 {5, ARMV4_5_MODE_ANY, NULL, NULL},
192 {6, ARMV4_5_MODE_ANY, NULL, NULL},
193 {7, ARMV4_5_MODE_ANY, NULL, NULL},
194 {8, ARMV4_5_MODE_ANY, NULL, NULL},
195 {9, ARMV4_5_MODE_ANY, NULL, NULL},
196 {10, ARMV4_5_MODE_ANY, NULL, NULL},
197 {11, ARMV4_5_MODE_ANY, NULL, NULL},
198 {12, ARMV4_5_MODE_ANY, NULL, NULL},
199 {13, ARMV4_5_MODE_USR, NULL, NULL},
200 {14, ARMV4_5_MODE_USR, NULL, NULL},
201 {15, ARMV4_5_MODE_ANY, NULL, NULL},
202
203 {8, ARMV4_5_MODE_FIQ, NULL, NULL},
204 {9, ARMV4_5_MODE_FIQ, NULL, NULL},
205 {10, ARMV4_5_MODE_FIQ, NULL, NULL},
206 {11, ARMV4_5_MODE_FIQ, NULL, NULL},
207 {12, ARMV4_5_MODE_FIQ, NULL, NULL},
208 {13, ARMV4_5_MODE_FIQ, NULL, NULL},
209 {14, ARMV4_5_MODE_FIQ, NULL, NULL},
210
211 {13, ARMV4_5_MODE_IRQ, NULL, NULL},
212 {14, ARMV4_5_MODE_IRQ, NULL, NULL},
213
214 {13, ARMV4_5_MODE_SVC, NULL, NULL},
215 {14, ARMV4_5_MODE_SVC, NULL, NULL},
216
217 {13, ARMV4_5_MODE_ABT, NULL, NULL},
218 {14, ARMV4_5_MODE_ABT, NULL, NULL},
219
220 {13, ARMV4_5_MODE_UND, NULL, NULL},
221 {14, ARMV4_5_MODE_UND, NULL, NULL},
222
223 {16, ARMV4_5_MODE_ANY, NULL, NULL},
224 {16, ARMV4_5_MODE_FIQ, NULL, NULL},
225 {16, ARMV4_5_MODE_IRQ, NULL, NULL},
226 {16, ARMV4_5_MODE_SVC, NULL, NULL},
227 {16, ARMV4_5_MODE_ABT, NULL, NULL},
228 {16, ARMV4_5_MODE_UND, NULL, NULL},
229
230 {13, ARM_MODE_MON, NULL, NULL},
231 {14, ARM_MODE_MON, NULL, NULL},
232 {16, ARM_MODE_MON, NULL, NULL},
233 };
234
235 /* map core mode (USR, FIQ, ...) and register number to indizes into the register cache */
236 const int armv4_5_core_reg_map[8][17] =
237 {
238 { /* USR */
239 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 31
240 },
241 { /* FIQ (8 shadows of USR, vs normal 3) */
242 0, 1, 2, 3, 4, 5, 6, 7, 16, 17, 18, 19, 20, 21, 22, 15, 32
243 },
244 { /* IRQ */
245 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 23, 24, 15, 33
246 },
247 { /* SVC */
248 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 25, 26, 15, 34
249 },
250 { /* ABT */
251 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 27, 28, 15, 35
252 },
253 { /* UND */
254 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 29, 30, 15, 36
255 },
256 { /* SYS (same registers as USR) */
257 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 31
258 },
259 { /* MON */
260 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 37, 38, 15, 39,
261 }
262 };
263
264 static const uint8_t arm_gdb_dummy_fp_value[12];
265
266 /**
267 * Dummy FPA registers are required to support GDB on ARM.
268 * Register packets require eight obsolete FPA register values.
269 * Modern ARM cores use Vector Floating Point (VFP), if they
270 * have any floating point support. VFP is not FPA-compatible.
271 */
272 struct reg arm_gdb_dummy_fp_reg =
273 {
274 .name = "GDB dummy FPA register",
275 .value = (uint8_t *) arm_gdb_dummy_fp_value,
276 .valid = 1,
277 .size = 96,
278 };
279
280 static const uint8_t arm_gdb_dummy_fps_value[4];
281
282 /**
283 * Dummy FPA status registers are required to support GDB on ARM.
284 * Register packets require an obsolete FPA status register.
285 */
286 struct reg arm_gdb_dummy_fps_reg =
287 {
288 .name = "GDB dummy FPA status register",
289 .value = (uint8_t *) arm_gdb_dummy_fps_value,
290 .valid = 1,
291 .size = 32,
292 };
293
294 static void arm_gdb_dummy_init(void) __attribute__ ((constructor));
295
296 static void arm_gdb_dummy_init(void)
297 {
298 register_init_dummy(&arm_gdb_dummy_fp_reg);
299 register_init_dummy(&arm_gdb_dummy_fps_reg);
300 }
301
302 static int armv4_5_get_core_reg(struct reg *reg)
303 {
304 int retval;
305 struct armv4_5_core_reg *armv4_5 = reg->arch_info;
306 struct target *target = armv4_5->target;
307
308 if (target->state != TARGET_HALTED)
309 {
310 LOG_ERROR("Target not halted");
311 return ERROR_TARGET_NOT_HALTED;
312 }
313
314 retval = armv4_5->armv4_5_common->read_core_reg(target, armv4_5->num, armv4_5->mode);
315 if (retval == ERROR_OK)
316 reg->valid = 1;
317
318 return retval;
319 }
320
321 static int armv4_5_set_core_reg(struct reg *reg, uint8_t *buf)
322 {
323 struct armv4_5_core_reg *armv4_5 = reg->arch_info;
324 struct target *target = armv4_5->target;
325 struct armv4_5_common_s *armv4_5_target = target_to_armv4_5(target);
326 uint32_t value = buf_get_u32(buf, 0, 32);
327
328 if (target->state != TARGET_HALTED)
329 {
330 LOG_ERROR("Target not halted");
331 return ERROR_TARGET_NOT_HALTED;
332 }
333
334 if (reg == &armv4_5_target->core_cache->reg_list[ARMV4_5_CPSR])
335 {
336 if (value & 0x20)
337 {
338 /* T bit should be set */
339 if (armv4_5_target->core_state == ARMV4_5_STATE_ARM)
340 {
341 /* change state to Thumb */
342 LOG_DEBUG("changing to Thumb state");
343 armv4_5_target->core_state = ARMV4_5_STATE_THUMB;
344 }
345 }
346 else
347 {
348 /* T bit should be cleared */
349 if (armv4_5_target->core_state == ARMV4_5_STATE_THUMB)
350 {
351 /* change state to ARM */
352 LOG_DEBUG("changing to ARM state");
353 armv4_5_target->core_state = ARMV4_5_STATE_ARM;
354 }
355 }
356
357 if (armv4_5_target->core_mode != (enum armv4_5_mode)(value & 0x1f))
358 {
359 LOG_DEBUG("changing ARM core mode to '%s'",
360 arm_mode_name(value & 0x1f));
361 armv4_5_target->core_mode = value & 0x1f;
362 armv4_5_target->write_core_reg(target, 16, ARMV4_5_MODE_ANY, value);
363 }
364 }
365
366 buf_set_u32(reg->value, 0, 32, value);
367 reg->dirty = 1;
368 reg->valid = 1;
369
370 return ERROR_OK;
371 }
372
373 static const struct reg_arch_type arm_reg_type = {
374 .get = armv4_5_get_core_reg,
375 .set = armv4_5_set_core_reg,
376 };
377
378 /** Marks the contents of the register cache as invalid (and clean). */
379 int armv4_5_invalidate_core_regs(struct target *target)
380 {
381 struct armv4_5_common_s *armv4_5 = target_to_armv4_5(target);
382 unsigned num_regs = armv4_5->core_cache->num_regs;
383 struct reg *reg = armv4_5->core_cache->reg_list;
384
385 for (unsigned i = 0; i < num_regs; i++, reg++) {
386 reg->valid = 0;
387 reg->dirty = 0;
388 }
389
390 /* FIXME don't bother returning a value then */
391 return ERROR_OK;
392 }
393
394 struct reg_cache* armv4_5_build_reg_cache(struct target *target, struct arm *armv4_5_common)
395 {
396 int num_regs = ARRAY_SIZE(armv4_5_core_reg_list_arch_info);
397 struct reg_cache *cache = malloc(sizeof(struct reg_cache));
398 struct reg *reg_list = calloc(num_regs, sizeof(struct reg));
399 struct armv4_5_core_reg *arch_info = calloc(num_regs,
400 sizeof(struct armv4_5_core_reg));
401 int i;
402
403 if (!cache || !reg_list || !arch_info) {
404 free(cache);
405 free(reg_list);
406 free(arch_info);
407 return NULL;
408 }
409
410 cache->name = "ARM registers";
411 cache->next = NULL;
412 cache->reg_list = reg_list;
413 cache->num_regs = 0;
414
415 for (i = 0; i < num_regs; i++)
416 {
417 /* Skip registers this core doesn't expose */
418 if (armv4_5_core_reg_list_arch_info[i].mode == ARM_MODE_MON
419 && armv4_5_common->core_type != ARM_MODE_MON)
420 continue;
421
422 /* REVISIT handle Cortex-M, which only shadows R13/SP */
423
424 arch_info[i] = armv4_5_core_reg_list_arch_info[i];
425 arch_info[i].target = target;
426 arch_info[i].armv4_5_common = armv4_5_common;
427 reg_list[i].name = (char *) armv4_5_core_reg_list[i];
428 reg_list[i].size = 32;
429 reg_list[i].value = calloc(1, 4);
430 reg_list[i].type = &arm_reg_type;
431 reg_list[i].arch_info = &arch_info[i];
432
433 cache->num_regs++;
434 }
435
436 return cache;
437 }
438
439 int armv4_5_arch_state(struct target *target)
440 {
441 struct armv4_5_common_s *armv4_5 = target_to_armv4_5(target);
442
443 if (armv4_5->common_magic != ARMV4_5_COMMON_MAGIC)
444 {
445 LOG_ERROR("BUG: called for a non-ARMv4/5 target");
446 return ERROR_FAIL;
447 }
448
449 LOG_USER("target halted in %s state due to %s, current mode: %s\ncpsr: 0x%8.8" PRIx32 " pc: 0x%8.8" PRIx32 "",
450 armv4_5_state_strings[armv4_5->core_state],
451 Jim_Nvp_value2name_simple(nvp_target_debug_reason, target->debug_reason)->name,
452 arm_mode_name(armv4_5->core_mode),
453 buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 32),
454 buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32));
455
456 return ERROR_OK;
457 }
458
459 #define ARMV4_5_CORE_REG_MODENUM(cache, mode, num) \
460 cache->reg_list[armv4_5_core_reg_map[mode][num]]
461
462 COMMAND_HANDLER(handle_armv4_5_reg_command)
463 {
464 char output[128];
465 int output_len;
466 int mode, num;
467 struct target *target = get_current_target(CMD_CTX);
468 struct armv4_5_common_s *armv4_5 = target_to_armv4_5(target);
469
470 if (!is_arm(armv4_5))
471 {
472 command_print(CMD_CTX, "current target isn't an ARM");
473 return ERROR_FAIL;
474 }
475
476 if (target->state != TARGET_HALTED)
477 {
478 command_print(CMD_CTX, "error: target must be halted for register accesses");
479 return ERROR_OK;
480 }
481
482 if (!is_arm_mode(armv4_5->core_mode))
483 return ERROR_FAIL;
484
485 if (!armv4_5->full_context) {
486 command_print(CMD_CTX, "error: target doesn't support %s",
487 CMD_NAME);
488 return ERROR_FAIL;
489 }
490
491 for (num = 0; num <= 15; num++)
492 {
493 output_len = 0;
494 for (mode = 0; mode < 6; mode++)
495 {
496 if (!ARMV4_5_CORE_REG_MODENUM(armv4_5->core_cache, mode, num).valid)
497 {
498 armv4_5->full_context(target);
499 }
500 output_len += snprintf(output + output_len,
501 128 - output_len,
502 "%8s: %8.8" PRIx32 " ",
503 ARMV4_5_CORE_REG_MODENUM(armv4_5->core_cache, mode, num).name,
504 buf_get_u32(ARMV4_5_CORE_REG_MODENUM(armv4_5->core_cache, mode, num).value, 0, 32));
505 }
506 command_print(CMD_CTX, "%s", output);
507 }
508 command_print(CMD_CTX,
509 " cpsr: %8.8" PRIx32 " spsr_fiq: %8.8" PRIx32 " spsr_irq: %8.8" PRIx32 " spsr_svc: %8.8" PRIx32 " spsr_abt: %8.8" PRIx32 " spsr_und: %8.8" PRIx32 "",
510 buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 32),
511 buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_SPSR_FIQ].value, 0, 32),
512 buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_SPSR_IRQ].value, 0, 32),
513 buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_SPSR_SVC].value, 0, 32),
514 buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_SPSR_ABT].value, 0, 32),
515 buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_SPSR_UND].value, 0, 32));
516
517 return ERROR_OK;
518 }
519
520 COMMAND_HANDLER(handle_armv4_5_core_state_command)
521 {
522 struct target *target = get_current_target(CMD_CTX);
523 struct armv4_5_common_s *armv4_5 = target_to_armv4_5(target);
524
525 if (!is_arm(armv4_5))
526 {
527 command_print(CMD_CTX, "current target isn't an ARM");
528 return ERROR_FAIL;
529 }
530
531 if (CMD_ARGC > 0)
532 {
533 if (strcmp(CMD_ARGV[0], "arm") == 0)
534 {
535 armv4_5->core_state = ARMV4_5_STATE_ARM;
536 }
537 if (strcmp(CMD_ARGV[0], "thumb") == 0)
538 {
539 armv4_5->core_state = ARMV4_5_STATE_THUMB;
540 }
541 }
542
543 command_print(CMD_CTX, "core state: %s", armv4_5_state_strings[armv4_5->core_state]);
544
545 return ERROR_OK;
546 }
547
548 COMMAND_HANDLER(handle_armv4_5_disassemble_command)
549 {
550 int retval = ERROR_OK;
551 struct target *target = get_current_target(CMD_CTX);
552 struct arm *arm = target ? target_to_arm(target) : NULL;
553 uint32_t address;
554 int count = 1;
555 int thumb = 0;
556
557 if (!is_arm(arm)) {
558 command_print(CMD_CTX, "current target isn't an ARM");
559 return ERROR_FAIL;
560 }
561
562 switch (CMD_ARGC) {
563 case 3:
564 if (strcmp(CMD_ARGV[2], "thumb") != 0)
565 goto usage;
566 thumb = 1;
567 /* FALL THROUGH */
568 case 2:
569 COMMAND_PARSE_NUMBER(int, CMD_ARGV[1], count);
570 /* FALL THROUGH */
571 case 1:
572 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], address);
573 if (address & 0x01) {
574 if (!thumb) {
575 command_print(CMD_CTX, "Disassemble as Thumb");
576 thumb = 1;
577 }
578 address &= ~1;
579 }
580 break;
581 default:
582 usage:
583 command_print(CMD_CTX,
584 "usage: arm disassemble <address> [<count> ['thumb']]");
585 count = 0;
586 retval = ERROR_FAIL;
587 }
588
589 while (count-- > 0) {
590 struct arm_instruction cur_instruction;
591
592 if (thumb) {
593 /* Always use Thumb2 disassembly for best handling
594 * of 32-bit BL/BLX, and to work with newer cores
595 * (some ARMv6, all ARMv7) that use Thumb2.
596 */
597 retval = thumb2_opcode(target, address,
598 &cur_instruction);
599 if (retval != ERROR_OK)
600 break;
601 } else {
602 uint32_t opcode;
603
604 retval = target_read_u32(target, address, &opcode);
605 if (retval != ERROR_OK)
606 break;
607 retval = arm_evaluate_opcode(opcode, address,
608 &cur_instruction) != ERROR_OK;
609 if (retval != ERROR_OK)
610 break;
611 }
612 command_print(CMD_CTX, "%s", cur_instruction.text);
613 address += cur_instruction.instruction_size;
614 }
615
616 return retval;
617 }
618
619 int armv4_5_register_commands(struct command_context *cmd_ctx)
620 {
621 struct command *armv4_5_cmd;
622
623 armv4_5_cmd = register_command(cmd_ctx, NULL, "arm",
624 NULL, COMMAND_ANY,
625 "generic ARM commands");
626
627 register_command(cmd_ctx, armv4_5_cmd, "reg",
628 handle_armv4_5_reg_command, COMMAND_EXEC,
629 "display ARM core registers");
630 register_command(cmd_ctx, armv4_5_cmd, "core_state",
631 handle_armv4_5_core_state_command, COMMAND_EXEC,
632 "display/change ARM core state <arm | thumb>");
633 register_command(cmd_ctx, armv4_5_cmd, "disassemble",
634 handle_armv4_5_disassemble_command, COMMAND_EXEC,
635 "disassemble instructions "
636 "<address> [<count> ['thumb']]");
637
638 return ERROR_OK;
639 }
640
641 int armv4_5_get_gdb_reg_list(struct target *target, struct reg **reg_list[], int *reg_list_size)
642 {
643 struct armv4_5_common_s *armv4_5 = target_to_armv4_5(target);
644 int i;
645
646 if (!is_arm_mode(armv4_5->core_mode))
647 return ERROR_FAIL;
648
649 *reg_list_size = 26;
650 *reg_list = malloc(sizeof(struct reg*) * (*reg_list_size));
651
652 for (i = 0; i < 16; i++)
653 {
654 (*reg_list)[i] = &ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, i);
655 }
656
657 for (i = 16; i < 24; i++)
658 {
659 (*reg_list)[i] = &arm_gdb_dummy_fp_reg;
660 }
661
662 (*reg_list)[24] = &arm_gdb_dummy_fps_reg;
663 (*reg_list)[25] = &armv4_5->core_cache->reg_list[ARMV4_5_CPSR];
664
665 return ERROR_OK;
666 }
667
668 /* wait for execution to complete and check exit point */
669 static int armv4_5_run_algorithm_completion(struct target *target, uint32_t exit_point, int timeout_ms, void *arch_info)
670 {
671 int retval;
672 struct armv4_5_common_s *armv4_5 = target_to_armv4_5(target);
673
674 if ((retval = target_wait_state(target, TARGET_HALTED, timeout_ms)) != ERROR_OK)
675 {
676 return retval;
677 }
678 if (target->state != TARGET_HALTED)
679 {
680 if ((retval = target_halt(target)) != ERROR_OK)
681 return retval;
682 if ((retval = target_wait_state(target, TARGET_HALTED, 500)) != ERROR_OK)
683 {
684 return retval;
685 }
686 return ERROR_TARGET_TIMEOUT;
687 }
688
689 /* fast exit: ARMv5+ code can use BKPT */
690 if (exit_point && buf_get_u32(armv4_5->core_cache->reg_list[15].value,
691 0, 32) != exit_point)
692 {
693 LOG_WARNING("target reentered debug state, but not at the desired exit point: 0x%4.4" PRIx32 "",
694 buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32));
695 return ERROR_TARGET_TIMEOUT;
696 }
697
698 return ERROR_OK;
699 }
700
701 int armv4_5_run_algorithm_inner(struct target *target, int num_mem_params, struct mem_param *mem_params, int num_reg_params, struct reg_param *reg_params, uint32_t entry_point, uint32_t exit_point, int timeout_ms, void *arch_info, int (*run_it)(struct target *target, uint32_t exit_point, int timeout_ms, void *arch_info))
702 {
703 struct armv4_5_common_s *armv4_5 = target_to_armv4_5(target);
704 struct armv4_5_algorithm *armv4_5_algorithm_info = arch_info;
705 enum armv4_5_state core_state = armv4_5->core_state;
706 enum armv4_5_mode core_mode = armv4_5->core_mode;
707 uint32_t context[17];
708 uint32_t cpsr;
709 int exit_breakpoint_size = 0;
710 int i;
711 int retval = ERROR_OK;
712 LOG_DEBUG("Running algorithm");
713
714 if (armv4_5_algorithm_info->common_magic != ARMV4_5_COMMON_MAGIC)
715 {
716 LOG_ERROR("current target isn't an ARMV4/5 target");
717 return ERROR_TARGET_INVALID;
718 }
719
720 if (target->state != TARGET_HALTED)
721 {
722 LOG_WARNING("target not halted");
723 return ERROR_TARGET_NOT_HALTED;
724 }
725
726 if (!is_arm_mode(armv4_5->core_mode))
727 return ERROR_FAIL;
728
729 /* armv5 and later can terminate with BKPT instruction; less overhead */
730 if (!exit_point && armv4_5->is_armv4)
731 {
732 LOG_ERROR("ARMv4 target needs HW breakpoint location");
733 return ERROR_FAIL;
734 }
735
736 for (i = 0; i <= 16; i++)
737 {
738 if (!ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5_algorithm_info->core_mode, i).valid)
739 armv4_5->read_core_reg(target, i, armv4_5_algorithm_info->core_mode);
740 context[i] = buf_get_u32(ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5_algorithm_info->core_mode, i).value, 0, 32);
741 }
742 cpsr = buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 32);
743
744 for (i = 0; i < num_mem_params; i++)
745 {
746 if ((retval = target_write_buffer(target, mem_params[i].address, mem_params[i].size, mem_params[i].value)) != ERROR_OK)
747 {
748 return retval;
749 }
750 }
751
752 for (i = 0; i < num_reg_params; i++)
753 {
754 struct reg *reg = register_get_by_name(armv4_5->core_cache, reg_params[i].reg_name, 0);
755 if (!reg)
756 {
757 LOG_ERROR("BUG: register '%s' not found", reg_params[i].reg_name);
758 return ERROR_INVALID_ARGUMENTS;
759 }
760
761 if (reg->size != reg_params[i].size)
762 {
763 LOG_ERROR("BUG: register '%s' size doesn't match reg_params[i].size", reg_params[i].reg_name);
764 return ERROR_INVALID_ARGUMENTS;
765 }
766
767 if ((retval = armv4_5_set_core_reg(reg, reg_params[i].value)) != ERROR_OK)
768 {
769 return retval;
770 }
771 }
772
773 armv4_5->core_state = armv4_5_algorithm_info->core_state;
774 if (armv4_5->core_state == ARMV4_5_STATE_ARM)
775 exit_breakpoint_size = 4;
776 else if (armv4_5->core_state == ARMV4_5_STATE_THUMB)
777 exit_breakpoint_size = 2;
778 else
779 {
780 LOG_ERROR("BUG: can't execute algorithms when not in ARM or Thumb state");
781 return ERROR_INVALID_ARGUMENTS;
782 }
783
784 if (armv4_5_algorithm_info->core_mode != ARMV4_5_MODE_ANY)
785 {
786 LOG_DEBUG("setting core_mode: 0x%2.2x", armv4_5_algorithm_info->core_mode);
787 buf_set_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 5, armv4_5_algorithm_info->core_mode);
788 armv4_5->core_cache->reg_list[ARMV4_5_CPSR].dirty = 1;
789 armv4_5->core_cache->reg_list[ARMV4_5_CPSR].valid = 1;
790 }
791
792 /* terminate using a hardware or (ARMv5+) software breakpoint */
793 if (exit_point && (retval = breakpoint_add(target, exit_point,
794 exit_breakpoint_size, BKPT_HARD)) != ERROR_OK)
795 {
796 LOG_ERROR("can't add HW breakpoint to terminate algorithm");
797 return ERROR_TARGET_FAILURE;
798 }
799
800 if ((retval = target_resume(target, 0, entry_point, 1, 1)) != ERROR_OK)
801 {
802 return retval;
803 }
804 int retvaltemp;
805 retval = run_it(target, exit_point, timeout_ms, arch_info);
806
807 if (exit_point)
808 breakpoint_remove(target, exit_point);
809
810 if (retval != ERROR_OK)
811 return retval;
812
813 for (i = 0; i < num_mem_params; i++)
814 {
815 if (mem_params[i].direction != PARAM_OUT)
816 if ((retvaltemp = target_read_buffer(target, mem_params[i].address, mem_params[i].size, mem_params[i].value)) != ERROR_OK)
817 {
818 retval = retvaltemp;
819 }
820 }
821
822 for (i = 0; i < num_reg_params; i++)
823 {
824 if (reg_params[i].direction != PARAM_OUT)
825 {
826
827 struct reg *reg = register_get_by_name(armv4_5->core_cache, reg_params[i].reg_name, 0);
828 if (!reg)
829 {
830 LOG_ERROR("BUG: register '%s' not found", reg_params[i].reg_name);
831 retval = ERROR_INVALID_ARGUMENTS;
832 continue;
833 }
834
835 if (reg->size != reg_params[i].size)
836 {
837 LOG_ERROR("BUG: register '%s' size doesn't match reg_params[i].size", reg_params[i].reg_name);
838 retval = ERROR_INVALID_ARGUMENTS;
839 continue;
840 }
841
842 buf_set_u32(reg_params[i].value, 0, 32, buf_get_u32(reg->value, 0, 32));
843 }
844 }
845
846 for (i = 0; i <= 16; i++)
847 {
848 uint32_t regvalue;
849 regvalue = buf_get_u32(ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5_algorithm_info->core_mode, i).value, 0, 32);
850 if (regvalue != context[i])
851 {
852 LOG_DEBUG("restoring register %s with value 0x%8.8" PRIx32 "", ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5_algorithm_info->core_mode, i).name, context[i]);
853 buf_set_u32(ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5_algorithm_info->core_mode, i).value, 0, 32, context[i]);
854 ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5_algorithm_info->core_mode, i).valid = 1;
855 ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5_algorithm_info->core_mode, i).dirty = 1;
856 }
857 }
858 buf_set_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 32, cpsr);
859 armv4_5->core_cache->reg_list[ARMV4_5_CPSR].valid = 1;
860 armv4_5->core_cache->reg_list[ARMV4_5_CPSR].dirty = 1;
861
862 armv4_5->core_state = core_state;
863 armv4_5->core_mode = core_mode;
864
865 return retval;
866 }
867
868 int armv4_5_run_algorithm(struct target *target, int num_mem_params, struct mem_param *mem_params, int num_reg_params, struct reg_param *reg_params, uint32_t entry_point, uint32_t exit_point, int timeout_ms, void *arch_info)
869 {
870 return armv4_5_run_algorithm_inner(target, num_mem_params, mem_params, num_reg_params, reg_params, entry_point, exit_point, timeout_ms, arch_info, armv4_5_run_algorithm_completion);
871 }
872
873 /**
874 * Runs ARM code in the target to calculate a CRC32 checksum.
875 *
876 * \todo On ARMv5+, rely on BKPT termination for reduced overhead.
877 */
878 int arm_checksum_memory(struct target *target,
879 uint32_t address, uint32_t count, uint32_t *checksum)
880 {
881 struct working_area *crc_algorithm;
882 struct armv4_5_algorithm armv4_5_info;
883 struct reg_param reg_params[2];
884 int retval;
885 uint32_t i;
886
887 static const uint32_t arm_crc_code[] = {
888 0xE1A02000, /* mov r2, r0 */
889 0xE3E00000, /* mov r0, #0xffffffff */
890 0xE1A03001, /* mov r3, r1 */
891 0xE3A04000, /* mov r4, #0 */
892 0xEA00000B, /* b ncomp */
893 /* nbyte: */
894 0xE7D21004, /* ldrb r1, [r2, r4] */
895 0xE59F7030, /* ldr r7, CRC32XOR */
896 0xE0200C01, /* eor r0, r0, r1, asl 24 */
897 0xE3A05000, /* mov r5, #0 */
898 /* loop: */
899 0xE3500000, /* cmp r0, #0 */
900 0xE1A06080, /* mov r6, r0, asl #1 */
901 0xE2855001, /* add r5, r5, #1 */
902 0xE1A00006, /* mov r0, r6 */
903 0xB0260007, /* eorlt r0, r6, r7 */
904 0xE3550008, /* cmp r5, #8 */
905 0x1AFFFFF8, /* bne loop */
906 0xE2844001, /* add r4, r4, #1 */
907 /* ncomp: */
908 0xE1540003, /* cmp r4, r3 */
909 0x1AFFFFF1, /* bne nbyte */
910 /* end: */
911 0xEAFFFFFE, /* b end */
912 /* CRC32XOR: */
913 0x04C11DB7 /* .word 0x04C11DB7 */
914 };
915
916 retval = target_alloc_working_area(target,
917 sizeof(arm_crc_code), &crc_algorithm);
918 if (retval != ERROR_OK)
919 return retval;
920
921 /* convert code into a buffer in target endianness */
922 for (i = 0; i < ARRAY_SIZE(arm_crc_code); i++) {
923 retval = target_write_u32(target,
924 crc_algorithm->address + i * sizeof(uint32_t),
925 arm_crc_code[i]);
926 if (retval != ERROR_OK)
927 return retval;
928 }
929
930 armv4_5_info.common_magic = ARMV4_5_COMMON_MAGIC;
931 armv4_5_info.core_mode = ARMV4_5_MODE_SVC;
932 armv4_5_info.core_state = ARMV4_5_STATE_ARM;
933
934 init_reg_param(&reg_params[0], "r0", 32, PARAM_IN_OUT);
935 init_reg_param(&reg_params[1], "r1", 32, PARAM_OUT);
936
937 buf_set_u32(reg_params[0].value, 0, 32, address);
938 buf_set_u32(reg_params[1].value, 0, 32, count);
939
940 /* 20 second timeout/megabyte */
941 int timeout = 20000 * (1 + (count / (1024 * 1024)));
942
943 retval = target_run_algorithm(target, 0, NULL, 2, reg_params,
944 crc_algorithm->address,
945 crc_algorithm->address + sizeof(arm_crc_code) - 8,
946 timeout, &armv4_5_info);
947 if (retval != ERROR_OK) {
948 LOG_ERROR("error executing ARM crc algorithm");
949 destroy_reg_param(&reg_params[0]);
950 destroy_reg_param(&reg_params[1]);
951 target_free_working_area(target, crc_algorithm);
952 return retval;
953 }
954
955 *checksum = buf_get_u32(reg_params[0].value, 0, 32);
956
957 destroy_reg_param(&reg_params[0]);
958 destroy_reg_param(&reg_params[1]);
959
960 target_free_working_area(target, crc_algorithm);
961
962 return ERROR_OK;
963 }
964
965 /**
966 * Runs ARM code in the target to check whether a memory block holds
967 * all ones. NOR flash which has been erased, and thus may be written,
968 * holds all ones.
969 *
970 * \todo On ARMv5+, rely on BKPT termination for reduced overhead.
971 */
972 int arm_blank_check_memory(struct target *target,
973 uint32_t address, uint32_t count, uint32_t *blank)
974 {
975 struct working_area *check_algorithm;
976 struct reg_param reg_params[3];
977 struct armv4_5_algorithm armv4_5_info;
978 int retval;
979 uint32_t i;
980
981 static const uint32_t check_code[] = {
982 /* loop: */
983 0xe4d03001, /* ldrb r3, [r0], #1 */
984 0xe0022003, /* and r2, r2, r3 */
985 0xe2511001, /* subs r1, r1, #1 */
986 0x1afffffb, /* bne loop */
987 /* end: */
988 0xeafffffe /* b end */
989 };
990
991 /* make sure we have a working area */
992 retval = target_alloc_working_area(target,
993 sizeof(check_code), &check_algorithm);
994 if (retval != ERROR_OK)
995 return retval;
996
997 /* convert code into a buffer in target endianness */
998 for (i = 0; i < ARRAY_SIZE(check_code); i++) {
999 retval = target_write_u32(target,
1000 check_algorithm->address
1001 + i * sizeof(uint32_t),
1002 check_code[i]);
1003 if (retval != ERROR_OK)
1004 return retval;
1005 }
1006
1007 armv4_5_info.common_magic = ARMV4_5_COMMON_MAGIC;
1008 armv4_5_info.core_mode = ARMV4_5_MODE_SVC;
1009 armv4_5_info.core_state = ARMV4_5_STATE_ARM;
1010
1011 init_reg_param(&reg_params[0], "r0", 32, PARAM_OUT);
1012 buf_set_u32(reg_params[0].value, 0, 32, address);
1013
1014 init_reg_param(&reg_params[1], "r1", 32, PARAM_OUT);
1015 buf_set_u32(reg_params[1].value, 0, 32, count);
1016
1017 init_reg_param(&reg_params[2], "r2", 32, PARAM_IN_OUT);
1018 buf_set_u32(reg_params[2].value, 0, 32, 0xff);
1019
1020 retval = target_run_algorithm(target, 0, NULL, 3, reg_params,
1021 check_algorithm->address,
1022 check_algorithm->address + sizeof(check_code) - 4,
1023 10000, &armv4_5_info);
1024 if (retval != ERROR_OK) {
1025 destroy_reg_param(&reg_params[0]);
1026 destroy_reg_param(&reg_params[1]);
1027 destroy_reg_param(&reg_params[2]);
1028 target_free_working_area(target, check_algorithm);
1029 return retval;
1030 }
1031
1032 *blank = buf_get_u32(reg_params[2].value, 0, 32);
1033
1034 destroy_reg_param(&reg_params[0]);
1035 destroy_reg_param(&reg_params[1]);
1036 destroy_reg_param(&reg_params[2]);
1037
1038 target_free_working_area(target, check_algorithm);
1039
1040 return ERROR_OK;
1041 }
1042
1043 static int arm_full_context(struct target *target)
1044 {
1045 struct armv4_5_common_s *armv4_5 = target_to_armv4_5(target);
1046 unsigned num_regs = armv4_5->core_cache->num_regs;
1047 struct reg *reg = armv4_5->core_cache->reg_list;
1048 int retval = ERROR_OK;
1049
1050 for (; num_regs && retval == ERROR_OK; num_regs--, reg++) {
1051 if (reg->valid)
1052 continue;
1053 retval = armv4_5_get_core_reg(reg);
1054 }
1055 return retval;
1056 }
1057
1058 int armv4_5_init_arch_info(struct target *target, struct arm *armv4_5)
1059 {
1060 target->arch_info = armv4_5;
1061
1062 armv4_5->common_magic = ARMV4_5_COMMON_MAGIC;
1063 armv4_5->core_state = ARMV4_5_STATE_ARM;
1064 armv4_5->core_mode = ARMV4_5_MODE_USR;
1065
1066 /* core_type may be overridden by subtype logic */
1067 armv4_5->core_type = ARMV4_5_MODE_ANY;
1068
1069 /* default full_context() has no core-specific optimizations */
1070 if (!armv4_5->full_context && armv4_5->read_core_reg)
1071 armv4_5->full_context = arm_full_context;
1072
1073 return ERROR_OK;
1074 }

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)