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 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)
106 for (i = 0; i < ARRAY_SIZE(arm_mode_data); i++) {
107 if (arm_mode_data[i].psr == psr_mode)
108 return arm_mode_data[i].name;
110 LOG_ERROR("unrecognized psr mode: %#02x", psr_mode);
111 return "UNRECOGNIZED";
114 /** Map PSR mode bits to linear number */
115 int armv4_5_mode_to_number(enum armv4_5_mode mode)
118 case ARMV4_5_MODE_ANY:
119 /* map MODE_ANY to user mode */
120 case ARMV4_5_MODE_USR:
122 case ARMV4_5_MODE_FIQ:
124 case ARMV4_5_MODE_IRQ:
126 case ARMV4_5_MODE_SVC:
128 case ARMV4_5_MODE_ABT:
130 case ARMV4_5_MODE_UND:
132 case ARMV4_5_MODE_SYS:
135 LOG_ERROR("invalid mode value encountered %d", mode);
140 /** Map linear number to PSR mode bits. */
141 enum armv4_5_mode armv4_5_number_to_mode(int number)
145 return ARMV4_5_MODE_USR;
147 return ARMV4_5_MODE_FIQ;
149 return ARMV4_5_MODE_IRQ;
151 return ARMV4_5_MODE_SVC;
153 return ARMV4_5_MODE_ABT;
155 return ARMV4_5_MODE_UND;
157 return ARMV4_5_MODE_SYS;
159 LOG_ERROR("mode index out of bounds %d", number);
160 return ARMV4_5_MODE_ANY;
164 char* armv4_5_state_strings[] =
166 "ARM", "Thumb", "Jazelle"
169 struct armv4_5_core_reg armv4_5_core_reg_list_arch_info[] =
171 {0, ARMV4_5_MODE_ANY, NULL, NULL},
172 {1, ARMV4_5_MODE_ANY, NULL, NULL},
173 {2, ARMV4_5_MODE_ANY, NULL, NULL},
174 {3, ARMV4_5_MODE_ANY, NULL, NULL},
175 {4, ARMV4_5_MODE_ANY, NULL, NULL},
176 {5, ARMV4_5_MODE_ANY, NULL, NULL},
177 {6, ARMV4_5_MODE_ANY, NULL, NULL},
178 {7, ARMV4_5_MODE_ANY, NULL, NULL},
179 {8, ARMV4_5_MODE_ANY, NULL, NULL},
180 {9, ARMV4_5_MODE_ANY, NULL, NULL},
181 {10, ARMV4_5_MODE_ANY, NULL, NULL},
182 {11, ARMV4_5_MODE_ANY, NULL, NULL},
183 {12, ARMV4_5_MODE_ANY, NULL, NULL},
184 {13, ARMV4_5_MODE_USR, NULL, NULL},
185 {14, ARMV4_5_MODE_USR, NULL, NULL},
186 {15, ARMV4_5_MODE_ANY, NULL, NULL},
188 {8, ARMV4_5_MODE_FIQ, NULL, NULL},
189 {9, ARMV4_5_MODE_FIQ, NULL, NULL},
190 {10, ARMV4_5_MODE_FIQ, NULL, NULL},
191 {11, ARMV4_5_MODE_FIQ, NULL, NULL},
192 {12, ARMV4_5_MODE_FIQ, NULL, NULL},
193 {13, ARMV4_5_MODE_FIQ, NULL, NULL},
194 {14, ARMV4_5_MODE_FIQ, NULL, NULL},
196 {13, ARMV4_5_MODE_IRQ, NULL, NULL},
197 {14, ARMV4_5_MODE_IRQ, NULL, NULL},
199 {13, ARMV4_5_MODE_SVC, NULL, NULL},
200 {14, ARMV4_5_MODE_SVC, NULL, NULL},
202 {13, ARMV4_5_MODE_ABT, NULL, NULL},
203 {14, ARMV4_5_MODE_ABT, NULL, NULL},
205 {13, ARMV4_5_MODE_UND, NULL, NULL},
206 {14, ARMV4_5_MODE_UND, NULL, NULL},
208 {16, ARMV4_5_MODE_ANY, NULL, NULL},
209 {16, ARMV4_5_MODE_FIQ, NULL, NULL},
210 {16, ARMV4_5_MODE_IRQ, NULL, NULL},
211 {16, ARMV4_5_MODE_SVC, NULL, NULL},
212 {16, ARMV4_5_MODE_ABT, NULL, NULL},
213 {16, ARMV4_5_MODE_UND, NULL, NULL}
216 /* map core mode (USR, FIQ, ...) and register number to indizes into the register cache */
217 int armv4_5_core_reg_map[7][17] =
220 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 31
223 0, 1, 2, 3, 4, 5, 6, 7, 16, 17, 18, 19, 20, 21, 22, 15, 32
226 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 23, 24, 15, 33
229 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 25, 26, 15, 34
232 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 27, 28, 15, 35
235 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 29, 30, 15, 36
238 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 31
242 static const uint8_t arm_gdb_dummy_fp_value[12];
245 * Dummy FPA registers are required to support GDB on ARM.
246 * Register packets require eight obsolete FPA register values.
247 * Modern ARM cores use Vector Floating Point (VFP), if they
248 * have any floating point support. VFP is not FPA-compatible.
250 struct reg arm_gdb_dummy_fp_reg =
252 .name = "GDB dummy FPA register",
253 .value = (uint8_t *) arm_gdb_dummy_fp_value,
258 static const uint8_t arm_gdb_dummy_fps_value[4];
261 * Dummy FPA status registers are required to support GDB on ARM.
262 * Register packets require an obsolete FPA status register.
264 struct reg arm_gdb_dummy_fps_reg =
266 .name = "GDB dummy FPA status register",
267 .value = (uint8_t *) arm_gdb_dummy_fps_value,
272 static void arm_gdb_dummy_init(void) __attribute__ ((constructor));
274 static void arm_gdb_dummy_init(void)
276 register_init_dummy(&arm_gdb_dummy_fp_reg);
277 register_init_dummy(&arm_gdb_dummy_fps_reg);
280 int armv4_5_get_core_reg(struct reg *reg)
283 struct armv4_5_core_reg *armv4_5 = reg->arch_info;
284 struct target *target = armv4_5->target;
286 if (target->state != TARGET_HALTED)
288 LOG_ERROR("Target not halted");
289 return ERROR_TARGET_NOT_HALTED;
292 /* retval = armv4_5->armv4_5_common->full_context(target); */
293 retval = armv4_5->armv4_5_common->read_core_reg(target, armv4_5->num, armv4_5->mode);
298 int armv4_5_set_core_reg(struct reg *reg, uint8_t *buf)
300 struct armv4_5_core_reg *armv4_5 = reg->arch_info;
301 struct target *target = armv4_5->target;
302 struct armv4_5_common_s *armv4_5_target = target_to_armv4_5(target);
303 uint32_t value = buf_get_u32(buf, 0, 32);
305 if (target->state != TARGET_HALTED)
307 return ERROR_TARGET_NOT_HALTED;
310 if (reg == &armv4_5_target->core_cache->reg_list[ARMV4_5_CPSR])
314 /* T bit should be set */
315 if (armv4_5_target->core_state == ARMV4_5_STATE_ARM)
317 /* change state to Thumb */
318 LOG_DEBUG("changing to Thumb state");
319 armv4_5_target->core_state = ARMV4_5_STATE_THUMB;
324 /* T bit should be cleared */
325 if (armv4_5_target->core_state == ARMV4_5_STATE_THUMB)
327 /* change state to ARM */
328 LOG_DEBUG("changing to ARM state");
329 armv4_5_target->core_state = ARMV4_5_STATE_ARM;
333 if (armv4_5_target->core_mode != (enum armv4_5_mode)(value & 0x1f))
335 LOG_DEBUG("changing ARM core mode to '%s'",
336 arm_mode_name(value & 0x1f));
337 armv4_5_target->core_mode = value & 0x1f;
338 armv4_5_target->write_core_reg(target, 16, ARMV4_5_MODE_ANY, value);
342 buf_set_u32(reg->value, 0, 32, value);
349 static const struct reg_arch_type arm_reg_type = {
350 .get = armv4_5_get_core_reg,
351 .set = armv4_5_set_core_reg,
354 int armv4_5_invalidate_core_regs(struct target *target)
356 struct armv4_5_common_s *armv4_5 = target_to_armv4_5(target);
359 for (i = 0; i < 37; i++)
361 armv4_5->core_cache->reg_list[i].valid = 0;
362 armv4_5->core_cache->reg_list[i].dirty = 0;
368 struct reg_cache* armv4_5_build_reg_cache(struct target *target, struct arm *armv4_5_common)
371 struct reg_cache *cache = malloc(sizeof(struct reg_cache));
372 struct reg *reg_list = malloc(sizeof(struct reg) * num_regs);
373 struct armv4_5_core_reg *arch_info = malloc(sizeof(struct armv4_5_core_reg) * num_regs);
376 cache->name = "arm v4/5 registers";
378 cache->reg_list = reg_list;
379 cache->num_regs = num_regs;
381 for (i = 0; i < 37; i++)
383 arch_info[i] = armv4_5_core_reg_list_arch_info[i];
384 arch_info[i].target = target;
385 arch_info[i].armv4_5_common = armv4_5_common;
386 reg_list[i].name = armv4_5_core_reg_list[i];
387 reg_list[i].size = 32;
388 reg_list[i].value = calloc(1, 4);
389 reg_list[i].dirty = 0;
390 reg_list[i].valid = 0;
391 reg_list[i].type = &arm_reg_type;
392 reg_list[i].arch_info = &arch_info[i];
398 int armv4_5_arch_state(struct target *target)
400 struct armv4_5_common_s *armv4_5 = target_to_armv4_5(target);
402 if (armv4_5->common_magic != ARMV4_5_COMMON_MAGIC)
404 LOG_ERROR("BUG: called for a non-ARMv4/5 target");
408 LOG_USER("target halted in %s state due to %s, current mode: %s\ncpsr: 0x%8.8" PRIx32 " pc: 0x%8.8" PRIx32 "",
409 armv4_5_state_strings[armv4_5->core_state],
410 Jim_Nvp_value2name_simple(nvp_target_debug_reason, target->debug_reason)->name,
411 arm_mode_name(armv4_5->core_mode),
412 buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 32),
413 buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32));
418 COMMAND_HANDLER(handle_armv4_5_reg_command)
423 struct target *target = get_current_target(CMD_CTX);
424 struct armv4_5_common_s *armv4_5 = target_to_armv4_5(target);
426 if (!is_arm(armv4_5))
428 command_print(CMD_CTX, "current target isn't an ARM");
432 if (target->state != TARGET_HALTED)
434 command_print(CMD_CTX, "error: target must be halted for register accesses");
438 if (armv4_5_mode_to_number(armv4_5->core_mode)==-1)
441 if (!armv4_5->full_context) {
442 command_print(CMD_CTX, "error: target doesn't support %s",
447 for (num = 0; num <= 15; num++)
450 for (mode = 0; mode < 6; mode++)
452 if (!ARMV4_5_CORE_REG_MODENUM(armv4_5->core_cache, mode, num).valid)
454 armv4_5->full_context(target);
456 output_len += snprintf(output + output_len,
458 "%8s: %8.8" PRIx32 " ",
459 ARMV4_5_CORE_REG_MODENUM(armv4_5->core_cache, mode, num).name,
460 buf_get_u32(ARMV4_5_CORE_REG_MODENUM(armv4_5->core_cache, mode, num).value, 0, 32));
462 command_print(CMD_CTX, "%s", output);
464 command_print(CMD_CTX,
465 " 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 "",
466 buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 32),
467 buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_SPSR_FIQ].value, 0, 32),
468 buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_SPSR_IRQ].value, 0, 32),
469 buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_SPSR_SVC].value, 0, 32),
470 buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_SPSR_ABT].value, 0, 32),
471 buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_SPSR_UND].value, 0, 32));
476 COMMAND_HANDLER(handle_armv4_5_core_state_command)
478 struct target *target = get_current_target(CMD_CTX);
479 struct armv4_5_common_s *armv4_5 = target_to_armv4_5(target);
481 if (!is_arm(armv4_5))
483 command_print(CMD_CTX, "current target isn't an ARM");
489 if (strcmp(CMD_ARGV[0], "arm") == 0)
491 armv4_5->core_state = ARMV4_5_STATE_ARM;
493 if (strcmp(CMD_ARGV[0], "thumb") == 0)
495 armv4_5->core_state = ARMV4_5_STATE_THUMB;
499 command_print(CMD_CTX, "core state: %s", armv4_5_state_strings[armv4_5->core_state]);
504 COMMAND_HANDLER(handle_armv4_5_disassemble_command)
506 int retval = ERROR_OK;
507 struct target *target = get_current_target(CMD_CTX);
508 struct arm *arm = target ? target_to_arm(target) : NULL;
514 command_print(CMD_CTX, "current target isn't an ARM");
520 if (strcmp(CMD_ARGV[2], "thumb") != 0)
525 COMMAND_PARSE_NUMBER(int, CMD_ARGV[1], count);
528 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], address);
529 if (address & 0x01) {
531 command_print(CMD_CTX, "Disassemble as Thumb");
539 command_print(CMD_CTX,
540 "usage: arm disassemble <address> [<count> ['thumb']]");
545 while (count-- > 0) {
546 struct arm_instruction cur_instruction;
549 /* Always use Thumb2 disassembly for best handling
550 * of 32-bit BL/BLX, and to work with newer cores
551 * (some ARMv6, all ARMv7) that use Thumb2.
553 retval = thumb2_opcode(target, address,
555 if (retval != ERROR_OK)
560 retval = target_read_u32(target, address, &opcode);
561 if (retval != ERROR_OK)
563 retval = arm_evaluate_opcode(opcode, address,
564 &cur_instruction) != ERROR_OK;
565 if (retval != ERROR_OK)
568 command_print(CMD_CTX, "%s", cur_instruction.text);
569 address += cur_instruction.instruction_size;
575 int armv4_5_register_commands(struct command_context *cmd_ctx)
577 struct command *armv4_5_cmd;
579 armv4_5_cmd = register_command(cmd_ctx, NULL, "arm",
581 "generic ARM commands");
583 register_command(cmd_ctx, armv4_5_cmd, "reg",
584 handle_armv4_5_reg_command, COMMAND_EXEC,
585 "display ARM core registers");
586 register_command(cmd_ctx, armv4_5_cmd, "core_state",
587 handle_armv4_5_core_state_command, COMMAND_EXEC,
588 "display/change ARM core state <arm | thumb>");
589 register_command(cmd_ctx, armv4_5_cmd, "disassemble",
590 handle_armv4_5_disassemble_command, COMMAND_EXEC,
591 "disassemble instructions "
592 "<address> [<count> ['thumb']]");
597 int armv4_5_get_gdb_reg_list(struct target *target, struct reg **reg_list[], int *reg_list_size)
599 struct armv4_5_common_s *armv4_5 = target_to_armv4_5(target);
602 if (armv4_5_mode_to_number(armv4_5->core_mode)==-1)
606 *reg_list = malloc(sizeof(struct reg*) * (*reg_list_size));
608 for (i = 0; i < 16; i++)
610 (*reg_list)[i] = &ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, i);
613 for (i = 16; i < 24; i++)
615 (*reg_list)[i] = &arm_gdb_dummy_fp_reg;
618 (*reg_list)[24] = &arm_gdb_dummy_fps_reg;
619 (*reg_list)[25] = &armv4_5->core_cache->reg_list[ARMV4_5_CPSR];
624 /* wait for execution to complete and check exit point */
625 static int armv4_5_run_algorithm_completion(struct target *target, uint32_t exit_point, int timeout_ms, void *arch_info)
628 struct armv4_5_common_s *armv4_5 = target_to_armv4_5(target);
630 if ((retval = target_wait_state(target, TARGET_HALTED, timeout_ms)) != ERROR_OK)
634 if (target->state != TARGET_HALTED)
636 if ((retval = target_halt(target)) != ERROR_OK)
638 if ((retval = target_wait_state(target, TARGET_HALTED, 500)) != ERROR_OK)
642 return ERROR_TARGET_TIMEOUT;
645 /* fast exit: ARMv5+ code can use BKPT */
646 if (exit_point && buf_get_u32(armv4_5->core_cache->reg_list[15].value,
647 0, 32) != exit_point)
649 LOG_WARNING("target reentered debug state, but not at the desired exit point: 0x%4.4" PRIx32 "",
650 buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32));
651 return ERROR_TARGET_TIMEOUT;
657 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))
659 struct armv4_5_common_s *armv4_5 = target_to_armv4_5(target);
660 struct armv4_5_algorithm *armv4_5_algorithm_info = arch_info;
661 enum armv4_5_state core_state = armv4_5->core_state;
662 enum armv4_5_mode core_mode = armv4_5->core_mode;
663 uint32_t context[17];
665 int exit_breakpoint_size = 0;
667 int retval = ERROR_OK;
668 LOG_DEBUG("Running algorithm");
670 if (armv4_5_algorithm_info->common_magic != ARMV4_5_COMMON_MAGIC)
672 LOG_ERROR("current target isn't an ARMV4/5 target");
673 return ERROR_TARGET_INVALID;
676 if (target->state != TARGET_HALTED)
678 LOG_WARNING("target not halted");
679 return ERROR_TARGET_NOT_HALTED;
682 if (armv4_5_mode_to_number(armv4_5->core_mode)==-1)
685 /* armv5 and later can terminate with BKPT instruction; less overhead */
686 if (!exit_point && armv4_5->is_armv4)
688 LOG_ERROR("ARMv4 target needs HW breakpoint location");
692 for (i = 0; i <= 16; i++)
694 if (!ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5_algorithm_info->core_mode, i).valid)
695 armv4_5->read_core_reg(target, i, armv4_5_algorithm_info->core_mode);
696 context[i] = buf_get_u32(ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5_algorithm_info->core_mode, i).value, 0, 32);
698 cpsr = buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 32);
700 for (i = 0; i < num_mem_params; i++)
702 if ((retval = target_write_buffer(target, mem_params[i].address, mem_params[i].size, mem_params[i].value)) != ERROR_OK)
708 for (i = 0; i < num_reg_params; i++)
710 struct reg *reg = register_get_by_name(armv4_5->core_cache, reg_params[i].reg_name, 0);
713 LOG_ERROR("BUG: register '%s' not found", reg_params[i].reg_name);
714 return ERROR_INVALID_ARGUMENTS;
717 if (reg->size != reg_params[i].size)
719 LOG_ERROR("BUG: register '%s' size doesn't match reg_params[i].size", reg_params[i].reg_name);
720 return ERROR_INVALID_ARGUMENTS;
723 if ((retval = armv4_5_set_core_reg(reg, reg_params[i].value)) != ERROR_OK)
729 armv4_5->core_state = armv4_5_algorithm_info->core_state;
730 if (armv4_5->core_state == ARMV4_5_STATE_ARM)
731 exit_breakpoint_size = 4;
732 else if (armv4_5->core_state == ARMV4_5_STATE_THUMB)
733 exit_breakpoint_size = 2;
736 LOG_ERROR("BUG: can't execute algorithms when not in ARM or Thumb state");
737 return ERROR_INVALID_ARGUMENTS;
740 if (armv4_5_algorithm_info->core_mode != ARMV4_5_MODE_ANY)
742 LOG_DEBUG("setting core_mode: 0x%2.2x", armv4_5_algorithm_info->core_mode);
743 buf_set_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 5, armv4_5_algorithm_info->core_mode);
744 armv4_5->core_cache->reg_list[ARMV4_5_CPSR].dirty = 1;
745 armv4_5->core_cache->reg_list[ARMV4_5_CPSR].valid = 1;
748 /* terminate using a hardware or (ARMv5+) software breakpoint */
749 if (exit_point && (retval = breakpoint_add(target, exit_point,
750 exit_breakpoint_size, BKPT_HARD)) != ERROR_OK)
752 LOG_ERROR("can't add HW breakpoint to terminate algorithm");
753 return ERROR_TARGET_FAILURE;
756 if ((retval = target_resume(target, 0, entry_point, 1, 1)) != ERROR_OK)
761 retval = run_it(target, exit_point, timeout_ms, arch_info);
764 breakpoint_remove(target, exit_point);
766 if (retval != ERROR_OK)
769 for (i = 0; i < num_mem_params; i++)
771 if (mem_params[i].direction != PARAM_OUT)
772 if ((retvaltemp = target_read_buffer(target, mem_params[i].address, mem_params[i].size, mem_params[i].value)) != ERROR_OK)
778 for (i = 0; i < num_reg_params; i++)
780 if (reg_params[i].direction != PARAM_OUT)
783 struct reg *reg = register_get_by_name(armv4_5->core_cache, reg_params[i].reg_name, 0);
786 LOG_ERROR("BUG: register '%s' not found", reg_params[i].reg_name);
787 retval = ERROR_INVALID_ARGUMENTS;
791 if (reg->size != reg_params[i].size)
793 LOG_ERROR("BUG: register '%s' size doesn't match reg_params[i].size", reg_params[i].reg_name);
794 retval = ERROR_INVALID_ARGUMENTS;
798 buf_set_u32(reg_params[i].value, 0, 32, buf_get_u32(reg->value, 0, 32));
802 for (i = 0; i <= 16; i++)
805 regvalue = buf_get_u32(ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5_algorithm_info->core_mode, i).value, 0, 32);
806 if (regvalue != context[i])
808 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]);
809 buf_set_u32(ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5_algorithm_info->core_mode, i).value, 0, 32, context[i]);
810 ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5_algorithm_info->core_mode, i).valid = 1;
811 ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5_algorithm_info->core_mode, i).dirty = 1;
814 buf_set_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 32, cpsr);
815 armv4_5->core_cache->reg_list[ARMV4_5_CPSR].valid = 1;
816 armv4_5->core_cache->reg_list[ARMV4_5_CPSR].dirty = 1;
818 armv4_5->core_state = core_state;
819 armv4_5->core_mode = core_mode;
824 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)
826 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);
830 * Runs ARM code in the target to calculate a CRC32 checksum.
832 * \todo On ARMv5+, rely on BKPT termination for reduced overhead.
834 int arm_checksum_memory(struct target *target,
835 uint32_t address, uint32_t count, uint32_t *checksum)
837 struct working_area *crc_algorithm;
838 struct armv4_5_algorithm armv4_5_info;
839 struct reg_param reg_params[2];
843 static const uint32_t arm_crc_code[] = {
844 0xE1A02000, /* mov r2, r0 */
845 0xE3E00000, /* mov r0, #0xffffffff */
846 0xE1A03001, /* mov r3, r1 */
847 0xE3A04000, /* mov r4, #0 */
848 0xEA00000B, /* b ncomp */
850 0xE7D21004, /* ldrb r1, [r2, r4] */
851 0xE59F7030, /* ldr r7, CRC32XOR */
852 0xE0200C01, /* eor r0, r0, r1, asl 24 */
853 0xE3A05000, /* mov r5, #0 */
855 0xE3500000, /* cmp r0, #0 */
856 0xE1A06080, /* mov r6, r0, asl #1 */
857 0xE2855001, /* add r5, r5, #1 */
858 0xE1A00006, /* mov r0, r6 */
859 0xB0260007, /* eorlt r0, r6, r7 */
860 0xE3550008, /* cmp r5, #8 */
861 0x1AFFFFF8, /* bne loop */
862 0xE2844001, /* add r4, r4, #1 */
864 0xE1540003, /* cmp r4, r3 */
865 0x1AFFFFF1, /* bne nbyte */
867 0xEAFFFFFE, /* b end */
869 0x04C11DB7 /* .word 0x04C11DB7 */
872 retval = target_alloc_working_area(target,
873 sizeof(arm_crc_code), &crc_algorithm);
874 if (retval != ERROR_OK)
877 /* convert code into a buffer in target endianness */
878 for (i = 0; i < ARRAY_SIZE(arm_crc_code); i++) {
879 retval = target_write_u32(target,
880 crc_algorithm->address + i * sizeof(uint32_t),
882 if (retval != ERROR_OK)
886 armv4_5_info.common_magic = ARMV4_5_COMMON_MAGIC;
887 armv4_5_info.core_mode = ARMV4_5_MODE_SVC;
888 armv4_5_info.core_state = ARMV4_5_STATE_ARM;
890 init_reg_param(®_params[0], "r0", 32, PARAM_IN_OUT);
891 init_reg_param(®_params[1], "r1", 32, PARAM_OUT);
893 buf_set_u32(reg_params[0].value, 0, 32, address);
894 buf_set_u32(reg_params[1].value, 0, 32, count);
896 /* 20 second timeout/megabyte */
897 int timeout = 20000 * (1 + (count / (1024 * 1024)));
899 retval = target_run_algorithm(target, 0, NULL, 2, reg_params,
900 crc_algorithm->address,
901 crc_algorithm->address + sizeof(arm_crc_code) - 8,
902 timeout, &armv4_5_info);
903 if (retval != ERROR_OK) {
904 LOG_ERROR("error executing ARM crc algorithm");
905 destroy_reg_param(®_params[0]);
906 destroy_reg_param(®_params[1]);
907 target_free_working_area(target, crc_algorithm);
911 *checksum = buf_get_u32(reg_params[0].value, 0, 32);
913 destroy_reg_param(®_params[0]);
914 destroy_reg_param(®_params[1]);
916 target_free_working_area(target, crc_algorithm);
922 * Runs ARM code in the target to check whether a memory block holds
923 * all ones. NOR flash which has been erased, and thus may be written,
926 * \todo On ARMv5+, rely on BKPT termination for reduced overhead.
928 int arm_blank_check_memory(struct target *target,
929 uint32_t address, uint32_t count, uint32_t *blank)
931 struct working_area *check_algorithm;
932 struct reg_param reg_params[3];
933 struct armv4_5_algorithm armv4_5_info;
937 static const uint32_t check_code[] = {
939 0xe4d03001, /* ldrb r3, [r0], #1 */
940 0xe0022003, /* and r2, r2, r3 */
941 0xe2511001, /* subs r1, r1, #1 */
942 0x1afffffb, /* bne loop */
944 0xeafffffe /* b end */
947 /* make sure we have a working area */
948 retval = target_alloc_working_area(target,
949 sizeof(check_code), &check_algorithm);
950 if (retval != ERROR_OK)
953 /* convert code into a buffer in target endianness */
954 for (i = 0; i < ARRAY_SIZE(check_code); i++) {
955 retval = target_write_u32(target,
956 check_algorithm->address
957 + i * sizeof(uint32_t),
959 if (retval != ERROR_OK)
963 armv4_5_info.common_magic = ARMV4_5_COMMON_MAGIC;
964 armv4_5_info.core_mode = ARMV4_5_MODE_SVC;
965 armv4_5_info.core_state = ARMV4_5_STATE_ARM;
967 init_reg_param(®_params[0], "r0", 32, PARAM_OUT);
968 buf_set_u32(reg_params[0].value, 0, 32, address);
970 init_reg_param(®_params[1], "r1", 32, PARAM_OUT);
971 buf_set_u32(reg_params[1].value, 0, 32, count);
973 init_reg_param(®_params[2], "r2", 32, PARAM_IN_OUT);
974 buf_set_u32(reg_params[2].value, 0, 32, 0xff);
976 retval = target_run_algorithm(target, 0, NULL, 3, reg_params,
977 check_algorithm->address,
978 check_algorithm->address + sizeof(check_code) - 4,
979 10000, &armv4_5_info);
980 if (retval != ERROR_OK) {
981 destroy_reg_param(®_params[0]);
982 destroy_reg_param(®_params[1]);
983 destroy_reg_param(®_params[2]);
984 target_free_working_area(target, check_algorithm);
988 *blank = buf_get_u32(reg_params[2].value, 0, 32);
990 destroy_reg_param(®_params[0]);
991 destroy_reg_param(®_params[1]);
992 destroy_reg_param(®_params[2]);
994 target_free_working_area(target, check_algorithm);
999 int armv4_5_init_arch_info(struct target *target, struct arm *armv4_5)
1001 target->arch_info = armv4_5;
1003 armv4_5->common_magic = ARMV4_5_COMMON_MAGIC;
1004 armv4_5->core_state = ARMV4_5_STATE_ARM;
1005 armv4_5->core_mode = ARMV4_5_MODE_USR;