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 /* offsets into armv4_5 core register cache */
42 ARMV4_5_SPSR_FIQ
= 32,
43 ARMV4_5_SPSR_IRQ
= 33,
44 ARMV4_5_SPSR_SVC
= 34,
45 ARMV4_5_SPSR_ABT
= 35,
46 ARMV4_5_SPSR_UND
= 36,
50 static const uint8_t arm_usr_indices
[17] = {
51 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, ARMV4_5_CPSR
,
54 static const uint8_t arm_fiq_indices
[8] = {
55 16, 17, 18, 19, 20, 21, 22, ARMV4_5_SPSR_FIQ
,
58 static const uint8_t arm_irq_indices
[3] = {
59 23, 24, ARMV4_5_SPSR_IRQ
,
62 static const uint8_t arm_svc_indices
[3] = {
63 25, 26, ARMV4_5_SPSR_SVC
,
66 static const uint8_t arm_abt_indices
[3] = {
67 27, 28, ARMV4_5_SPSR_ABT
,
70 static const uint8_t arm_und_indices
[3] = {
71 29, 30, ARMV4_5_SPSR_UND
,
74 static const uint8_t arm_mon_indices
[3] = {
81 /* For user and system modes, these list indices for all registers.
82 * otherwise they're just indices for the shadow registers and SPSR.
84 unsigned short n_indices
;
85 const uint8_t *indices
;
87 /* Seven modes are standard from ARM7 on. "System" and "User" share
88 * the same registers; other modes shadow from 3 to 8 registers.
92 .psr
= ARMV4_5_MODE_USR
,
93 .n_indices
= ARRAY_SIZE(arm_usr_indices
),
94 .indices
= arm_usr_indices
,
98 .psr
= ARMV4_5_MODE_FIQ
,
99 .n_indices
= ARRAY_SIZE(arm_fiq_indices
),
100 .indices
= arm_fiq_indices
,
103 .name
= "Supervisor",
104 .psr
= ARMV4_5_MODE_SVC
,
105 .n_indices
= ARRAY_SIZE(arm_svc_indices
),
106 .indices
= arm_svc_indices
,
110 .psr
= ARMV4_5_MODE_ABT
,
111 .n_indices
= ARRAY_SIZE(arm_abt_indices
),
112 .indices
= arm_abt_indices
,
116 .psr
= ARMV4_5_MODE_IRQ
,
117 .n_indices
= ARRAY_SIZE(arm_irq_indices
),
118 .indices
= arm_irq_indices
,
121 .name
= "Undefined instruction",
122 .psr
= ARMV4_5_MODE_UND
,
123 .n_indices
= ARRAY_SIZE(arm_und_indices
),
124 .indices
= arm_und_indices
,
128 .psr
= ARMV4_5_MODE_SYS
,
129 .n_indices
= ARRAY_SIZE(arm_usr_indices
),
130 .indices
= arm_usr_indices
,
132 /* TrustZone "Security Extensions" add a secure monitor mode.
133 * This is distinct from a "debug monitor" which can support
134 * non-halting debug, in conjunction with some debuggers.
137 .name
= "Secure Monitor",
139 .n_indices
= ARRAY_SIZE(arm_mon_indices
),
140 .indices
= arm_mon_indices
,
144 /** Map PSR mode bits to the name of an ARM processor operating mode. */
145 const char *arm_mode_name(unsigned psr_mode
)
147 for (unsigned i
= 0; i
< ARRAY_SIZE(arm_mode_data
); i
++) {
148 if (arm_mode_data
[i
].psr
== psr_mode
)
149 return arm_mode_data
[i
].name
;
151 LOG_ERROR("unrecognized psr mode: %#02x", psr_mode
);
152 return "UNRECOGNIZED";
155 /** Return true iff the parameter denotes a valid ARM processor mode. */
156 bool is_arm_mode(unsigned psr_mode
)
158 for (unsigned i
= 0; i
< ARRAY_SIZE(arm_mode_data
); i
++) {
159 if (arm_mode_data
[i
].psr
== psr_mode
)
165 /** Map PSR mode bits to linear number indexing armv4_5_core_reg_map */
166 int armv4_5_mode_to_number(enum armv4_5_mode mode
)
169 case ARMV4_5_MODE_ANY
:
170 /* map MODE_ANY to user mode */
171 case ARMV4_5_MODE_USR
:
173 case ARMV4_5_MODE_FIQ
:
175 case ARMV4_5_MODE_IRQ
:
177 case ARMV4_5_MODE_SVC
:
179 case ARMV4_5_MODE_ABT
:
181 case ARMV4_5_MODE_UND
:
183 case ARMV4_5_MODE_SYS
:
188 LOG_ERROR("invalid mode value encountered %d", mode
);
193 /** Map linear number indexing armv4_5_core_reg_map to PSR mode bits. */
194 enum armv4_5_mode
armv4_5_number_to_mode(int number
)
198 return ARMV4_5_MODE_USR
;
200 return ARMV4_5_MODE_FIQ
;
202 return ARMV4_5_MODE_IRQ
;
204 return ARMV4_5_MODE_SVC
;
206 return ARMV4_5_MODE_ABT
;
208 return ARMV4_5_MODE_UND
;
210 return ARMV4_5_MODE_SYS
;
214 LOG_ERROR("mode index out of bounds %d", number
);
215 return ARMV4_5_MODE_ANY
;
219 char* armv4_5_state_strings
[] =
221 "ARM", "Thumb", "Jazelle", "ThumbEE",
224 /* Templates for ARM core registers.
226 * NOTE: offsets in this table are coupled to the arm_mode_data
227 * table above, the armv4_5_core_reg_map array below, and also to
228 * the ARMV4_5_CPSR symbol (which should vanish after ARM11 updates).
230 static const struct {
231 /* The name is used for e.g. the "regs" command. */
234 /* The {cookie, mode} tuple uniquely identifies one register.
235 * In a given mode, cookies 0..15 map to registers R0..R15,
236 * with R13..R15 usually called SP, LR, PC.
238 * MODE_ANY is used as *input* to the mapping, and indicates
239 * various special cases (sigh) and errors.
241 * Cookie 16 is (currently) confusing, since it indicates
242 * CPSR -or- SPSR depending on whether 'mode' is MODE_ANY.
243 * (Exception modes have both CPSR and SPSR registers ...)
246 enum armv4_5_mode mode
;
247 } arm_core_regs
[] = {
248 { .name
= "r0", .cookie
= 0, .mode
= ARMV4_5_MODE_ANY
, },
249 { .name
= "r1", .cookie
= 1, .mode
= ARMV4_5_MODE_ANY
, },
250 { .name
= "r2", .cookie
= 2, .mode
= ARMV4_5_MODE_ANY
, },
251 { .name
= "r3", .cookie
= 3, .mode
= ARMV4_5_MODE_ANY
, },
252 { .name
= "r4", .cookie
= 4, .mode
= ARMV4_5_MODE_ANY
, },
253 { .name
= "r5", .cookie
= 5, .mode
= ARMV4_5_MODE_ANY
, },
254 { .name
= "r6", .cookie
= 6, .mode
= ARMV4_5_MODE_ANY
, },
255 { .name
= "r7", .cookie
= 7, .mode
= ARMV4_5_MODE_ANY
, },
257 /* NOTE: regs 8..12 might be shadowed by FIQ ... flagging
258 * them as MODE_ANY creates special cases.
260 { .name
= "r8", .cookie
= 8, .mode
= ARMV4_5_MODE_ANY
, },
261 { .name
= "r9", .cookie
= 9, .mode
= ARMV4_5_MODE_ANY
, },
262 { .name
= "r10", .cookie
= 10, .mode
= ARMV4_5_MODE_ANY
, },
263 { .name
= "r11", .cookie
= 11, .mode
= ARMV4_5_MODE_ANY
, },
264 { .name
= "r12", .cookie
= 12, .mode
= ARMV4_5_MODE_ANY
, },
266 /* NOTE all MODE_USR registers are equivalent to MODE_SYS ones */
267 { .name
= "sp_usr", .cookie
= 13, .mode
= ARMV4_5_MODE_USR
, },
268 { .name
= "lr_usr", .cookie
= 14, .mode
= ARMV4_5_MODE_USR
, },
270 { .name
= "pc", .cookie
= 15, .mode
= ARMV4_5_MODE_ANY
, },
272 { .name
= "r8_fiq", .cookie
= 8, .mode
= ARMV4_5_MODE_FIQ
, },
273 { .name
= "r9_fiq", .cookie
= 9, .mode
= ARMV4_5_MODE_FIQ
, },
274 { .name
= "r10_fiq", .cookie
= 10, .mode
= ARMV4_5_MODE_FIQ
, },
275 { .name
= "r11_fiq", .cookie
= 11, .mode
= ARMV4_5_MODE_FIQ
, },
276 { .name
= "r12_fiq", .cookie
= 12, .mode
= ARMV4_5_MODE_FIQ
, },
278 { .name
= "lr_fiq", .cookie
= 13, .mode
= ARMV4_5_MODE_FIQ
, },
279 { .name
= "sp_fiq", .cookie
= 14, .mode
= ARMV4_5_MODE_FIQ
, },
281 { .name
= "lr_irq", .cookie
= 13, .mode
= ARMV4_5_MODE_IRQ
, },
282 { .name
= "sp_irq", .cookie
= 14, .mode
= ARMV4_5_MODE_IRQ
, },
284 { .name
= "lr_svc", .cookie
= 13, .mode
= ARMV4_5_MODE_SVC
, },
285 { .name
= "sp_svc", .cookie
= 14, .mode
= ARMV4_5_MODE_SVC
, },
287 { .name
= "lr_abt", .cookie
= 13, .mode
= ARMV4_5_MODE_ABT
, },
288 { .name
= "sp_abt", .cookie
= 14, .mode
= ARMV4_5_MODE_ABT
, },
290 { .name
= "lr_und", .cookie
= 13, .mode
= ARMV4_5_MODE_UND
, },
291 { .name
= "sp_und", .cookie
= 14, .mode
= ARMV4_5_MODE_UND
, },
293 { .name
= "cpsr", .cookie
= 16, .mode
= ARMV4_5_MODE_ANY
, },
294 { .name
= "spsr_fiq", .cookie
= 16, .mode
= ARMV4_5_MODE_FIQ
, },
295 { .name
= "spsr_irq", .cookie
= 16, .mode
= ARMV4_5_MODE_IRQ
, },
296 { .name
= "spsr_svc", .cookie
= 16, .mode
= ARMV4_5_MODE_SVC
, },
297 { .name
= "spsr_abt", .cookie
= 16, .mode
= ARMV4_5_MODE_ABT
, },
298 { .name
= "spsr_und", .cookie
= 16, .mode
= ARMV4_5_MODE_UND
, },
300 { .name
= "lr_mon", .cookie
= 13, .mode
= ARM_MODE_MON
, },
301 { .name
= "sp_mon", .cookie
= 14, .mode
= ARM_MODE_MON
, },
302 { .name
= "spsr_mon", .cookie
= 16, .mode
= ARM_MODE_MON
, },
305 /* map core mode (USR, FIQ, ...) and register number to
306 * indices into the register cache
308 const int armv4_5_core_reg_map
[8][17] =
311 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 31
313 { /* FIQ (8 shadows of USR, vs normal 3) */
314 0, 1, 2, 3, 4, 5, 6, 7, 16, 17, 18, 19, 20, 21, 22, 15, 32
317 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 23, 24, 15, 33
320 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 25, 26, 15, 34
323 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 27, 28, 15, 35
326 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 29, 30, 15, 36
328 { /* SYS (same registers as USR) */
329 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 31
332 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 37, 38, 15, 39,
336 static const uint8_t arm_gdb_dummy_fp_value
[12];
339 * Dummy FPA registers are required to support GDB on ARM.
340 * Register packets require eight obsolete FPA register values.
341 * Modern ARM cores use Vector Floating Point (VFP), if they
342 * have any floating point support. VFP is not FPA-compatible.
344 struct reg arm_gdb_dummy_fp_reg
=
346 .name
= "GDB dummy FPA register",
347 .value
= (uint8_t *) arm_gdb_dummy_fp_value
,
352 static const uint8_t arm_gdb_dummy_fps_value
[4];
355 * Dummy FPA status registers are required to support GDB on ARM.
356 * Register packets require an obsolete FPA status register.
358 struct reg arm_gdb_dummy_fps_reg
=
360 .name
= "GDB dummy FPA status register",
361 .value
= (uint8_t *) arm_gdb_dummy_fps_value
,
366 static void arm_gdb_dummy_init(void) __attribute__ ((constructor
));
368 static void arm_gdb_dummy_init(void)
370 register_init_dummy(&arm_gdb_dummy_fp_reg
);
371 register_init_dummy(&arm_gdb_dummy_fps_reg
);
374 static int armv4_5_get_core_reg(struct reg
*reg
)
377 struct arm_reg
*armv4_5
= reg
->arch_info
;
378 struct target
*target
= armv4_5
->target
;
380 if (target
->state
!= TARGET_HALTED
)
382 LOG_ERROR("Target not halted");
383 return ERROR_TARGET_NOT_HALTED
;
386 retval
= armv4_5
->armv4_5_common
->read_core_reg(target
, reg
, armv4_5
->num
, armv4_5
->mode
);
387 if (retval
== ERROR_OK
) {
395 static int armv4_5_set_core_reg(struct reg
*reg
, uint8_t *buf
)
397 struct arm_reg
*armv4_5
= reg
->arch_info
;
398 struct target
*target
= armv4_5
->target
;
399 struct armv4_5_common_s
*armv4_5_target
= target_to_armv4_5(target
);
400 uint32_t value
= buf_get_u32(buf
, 0, 32);
402 if (target
->state
!= TARGET_HALTED
)
404 LOG_ERROR("Target not halted");
405 return ERROR_TARGET_NOT_HALTED
;
408 /* Except for CPSR, the "reg" command exposes a writeback model
409 * for the register cache.
411 buf_set_u32(reg
->value
, 0, 32, value
);
415 if (reg
== armv4_5_target
->cpsr
)
417 /* FIXME handle J bit too; mostly for ThumbEE, also Jazelle */
420 /* T bit should be set */
421 if (armv4_5_target
->core_state
== ARMV4_5_STATE_ARM
)
423 /* change state to Thumb */
424 LOG_DEBUG("changing to Thumb state");
425 armv4_5_target
->core_state
= ARMV4_5_STATE_THUMB
;
430 /* T bit should be cleared */
431 if (armv4_5_target
->core_state
== ARMV4_5_STATE_THUMB
)
433 /* change state to ARM */
434 LOG_DEBUG("changing to ARM state");
435 armv4_5_target
->core_state
= ARMV4_5_STATE_ARM
;
439 /* REVISIT Why only update core for mode change, not also
440 * for state changes? Possibly older cores need to stay
441 * in ARM mode during halt mode debug, not execute Thumb;
442 * v6/v7a/v7r seem to do that automatically...
445 if (armv4_5_target
->core_mode
!= (enum armv4_5_mode
)(value
& 0x1f))
447 LOG_DEBUG("changing ARM core mode to '%s'",
448 arm_mode_name(value
& 0x1f));
449 armv4_5_target
->core_mode
= value
& 0x1f;
450 armv4_5_target
->write_core_reg(target
, reg
,
451 16, ARMV4_5_MODE_ANY
, value
);
459 static const struct reg_arch_type arm_reg_type
= {
460 .get
= armv4_5_get_core_reg
,
461 .set
= armv4_5_set_core_reg
,
464 struct reg_cache
* armv4_5_build_reg_cache(struct target
*target
, struct arm
*armv4_5_common
)
466 int num_regs
= ARRAY_SIZE(arm_core_regs
);
467 struct reg_cache
*cache
= malloc(sizeof(struct reg_cache
));
468 struct reg
*reg_list
= calloc(num_regs
, sizeof(struct reg
));
469 struct arm_reg
*arch_info
= calloc(num_regs
, sizeof(struct arm_reg
));
472 if (!cache
|| !reg_list
|| !arch_info
) {
479 cache
->name
= "ARM registers";
481 cache
->reg_list
= reg_list
;
484 for (i
= 0; i
< num_regs
; i
++)
486 /* Skip registers this core doesn't expose */
487 if (arm_core_regs
[i
].mode
== ARM_MODE_MON
488 && armv4_5_common
->core_type
!= ARM_MODE_MON
)
491 /* REVISIT handle Cortex-M, which only shadows R13/SP */
493 arch_info
[i
].num
= arm_core_regs
[i
].cookie
;
494 arch_info
[i
].mode
= arm_core_regs
[i
].mode
;
495 arch_info
[i
].target
= target
;
496 arch_info
[i
].armv4_5_common
= armv4_5_common
;
498 reg_list
[i
].name
= (char *) arm_core_regs
[i
].name
;
499 reg_list
[i
].size
= 32;
500 reg_list
[i
].value
= &arch_info
[i
].value
;
501 reg_list
[i
].type
= &arm_reg_type
;
502 reg_list
[i
].arch_info
= &arch_info
[i
];
507 armv4_5_common
->cpsr
= reg_list
+ ARMV4_5_CPSR
;
508 armv4_5_common
->core_cache
= cache
;
512 int armv4_5_arch_state(struct target
*target
)
514 struct armv4_5_common_s
*armv4_5
= target_to_armv4_5(target
);
516 if (armv4_5
->common_magic
!= ARMV4_5_COMMON_MAGIC
)
518 LOG_ERROR("BUG: called for a non-ARMv4/5 target");
522 LOG_USER("target halted in %s state due to %s, current mode: %s\ncpsr: 0x%8.8" PRIx32
" pc: 0x%8.8" PRIx32
"",
523 armv4_5_state_strings
[armv4_5
->core_state
],
524 Jim_Nvp_value2name_simple(nvp_target_debug_reason
, target
->debug_reason
)->name
,
525 arm_mode_name(armv4_5
->core_mode
),
526 buf_get_u32(armv4_5
->cpsr
->value
, 0, 32),
527 buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32));
532 #define ARMV4_5_CORE_REG_MODENUM(cache, mode, num) \
533 cache->reg_list[armv4_5_core_reg_map[mode][num]]
535 COMMAND_HANDLER(handle_armv4_5_reg_command
)
537 struct target
*target
= get_current_target(CMD_CTX
);
538 struct armv4_5_common_s
*armv4_5
= target_to_armv4_5(target
);
542 if (!is_arm(armv4_5
))
544 command_print(CMD_CTX
, "current target isn't an ARM");
548 if (target
->state
!= TARGET_HALTED
)
550 command_print(CMD_CTX
, "error: target must be halted for register accesses");
554 if (!is_arm_mode(armv4_5
->core_mode
))
557 if (!armv4_5
->full_context
) {
558 command_print(CMD_CTX
, "error: target doesn't support %s",
563 num_regs
= armv4_5
->core_cache
->num_regs
;
564 regs
= armv4_5
->core_cache
->reg_list
;
566 for (unsigned mode
= 0; mode
< ARRAY_SIZE(arm_mode_data
); mode
++) {
571 /* label this bank of registers (or shadows) */
572 switch (arm_mode_data
[mode
].psr
) {
573 case ARMV4_5_MODE_SYS
:
575 case ARMV4_5_MODE_USR
:
576 name
= "System and User";
580 if (armv4_5
->core_type
!= ARM_MODE_MON
)
584 name
= arm_mode_data
[mode
].name
;
588 command_print(CMD_CTX
, "%s%s mode %sregisters",
591 /* display N rows of up to 4 registers each */
592 for (unsigned i
= 0; i
< arm_mode_data
[mode
].n_indices
;) {
596 for (unsigned j
= 0; j
< 4; j
++, i
++) {
598 struct reg
*reg
= regs
;
600 if (i
>= arm_mode_data
[mode
].n_indices
)
603 reg
+= arm_mode_data
[mode
].indices
[i
];
605 /* REVISIT be smarter about faults... */
607 armv4_5
->full_context(target
);
609 value
= buf_get_u32(reg
->value
, 0, 32);
610 output_len
+= snprintf(output
+ output_len
,
611 sizeof(output
) - output_len
,
612 "%8s: %8.8" PRIx32
" ",
615 command_print(CMD_CTX
, "%s", output
);
622 COMMAND_HANDLER(handle_armv4_5_core_state_command
)
624 struct target
*target
= get_current_target(CMD_CTX
);
625 struct armv4_5_common_s
*armv4_5
= target_to_armv4_5(target
);
627 if (!is_arm(armv4_5
))
629 command_print(CMD_CTX
, "current target isn't an ARM");
635 if (strcmp(CMD_ARGV
[0], "arm") == 0)
637 armv4_5
->core_state
= ARMV4_5_STATE_ARM
;
639 if (strcmp(CMD_ARGV
[0], "thumb") == 0)
641 armv4_5
->core_state
= ARMV4_5_STATE_THUMB
;
645 command_print(CMD_CTX
, "core state: %s", armv4_5_state_strings
[armv4_5
->core_state
]);
650 COMMAND_HANDLER(handle_armv4_5_disassemble_command
)
652 int retval
= ERROR_OK
;
653 struct target
*target
= get_current_target(CMD_CTX
);
654 struct arm
*arm
= target
? target_to_arm(target
) : NULL
;
660 command_print(CMD_CTX
, "current target isn't an ARM");
666 if (strcmp(CMD_ARGV
[2], "thumb") != 0)
671 COMMAND_PARSE_NUMBER(int, CMD_ARGV
[1], count
);
674 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[0], address
);
675 if (address
& 0x01) {
677 command_print(CMD_CTX
, "Disassemble as Thumb");
685 command_print(CMD_CTX
,
686 "usage: arm disassemble <address> [<count> ['thumb']]");
691 while (count
-- > 0) {
692 struct arm_instruction cur_instruction
;
695 /* Always use Thumb2 disassembly for best handling
696 * of 32-bit BL/BLX, and to work with newer cores
697 * (some ARMv6, all ARMv7) that use Thumb2.
699 retval
= thumb2_opcode(target
, address
,
701 if (retval
!= ERROR_OK
)
706 retval
= target_read_u32(target
, address
, &opcode
);
707 if (retval
!= ERROR_OK
)
709 retval
= arm_evaluate_opcode(opcode
, address
,
710 &cur_instruction
) != ERROR_OK
;
711 if (retval
!= ERROR_OK
)
714 command_print(CMD_CTX
, "%s", cur_instruction
.text
);
715 address
+= cur_instruction
.instruction_size
;
721 int armv4_5_register_commands(struct command_context
*cmd_ctx
)
723 struct command
*armv4_5_cmd
;
725 armv4_5_cmd
= register_command(cmd_ctx
, NULL
, "arm",
727 "generic ARM commands");
729 register_command(cmd_ctx
, armv4_5_cmd
, "reg",
730 handle_armv4_5_reg_command
, COMMAND_EXEC
,
731 "display ARM core registers");
732 register_command(cmd_ctx
, armv4_5_cmd
, "core_state",
733 handle_armv4_5_core_state_command
, COMMAND_EXEC
,
734 "display/change ARM core state <arm | thumb>");
735 register_command(cmd_ctx
, armv4_5_cmd
, "disassemble",
736 handle_armv4_5_disassemble_command
, COMMAND_EXEC
,
737 "disassemble instructions "
738 "<address> [<count> ['thumb']]");
743 int armv4_5_get_gdb_reg_list(struct target
*target
, struct reg
**reg_list
[], int *reg_list_size
)
745 struct armv4_5_common_s
*armv4_5
= target_to_armv4_5(target
);
748 if (!is_arm_mode(armv4_5
->core_mode
))
752 *reg_list
= malloc(sizeof(struct reg
*) * (*reg_list_size
));
754 for (i
= 0; i
< 16; i
++)
756 (*reg_list
)[i
] = &ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5
->core_mode
, i
);
759 for (i
= 16; i
< 24; i
++)
761 (*reg_list
)[i
] = &arm_gdb_dummy_fp_reg
;
764 (*reg_list
)[24] = &arm_gdb_dummy_fps_reg
;
765 (*reg_list
)[25] = armv4_5
->cpsr
;
770 /* wait for execution to complete and check exit point */
771 static int armv4_5_run_algorithm_completion(struct target
*target
, uint32_t exit_point
, int timeout_ms
, void *arch_info
)
774 struct armv4_5_common_s
*armv4_5
= target_to_armv4_5(target
);
776 if ((retval
= target_wait_state(target
, TARGET_HALTED
, timeout_ms
)) != ERROR_OK
)
780 if (target
->state
!= TARGET_HALTED
)
782 if ((retval
= target_halt(target
)) != ERROR_OK
)
784 if ((retval
= target_wait_state(target
, TARGET_HALTED
, 500)) != ERROR_OK
)
788 return ERROR_TARGET_TIMEOUT
;
791 /* fast exit: ARMv5+ code can use BKPT */
792 if (exit_point
&& buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
,
793 0, 32) != exit_point
)
795 LOG_WARNING("target reentered debug state, but not at the desired exit point: 0x%4.4" PRIx32
"",
796 buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32));
797 return ERROR_TARGET_TIMEOUT
;
803 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
))
805 struct armv4_5_common_s
*armv4_5
= target_to_armv4_5(target
);
806 struct armv4_5_algorithm
*armv4_5_algorithm_info
= arch_info
;
807 enum armv4_5_state core_state
= armv4_5
->core_state
;
808 enum armv4_5_mode core_mode
= armv4_5
->core_mode
;
809 uint32_t context
[17];
811 int exit_breakpoint_size
= 0;
813 int retval
= ERROR_OK
;
814 LOG_DEBUG("Running algorithm");
816 if (armv4_5_algorithm_info
->common_magic
!= ARMV4_5_COMMON_MAGIC
)
818 LOG_ERROR("current target isn't an ARMV4/5 target");
819 return ERROR_TARGET_INVALID
;
822 if (target
->state
!= TARGET_HALTED
)
824 LOG_WARNING("target not halted");
825 return ERROR_TARGET_NOT_HALTED
;
828 if (!is_arm_mode(armv4_5
->core_mode
))
831 /* armv5 and later can terminate with BKPT instruction; less overhead */
832 if (!exit_point
&& armv4_5
->is_armv4
)
834 LOG_ERROR("ARMv4 target needs HW breakpoint location");
838 for (i
= 0; i
<= 16; i
++)
842 r
= &ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
,
843 armv4_5_algorithm_info
->core_mode
, i
);
845 armv4_5
->read_core_reg(target
, r
, i
,
846 armv4_5_algorithm_info
->core_mode
);
847 context
[i
] = buf_get_u32(r
->value
, 0, 32);
849 cpsr
= buf_get_u32(armv4_5
->cpsr
->value
, 0, 32);
851 for (i
= 0; i
< num_mem_params
; i
++)
853 if ((retval
= target_write_buffer(target
, mem_params
[i
].address
, mem_params
[i
].size
, mem_params
[i
].value
)) != ERROR_OK
)
859 for (i
= 0; i
< num_reg_params
; i
++)
861 struct reg
*reg
= register_get_by_name(armv4_5
->core_cache
, reg_params
[i
].reg_name
, 0);
864 LOG_ERROR("BUG: register '%s' not found", reg_params
[i
].reg_name
);
865 return ERROR_INVALID_ARGUMENTS
;
868 if (reg
->size
!= reg_params
[i
].size
)
870 LOG_ERROR("BUG: register '%s' size doesn't match reg_params[i].size", reg_params
[i
].reg_name
);
871 return ERROR_INVALID_ARGUMENTS
;
874 if ((retval
= armv4_5_set_core_reg(reg
, reg_params
[i
].value
)) != ERROR_OK
)
880 armv4_5
->core_state
= armv4_5_algorithm_info
->core_state
;
881 if (armv4_5
->core_state
== ARMV4_5_STATE_ARM
)
882 exit_breakpoint_size
= 4;
883 else if (armv4_5
->core_state
== ARMV4_5_STATE_THUMB
)
884 exit_breakpoint_size
= 2;
887 LOG_ERROR("BUG: can't execute algorithms when not in ARM or Thumb state");
888 return ERROR_INVALID_ARGUMENTS
;
891 if (armv4_5_algorithm_info
->core_mode
!= ARMV4_5_MODE_ANY
)
893 LOG_DEBUG("setting core_mode: 0x%2.2x",
894 armv4_5_algorithm_info
->core_mode
);
895 buf_set_u32(armv4_5
->cpsr
->value
, 0, 5,
896 armv4_5_algorithm_info
->core_mode
);
897 armv4_5
->cpsr
->dirty
= 1;
898 armv4_5
->cpsr
->valid
= 1;
901 /* terminate using a hardware or (ARMv5+) software breakpoint */
902 if (exit_point
&& (retval
= breakpoint_add(target
, exit_point
,
903 exit_breakpoint_size
, BKPT_HARD
)) != ERROR_OK
)
905 LOG_ERROR("can't add HW breakpoint to terminate algorithm");
906 return ERROR_TARGET_FAILURE
;
909 if ((retval
= target_resume(target
, 0, entry_point
, 1, 1)) != ERROR_OK
)
914 retval
= run_it(target
, exit_point
, timeout_ms
, arch_info
);
917 breakpoint_remove(target
, exit_point
);
919 if (retval
!= ERROR_OK
)
922 for (i
= 0; i
< num_mem_params
; i
++)
924 if (mem_params
[i
].direction
!= PARAM_OUT
)
925 if ((retvaltemp
= target_read_buffer(target
, mem_params
[i
].address
, mem_params
[i
].size
, mem_params
[i
].value
)) != ERROR_OK
)
931 for (i
= 0; i
< num_reg_params
; i
++)
933 if (reg_params
[i
].direction
!= PARAM_OUT
)
936 struct reg
*reg
= register_get_by_name(armv4_5
->core_cache
, reg_params
[i
].reg_name
, 0);
939 LOG_ERROR("BUG: register '%s' not found", reg_params
[i
].reg_name
);
940 retval
= ERROR_INVALID_ARGUMENTS
;
944 if (reg
->size
!= reg_params
[i
].size
)
946 LOG_ERROR("BUG: register '%s' size doesn't match reg_params[i].size", reg_params
[i
].reg_name
);
947 retval
= ERROR_INVALID_ARGUMENTS
;
951 buf_set_u32(reg_params
[i
].value
, 0, 32, buf_get_u32(reg
->value
, 0, 32));
955 for (i
= 0; i
<= 16; i
++)
958 regvalue
= buf_get_u32(ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5_algorithm_info
->core_mode
, i
).value
, 0, 32);
959 if (regvalue
!= context
[i
])
961 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
]);
962 buf_set_u32(ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5_algorithm_info
->core_mode
, i
).value
, 0, 32, context
[i
]);
963 ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5_algorithm_info
->core_mode
, i
).valid
= 1;
964 ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5_algorithm_info
->core_mode
, i
).dirty
= 1;
967 buf_set_u32(armv4_5
->cpsr
->value
, 0, 32, cpsr
);
968 armv4_5
->cpsr
->valid
= 1;
969 armv4_5
->cpsr
->dirty
= 1;
971 armv4_5
->core_state
= core_state
;
972 armv4_5
->core_mode
= core_mode
;
977 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
)
979 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
);
983 * Runs ARM code in the target to calculate a CRC32 checksum.
985 * \todo On ARMv5+, rely on BKPT termination for reduced overhead.
987 int arm_checksum_memory(struct target
*target
,
988 uint32_t address
, uint32_t count
, uint32_t *checksum
)
990 struct working_area
*crc_algorithm
;
991 struct armv4_5_algorithm armv4_5_info
;
992 struct reg_param reg_params
[2];
996 static const uint32_t arm_crc_code
[] = {
997 0xE1A02000, /* mov r2, r0 */
998 0xE3E00000, /* mov r0, #0xffffffff */
999 0xE1A03001, /* mov r3, r1 */
1000 0xE3A04000, /* mov r4, #0 */
1001 0xEA00000B, /* b ncomp */
1003 0xE7D21004, /* ldrb r1, [r2, r4] */
1004 0xE59F7030, /* ldr r7, CRC32XOR */
1005 0xE0200C01, /* eor r0, r0, r1, asl 24 */
1006 0xE3A05000, /* mov r5, #0 */
1008 0xE3500000, /* cmp r0, #0 */
1009 0xE1A06080, /* mov r6, r0, asl #1 */
1010 0xE2855001, /* add r5, r5, #1 */
1011 0xE1A00006, /* mov r0, r6 */
1012 0xB0260007, /* eorlt r0, r6, r7 */
1013 0xE3550008, /* cmp r5, #8 */
1014 0x1AFFFFF8, /* bne loop */
1015 0xE2844001, /* add r4, r4, #1 */
1017 0xE1540003, /* cmp r4, r3 */
1018 0x1AFFFFF1, /* bne nbyte */
1020 0xEAFFFFFE, /* b end */
1022 0x04C11DB7 /* .word 0x04C11DB7 */
1025 retval
= target_alloc_working_area(target
,
1026 sizeof(arm_crc_code
), &crc_algorithm
);
1027 if (retval
!= ERROR_OK
)
1030 /* convert code into a buffer in target endianness */
1031 for (i
= 0; i
< ARRAY_SIZE(arm_crc_code
); i
++) {
1032 retval
= target_write_u32(target
,
1033 crc_algorithm
->address
+ i
* sizeof(uint32_t),
1035 if (retval
!= ERROR_OK
)
1039 armv4_5_info
.common_magic
= ARMV4_5_COMMON_MAGIC
;
1040 armv4_5_info
.core_mode
= ARMV4_5_MODE_SVC
;
1041 armv4_5_info
.core_state
= ARMV4_5_STATE_ARM
;
1043 init_reg_param(®_params
[0], "r0", 32, PARAM_IN_OUT
);
1044 init_reg_param(®_params
[1], "r1", 32, PARAM_OUT
);
1046 buf_set_u32(reg_params
[0].value
, 0, 32, address
);
1047 buf_set_u32(reg_params
[1].value
, 0, 32, count
);
1049 /* 20 second timeout/megabyte */
1050 int timeout
= 20000 * (1 + (count
/ (1024 * 1024)));
1052 retval
= target_run_algorithm(target
, 0, NULL
, 2, reg_params
,
1053 crc_algorithm
->address
,
1054 crc_algorithm
->address
+ sizeof(arm_crc_code
) - 8,
1055 timeout
, &armv4_5_info
);
1056 if (retval
!= ERROR_OK
) {
1057 LOG_ERROR("error executing ARM crc algorithm");
1058 destroy_reg_param(®_params
[0]);
1059 destroy_reg_param(®_params
[1]);
1060 target_free_working_area(target
, crc_algorithm
);
1064 *checksum
= buf_get_u32(reg_params
[0].value
, 0, 32);
1066 destroy_reg_param(®_params
[0]);
1067 destroy_reg_param(®_params
[1]);
1069 target_free_working_area(target
, crc_algorithm
);
1075 * Runs ARM code in the target to check whether a memory block holds
1076 * all ones. NOR flash which has been erased, and thus may be written,
1079 * \todo On ARMv5+, rely on BKPT termination for reduced overhead.
1081 int arm_blank_check_memory(struct target
*target
,
1082 uint32_t address
, uint32_t count
, uint32_t *blank
)
1084 struct working_area
*check_algorithm
;
1085 struct reg_param reg_params
[3];
1086 struct armv4_5_algorithm armv4_5_info
;
1090 static const uint32_t check_code
[] = {
1092 0xe4d03001, /* ldrb r3, [r0], #1 */
1093 0xe0022003, /* and r2, r2, r3 */
1094 0xe2511001, /* subs r1, r1, #1 */
1095 0x1afffffb, /* bne loop */
1097 0xeafffffe /* b end */
1100 /* make sure we have a working area */
1101 retval
= target_alloc_working_area(target
,
1102 sizeof(check_code
), &check_algorithm
);
1103 if (retval
!= ERROR_OK
)
1106 /* convert code into a buffer in target endianness */
1107 for (i
= 0; i
< ARRAY_SIZE(check_code
); i
++) {
1108 retval
= target_write_u32(target
,
1109 check_algorithm
->address
1110 + i
* sizeof(uint32_t),
1112 if (retval
!= ERROR_OK
)
1116 armv4_5_info
.common_magic
= ARMV4_5_COMMON_MAGIC
;
1117 armv4_5_info
.core_mode
= ARMV4_5_MODE_SVC
;
1118 armv4_5_info
.core_state
= ARMV4_5_STATE_ARM
;
1120 init_reg_param(®_params
[0], "r0", 32, PARAM_OUT
);
1121 buf_set_u32(reg_params
[0].value
, 0, 32, address
);
1123 init_reg_param(®_params
[1], "r1", 32, PARAM_OUT
);
1124 buf_set_u32(reg_params
[1].value
, 0, 32, count
);
1126 init_reg_param(®_params
[2], "r2", 32, PARAM_IN_OUT
);
1127 buf_set_u32(reg_params
[2].value
, 0, 32, 0xff);
1129 retval
= target_run_algorithm(target
, 0, NULL
, 3, reg_params
,
1130 check_algorithm
->address
,
1131 check_algorithm
->address
+ sizeof(check_code
) - 4,
1132 10000, &armv4_5_info
);
1133 if (retval
!= ERROR_OK
) {
1134 destroy_reg_param(®_params
[0]);
1135 destroy_reg_param(®_params
[1]);
1136 destroy_reg_param(®_params
[2]);
1137 target_free_working_area(target
, check_algorithm
);
1141 *blank
= buf_get_u32(reg_params
[2].value
, 0, 32);
1143 destroy_reg_param(®_params
[0]);
1144 destroy_reg_param(®_params
[1]);
1145 destroy_reg_param(®_params
[2]);
1147 target_free_working_area(target
, check_algorithm
);
1152 static int arm_full_context(struct target
*target
)
1154 struct armv4_5_common_s
*armv4_5
= target_to_armv4_5(target
);
1155 unsigned num_regs
= armv4_5
->core_cache
->num_regs
;
1156 struct reg
*reg
= armv4_5
->core_cache
->reg_list
;
1157 int retval
= ERROR_OK
;
1159 for (; num_regs
&& retval
== ERROR_OK
; num_regs
--, reg
++) {
1162 retval
= armv4_5_get_core_reg(reg
);
1167 int armv4_5_init_arch_info(struct target
*target
, struct arm
*armv4_5
)
1169 target
->arch_info
= armv4_5
;
1171 armv4_5
->common_magic
= ARMV4_5_COMMON_MAGIC
;
1172 armv4_5
->core_state
= ARMV4_5_STATE_ARM
;
1173 armv4_5
->core_mode
= ARMV4_5_MODE_USR
;
1175 /* core_type may be overridden by subtype logic */
1176 armv4_5
->core_type
= ARMV4_5_MODE_ANY
;
1178 /* default full_context() has no core-specific optimizations */
1179 if (!armv4_5
->full_context
&& armv4_5
->read_core_reg
)
1180 armv4_5
->full_context
= arm_full_context
;