summaryrefslogtreecommitdiff
path: root/src/target/armv4_5.c
diff options
context:
space:
mode:
authorDavid Brownell <dbrownell@users.sourceforge.net>2009-11-16 15:29:14 -0800
committerDavid Brownell <dbrownell@users.sourceforge.net>2009-11-16 15:29:14 -0800
commit91ac164d95e1101120b938c684b78934d23dd51c (patch)
tree168693f52c4e17a9173b4eddf20670c7512684ec /src/target/armv4_5.c
parentbf972374011359a1d160b0359e59c4350e78aefe (diff)
downloadopenocd_libswd-91ac164d95e1101120b938c684b78934d23dd51c.tar.gz
openocd_libswd-91ac164d95e1101120b938c684b78934d23dd51c.tar.bz2
openocd_libswd-91ac164d95e1101120b938c684b78934d23dd51c.tar.xz
openocd_libswd-91ac164d95e1101120b938c684b78934d23dd51c.zip
ARM: standard disassembler uses Thumb2 entry
Tweak "standard" ARM disassembler diagnostics to fail if the target is not "an ARM" (vs. not "an ARMV4/5"), so it makes more sense for cores inheriting this as the "generic" disassembler. Also, to use the Thumb2 entry instead of the original Thumb entry. This makes it work better for both newer cores (which support those added instructions) and for BL and BLX instructions on older cores. (Those instructions are 32-bits, which requires curious state-aware code to go through a 16-bit decode interface...) Plus minor cleanups, notably to have fewer exit paths and to make sure they all return failure codes. Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
Diffstat (limited to 'src/target/armv4_5.c')
-rw-r--r--src/target/armv4_5.c68
1 files changed, 32 insertions, 36 deletions
diff --git a/src/target/armv4_5.c b/src/target/armv4_5.c
index 334f834a..e112e7b1 100644
--- a/src/target/armv4_5.c
+++ b/src/target/armv4_5.c
@@ -439,19 +439,14 @@ COMMAND_HANDLER(handle_armv4_5_disassemble_command)
{
int retval = ERROR_OK;
struct target *target = get_current_target(cmd_ctx);
- struct armv4_5_common_s *armv4_5 = target_to_armv4_5(target);
+ struct arm *arm = target ? target_to_arm(target) : NULL;
uint32_t address;
int count = 1;
- int i;
- struct arm_instruction cur_instruction;
- uint32_t opcode;
- uint16_t thumb_opcode;
int thumb = 0;
- if (armv4_5->common_magic != ARMV4_5_COMMON_MAGIC)
- {
- command_print(cmd_ctx, "current target isn't an ARMV4/5 target");
- return ERROR_OK;
+ if (!is_arm(arm)) {
+ command_print(cmd_ctx, "current target isn't an ARM");
+ return ERROR_FAIL;
}
switch (argc) {
@@ -477,37 +472,38 @@ COMMAND_HANDLER(handle_armv4_5_disassemble_command)
usage:
command_print(cmd_ctx,
"usage: armv4_5 disassemble <address> [<count> ['thumb']]");
- return ERROR_OK;
- }
-
- for (i = 0; i < count; i++)
- {
- if (thumb)
- {
- if ((retval = target_read_u16(target, address, &thumb_opcode)) != ERROR_OK)
- {
- return retval;
- }
- if ((retval = thumb_evaluate_opcode(thumb_opcode, address, &cur_instruction)) != ERROR_OK)
- {
- return retval;
- }
- }
- else {
- if ((retval = target_read_u32(target, address, &opcode)) != ERROR_OK)
- {
- return retval;
- }
- if ((retval = arm_evaluate_opcode(opcode, address, &cur_instruction)) != ERROR_OK)
- {
- return retval;
- }
+ count = 0;
+ retval = ERROR_FAIL;
+ }
+
+ while (count-- > 0) {
+ struct arm_instruction cur_instruction;
+
+ if (thumb) {
+ /* Always use Thumb2 disassembly for best handling
+ * of 32-bit BL/BLX, and to work with newer cores
+ * (some ARMv6, all ARMv7) that use Thumb2.
+ */
+ retval = thumb2_opcode(target, address,
+ &cur_instruction);
+ if (retval != ERROR_OK)
+ break;
+ } else {
+ uint32_t opcode;
+
+ retval = target_read_u32(target, address, &opcode);
+ if (retval != ERROR_OK)
+ break;
+ retval = arm_evaluate_opcode(opcode, address,
+ &cur_instruction) != ERROR_OK;
+ if (retval != ERROR_OK)
+ break;
}
command_print(cmd_ctx, "%s", cur_instruction.text);
- address += (thumb) ? 2 : 4;
+ address += cur_instruction.instruction_size;
}
- return ERROR_OK;
+ return retval;
}
int armv4_5_register_commands(struct command_context *cmd_ctx)