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"
56 static const char *armv4_5_mode_strings_list[] =
58 "Illegal mode value", "User", "FIQ", "IRQ", "Supervisor", "Abort", "Undefined", "System"
61 /* Hack! Yuk! allow -1 index, which simplifies codepaths elsewhere in the code */
62 const char **armv4_5_mode_strings = armv4_5_mode_strings_list + 1;
64 /** Map PSR mode bits to linear number */
65 int armv4_5_mode_to_number(enum armv4_5_mode mode)
68 case ARMV4_5_MODE_ANY:
69 /* map MODE_ANY to user mode */
70 case ARMV4_5_MODE_USR:
72 case ARMV4_5_MODE_FIQ:
74 case ARMV4_5_MODE_IRQ:
76 case ARMV4_5_MODE_SVC:
78 case ARMV4_5_MODE_ABT:
80 case ARMV4_5_MODE_UND:
82 case ARMV4_5_MODE_SYS:
85 LOG_ERROR("invalid mode value encountered %d", mode);
90 /** Map linear number to PSR mode bits. */
91 enum armv4_5_mode armv4_5_number_to_mode(int number)
95 return ARMV4_5_MODE_USR;
97 return ARMV4_5_MODE_FIQ;
99 return ARMV4_5_MODE_IRQ;
101 return ARMV4_5_MODE_SVC;
103 return ARMV4_5_MODE_ABT;
105 return ARMV4_5_MODE_UND;
107 return ARMV4_5_MODE_SYS;
109 LOG_ERROR("mode index out of bounds %d", number);
110 return ARMV4_5_MODE_ANY;
114 char* armv4_5_state_strings[] =
116 "ARM", "Thumb", "Jazelle"
119 struct armv4_5_core_reg armv4_5_core_reg_list_arch_info[] =
121 {0, ARMV4_5_MODE_ANY, NULL, NULL},
122 {1, ARMV4_5_MODE_ANY, NULL, NULL},
123 {2, ARMV4_5_MODE_ANY, NULL, NULL},
124 {3, ARMV4_5_MODE_ANY, NULL, NULL},
125 {4, ARMV4_5_MODE_ANY, NULL, NULL},
126 {5, ARMV4_5_MODE_ANY, NULL, NULL},
127 {6, ARMV4_5_MODE_ANY, NULL, NULL},
128 {7, ARMV4_5_MODE_ANY, NULL, NULL},
129 {8, ARMV4_5_MODE_ANY, NULL, NULL},
130 {9, ARMV4_5_MODE_ANY, NULL, NULL},
131 {10, ARMV4_5_MODE_ANY, NULL, NULL},
132 {11, ARMV4_5_MODE_ANY, NULL, NULL},
133 {12, ARMV4_5_MODE_ANY, NULL, NULL},
134 {13, ARMV4_5_MODE_USR, NULL, NULL},
135 {14, ARMV4_5_MODE_USR, NULL, NULL},
136 {15, ARMV4_5_MODE_ANY, NULL, NULL},
138 {8, ARMV4_5_MODE_FIQ, NULL, NULL},
139 {9, ARMV4_5_MODE_FIQ, NULL, NULL},
140 {10, ARMV4_5_MODE_FIQ, NULL, NULL},
141 {11, ARMV4_5_MODE_FIQ, NULL, NULL},
142 {12, ARMV4_5_MODE_FIQ, NULL, NULL},
143 {13, ARMV4_5_MODE_FIQ, NULL, NULL},
144 {14, ARMV4_5_MODE_FIQ, NULL, NULL},
146 {13, ARMV4_5_MODE_IRQ, NULL, NULL},
147 {14, ARMV4_5_MODE_IRQ, NULL, NULL},
149 {13, ARMV4_5_MODE_SVC, NULL, NULL},
150 {14, ARMV4_5_MODE_SVC, NULL, NULL},
152 {13, ARMV4_5_MODE_ABT, NULL, NULL},
153 {14, ARMV4_5_MODE_ABT, NULL, NULL},
155 {13, ARMV4_5_MODE_UND, NULL, NULL},
156 {14, ARMV4_5_MODE_UND, NULL, NULL},
158 {16, ARMV4_5_MODE_ANY, NULL, NULL},
159 {16, ARMV4_5_MODE_FIQ, NULL, NULL},
160 {16, ARMV4_5_MODE_IRQ, NULL, NULL},
161 {16, ARMV4_5_MODE_SVC, NULL, NULL},
162 {16, ARMV4_5_MODE_ABT, NULL, NULL},
163 {16, ARMV4_5_MODE_UND, NULL, NULL}
166 /* map core mode (USR, FIQ, ...) and register number to indizes into the register cache */
167 int armv4_5_core_reg_map[7][17] =
170 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 31
173 0, 1, 2, 3, 4, 5, 6, 7, 16, 17, 18, 19, 20, 21, 22, 15, 32
176 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 23, 24, 15, 33
179 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 25, 26, 15, 34
182 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 27, 28, 15, 35
185 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 29, 30, 15, 36
188 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 31
192 static const uint8_t arm_gdb_dummy_fp_value[12];
195 * Dummy FPA registers are required to support GDB on ARM.
196 * Register packets require eight obsolete FPA register values.
197 * Modern ARM cores use Vector Floating Point (VFP), if they
198 * have any floating point support. VFP is not FPA-compatible.
200 struct reg arm_gdb_dummy_fp_reg =
202 .name = "GDB dummy FPA register",
203 .value = (uint8_t *) arm_gdb_dummy_fp_value,
208 static const uint8_t arm_gdb_dummy_fps_value[4];
211 * Dummy FPA status registers are required to support GDB on ARM.
212 * Register packets require an obsolete FPA status register.
214 struct reg arm_gdb_dummy_fps_reg =
216 .name = "GDB dummy FPA status register",
217 .value = (uint8_t *) arm_gdb_dummy_fps_value,
222 static void arm_gdb_dummy_init(void) __attribute__ ((constructor));
224 static void arm_gdb_dummy_init(void)
226 register_init_dummy(&arm_gdb_dummy_fp_reg);
227 register_init_dummy(&arm_gdb_dummy_fps_reg);
230 int armv4_5_get_core_reg(struct reg *reg)
233 struct armv4_5_core_reg *armv4_5 = reg->arch_info;
234 struct target *target = armv4_5->target;
236 if (target->state != TARGET_HALTED)
238 LOG_ERROR("Target not halted");
239 return ERROR_TARGET_NOT_HALTED;
242 /* retval = armv4_5->armv4_5_common->full_context(target); */
243 retval = armv4_5->armv4_5_common->read_core_reg(target, armv4_5->num, armv4_5->mode);
248 int armv4_5_set_core_reg(struct reg *reg, uint8_t *buf)
250 struct armv4_5_core_reg *armv4_5 = reg->arch_info;
251 struct target *target = armv4_5->target;
252 struct armv4_5_common_s *armv4_5_target = target_to_armv4_5(target);
253 uint32_t value = buf_get_u32(buf, 0, 32);
255 if (target->state != TARGET_HALTED)
257 return ERROR_TARGET_NOT_HALTED;
260 if (reg == &armv4_5_target->core_cache->reg_list[ARMV4_5_CPSR])
264 /* T bit should be set */
265 if (armv4_5_target->core_state == ARMV4_5_STATE_ARM)
267 /* change state to Thumb */
268 LOG_DEBUG("changing to Thumb state");
269 armv4_5_target->core_state = ARMV4_5_STATE_THUMB;
274 /* T bit should be cleared */
275 if (armv4_5_target->core_state == ARMV4_5_STATE_THUMB)
277 /* change state to ARM */
278 LOG_DEBUG("changing to ARM state");
279 armv4_5_target->core_state = ARMV4_5_STATE_ARM;
283 if (armv4_5_target->core_mode != (enum armv4_5_mode)(value & 0x1f))
285 LOG_DEBUG("changing ARM core mode to '%s'", armv4_5_mode_strings[armv4_5_mode_to_number(value & 0x1f)]);
286 armv4_5_target->core_mode = value & 0x1f;
287 armv4_5_target->write_core_reg(target, 16, ARMV4_5_MODE_ANY, value);
291 buf_set_u32(reg->value, 0, 32, value);
298 static const struct reg_arch_type arm_reg_type = {
299 .get = armv4_5_get_core_reg,
300 .set = armv4_5_set_core_reg,
303 int armv4_5_invalidate_core_regs(struct target *target)
305 struct armv4_5_common_s *armv4_5 = target_to_armv4_5(target);
308 for (i = 0; i < 37; i++)
310 armv4_5->core_cache->reg_list[i].valid = 0;
311 armv4_5->core_cache->reg_list[i].dirty = 0;
317 struct reg_cache* armv4_5_build_reg_cache(struct target *target, struct arm *armv4_5_common)
320 struct reg_cache *cache = malloc(sizeof(struct reg_cache));
321 struct reg *reg_list = malloc(sizeof(struct reg) * num_regs);
322 struct armv4_5_core_reg *arch_info = malloc(sizeof(struct armv4_5_core_reg) * num_regs);
325 cache->name = "arm v4/5 registers";
327 cache->reg_list = reg_list;
328 cache->num_regs = num_regs;
330 for (i = 0; i < 37; i++)
332 arch_info[i] = armv4_5_core_reg_list_arch_info[i];
333 arch_info[i].target = target;
334 arch_info[i].armv4_5_common = armv4_5_common;
335 reg_list[i].name = armv4_5_core_reg_list[i];
336 reg_list[i].size = 32;
337 reg_list[i].value = calloc(1, 4);
338 reg_list[i].dirty = 0;
339 reg_list[i].valid = 0;
340 reg_list[i].type = &arm_reg_type;
341 reg_list[i].arch_info = &arch_info[i];
347 int armv4_5_arch_state(struct target *target)
349 struct armv4_5_common_s *armv4_5 = target_to_armv4_5(target);
351 if (armv4_5->common_magic != ARMV4_5_COMMON_MAGIC)
353 LOG_ERROR("BUG: called for a non-ARMv4/5 target");
357 LOG_USER("target halted in %s state due to %s, current mode: %s\ncpsr: 0x%8.8" PRIx32 " pc: 0x%8.8" PRIx32 "",
358 armv4_5_state_strings[armv4_5->core_state],
359 Jim_Nvp_value2name_simple(nvp_target_debug_reason, target->debug_reason)->name,
360 armv4_5_mode_strings[armv4_5_mode_to_number(armv4_5->core_mode)],
361 buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 32),
362 buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32));
367 COMMAND_HANDLER(handle_armv4_5_reg_command)
372 struct target *target = get_current_target(CMD_CTX);
373 struct armv4_5_common_s *armv4_5 = target_to_armv4_5(target);
375 if (!is_arm(armv4_5))
377 command_print(CMD_CTX, "current target isn't an ARM");
381 if (target->state != TARGET_HALTED)
383 command_print(CMD_CTX, "error: target must be halted for register accesses");
387 if (armv4_5_mode_to_number(armv4_5->core_mode)==-1)
390 if (!armv4_5->full_context) {
391 command_print(CMD_CTX, "error: target doesn't support %s",
396 for (num = 0; num <= 15; num++)
399 for (mode = 0; mode < 6; mode++)
401 if (!ARMV4_5_CORE_REG_MODENUM(armv4_5->core_cache, mode, num).valid)
403 armv4_5->full_context(target);
405 output_len += snprintf(output + output_len,
407 "%8s: %8.8" PRIx32 " ",
408 ARMV4_5_CORE_REG_MODENUM(armv4_5->core_cache, mode, num).name,
409 buf_get_u32(ARMV4_5_CORE_REG_MODENUM(armv4_5->core_cache, mode, num).value, 0, 32));
411 command_print(CMD_CTX, "%s", output);
413 command_print(CMD_CTX,
414 " 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 "",
415 buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 32),
416 buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_SPSR_FIQ].value, 0, 32),
417 buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_SPSR_IRQ].value, 0, 32),
418 buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_SPSR_SVC].value, 0, 32),
419 buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_SPSR_ABT].value, 0, 32),
420 buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_SPSR_UND].value, 0, 32));
425 COMMAND_HANDLER(handle_armv4_5_core_state_command)
427 struct target *target = get_current_target(CMD_CTX);
428 struct armv4_5_common_s *armv4_5 = target_to_armv4_5(target);
430 if (!is_arm(armv4_5))
432 command_print(CMD_CTX, "current target isn't an ARM");
438 if (strcmp(CMD_ARGV[0], "arm") == 0)
440 armv4_5->core_state = ARMV4_5_STATE_ARM;
442 if (strcmp(CMD_ARGV[0], "thumb") == 0)
444 armv4_5->core_state = ARMV4_5_STATE_THUMB;
448 command_print(CMD_CTX, "core state: %s", armv4_5_state_strings[armv4_5->core_state]);
453 COMMAND_HANDLER(handle_armv4_5_disassemble_command)
455 int retval = ERROR_OK;
456 struct target *target = get_current_target(CMD_CTX);
457 struct arm *arm = target ? target_to_arm(target) : NULL;
463 command_print(CMD_CTX, "current target isn't an ARM");
469 if (strcmp(CMD_ARGV[2], "thumb") != 0)
474 COMMAND_PARSE_NUMBER(int, CMD_ARGV[1], count);
477 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], address);
478 if (address & 0x01) {
480 command_print(CMD_CTX, "Disassemble as Thumb");
488 command_print(CMD_CTX,
489 "usage: arm disassemble <address> [<count> ['thumb']]");
494 while (count-- > 0) {
495 struct arm_instruction cur_instruction;
498 /* Always use Thumb2 disassembly for best handling
499 * of 32-bit BL/BLX, and to work with newer cores
500 * (some ARMv6, all ARMv7) that use Thumb2.
502 retval = thumb2_opcode(target, address,
504 if (retval != ERROR_OK)
509 retval = target_read_u32(target, address, &opcode);
510 if (retval != ERROR_OK)
512 retval = arm_evaluate_opcode(opcode, address,
513 &cur_instruction) != ERROR_OK;
514 if (retval != ERROR_OK)
517 command_print(CMD_CTX, "%s", cur_instruction.text);
518 address += cur_instruction.instruction_size;
524 int armv4_5_register_commands(struct command_context *cmd_ctx)
526 struct command *armv4_5_cmd;
528 armv4_5_cmd = register_command(cmd_ctx, NULL, "arm",
530 "generic ARM commands");
532 register_command(cmd_ctx, armv4_5_cmd, "reg",
533 handle_armv4_5_reg_command, COMMAND_EXEC,
534 "display ARM core registers");
535 register_command(cmd_ctx, armv4_5_cmd, "core_state",
536 handle_armv4_5_core_state_command, COMMAND_EXEC,
537 "display/change ARM core state <arm | thumb>");
538 register_command(cmd_ctx, armv4_5_cmd, "disassemble",
539 handle_armv4_5_disassemble_command, COMMAND_EXEC,
540 "disassemble instructions "
541 "<address> [<count> ['thumb']]");
546 int armv4_5_get_gdb_reg_list(struct target *target, struct reg **reg_list[], int *reg_list_size)
548 struct armv4_5_common_s *armv4_5 = target_to_armv4_5(target);
551 if (armv4_5_mode_to_number(armv4_5->core_mode)==-1)
555 *reg_list = malloc(sizeof(struct reg*) * (*reg_list_size));
557 for (i = 0; i < 16; i++)
559 (*reg_list)[i] = &ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, i);
562 for (i = 16; i < 24; i++)
564 (*reg_list)[i] = &arm_gdb_dummy_fp_reg;
567 (*reg_list)[24] = &arm_gdb_dummy_fps_reg;
568 (*reg_list)[25] = &armv4_5->core_cache->reg_list[ARMV4_5_CPSR];
573 /* wait for execution to complete and check exit point */
574 static int armv4_5_run_algorithm_completion(struct target *target, uint32_t exit_point, int timeout_ms, void *arch_info)
577 struct armv4_5_common_s *armv4_5 = target_to_armv4_5(target);
579 if ((retval = target_wait_state(target, TARGET_HALTED, timeout_ms)) != ERROR_OK)
583 if (target->state != TARGET_HALTED)
585 if ((retval = target_halt(target)) != ERROR_OK)
587 if ((retval = target_wait_state(target, TARGET_HALTED, 500)) != ERROR_OK)
591 return ERROR_TARGET_TIMEOUT;
594 /* fast exit: ARMv5+ code can use BKPT */
595 if (exit_point && buf_get_u32(armv4_5->core_cache->reg_list[15].value,
596 0, 32) != exit_point)
598 LOG_WARNING("target reentered debug state, but not at the desired exit point: 0x%4.4" PRIx32 "",
599 buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32));
600 return ERROR_TARGET_TIMEOUT;
606 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))
608 struct armv4_5_common_s *armv4_5 = target_to_armv4_5(target);
609 struct armv4_5_algorithm *armv4_5_algorithm_info = arch_info;
610 enum armv4_5_state core_state = armv4_5->core_state;
611 enum armv4_5_mode core_mode = armv4_5->core_mode;
612 uint32_t context[17];
614 int exit_breakpoint_size = 0;
616 int retval = ERROR_OK;
617 LOG_DEBUG("Running algorithm");
619 if (armv4_5_algorithm_info->common_magic != ARMV4_5_COMMON_MAGIC)
621 LOG_ERROR("current target isn't an ARMV4/5 target");
622 return ERROR_TARGET_INVALID;
625 if (target->state != TARGET_HALTED)
627 LOG_WARNING("target not halted");
628 return ERROR_TARGET_NOT_HALTED;
631 if (armv4_5_mode_to_number(armv4_5->core_mode)==-1)
634 /* armv5 and later can terminate with BKPT instruction; less overhead */
635 if (!exit_point && armv4_5->is_armv4)
637 LOG_ERROR("ARMv4 target needs HW breakpoint location");
641 for (i = 0; i <= 16; i++)
643 if (!ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5_algorithm_info->core_mode, i).valid)
644 armv4_5->read_core_reg(target, i, armv4_5_algorithm_info->core_mode);
645 context[i] = buf_get_u32(ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5_algorithm_info->core_mode, i).value, 0, 32);
647 cpsr = buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 32);
649 for (i = 0; i < num_mem_params; i++)
651 if ((retval = target_write_buffer(target, mem_params[i].address, mem_params[i].size, mem_params[i].value)) != ERROR_OK)
657 for (i = 0; i < num_reg_params; i++)
659 struct reg *reg = register_get_by_name(armv4_5->core_cache, reg_params[i].reg_name, 0);
662 LOG_ERROR("BUG: register '%s' not found", reg_params[i].reg_name);
663 return ERROR_INVALID_ARGUMENTS;
666 if (reg->size != reg_params[i].size)
668 LOG_ERROR("BUG: register '%s' size doesn't match reg_params[i].size", reg_params[i].reg_name);
669 return ERROR_INVALID_ARGUMENTS;
672 if ((retval = armv4_5_set_core_reg(reg, reg_params[i].value)) != ERROR_OK)
678 armv4_5->core_state = armv4_5_algorithm_info->core_state;
679 if (armv4_5->core_state == ARMV4_5_STATE_ARM)
680 exit_breakpoint_size = 4;
681 else if (armv4_5->core_state == ARMV4_5_STATE_THUMB)
682 exit_breakpoint_size = 2;
685 LOG_ERROR("BUG: can't execute algorithms when not in ARM or Thumb state");
686 return ERROR_INVALID_ARGUMENTS;
689 if (armv4_5_algorithm_info->core_mode != ARMV4_5_MODE_ANY)
691 LOG_DEBUG("setting core_mode: 0x%2.2x", armv4_5_algorithm_info->core_mode);
692 buf_set_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 5, armv4_5_algorithm_info->core_mode);
693 armv4_5->core_cache->reg_list[ARMV4_5_CPSR].dirty = 1;
694 armv4_5->core_cache->reg_list[ARMV4_5_CPSR].valid = 1;
697 /* terminate using a hardware or (ARMv5+) software breakpoint */
698 if (exit_point && (retval = breakpoint_add(target, exit_point,
699 exit_breakpoint_size, BKPT_HARD)) != ERROR_OK)
701 LOG_ERROR("can't add HW breakpoint to terminate algorithm");
702 return ERROR_TARGET_FAILURE;
705 if ((retval = target_resume(target, 0, entry_point, 1, 1)) != ERROR_OK)
710 retval = run_it(target, exit_point, timeout_ms, arch_info);
713 breakpoint_remove(target, exit_point);
715 if (retval != ERROR_OK)
718 for (i = 0; i < num_mem_params; i++)
720 if (mem_params[i].direction != PARAM_OUT)
721 if ((retvaltemp = target_read_buffer(target, mem_params[i].address, mem_params[i].size, mem_params[i].value)) != ERROR_OK)
727 for (i = 0; i < num_reg_params; i++)
729 if (reg_params[i].direction != PARAM_OUT)
732 struct reg *reg = register_get_by_name(armv4_5->core_cache, reg_params[i].reg_name, 0);
735 LOG_ERROR("BUG: register '%s' not found", reg_params[i].reg_name);
736 retval = ERROR_INVALID_ARGUMENTS;
740 if (reg->size != reg_params[i].size)
742 LOG_ERROR("BUG: register '%s' size doesn't match reg_params[i].size", reg_params[i].reg_name);
743 retval = ERROR_INVALID_ARGUMENTS;
747 buf_set_u32(reg_params[i].value, 0, 32, buf_get_u32(reg->value, 0, 32));
751 for (i = 0; i <= 16; i++)
754 regvalue = buf_get_u32(ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5_algorithm_info->core_mode, i).value, 0, 32);
755 if (regvalue != context[i])
757 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]);
758 buf_set_u32(ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5_algorithm_info->core_mode, i).value, 0, 32, context[i]);
759 ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5_algorithm_info->core_mode, i).valid = 1;
760 ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5_algorithm_info->core_mode, i).dirty = 1;
763 buf_set_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 32, cpsr);
764 armv4_5->core_cache->reg_list[ARMV4_5_CPSR].valid = 1;
765 armv4_5->core_cache->reg_list[ARMV4_5_CPSR].dirty = 1;
767 armv4_5->core_state = core_state;
768 armv4_5->core_mode = core_mode;
773 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)
775 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);
779 * Runs ARM code in the target to calculate a CRC32 checksum.
781 * \todo On ARMv5+, rely on BKPT termination for reduced overhead.
783 int arm_checksum_memory(struct target *target,
784 uint32_t address, uint32_t count, uint32_t *checksum)
786 struct working_area *crc_algorithm;
787 struct armv4_5_algorithm armv4_5_info;
788 struct reg_param reg_params[2];
792 static const uint32_t arm_crc_code[] = {
793 0xE1A02000, /* mov r2, r0 */
794 0xE3E00000, /* mov r0, #0xffffffff */
795 0xE1A03001, /* mov r3, r1 */
796 0xE3A04000, /* mov r4, #0 */
797 0xEA00000B, /* b ncomp */
799 0xE7D21004, /* ldrb r1, [r2, r4] */
800 0xE59F7030, /* ldr r7, CRC32XOR */
801 0xE0200C01, /* eor r0, r0, r1, asl 24 */
802 0xE3A05000, /* mov r5, #0 */
804 0xE3500000, /* cmp r0, #0 */
805 0xE1A06080, /* mov r6, r0, asl #1 */
806 0xE2855001, /* add r5, r5, #1 */
807 0xE1A00006, /* mov r0, r6 */
808 0xB0260007, /* eorlt r0, r6, r7 */
809 0xE3550008, /* cmp r5, #8 */
810 0x1AFFFFF8, /* bne loop */
811 0xE2844001, /* add r4, r4, #1 */
813 0xE1540003, /* cmp r4, r3 */
814 0x1AFFFFF1, /* bne nbyte */
816 0xEAFFFFFE, /* b end */
818 0x04C11DB7 /* .word 0x04C11DB7 */
821 retval = target_alloc_working_area(target,
822 sizeof(arm_crc_code), &crc_algorithm);
823 if (retval != ERROR_OK)
826 /* convert code into a buffer in target endianness */
827 for (i = 0; i < ARRAY_SIZE(arm_crc_code); i++) {
828 retval = target_write_u32(target,
829 crc_algorithm->address + i * sizeof(uint32_t),
831 if (retval != ERROR_OK)
835 armv4_5_info.common_magic = ARMV4_5_COMMON_MAGIC;
836 armv4_5_info.core_mode = ARMV4_5_MODE_SVC;
837 armv4_5_info.core_state = ARMV4_5_STATE_ARM;
839 init_reg_param(®_params[0], "r0", 32, PARAM_IN_OUT);
840 init_reg_param(®_params[1], "r1", 32, PARAM_OUT);
842 buf_set_u32(reg_params[0].value, 0, 32, address);
843 buf_set_u32(reg_params[1].value, 0, 32, count);
845 /* 20 second timeout/megabyte */
846 int timeout = 20000 * (1 + (count / (1024 * 1024)));
848 retval = target_run_algorithm(target, 0, NULL, 2, reg_params,
849 crc_algorithm->address,
850 crc_algorithm->address + sizeof(arm_crc_code) - 8,
851 timeout, &armv4_5_info);
852 if (retval != ERROR_OK) {
853 LOG_ERROR("error executing ARM crc algorithm");
854 destroy_reg_param(®_params[0]);
855 destroy_reg_param(®_params[1]);
856 target_free_working_area(target, crc_algorithm);
860 *checksum = buf_get_u32(reg_params[0].value, 0, 32);
862 destroy_reg_param(®_params[0]);
863 destroy_reg_param(®_params[1]);
865 target_free_working_area(target, crc_algorithm);
871 * Runs ARM code in the target to check whether a memory block holds
872 * all ones. NOR flash which has been erased, and thus may be written,
875 * \todo On ARMv5+, rely on BKPT termination for reduced overhead.
877 int arm_blank_check_memory(struct target *target,
878 uint32_t address, uint32_t count, uint32_t *blank)
880 struct working_area *check_algorithm;
881 struct reg_param reg_params[3];
882 struct armv4_5_algorithm armv4_5_info;
886 static const uint32_t check_code[] = {
888 0xe4d03001, /* ldrb r3, [r0], #1 */
889 0xe0022003, /* and r2, r2, r3 */
890 0xe2511001, /* subs r1, r1, #1 */
891 0x1afffffb, /* bne loop */
893 0xeafffffe /* b end */
896 /* make sure we have a working area */
897 retval = target_alloc_working_area(target,
898 sizeof(check_code), &check_algorithm);
899 if (retval != ERROR_OK)
902 /* convert code into a buffer in target endianness */
903 for (i = 0; i < ARRAY_SIZE(check_code); i++) {
904 retval = target_write_u32(target,
905 check_algorithm->address
906 + i * sizeof(uint32_t),
908 if (retval != ERROR_OK)
912 armv4_5_info.common_magic = ARMV4_5_COMMON_MAGIC;
913 armv4_5_info.core_mode = ARMV4_5_MODE_SVC;
914 armv4_5_info.core_state = ARMV4_5_STATE_ARM;
916 init_reg_param(®_params[0], "r0", 32, PARAM_OUT);
917 buf_set_u32(reg_params[0].value, 0, 32, address);
919 init_reg_param(®_params[1], "r1", 32, PARAM_OUT);
920 buf_set_u32(reg_params[1].value, 0, 32, count);
922 init_reg_param(®_params[2], "r2", 32, PARAM_IN_OUT);
923 buf_set_u32(reg_params[2].value, 0, 32, 0xff);
925 retval = target_run_algorithm(target, 0, NULL, 3, reg_params,
926 check_algorithm->address,
927 check_algorithm->address + sizeof(check_code) - 4,
928 10000, &armv4_5_info);
929 if (retval != ERROR_OK) {
930 destroy_reg_param(®_params[0]);
931 destroy_reg_param(®_params[1]);
932 destroy_reg_param(®_params[2]);
933 target_free_working_area(target, check_algorithm);
937 *blank = buf_get_u32(reg_params[2].value, 0, 32);
939 destroy_reg_param(®_params[0]);
940 destroy_reg_param(®_params[1]);
941 destroy_reg_param(®_params[2]);
943 target_free_working_area(target, check_algorithm);
948 int armv4_5_init_arch_info(struct target *target, struct arm *armv4_5)
950 target->arch_info = armv4_5;
952 armv4_5->common_magic = ARMV4_5_COMMON_MAGIC;
953 armv4_5->core_state = ARMV4_5_STATE_ARM;
954 armv4_5->core_mode = ARMV4_5_MODE_USR;