1 /***************************************************************************
2 * Copyright (C) 2005 by Dominic Rath *
3 * Dominic.Rath@gmx.de *
5 * Copyright (C) 2008 by Spencer Oliver *
6 * spen@spen-soft.co.uk *
8 * Copyright (C) 2008 by Oyvind Harboe *
9 * oyvind.harboe@zylin.com *
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. *
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. *
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 ***************************************************************************/
32 #include "breakpoints.h"
33 #include "arm_disassembler.h"
34 #include "binarybuffer.h"
35 #include "algorithm.h"
39 static const char *armv4_5_core_reg_list[] =
41 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "r13_usr", "lr_usr", "pc",
43 "r8_fiq", "r9_fiq", "r10_fiq", "r11_fiq", "r12_fiq", "r13_fiq", "lr_fiq",
53 "cpsr", "spsr_fiq", "spsr_irq", "spsr_svc", "spsr_abt", "spsr_und"
60 /* Seven modes are standard from ARM7 on. "System" and "User" share
61 * the same registers; other modes shadow from 3 to 8 registers.
65 .psr = ARMV4_5_MODE_USR,
69 .psr = ARMV4_5_MODE_FIQ,
73 .psr = ARMV4_5_MODE_SVC,
77 .psr = ARMV4_5_MODE_ABT,
81 .psr = ARMV4_5_MODE_IRQ,
84 .name = "Undefined" /* instruction */,
85 .psr = ARMV4_5_MODE_UND,
89 .psr = ARMV4_5_MODE_SYS,
91 /* TrustZone "Security Extensions" add a secure monitor mode.
92 * This is distinct from a "debug monitor" which can support
93 * non-halting debug, in conjunction with some debuggers.
96 .name = "Secure Monitor",
101 /** Map PSR mode bits to the name of an ARM processor operating mode. */
102 const char *arm_mode_name(unsigned psr_mode)
104 for (unsigned i = 0; i < ARRAY_SIZE(arm_mode_data); i++) {
105 if (arm_mode_data[i].psr == psr_mode)
106 return arm_mode_data[i].name;
108 LOG_ERROR("unrecognized psr mode: %#02x", psr_mode);
109 return "UNRECOGNIZED";
112 /** Return true iff the parameter denotes a valid ARM processor mode. */
113 bool is_arm_mode(unsigned psr_mode)
115 for (unsigned i = 0; i < ARRAY_SIZE(arm_mode_data); i++) {
116 if (arm_mode_data[i].psr == psr_mode)
122 /** Map PSR mode bits to linear number indexing armv4_5_core_reg_map */
123 int armv4_5_mode_to_number(enum armv4_5_mode mode)
126 case ARMV4_5_MODE_ANY:
127 /* map MODE_ANY to user mode */
128 case ARMV4_5_MODE_USR:
130 case ARMV4_5_MODE_FIQ:
132 case ARMV4_5_MODE_IRQ:
134 case ARMV4_5_MODE_SVC:
136 case ARMV4_5_MODE_ABT:
138 case ARMV4_5_MODE_UND:
140 case ARMV4_5_MODE_SYS:
143 LOG_ERROR("invalid mode value encountered %d", mode);
148 /** Map linear number indexing armv4_5_core_reg_map to PSR mode bits. */
149 enum armv4_5_mode armv4_5_number_to_mode(int number)
153 return ARMV4_5_MODE_USR;
155 return ARMV4_5_MODE_FIQ;
157 return ARMV4_5_MODE_IRQ;
159 return ARMV4_5_MODE_SVC;
161 return ARMV4_5_MODE_ABT;
163 return ARMV4_5_MODE_UND;
165 return ARMV4_5_MODE_SYS;
167 LOG_ERROR("mode index out of bounds %d", number);
168 return ARMV4_5_MODE_ANY;
172 char* armv4_5_state_strings[] =
174 "ARM", "Thumb", "Jazelle"
177 static const struct armv4_5_core_reg armv4_5_core_reg_list_arch_info[] =
179 {0, ARMV4_5_MODE_ANY, NULL, NULL},
180 {1, ARMV4_5_MODE_ANY, NULL, NULL},
181 {2, ARMV4_5_MODE_ANY, NULL, NULL},
182 {3, ARMV4_5_MODE_ANY, NULL, NULL},
183 {4, ARMV4_5_MODE_ANY, NULL, NULL},
184 {5, ARMV4_5_MODE_ANY, NULL, NULL},
185 {6, ARMV4_5_MODE_ANY, NULL, NULL},
186 {7, ARMV4_5_MODE_ANY, NULL, NULL},
187 {8, ARMV4_5_MODE_ANY, NULL, NULL},
188 {9, ARMV4_5_MODE_ANY, NULL, NULL},
189 {10, ARMV4_5_MODE_ANY, NULL, NULL},
190 {11, ARMV4_5_MODE_ANY, NULL, NULL},
191 {12, ARMV4_5_MODE_ANY, NULL, NULL},
192 {13, ARMV4_5_MODE_USR, NULL, NULL},
193 {14, ARMV4_5_MODE_USR, NULL, NULL},
194 {15, ARMV4_5_MODE_ANY, NULL, NULL},
196 {8, ARMV4_5_MODE_FIQ, NULL, NULL},
197 {9, ARMV4_5_MODE_FIQ, NULL, NULL},
198 {10, ARMV4_5_MODE_FIQ, NULL, NULL},
199 {11, ARMV4_5_MODE_FIQ, NULL, NULL},
200 {12, ARMV4_5_MODE_FIQ, NULL, NULL},
201 {13, ARMV4_5_MODE_FIQ, NULL, NULL},
202 {14, ARMV4_5_MODE_FIQ, NULL, NULL},
204 {13, ARMV4_5_MODE_IRQ, NULL, NULL},
205 {14, ARMV4_5_MODE_IRQ, NULL, NULL},
207 {13, ARMV4_5_MODE_SVC, NULL, NULL},
208 {14, ARMV4_5_MODE_SVC, NULL, NULL},
210 {13, ARMV4_5_MODE_ABT, NULL, NULL},
211 {14, ARMV4_5_MODE_ABT, NULL, NULL},
213 {13, ARMV4_5_MODE_UND, NULL, NULL},
214 {14, ARMV4_5_MODE_UND, NULL, NULL},
216 {16, ARMV4_5_MODE_ANY, NULL, NULL},
217 {16, ARMV4_5_MODE_FIQ, NULL, NULL},
218 {16, ARMV4_5_MODE_IRQ, NULL, NULL},
219 {16, ARMV4_5_MODE_SVC, NULL, NULL},
220 {16, ARMV4_5_MODE_ABT, NULL, NULL},
221 {16, ARMV4_5_MODE_UND, NULL, NULL}
224 /* map core mode (USR, FIQ, ...) and register number to indizes into the register cache */
225 const int armv4_5_core_reg_map[7][17] =
228 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 31
231 0, 1, 2, 3, 4, 5, 6, 7, 16, 17, 18, 19, 20, 21, 22, 15, 32
234 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 23, 24, 15, 33
237 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 25, 26, 15, 34
240 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 27, 28, 15, 35
243 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 29, 30, 15, 36
246 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 31
250 static const uint8_t arm_gdb_dummy_fp_value[12];
253 * Dummy FPA registers are required to support GDB on ARM.
254 * Register packets require eight obsolete FPA register values.
255 * Modern ARM cores use Vector Floating Point (VFP), if they
256 * have any floating point support. VFP is not FPA-compatible.
258 struct reg arm_gdb_dummy_fp_reg =
260 .name = "GDB dummy FPA register",
261 .value = (uint8_t *) arm_gdb_dummy_fp_value,
266 static const uint8_t arm_gdb_dummy_fps_value[4];
269 * Dummy FPA status registers are required to support GDB on ARM.
270 * Register packets require an obsolete FPA status register.
272 struct reg arm_gdb_dummy_fps_reg =
274 .name = "GDB dummy FPA status register",
275 .value = (uint8_t *) arm_gdb_dummy_fps_value,
280 static void arm_gdb_dummy_init(void) __attribute__ ((constructor));
282 static void arm_gdb_dummy_init(void)
284 register_init_dummy(&arm_gdb_dummy_fp_reg);
285 register_init_dummy(&arm_gdb_dummy_fps_reg);
288 int armv4_5_get_core_reg(struct reg *reg)
291 struct armv4_5_core_reg *armv4_5 = reg->arch_info;
292 struct target *target = armv4_5->target;
294 if (target->state != TARGET_HALTED)
296 LOG_ERROR("Target not halted");
297 return ERROR_TARGET_NOT_HALTED;
300 /* retval = armv4_5->armv4_5_common->full_context(target); */
301 retval = armv4_5->armv4_5_common->read_core_reg(target, armv4_5->num, armv4_5->mode);
306 int armv4_5_set_core_reg(struct reg *reg, uint8_t *buf)
308 struct armv4_5_core_reg *armv4_5 = reg->arch_info;
309 struct target *target = armv4_5->target;
310 struct armv4_5_common_s *armv4_5_target = target_to_armv4_5(target);
311 uint32_t value = buf_get_u32(buf, 0, 32);
313 if (target->state != TARGET_HALTED)
315 return ERROR_TARGET_NOT_HALTED;
318 if (reg == &armv4_5_target->core_cache->reg_list[ARMV4_5_CPSR])
322 /* T bit should be set */
323 if (armv4_5_target->core_state == ARMV4_5_STATE_ARM)
325 /* change state to Thumb */
326 LOG_DEBUG("changing to Thumb state");
327 armv4_5_target->core_state = ARMV4_5_STATE_THUMB;
332 /* T bit should be cleared */
333 if (armv4_5_target->core_state == ARMV4_5_STATE_THUMB)
335 /* change state to ARM */
336 LOG_DEBUG("changing to ARM state");
337 armv4_5_target->core_state = ARMV4_5_STATE_ARM;
341 if (armv4_5_target->core_mode != (enum armv4_5_mode)(value & 0x1f))
343 LOG_DEBUG("changing ARM core mode to '%s'",
344 arm_mode_name(value & 0x1f));
345 armv4_5_target->core_mode = value & 0x1f;
346 armv4_5_target->write_core_reg(target, 16, ARMV4_5_MODE_ANY, value);
350 buf_set_u32(reg->value, 0, 32, value);
357 static const struct reg_arch_type arm_reg_type = {
358 .get = armv4_5_get_core_reg,
359 .set = armv4_5_set_core_reg,
362 int armv4_5_invalidate_core_regs(struct target *target)
364 struct armv4_5_common_s *armv4_5 = target_to_armv4_5(target);
367 for (i = 0; i < 37; i++)
369 armv4_5->core_cache->reg_list[i].valid = 0;
370 armv4_5->core_cache->reg_list[i].dirty = 0;
376 struct reg_cache* armv4_5_build_reg_cache(struct target *target, struct arm *armv4_5_common)
379 struct reg_cache *cache = malloc(sizeof(struct reg_cache));
380 struct reg *reg_list = malloc(sizeof(struct reg) * num_regs);
381 struct armv4_5_core_reg *arch_info = malloc(sizeof(struct armv4_5_core_reg) * num_regs);
384 cache->name = "arm v4/5 registers";
386 cache->reg_list = reg_list;
387 cache->num_regs = num_regs;
389 for (i = 0; i < 37; i++)
391 arch_info[i] = armv4_5_core_reg_list_arch_info[i];
392 arch_info[i].target = target;
393 arch_info[i].armv4_5_common = armv4_5_common;
394 reg_list[i].name = (char *) armv4_5_core_reg_list[i];
395 reg_list[i].size = 32;
396 reg_list[i].value = calloc(1, 4);
397 reg_list[i].dirty = 0;
398 reg_list[i].valid = 0;
399 reg_list[i].type = &arm_reg_type;
400 reg_list[i].arch_info = &arch_info[i];
406 int armv4_5_arch_state(struct target *target)
408 struct armv4_5_common_s *armv4_5 = target_to_armv4_5(target);
410 if (armv4_5->common_magic != ARMV4_5_COMMON_MAGIC)
412 LOG_ERROR("BUG: called for a non-ARMv4/5 target");
416 LOG_USER("target halted in %s state due to %s, current mode: %s\ncpsr: 0x%8.8" PRIx32 " pc: 0x%8.8" PRIx32 "",
417 armv4_5_state_strings[armv4_5->core_state],
418 Jim_Nvp_value2name_simple(nvp_target_debug_reason, target->debug_reason)->name,
419 arm_mode_name(armv4_5->core_mode),
420 buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 32),
421 buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32));
426 #define ARMV4_5_CORE_REG_MODENUM(cache, mode, num) \
427 cache->reg_list[armv4_5_core_reg_map[mode][num]]
429 COMMAND_HANDLER(handle_armv4_5_reg_command)
434 struct target *target = get_current_target(CMD_CTX);
435 struct armv4_5_common_s *armv4_5 = target_to_armv4_5(target);
437 if (!is_arm(armv4_5))
439 command_print(CMD_CTX, "current target isn't an ARM");
443 if (target->state != TARGET_HALTED)
445 command_print(CMD_CTX, "error: target must be halted for register accesses");
449 if (!is_arm_mode(armv4_5->core_mode))
452 if (!armv4_5->full_context) {
453 command_print(CMD_CTX, "error: target doesn't support %s",
458 for (num = 0; num <= 15; num++)
461 for (mode = 0; mode < 6; mode++)
463 if (!ARMV4_5_CORE_REG_MODENUM(armv4_5->core_cache, mode, num).valid)
465 armv4_5->full_context(target);
467 output_len += snprintf(output + output_len,
469 "%8s: %8.8" PRIx32 " ",
470 ARMV4_5_CORE_REG_MODENUM(armv4_5->core_cache, mode, num).name,
471 buf_get_u32(ARMV4_5_CORE_REG_MODENUM(armv4_5->core_cache, mode, num).value, 0, 32));
473 command_print(CMD_CTX, "%s", output);
475 command_print(CMD_CTX,
476 " 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 "",
477 buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 32),
478 buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_SPSR_FIQ].value, 0, 32),
479 buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_SPSR_IRQ].value, 0, 32),
480 buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_SPSR_SVC].value, 0, 32),
481 buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_SPSR_ABT].value, 0, 32),
482 buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_SPSR_UND].value, 0, 32));
487 COMMAND_HANDLER(handle_armv4_5_core_state_command)
489 struct target *target = get_current_target(CMD_CTX);
490 struct armv4_5_common_s *armv4_5 = target_to_armv4_5(target);
492 if (!is_arm(armv4_5))
494 command_print(CMD_CTX, "current target isn't an ARM");
500 if (strcmp(CMD_ARGV[0], "arm") == 0)
502 armv4_5->core_state = ARMV4_5_STATE_ARM;
504 if (strcmp(CMD_ARGV[0], "thumb") == 0)
506 armv4_5->core_state = ARMV4_5_STATE_THUMB;
510 command_print(CMD_CTX, "core state: %s", armv4_5_state_strings[armv4_5->core_state]);
515 COMMAND_HANDLER(handle_armv4_5_disassemble_command)
517 int retval = ERROR_OK;
518 struct target *target = get_current_target(CMD_CTX);
519 struct arm *arm = target ? target_to_arm(target) : NULL;
525 command_print(CMD_CTX, "current target isn't an ARM");
531 if (strcmp(CMD_ARGV[2], "thumb") != 0)
536 COMMAND_PARSE_NUMBER(int, CMD_ARGV[1], count);
539 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], address);
540 if (address & 0x01) {
542 command_print(CMD_CTX, "Disassemble as Thumb");
550 command_print(CMD_CTX,
551 "usage: arm disassemble <address> [<count> ['thumb']]");
556 while (count-- > 0) {
557 struct arm_instruction cur_instruction;
560 /* Always use Thumb2 disassembly for best handling
561 * of 32-bit BL/BLX, and to work with newer cores
562 * (some ARMv6, all ARMv7) that use Thumb2.
564 retval = thumb2_opcode(target, address,
566 if (retval != ERROR_OK)
571 retval = target_read_u32(target, address, &opcode);
572 if (retval != ERROR_OK)
574 retval = arm_evaluate_opcode(opcode, address,
575 &cur_instruction) != ERROR_OK;
576 if (retval != ERROR_OK)
579 command_print(CMD_CTX, "%s", cur_instruction.text);
580 address += cur_instruction.instruction_size;
586 int armv4_5_register_commands(struct command_context *cmd_ctx)
588 struct command *armv4_5_cmd;
590 armv4_5_cmd = register_command(cmd_ctx, NULL, "arm",
592 "generic ARM commands");
594 register_command(cmd_ctx, armv4_5_cmd, "reg",
595 handle_armv4_5_reg_command, COMMAND_EXEC,
596 "display ARM core registers");
597 register_command(cmd_ctx, armv4_5_cmd, "core_state",
598 handle_armv4_5_core_state_command, COMMAND_EXEC,
599 "display/change ARM core state <arm | thumb>");
600 register_command(cmd_ctx, armv4_5_cmd, "disassemble",
601 handle_armv4_5_disassemble_command, COMMAND_EXEC,
602 "disassemble instructions "
603 "<address> [<count> ['thumb']]");
608 int armv4_5_get_gdb_reg_list(struct target *target, struct reg **reg_list[], int *reg_list_size)
610 struct armv4_5_common_s *armv4_5 = target_to_armv4_5(target);
613 if (!is_arm_mode(armv4_5->core_mode))
617 *reg_list = malloc(sizeof(struct reg*) * (*reg_list_size));
619 for (i = 0; i < 16; i++)
621 (*reg_list)[i] = &ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, i);
624 for (i = 16; i < 24; i++)
626 (*reg_list)[i] = &arm_gdb_dummy_fp_reg;
629 (*reg_list)[24] = &arm_gdb_dummy_fps_reg;
630 (*reg_list)[25] = &armv4_5->core_cache->reg_list[ARMV4_5_CPSR];
635 /* wait for execution to complete and check exit point */
636 static int armv4_5_run_algorithm_completion(struct target *target, uint32_t exit_point, int timeout_ms, void *arch_info)
639 struct armv4_5_common_s *armv4_5 = target_to_armv4_5(target);
641 if ((retval = target_wait_state(target, TARGET_HALTED, timeout_ms)) != ERROR_OK)
645 if (target->state != TARGET_HALTED)
647 if ((retval = target_halt(target)) != ERROR_OK)
649 if ((retval = target_wait_state(target, TARGET_HALTED, 500)) != ERROR_OK)
653 return ERROR_TARGET_TIMEOUT;
656 /* fast exit: ARMv5+ code can use BKPT */
657 if (exit_point && buf_get_u32(armv4_5->core_cache->reg_list[15].value,
658 0, 32) != exit_point)
660 LOG_WARNING("target reentered debug state, but not at the desired exit point: 0x%4.4" PRIx32 "",
661 buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32));
662 return ERROR_TARGET_TIMEOUT;
668 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))
670 struct armv4_5_common_s *armv4_5 = target_to_armv4_5(target);
671 struct armv4_5_algorithm *armv4_5_algorithm_info = arch_info;
672 enum armv4_5_state core_state = armv4_5->core_state;
673 enum armv4_5_mode core_mode = armv4_5->core_mode;
674 uint32_t context[17];
676 int exit_breakpoint_size = 0;
678 int retval = ERROR_OK;
679 LOG_DEBUG("Running algorithm");
681 if (armv4_5_algorithm_info->common_magic != ARMV4_5_COMMON_MAGIC)
683 LOG_ERROR("current target isn't an ARMV4/5 target");
684 return ERROR_TARGET_INVALID;
687 if (target->state != TARGET_HALTED)
689 LOG_WARNING("target not halted");
690 return ERROR_TARGET_NOT_HALTED;
693 if (!is_arm_mode(armv4_5->core_mode))
696 /* armv5 and later can terminate with BKPT instruction; less overhead */
697 if (!exit_point && armv4_5->is_armv4)
699 LOG_ERROR("ARMv4 target needs HW breakpoint location");
703 for (i = 0; i <= 16; i++)
705 if (!ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5_algorithm_info->core_mode, i).valid)
706 armv4_5->read_core_reg(target, i, armv4_5_algorithm_info->core_mode);
707 context[i] = buf_get_u32(ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5_algorithm_info->core_mode, i).value, 0, 32);
709 cpsr = buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 32);
711 for (i = 0; i < num_mem_params; i++)
713 if ((retval = target_write_buffer(target, mem_params[i].address, mem_params[i].size, mem_params[i].value)) != ERROR_OK)
719 for (i = 0; i < num_reg_params; i++)
721 struct reg *reg = register_get_by_name(armv4_5->core_cache, reg_params[i].reg_name, 0);
724 LOG_ERROR("BUG: register '%s' not found", reg_params[i].reg_name);
725 return ERROR_INVALID_ARGUMENTS;
728 if (reg->size != reg_params[i].size)
730 LOG_ERROR("BUG: register '%s' size doesn't match reg_params[i].size", reg_params[i].reg_name);
731 return ERROR_INVALID_ARGUMENTS;
734 if ((retval = armv4_5_set_core_reg(reg, reg_params[i].value)) != ERROR_OK)
740 armv4_5->core_state = armv4_5_algorithm_info->core_state;
741 if (armv4_5->core_state == ARMV4_5_STATE_ARM)
742 exit_breakpoint_size = 4;
743 else if (armv4_5->core_state == ARMV4_5_STATE_THUMB)
744 exit_breakpoint_size = 2;
747 LOG_ERROR("BUG: can't execute algorithms when not in ARM or Thumb state");
748 return ERROR_INVALID_ARGUMENTS;
751 if (armv4_5_algorithm_info->core_mode != ARMV4_5_MODE_ANY)
753 LOG_DEBUG("setting core_mode: 0x%2.2x", armv4_5_algorithm_info->core_mode);
754 buf_set_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 5, armv4_5_algorithm_info->core_mode);
755 armv4_5->core_cache->reg_list[ARMV4_5_CPSR].dirty = 1;
756 armv4_5->core_cache->reg_list[ARMV4_5_CPSR].valid = 1;
759 /* terminate using a hardware or (ARMv5+) software breakpoint */
760 if (exit_point && (retval = breakpoint_add(target, exit_point,
761 exit_breakpoint_size, BKPT_HARD)) != ERROR_OK)
763 LOG_ERROR("can't add HW breakpoint to terminate algorithm");
764 return ERROR_TARGET_FAILURE;
767 if ((retval = target_resume(target, 0, entry_point, 1, 1)) != ERROR_OK)
772 retval = run_it(target, exit_point, timeout_ms, arch_info);
775 breakpoint_remove(target, exit_point);
777 if (retval != ERROR_OK)
780 for (i = 0; i < num_mem_params; i++)
782 if (mem_params[i].direction != PARAM_OUT)
783 if ((retvaltemp = target_read_buffer(target, mem_params[i].address, mem_params[i].size, mem_params[i].value)) != ERROR_OK)
789 for (i = 0; i < num_reg_params; i++)
791 if (reg_params[i].direction != PARAM_OUT)
794 struct reg *reg = register_get_by_name(armv4_5->core_cache, reg_params[i].reg_name, 0);
797 LOG_ERROR("BUG: register '%s' not found", reg_params[i].reg_name);
798 retval = ERROR_INVALID_ARGUMENTS;
802 if (reg->size != reg_params[i].size)
804 LOG_ERROR("BUG: register '%s' size doesn't match reg_params[i].size", reg_params[i].reg_name);
805 retval = ERROR_INVALID_ARGUMENTS;
809 buf_set_u32(reg_params[i].value, 0, 32, buf_get_u32(reg->value, 0, 32));
813 for (i = 0; i <= 16; i++)
816 regvalue = buf_get_u32(ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5_algorithm_info->core_mode, i).value, 0, 32);
817 if (regvalue != context[i])
819 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]);
820 buf_set_u32(ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5_algorithm_info->core_mode, i).value, 0, 32, context[i]);
821 ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5_algorithm_info->core_mode, i).valid = 1;
822 ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5_algorithm_info->core_mode, i).dirty = 1;
825 buf_set_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 32, cpsr);
826 armv4_5->core_cache->reg_list[ARMV4_5_CPSR].valid = 1;
827 armv4_5->core_cache->reg_list[ARMV4_5_CPSR].dirty = 1;
829 armv4_5->core_state = core_state;
830 armv4_5->core_mode = core_mode;
835 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)
837 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);
841 * Runs ARM code in the target to calculate a CRC32 checksum.
843 * \todo On ARMv5+, rely on BKPT termination for reduced overhead.
845 int arm_checksum_memory(struct target *target,
846 uint32_t address, uint32_t count, uint32_t *checksum)
848 struct working_area *crc_algorithm;
849 struct armv4_5_algorithm armv4_5_info;
850 struct reg_param reg_params[2];
854 static const uint32_t arm_crc_code[] = {
855 0xE1A02000, /* mov r2, r0 */
856 0xE3E00000, /* mov r0, #0xffffffff */
857 0xE1A03001, /* mov r3, r1 */
858 0xE3A04000, /* mov r4, #0 */
859 0xEA00000B, /* b ncomp */
861 0xE7D21004, /* ldrb r1, [r2, r4] */
862 0xE59F7030, /* ldr r7, CRC32XOR */
863 0xE0200C01, /* eor r0, r0, r1, asl 24 */
864 0xE3A05000, /* mov r5, #0 */
866 0xE3500000, /* cmp r0, #0 */
867 0xE1A06080, /* mov r6, r0, asl #1 */
868 0xE2855001, /* add r5, r5, #1 */
869 0xE1A00006, /* mov r0, r6 */
870 0xB0260007, /* eorlt r0, r6, r7 */
871 0xE3550008, /* cmp r5, #8 */
872 0x1AFFFFF8, /* bne loop */
873 0xE2844001, /* add r4, r4, #1 */
875 0xE1540003, /* cmp r4, r3 */
876 0x1AFFFFF1, /* bne nbyte */
878 0xEAFFFFFE, /* b end */
880 0x04C11DB7 /* .word 0x04C11DB7 */
883 retval = target_alloc_working_area(target,
884 sizeof(arm_crc_code), &crc_algorithm);
885 if (retval != ERROR_OK)
888 /* convert code into a buffer in target endianness */
889 for (i = 0; i < ARRAY_SIZE(arm_crc_code); i++) {
890 retval = target_write_u32(target,
891 crc_algorithm->address + i * sizeof(uint32_t),
893 if (retval != ERROR_OK)
897 armv4_5_info.common_magic = ARMV4_5_COMMON_MAGIC;
898 armv4_5_info.core_mode = ARMV4_5_MODE_SVC;
899 armv4_5_info.core_state = ARMV4_5_STATE_ARM;
901 init_reg_param(®_params[0], "r0", 32, PARAM_IN_OUT);
902 init_reg_param(®_params[1], "r1", 32, PARAM_OUT);
904 buf_set_u32(reg_params[0].value, 0, 32, address);
905 buf_set_u32(reg_params[1].value, 0, 32, count);
907 /* 20 second timeout/megabyte */
908 int timeout = 20000 * (1 + (count / (1024 * 1024)));
910 retval = target_run_algorithm(target, 0, NULL, 2, reg_params,
911 crc_algorithm->address,
912 crc_algorithm->address + sizeof(arm_crc_code) - 8,
913 timeout, &armv4_5_info);
914 if (retval != ERROR_OK) {
915 LOG_ERROR("error executing ARM crc algorithm");
916 destroy_reg_param(®_params[0]);
917 destroy_reg_param(®_params[1]);
918 target_free_working_area(target, crc_algorithm);
922 *checksum = buf_get_u32(reg_params[0].value, 0, 32);
924 destroy_reg_param(®_params[0]);
925 destroy_reg_param(®_params[1]);
927 target_free_working_area(target, crc_algorithm);
933 * Runs ARM code in the target to check whether a memory block holds
934 * all ones. NOR flash which has been erased, and thus may be written,
937 * \todo On ARMv5+, rely on BKPT termination for reduced overhead.
939 int arm_blank_check_memory(struct target *target,
940 uint32_t address, uint32_t count, uint32_t *blank)
942 struct working_area *check_algorithm;
943 struct reg_param reg_params[3];
944 struct armv4_5_algorithm armv4_5_info;
948 static const uint32_t check_code[] = {
950 0xe4d03001, /* ldrb r3, [r0], #1 */
951 0xe0022003, /* and r2, r2, r3 */
952 0xe2511001, /* subs r1, r1, #1 */
953 0x1afffffb, /* bne loop */
955 0xeafffffe /* b end */
958 /* make sure we have a working area */
959 retval = target_alloc_working_area(target,
960 sizeof(check_code), &check_algorithm);
961 if (retval != ERROR_OK)
964 /* convert code into a buffer in target endianness */
965 for (i = 0; i < ARRAY_SIZE(check_code); i++) {
966 retval = target_write_u32(target,
967 check_algorithm->address
968 + i * sizeof(uint32_t),
970 if (retval != ERROR_OK)
974 armv4_5_info.common_magic = ARMV4_5_COMMON_MAGIC;
975 armv4_5_info.core_mode = ARMV4_5_MODE_SVC;
976 armv4_5_info.core_state = ARMV4_5_STATE_ARM;
978 init_reg_param(®_params[0], "r0", 32, PARAM_OUT);
979 buf_set_u32(reg_params[0].value, 0, 32, address);
981 init_reg_param(®_params[1], "r1", 32, PARAM_OUT);
982 buf_set_u32(reg_params[1].value, 0, 32, count);
984 init_reg_param(®_params[2], "r2", 32, PARAM_IN_OUT);
985 buf_set_u32(reg_params[2].value, 0, 32, 0xff);
987 retval = target_run_algorithm(target, 0, NULL, 3, reg_params,
988 check_algorithm->address,
989 check_algorithm->address + sizeof(check_code) - 4,
990 10000, &armv4_5_info);
991 if (retval != ERROR_OK) {
992 destroy_reg_param(®_params[0]);
993 destroy_reg_param(®_params[1]);
994 destroy_reg_param(®_params[2]);
995 target_free_working_area(target, check_algorithm);
999 *blank = buf_get_u32(reg_params[2].value, 0, 32);
1001 destroy_reg_param(®_params[0]);
1002 destroy_reg_param(®_params[1]);
1003 destroy_reg_param(®_params[2]);
1005 target_free_working_area(target, check_algorithm);
1010 int armv4_5_init_arch_info(struct target *target, struct arm *armv4_5)
1012 target->arch_info = armv4_5;
1014 armv4_5->common_magic = ARMV4_5_COMMON_MAGIC;
1015 armv4_5->core_state = ARMV4_5_STATE_ARM;
1016 armv4_5->core_mode = ARMV4_5_MODE_USR;