ARMv7-A: use standard ARM core states
[openocd/ztw.git] / src / target / armv4_5.c
blob5e882e67fb76406eaf5956edff49c54ea0df0bd4
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
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"
39 static const char *armv4_5_core_reg_list[] =
41 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
42 "r8", "r9", "r10", "r11", "r12", "sp_usr", "lr_usr", "pc",
44 "r8_fiq", "r9_fiq", "r10_fiq", "r11_fiq", "r12_fiq", "sp_fiq", "lr_fiq",
46 "sp_irq", "lr_irq",
48 "sp_svc", "lr_svc",
50 "sp_abt", "lr_abt",
52 "sp_und", "lr_und",
54 "cpsr", "spsr_fiq", "spsr_irq", "spsr_svc", "spsr_abt", "spsr_und",
56 "sp_mon", "lr_mon", "spsr_mon",
59 static const uint8_t arm_usr_indices[17] = {
60 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, ARMV4_5_CPSR,
63 static const uint8_t arm_fiq_indices[8] = {
64 16, 17, 18, 19, 20, 21, 22, ARMV4_5_SPSR_FIQ,
67 static const uint8_t arm_irq_indices[3] = {
68 23, 24, ARMV4_5_SPSR_IRQ,
71 static const uint8_t arm_svc_indices[3] = {
72 25, 26, ARMV4_5_SPSR_SVC,
75 static const uint8_t arm_abt_indices[3] = {
76 27, 28, ARMV4_5_SPSR_ABT,
79 static const uint8_t arm_und_indices[3] = {
80 29, 30, ARMV4_5_SPSR_UND,
83 static const uint8_t arm_mon_indices[3] = {
84 37, 38, ARM_SPSR_MON,
87 static const struct {
88 const char *name;
89 unsigned short psr;
90 /* For user and system modes, these list indices for all registers.
91 * otherwise they're just indices for the shadow registers and SPSR.
93 unsigned short n_indices;
94 const uint8_t *indices;
95 } arm_mode_data[] = {
96 /* Seven modes are standard from ARM7 on. "System" and "User" share
97 * the same registers; other modes shadow from 3 to 8 registers.
100 .name = "User",
101 .psr = ARMV4_5_MODE_USR,
102 .n_indices = ARRAY_SIZE(arm_usr_indices),
103 .indices = arm_usr_indices,
106 .name = "FIQ",
107 .psr = ARMV4_5_MODE_FIQ,
108 .n_indices = ARRAY_SIZE(arm_fiq_indices),
109 .indices = arm_fiq_indices,
112 .name = "Supervisor",
113 .psr = ARMV4_5_MODE_SVC,
114 .n_indices = ARRAY_SIZE(arm_svc_indices),
115 .indices = arm_svc_indices,
118 .name = "Abort",
119 .psr = ARMV4_5_MODE_ABT,
120 .n_indices = ARRAY_SIZE(arm_abt_indices),
121 .indices = arm_abt_indices,
124 .name = "IRQ",
125 .psr = ARMV4_5_MODE_IRQ,
126 .n_indices = ARRAY_SIZE(arm_irq_indices),
127 .indices = arm_irq_indices,
130 .name = "Undefined instruction",
131 .psr = ARMV4_5_MODE_UND,
132 .n_indices = ARRAY_SIZE(arm_und_indices),
133 .indices = arm_und_indices,
136 .name = "System",
137 .psr = ARMV4_5_MODE_SYS,
138 .n_indices = ARRAY_SIZE(arm_usr_indices),
139 .indices = arm_usr_indices,
141 /* TrustZone "Security Extensions" add a secure monitor mode.
142 * This is distinct from a "debug monitor" which can support
143 * non-halting debug, in conjunction with some debuggers.
146 .name = "Secure Monitor",
147 .psr = ARM_MODE_MON,
148 .n_indices = ARRAY_SIZE(arm_mon_indices),
149 .indices = arm_mon_indices,
153 /** Map PSR mode bits to the name of an ARM processor operating mode. */
154 const char *arm_mode_name(unsigned psr_mode)
156 for (unsigned i = 0; i < ARRAY_SIZE(arm_mode_data); i++) {
157 if (arm_mode_data[i].psr == psr_mode)
158 return arm_mode_data[i].name;
160 LOG_ERROR("unrecognized psr mode: %#02x", psr_mode);
161 return "UNRECOGNIZED";
164 /** Return true iff the parameter denotes a valid ARM processor mode. */
165 bool is_arm_mode(unsigned psr_mode)
167 for (unsigned i = 0; i < ARRAY_SIZE(arm_mode_data); i++) {
168 if (arm_mode_data[i].psr == psr_mode)
169 return true;
171 return false;
174 /** Map PSR mode bits to linear number indexing armv4_5_core_reg_map */
175 int armv4_5_mode_to_number(enum armv4_5_mode mode)
177 switch (mode) {
178 case ARMV4_5_MODE_ANY:
179 /* map MODE_ANY to user mode */
180 case ARMV4_5_MODE_USR:
181 return 0;
182 case ARMV4_5_MODE_FIQ:
183 return 1;
184 case ARMV4_5_MODE_IRQ:
185 return 2;
186 case ARMV4_5_MODE_SVC:
187 return 3;
188 case ARMV4_5_MODE_ABT:
189 return 4;
190 case ARMV4_5_MODE_UND:
191 return 5;
192 case ARMV4_5_MODE_SYS:
193 return 6;
194 case ARM_MODE_MON:
195 return 7;
196 default:
197 LOG_ERROR("invalid mode value encountered %d", mode);
198 return -1;
202 /** Map linear number indexing armv4_5_core_reg_map to PSR mode bits. */
203 enum armv4_5_mode armv4_5_number_to_mode(int number)
205 switch (number) {
206 case 0:
207 return ARMV4_5_MODE_USR;
208 case 1:
209 return ARMV4_5_MODE_FIQ;
210 case 2:
211 return ARMV4_5_MODE_IRQ;
212 case 3:
213 return ARMV4_5_MODE_SVC;
214 case 4:
215 return ARMV4_5_MODE_ABT;
216 case 5:
217 return ARMV4_5_MODE_UND;
218 case 6:
219 return ARMV4_5_MODE_SYS;
220 case 7:
221 return ARM_MODE_MON;
222 default:
223 LOG_ERROR("mode index out of bounds %d", number);
224 return ARMV4_5_MODE_ANY;
228 char* armv4_5_state_strings[] =
230 "ARM", "Thumb", "Jazelle", "ThumbEE",
233 static const struct armv4_5_core_reg armv4_5_core_reg_list_arch_info[] =
235 {0, ARMV4_5_MODE_ANY, NULL, NULL},
236 {1, ARMV4_5_MODE_ANY, NULL, NULL},
237 {2, ARMV4_5_MODE_ANY, NULL, NULL},
238 {3, ARMV4_5_MODE_ANY, NULL, NULL},
239 {4, ARMV4_5_MODE_ANY, NULL, NULL},
240 {5, ARMV4_5_MODE_ANY, NULL, NULL},
241 {6, ARMV4_5_MODE_ANY, NULL, NULL},
242 {7, ARMV4_5_MODE_ANY, NULL, NULL},
243 {8, ARMV4_5_MODE_ANY, NULL, NULL},
244 {9, ARMV4_5_MODE_ANY, NULL, NULL},
245 {10, ARMV4_5_MODE_ANY, NULL, NULL},
246 {11, ARMV4_5_MODE_ANY, NULL, NULL},
247 {12, ARMV4_5_MODE_ANY, NULL, NULL},
248 {13, ARMV4_5_MODE_USR, NULL, NULL},
249 {14, ARMV4_5_MODE_USR, NULL, NULL},
250 {15, ARMV4_5_MODE_ANY, NULL, NULL},
252 {8, ARMV4_5_MODE_FIQ, NULL, NULL},
253 {9, ARMV4_5_MODE_FIQ, NULL, NULL},
254 {10, ARMV4_5_MODE_FIQ, NULL, NULL},
255 {11, ARMV4_5_MODE_FIQ, NULL, NULL},
256 {12, ARMV4_5_MODE_FIQ, NULL, NULL},
257 {13, ARMV4_5_MODE_FIQ, NULL, NULL},
258 {14, ARMV4_5_MODE_FIQ, NULL, NULL},
260 {13, ARMV4_5_MODE_IRQ, NULL, NULL},
261 {14, ARMV4_5_MODE_IRQ, NULL, NULL},
263 {13, ARMV4_5_MODE_SVC, NULL, NULL},
264 {14, ARMV4_5_MODE_SVC, NULL, NULL},
266 {13, ARMV4_5_MODE_ABT, NULL, NULL},
267 {14, ARMV4_5_MODE_ABT, NULL, NULL},
269 {13, ARMV4_5_MODE_UND, NULL, NULL},
270 {14, ARMV4_5_MODE_UND, NULL, NULL},
272 {16, ARMV4_5_MODE_ANY, NULL, NULL},
273 {16, ARMV4_5_MODE_FIQ, NULL, NULL},
274 {16, ARMV4_5_MODE_IRQ, NULL, NULL},
275 {16, ARMV4_5_MODE_SVC, NULL, NULL},
276 {16, ARMV4_5_MODE_ABT, NULL, NULL},
277 {16, ARMV4_5_MODE_UND, NULL, NULL},
279 {13, ARM_MODE_MON, NULL, NULL},
280 {14, ARM_MODE_MON, NULL, NULL},
281 {16, ARM_MODE_MON, NULL, NULL},
284 /* map core mode (USR, FIQ, ...) and register number to indizes into the register cache */
285 const int armv4_5_core_reg_map[8][17] =
287 { /* USR */
288 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 31
290 { /* FIQ (8 shadows of USR, vs normal 3) */
291 0, 1, 2, 3, 4, 5, 6, 7, 16, 17, 18, 19, 20, 21, 22, 15, 32
293 { /* IRQ */
294 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 23, 24, 15, 33
296 { /* SVC */
297 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 25, 26, 15, 34
299 { /* ABT */
300 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 27, 28, 15, 35
302 { /* UND */
303 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 29, 30, 15, 36
305 { /* SYS (same registers as USR) */
306 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 31
308 { /* MON */
309 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 37, 38, 15, 39,
313 static const uint8_t arm_gdb_dummy_fp_value[12];
316 * Dummy FPA registers are required to support GDB on ARM.
317 * Register packets require eight obsolete FPA register values.
318 * Modern ARM cores use Vector Floating Point (VFP), if they
319 * have any floating point support. VFP is not FPA-compatible.
321 struct reg arm_gdb_dummy_fp_reg =
323 .name = "GDB dummy FPA register",
324 .value = (uint8_t *) arm_gdb_dummy_fp_value,
325 .valid = 1,
326 .size = 96,
329 static const uint8_t arm_gdb_dummy_fps_value[4];
332 * Dummy FPA status registers are required to support GDB on ARM.
333 * Register packets require an obsolete FPA status register.
335 struct reg arm_gdb_dummy_fps_reg =
337 .name = "GDB dummy FPA status register",
338 .value = (uint8_t *) arm_gdb_dummy_fps_value,
339 .valid = 1,
340 .size = 32,
343 static void arm_gdb_dummy_init(void) __attribute__ ((constructor));
345 static void arm_gdb_dummy_init(void)
347 register_init_dummy(&arm_gdb_dummy_fp_reg);
348 register_init_dummy(&arm_gdb_dummy_fps_reg);
351 static int armv4_5_get_core_reg(struct reg *reg)
353 int retval;
354 struct armv4_5_core_reg *armv4_5 = reg->arch_info;
355 struct target *target = armv4_5->target;
357 if (target->state != TARGET_HALTED)
359 LOG_ERROR("Target not halted");
360 return ERROR_TARGET_NOT_HALTED;
363 retval = armv4_5->armv4_5_common->read_core_reg(target, armv4_5->num, armv4_5->mode);
364 if (retval == ERROR_OK)
365 reg->valid = 1;
367 return retval;
370 static int armv4_5_set_core_reg(struct reg *reg, uint8_t *buf)
372 struct armv4_5_core_reg *armv4_5 = reg->arch_info;
373 struct target *target = armv4_5->target;
374 struct armv4_5_common_s *armv4_5_target = target_to_armv4_5(target);
375 uint32_t value = buf_get_u32(buf, 0, 32);
377 if (target->state != TARGET_HALTED)
379 LOG_ERROR("Target not halted");
380 return ERROR_TARGET_NOT_HALTED;
383 if (reg == &armv4_5_target->core_cache->reg_list[ARMV4_5_CPSR])
385 if (value & 0x20)
387 /* T bit should be set */
388 if (armv4_5_target->core_state == ARMV4_5_STATE_ARM)
390 /* change state to Thumb */
391 LOG_DEBUG("changing to Thumb state");
392 armv4_5_target->core_state = ARMV4_5_STATE_THUMB;
395 else
397 /* T bit should be cleared */
398 if (armv4_5_target->core_state == ARMV4_5_STATE_THUMB)
400 /* change state to ARM */
401 LOG_DEBUG("changing to ARM state");
402 armv4_5_target->core_state = ARMV4_5_STATE_ARM;
406 if (armv4_5_target->core_mode != (enum armv4_5_mode)(value & 0x1f))
408 LOG_DEBUG("changing ARM core mode to '%s'",
409 arm_mode_name(value & 0x1f));
410 armv4_5_target->core_mode = value & 0x1f;
411 armv4_5_target->write_core_reg(target, 16, ARMV4_5_MODE_ANY, value);
415 buf_set_u32(reg->value, 0, 32, value);
416 reg->dirty = 1;
417 reg->valid = 1;
419 return ERROR_OK;
422 static const struct reg_arch_type arm_reg_type = {
423 .get = armv4_5_get_core_reg,
424 .set = armv4_5_set_core_reg,
427 /** Marks the contents of the register cache as invalid (and clean). */
428 int armv4_5_invalidate_core_regs(struct target *target)
430 struct armv4_5_common_s *armv4_5 = target_to_armv4_5(target);
431 unsigned num_regs = armv4_5->core_cache->num_regs;
432 struct reg *reg = armv4_5->core_cache->reg_list;
434 for (unsigned i = 0; i < num_regs; i++, reg++) {
435 reg->valid = 0;
436 reg->dirty = 0;
439 /* FIXME don't bother returning a value then */
440 return ERROR_OK;
443 struct reg_cache* armv4_5_build_reg_cache(struct target *target, struct arm *armv4_5_common)
445 int num_regs = ARRAY_SIZE(armv4_5_core_reg_list_arch_info);
446 struct reg_cache *cache = malloc(sizeof(struct reg_cache));
447 struct reg *reg_list = calloc(num_regs, sizeof(struct reg));
448 struct armv4_5_core_reg *arch_info = calloc(num_regs,
449 sizeof(struct armv4_5_core_reg));
450 int i;
452 if (!cache || !reg_list || !arch_info) {
453 free(cache);
454 free(reg_list);
455 free(arch_info);
456 return NULL;
459 cache->name = "ARM registers";
460 cache->next = NULL;
461 cache->reg_list = reg_list;
462 cache->num_regs = 0;
464 for (i = 0; i < num_regs; i++)
466 /* Skip registers this core doesn't expose */
467 if (armv4_5_core_reg_list_arch_info[i].mode == ARM_MODE_MON
468 && armv4_5_common->core_type != ARM_MODE_MON)
469 continue;
471 /* REVISIT handle Cortex-M, which only shadows R13/SP */
473 arch_info[i] = armv4_5_core_reg_list_arch_info[i];
474 arch_info[i].target = target;
475 arch_info[i].armv4_5_common = armv4_5_common;
476 reg_list[i].name = (char *) armv4_5_core_reg_list[i];
477 reg_list[i].size = 32;
478 reg_list[i].value = calloc(1, 4);
479 reg_list[i].type = &arm_reg_type;
480 reg_list[i].arch_info = &arch_info[i];
482 cache->num_regs++;
485 return cache;
488 int armv4_5_arch_state(struct target *target)
490 struct armv4_5_common_s *armv4_5 = target_to_armv4_5(target);
492 if (armv4_5->common_magic != ARMV4_5_COMMON_MAGIC)
494 LOG_ERROR("BUG: called for a non-ARMv4/5 target");
495 return ERROR_FAIL;
498 LOG_USER("target halted in %s state due to %s, current mode: %s\ncpsr: 0x%8.8" PRIx32 " pc: 0x%8.8" PRIx32 "",
499 armv4_5_state_strings[armv4_5->core_state],
500 Jim_Nvp_value2name_simple(nvp_target_debug_reason, target->debug_reason)->name,
501 arm_mode_name(armv4_5->core_mode),
502 buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 32),
503 buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32));
505 return ERROR_OK;
508 #define ARMV4_5_CORE_REG_MODENUM(cache, mode, num) \
509 cache->reg_list[armv4_5_core_reg_map[mode][num]]
511 COMMAND_HANDLER(handle_armv4_5_reg_command)
513 struct target *target = get_current_target(CMD_CTX);
514 struct armv4_5_common_s *armv4_5 = target_to_armv4_5(target);
515 unsigned num_regs;
516 struct reg *regs;
518 if (!is_arm(armv4_5))
520 command_print(CMD_CTX, "current target isn't an ARM");
521 return ERROR_FAIL;
524 if (target->state != TARGET_HALTED)
526 command_print(CMD_CTX, "error: target must be halted for register accesses");
527 return ERROR_FAIL;
530 if (!is_arm_mode(armv4_5->core_mode))
531 return ERROR_FAIL;
533 if (!armv4_5->full_context) {
534 command_print(CMD_CTX, "error: target doesn't support %s",
535 CMD_NAME);
536 return ERROR_FAIL;
539 num_regs = armv4_5->core_cache->num_regs;
540 regs = armv4_5->core_cache->reg_list;
542 for (unsigned mode = 0; mode < ARRAY_SIZE(arm_mode_data); mode++) {
543 const char *name;
544 char *sep = "\n";
545 char *shadow = "";
547 /* label this bank of registers (or shadows) */
548 switch (arm_mode_data[mode].psr) {
549 case ARMV4_5_MODE_SYS:
550 continue;
551 case ARMV4_5_MODE_USR:
552 name = "System and User";
553 sep = "";
554 break;
555 case ARM_MODE_MON:
556 if (armv4_5->core_type != ARM_MODE_MON)
557 continue;
558 /* FALLTHROUGH */
559 default:
560 name = arm_mode_data[mode].name;
561 shadow = "shadow ";
562 break;
564 command_print(CMD_CTX, "%s%s mode %sregisters",
565 sep, name, shadow);
567 /* display N rows of up to 4 registers each */
568 for (unsigned i = 0; i < arm_mode_data[mode].n_indices;) {
569 char output[80];
570 int output_len = 0;
572 for (unsigned j = 0; j < 4; j++, i++) {
573 uint32_t value;
574 struct reg *reg = regs;
576 if (i >= arm_mode_data[mode].n_indices)
577 break;
579 reg += arm_mode_data[mode].indices[i];
581 /* REVISIT be smarter about faults... */
582 if (!reg->valid)
583 armv4_5->full_context(target);
585 value = buf_get_u32(reg->value, 0, 32);
586 output_len += snprintf(output + output_len,
587 sizeof(output) - output_len,
588 "%8s: %8.8" PRIx32 " ",
589 reg->name, value);
591 command_print(CMD_CTX, "%s", output);
595 return ERROR_OK;
598 COMMAND_HANDLER(handle_armv4_5_core_state_command)
600 struct target *target = get_current_target(CMD_CTX);
601 struct armv4_5_common_s *armv4_5 = target_to_armv4_5(target);
603 if (!is_arm(armv4_5))
605 command_print(CMD_CTX, "current target isn't an ARM");
606 return ERROR_FAIL;
609 if (CMD_ARGC > 0)
611 if (strcmp(CMD_ARGV[0], "arm") == 0)
613 armv4_5->core_state = ARMV4_5_STATE_ARM;
615 if (strcmp(CMD_ARGV[0], "thumb") == 0)
617 armv4_5->core_state = ARMV4_5_STATE_THUMB;
621 command_print(CMD_CTX, "core state: %s", armv4_5_state_strings[armv4_5->core_state]);
623 return ERROR_OK;
626 COMMAND_HANDLER(handle_armv4_5_disassemble_command)
628 int retval = ERROR_OK;
629 struct target *target = get_current_target(CMD_CTX);
630 struct arm *arm = target ? target_to_arm(target) : NULL;
631 uint32_t address;
632 int count = 1;
633 int thumb = 0;
635 if (!is_arm(arm)) {
636 command_print(CMD_CTX, "current target isn't an ARM");
637 return ERROR_FAIL;
640 switch (CMD_ARGC) {
641 case 3:
642 if (strcmp(CMD_ARGV[2], "thumb") != 0)
643 goto usage;
644 thumb = 1;
645 /* FALL THROUGH */
646 case 2:
647 COMMAND_PARSE_NUMBER(int, CMD_ARGV[1], count);
648 /* FALL THROUGH */
649 case 1:
650 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], address);
651 if (address & 0x01) {
652 if (!thumb) {
653 command_print(CMD_CTX, "Disassemble as Thumb");
654 thumb = 1;
656 address &= ~1;
658 break;
659 default:
660 usage:
661 command_print(CMD_CTX,
662 "usage: arm disassemble <address> [<count> ['thumb']]");
663 count = 0;
664 retval = ERROR_FAIL;
667 while (count-- > 0) {
668 struct arm_instruction cur_instruction;
670 if (thumb) {
671 /* Always use Thumb2 disassembly for best handling
672 * of 32-bit BL/BLX, and to work with newer cores
673 * (some ARMv6, all ARMv7) that use Thumb2.
675 retval = thumb2_opcode(target, address,
676 &cur_instruction);
677 if (retval != ERROR_OK)
678 break;
679 } else {
680 uint32_t opcode;
682 retval = target_read_u32(target, address, &opcode);
683 if (retval != ERROR_OK)
684 break;
685 retval = arm_evaluate_opcode(opcode, address,
686 &cur_instruction) != ERROR_OK;
687 if (retval != ERROR_OK)
688 break;
690 command_print(CMD_CTX, "%s", cur_instruction.text);
691 address += cur_instruction.instruction_size;
694 return retval;
697 int armv4_5_register_commands(struct command_context *cmd_ctx)
699 struct command *armv4_5_cmd;
701 armv4_5_cmd = register_command(cmd_ctx, NULL, "arm",
702 NULL, COMMAND_ANY,
703 "generic ARM commands");
705 register_command(cmd_ctx, armv4_5_cmd, "reg",
706 handle_armv4_5_reg_command, COMMAND_EXEC,
707 "display ARM core registers");
708 register_command(cmd_ctx, armv4_5_cmd, "core_state",
709 handle_armv4_5_core_state_command, COMMAND_EXEC,
710 "display/change ARM core state <arm | thumb>");
711 register_command(cmd_ctx, armv4_5_cmd, "disassemble",
712 handle_armv4_5_disassemble_command, COMMAND_EXEC,
713 "disassemble instructions "
714 "<address> [<count> ['thumb']]");
716 return ERROR_OK;
719 int armv4_5_get_gdb_reg_list(struct target *target, struct reg **reg_list[], int *reg_list_size)
721 struct armv4_5_common_s *armv4_5 = target_to_armv4_5(target);
722 int i;
724 if (!is_arm_mode(armv4_5->core_mode))
725 return ERROR_FAIL;
727 *reg_list_size = 26;
728 *reg_list = malloc(sizeof(struct reg*) * (*reg_list_size));
730 for (i = 0; i < 16; i++)
732 (*reg_list)[i] = &ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, i);
735 for (i = 16; i < 24; i++)
737 (*reg_list)[i] = &arm_gdb_dummy_fp_reg;
740 (*reg_list)[24] = &arm_gdb_dummy_fps_reg;
741 (*reg_list)[25] = &armv4_5->core_cache->reg_list[ARMV4_5_CPSR];
743 return ERROR_OK;
746 /* wait for execution to complete and check exit point */
747 static int armv4_5_run_algorithm_completion(struct target *target, uint32_t exit_point, int timeout_ms, void *arch_info)
749 int retval;
750 struct armv4_5_common_s *armv4_5 = target_to_armv4_5(target);
752 if ((retval = target_wait_state(target, TARGET_HALTED, timeout_ms)) != ERROR_OK)
754 return retval;
756 if (target->state != TARGET_HALTED)
758 if ((retval = target_halt(target)) != ERROR_OK)
759 return retval;
760 if ((retval = target_wait_state(target, TARGET_HALTED, 500)) != ERROR_OK)
762 return retval;
764 return ERROR_TARGET_TIMEOUT;
767 /* fast exit: ARMv5+ code can use BKPT */
768 if (exit_point && buf_get_u32(armv4_5->core_cache->reg_list[15].value,
769 0, 32) != exit_point)
771 LOG_WARNING("target reentered debug state, but not at the desired exit point: 0x%4.4" PRIx32 "",
772 buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32));
773 return ERROR_TARGET_TIMEOUT;
776 return ERROR_OK;
779 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))
781 struct armv4_5_common_s *armv4_5 = target_to_armv4_5(target);
782 struct armv4_5_algorithm *armv4_5_algorithm_info = arch_info;
783 enum armv4_5_state core_state = armv4_5->core_state;
784 enum armv4_5_mode core_mode = armv4_5->core_mode;
785 uint32_t context[17];
786 uint32_t cpsr;
787 int exit_breakpoint_size = 0;
788 int i;
789 int retval = ERROR_OK;
790 LOG_DEBUG("Running algorithm");
792 if (armv4_5_algorithm_info->common_magic != ARMV4_5_COMMON_MAGIC)
794 LOG_ERROR("current target isn't an ARMV4/5 target");
795 return ERROR_TARGET_INVALID;
798 if (target->state != TARGET_HALTED)
800 LOG_WARNING("target not halted");
801 return ERROR_TARGET_NOT_HALTED;
804 if (!is_arm_mode(armv4_5->core_mode))
805 return ERROR_FAIL;
807 /* armv5 and later can terminate with BKPT instruction; less overhead */
808 if (!exit_point && armv4_5->is_armv4)
810 LOG_ERROR("ARMv4 target needs HW breakpoint location");
811 return ERROR_FAIL;
814 for (i = 0; i <= 16; i++)
816 if (!ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5_algorithm_info->core_mode, i).valid)
817 armv4_5->read_core_reg(target, i, armv4_5_algorithm_info->core_mode);
818 context[i] = buf_get_u32(ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5_algorithm_info->core_mode, i).value, 0, 32);
820 cpsr = buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 32);
822 for (i = 0; i < num_mem_params; i++)
824 if ((retval = target_write_buffer(target, mem_params[i].address, mem_params[i].size, mem_params[i].value)) != ERROR_OK)
826 return retval;
830 for (i = 0; i < num_reg_params; i++)
832 struct reg *reg = register_get_by_name(armv4_5->core_cache, reg_params[i].reg_name, 0);
833 if (!reg)
835 LOG_ERROR("BUG: register '%s' not found", reg_params[i].reg_name);
836 return ERROR_INVALID_ARGUMENTS;
839 if (reg->size != reg_params[i].size)
841 LOG_ERROR("BUG: register '%s' size doesn't match reg_params[i].size", reg_params[i].reg_name);
842 return ERROR_INVALID_ARGUMENTS;
845 if ((retval = armv4_5_set_core_reg(reg, reg_params[i].value)) != ERROR_OK)
847 return retval;
851 armv4_5->core_state = armv4_5_algorithm_info->core_state;
852 if (armv4_5->core_state == ARMV4_5_STATE_ARM)
853 exit_breakpoint_size = 4;
854 else if (armv4_5->core_state == ARMV4_5_STATE_THUMB)
855 exit_breakpoint_size = 2;
856 else
858 LOG_ERROR("BUG: can't execute algorithms when not in ARM or Thumb state");
859 return ERROR_INVALID_ARGUMENTS;
862 if (armv4_5_algorithm_info->core_mode != ARMV4_5_MODE_ANY)
864 LOG_DEBUG("setting core_mode: 0x%2.2x", armv4_5_algorithm_info->core_mode);
865 buf_set_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 5, armv4_5_algorithm_info->core_mode);
866 armv4_5->core_cache->reg_list[ARMV4_5_CPSR].dirty = 1;
867 armv4_5->core_cache->reg_list[ARMV4_5_CPSR].valid = 1;
870 /* terminate using a hardware or (ARMv5+) software breakpoint */
871 if (exit_point && (retval = breakpoint_add(target, exit_point,
872 exit_breakpoint_size, BKPT_HARD)) != ERROR_OK)
874 LOG_ERROR("can't add HW breakpoint to terminate algorithm");
875 return ERROR_TARGET_FAILURE;
878 if ((retval = target_resume(target, 0, entry_point, 1, 1)) != ERROR_OK)
880 return retval;
882 int retvaltemp;
883 retval = run_it(target, exit_point, timeout_ms, arch_info);
885 if (exit_point)
886 breakpoint_remove(target, exit_point);
888 if (retval != ERROR_OK)
889 return retval;
891 for (i = 0; i < num_mem_params; i++)
893 if (mem_params[i].direction != PARAM_OUT)
894 if ((retvaltemp = target_read_buffer(target, mem_params[i].address, mem_params[i].size, mem_params[i].value)) != ERROR_OK)
896 retval = retvaltemp;
900 for (i = 0; i < num_reg_params; i++)
902 if (reg_params[i].direction != PARAM_OUT)
905 struct reg *reg = register_get_by_name(armv4_5->core_cache, reg_params[i].reg_name, 0);
906 if (!reg)
908 LOG_ERROR("BUG: register '%s' not found", reg_params[i].reg_name);
909 retval = ERROR_INVALID_ARGUMENTS;
910 continue;
913 if (reg->size != reg_params[i].size)
915 LOG_ERROR("BUG: register '%s' size doesn't match reg_params[i].size", reg_params[i].reg_name);
916 retval = ERROR_INVALID_ARGUMENTS;
917 continue;
920 buf_set_u32(reg_params[i].value, 0, 32, buf_get_u32(reg->value, 0, 32));
924 for (i = 0; i <= 16; i++)
926 uint32_t regvalue;
927 regvalue = buf_get_u32(ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5_algorithm_info->core_mode, i).value, 0, 32);
928 if (regvalue != context[i])
930 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]);
931 buf_set_u32(ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5_algorithm_info->core_mode, i).value, 0, 32, context[i]);
932 ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5_algorithm_info->core_mode, i).valid = 1;
933 ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5_algorithm_info->core_mode, i).dirty = 1;
936 buf_set_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 32, cpsr);
937 armv4_5->core_cache->reg_list[ARMV4_5_CPSR].valid = 1;
938 armv4_5->core_cache->reg_list[ARMV4_5_CPSR].dirty = 1;
940 armv4_5->core_state = core_state;
941 armv4_5->core_mode = core_mode;
943 return retval;
946 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)
948 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);
952 * Runs ARM code in the target to calculate a CRC32 checksum.
954 * \todo On ARMv5+, rely on BKPT termination for reduced overhead.
956 int arm_checksum_memory(struct target *target,
957 uint32_t address, uint32_t count, uint32_t *checksum)
959 struct working_area *crc_algorithm;
960 struct armv4_5_algorithm armv4_5_info;
961 struct reg_param reg_params[2];
962 int retval;
963 uint32_t i;
965 static const uint32_t arm_crc_code[] = {
966 0xE1A02000, /* mov r2, r0 */
967 0xE3E00000, /* mov r0, #0xffffffff */
968 0xE1A03001, /* mov r3, r1 */
969 0xE3A04000, /* mov r4, #0 */
970 0xEA00000B, /* b ncomp */
971 /* nbyte: */
972 0xE7D21004, /* ldrb r1, [r2, r4] */
973 0xE59F7030, /* ldr r7, CRC32XOR */
974 0xE0200C01, /* eor r0, r0, r1, asl 24 */
975 0xE3A05000, /* mov r5, #0 */
976 /* loop: */
977 0xE3500000, /* cmp r0, #0 */
978 0xE1A06080, /* mov r6, r0, asl #1 */
979 0xE2855001, /* add r5, r5, #1 */
980 0xE1A00006, /* mov r0, r6 */
981 0xB0260007, /* eorlt r0, r6, r7 */
982 0xE3550008, /* cmp r5, #8 */
983 0x1AFFFFF8, /* bne loop */
984 0xE2844001, /* add r4, r4, #1 */
985 /* ncomp: */
986 0xE1540003, /* cmp r4, r3 */
987 0x1AFFFFF1, /* bne nbyte */
988 /* end: */
989 0xEAFFFFFE, /* b end */
990 /* CRC32XOR: */
991 0x04C11DB7 /* .word 0x04C11DB7 */
994 retval = target_alloc_working_area(target,
995 sizeof(arm_crc_code), &crc_algorithm);
996 if (retval != ERROR_OK)
997 return retval;
999 /* convert code into a buffer in target endianness */
1000 for (i = 0; i < ARRAY_SIZE(arm_crc_code); i++) {
1001 retval = target_write_u32(target,
1002 crc_algorithm->address + i * sizeof(uint32_t),
1003 arm_crc_code[i]);
1004 if (retval != ERROR_OK)
1005 return retval;
1008 armv4_5_info.common_magic = ARMV4_5_COMMON_MAGIC;
1009 armv4_5_info.core_mode = ARMV4_5_MODE_SVC;
1010 armv4_5_info.core_state = ARMV4_5_STATE_ARM;
1012 init_reg_param(&reg_params[0], "r0", 32, PARAM_IN_OUT);
1013 init_reg_param(&reg_params[1], "r1", 32, PARAM_OUT);
1015 buf_set_u32(reg_params[0].value, 0, 32, address);
1016 buf_set_u32(reg_params[1].value, 0, 32, count);
1018 /* 20 second timeout/megabyte */
1019 int timeout = 20000 * (1 + (count / (1024 * 1024)));
1021 retval = target_run_algorithm(target, 0, NULL, 2, reg_params,
1022 crc_algorithm->address,
1023 crc_algorithm->address + sizeof(arm_crc_code) - 8,
1024 timeout, &armv4_5_info);
1025 if (retval != ERROR_OK) {
1026 LOG_ERROR("error executing ARM crc algorithm");
1027 destroy_reg_param(&reg_params[0]);
1028 destroy_reg_param(&reg_params[1]);
1029 target_free_working_area(target, crc_algorithm);
1030 return retval;
1033 *checksum = buf_get_u32(reg_params[0].value, 0, 32);
1035 destroy_reg_param(&reg_params[0]);
1036 destroy_reg_param(&reg_params[1]);
1038 target_free_working_area(target, crc_algorithm);
1040 return ERROR_OK;
1044 * Runs ARM code in the target to check whether a memory block holds
1045 * all ones. NOR flash which has been erased, and thus may be written,
1046 * holds all ones.
1048 * \todo On ARMv5+, rely on BKPT termination for reduced overhead.
1050 int arm_blank_check_memory(struct target *target,
1051 uint32_t address, uint32_t count, uint32_t *blank)
1053 struct working_area *check_algorithm;
1054 struct reg_param reg_params[3];
1055 struct armv4_5_algorithm armv4_5_info;
1056 int retval;
1057 uint32_t i;
1059 static const uint32_t check_code[] = {
1060 /* loop: */
1061 0xe4d03001, /* ldrb r3, [r0], #1 */
1062 0xe0022003, /* and r2, r2, r3 */
1063 0xe2511001, /* subs r1, r1, #1 */
1064 0x1afffffb, /* bne loop */
1065 /* end: */
1066 0xeafffffe /* b end */
1069 /* make sure we have a working area */
1070 retval = target_alloc_working_area(target,
1071 sizeof(check_code), &check_algorithm);
1072 if (retval != ERROR_OK)
1073 return retval;
1075 /* convert code into a buffer in target endianness */
1076 for (i = 0; i < ARRAY_SIZE(check_code); i++) {
1077 retval = target_write_u32(target,
1078 check_algorithm->address
1079 + i * sizeof(uint32_t),
1080 check_code[i]);
1081 if (retval != ERROR_OK)
1082 return retval;
1085 armv4_5_info.common_magic = ARMV4_5_COMMON_MAGIC;
1086 armv4_5_info.core_mode = ARMV4_5_MODE_SVC;
1087 armv4_5_info.core_state = ARMV4_5_STATE_ARM;
1089 init_reg_param(&reg_params[0], "r0", 32, PARAM_OUT);
1090 buf_set_u32(reg_params[0].value, 0, 32, address);
1092 init_reg_param(&reg_params[1], "r1", 32, PARAM_OUT);
1093 buf_set_u32(reg_params[1].value, 0, 32, count);
1095 init_reg_param(&reg_params[2], "r2", 32, PARAM_IN_OUT);
1096 buf_set_u32(reg_params[2].value, 0, 32, 0xff);
1098 retval = target_run_algorithm(target, 0, NULL, 3, reg_params,
1099 check_algorithm->address,
1100 check_algorithm->address + sizeof(check_code) - 4,
1101 10000, &armv4_5_info);
1102 if (retval != ERROR_OK) {
1103 destroy_reg_param(&reg_params[0]);
1104 destroy_reg_param(&reg_params[1]);
1105 destroy_reg_param(&reg_params[2]);
1106 target_free_working_area(target, check_algorithm);
1107 return retval;
1110 *blank = buf_get_u32(reg_params[2].value, 0, 32);
1112 destroy_reg_param(&reg_params[0]);
1113 destroy_reg_param(&reg_params[1]);
1114 destroy_reg_param(&reg_params[2]);
1116 target_free_working_area(target, check_algorithm);
1118 return ERROR_OK;
1121 static int arm_full_context(struct target *target)
1123 struct armv4_5_common_s *armv4_5 = target_to_armv4_5(target);
1124 unsigned num_regs = armv4_5->core_cache->num_regs;
1125 struct reg *reg = armv4_5->core_cache->reg_list;
1126 int retval = ERROR_OK;
1128 for (; num_regs && retval == ERROR_OK; num_regs--, reg++) {
1129 if (reg->valid)
1130 continue;
1131 retval = armv4_5_get_core_reg(reg);
1133 return retval;
1136 int armv4_5_init_arch_info(struct target *target, struct arm *armv4_5)
1138 target->arch_info = armv4_5;
1140 armv4_5->common_magic = ARMV4_5_COMMON_MAGIC;
1141 armv4_5->core_state = ARMV4_5_STATE_ARM;
1142 armv4_5->core_mode = ARMV4_5_MODE_USR;
1144 /* core_type may be overridden by subtype logic */
1145 armv4_5->core_type = ARMV4_5_MODE_ANY;
1147 /* default full_context() has no core-specific optimizations */
1148 if (!armv4_5->full_context && armv4_5->read_core_reg)
1149 armv4_5->full_context = arm_full_context;
1151 return ERROR_OK;