fileio: improve API types
[fw/openocd] / src / target / armv4_5.c
index f9b22b940e374c5a111aa97c442c3a8f6dae0269..e112e7b11ce5d855665a134fa343a82ed070b9a4 100644 (file)
 #endif
 
 #include "armv4_5.h"
+#include "arm_jtag.h"
+#include "breakpoints.h"
 #include "arm_disassembler.h"
 #include "binarybuffer.h"
+#include "algorithm.h"
+#include "register.h"
 
 
 char* armv4_5_core_reg_list[] =
@@ -49,13 +53,63 @@ char* armv4_5_core_reg_list[] =
        "cpsr", "spsr_fiq", "spsr_irq", "spsr_svc", "spsr_abt", "spsr_und"
 };
 
-char * armv4_5_mode_strings_list[] =
+static const char *armv4_5_mode_strings_list[] =
 {
        "Illegal mode value", "User", "FIQ", "IRQ", "Supervisor", "Abort", "Undefined", "System"
 };
 
 /* Hack! Yuk! allow -1 index, which simplifies codepaths elsewhere in the code */
-char** armv4_5_mode_strings = armv4_5_mode_strings_list + 1;
+const char **armv4_5_mode_strings = armv4_5_mode_strings_list + 1;
+
+/** Map PSR mode bits to linear number */
+int armv4_5_mode_to_number(enum armv4_5_mode mode)
+{
+       switch (mode) {
+       case ARMV4_5_MODE_ANY:
+               /* map MODE_ANY to user mode */
+       case ARMV4_5_MODE_USR:
+               return 0;
+       case ARMV4_5_MODE_FIQ:
+               return 1;
+       case ARMV4_5_MODE_IRQ:
+               return 2;
+       case ARMV4_5_MODE_SVC:
+               return 3;
+       case ARMV4_5_MODE_ABT:
+               return 4;
+       case ARMV4_5_MODE_UND:
+               return 5;
+       case ARMV4_5_MODE_SYS:
+               return 6;
+       default:
+               LOG_ERROR("invalid mode value encountered %d", mode);
+               return -1;
+       }
+}
+
+/** Map linear number to PSR mode bits. */
+enum armv4_5_mode armv4_5_number_to_mode(int number)
+{
+       switch (number) {
+       case 0:
+               return ARMV4_5_MODE_USR;
+       case 1:
+               return ARMV4_5_MODE_FIQ;
+       case 2:
+               return ARMV4_5_MODE_IRQ;
+       case 3:
+               return ARMV4_5_MODE_SVC;
+       case 4:
+               return ARMV4_5_MODE_ABT;
+       case 5:
+               return ARMV4_5_MODE_UND;
+       case 6:
+               return ARMV4_5_MODE_SYS;
+       default:
+               LOG_ERROR("mode index out of bounds %d", number);
+               return ARMV4_5_MODE_ANY;
+       }
+}
 
 char* armv4_5_state_strings[] =
 {
@@ -385,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) {
@@ -423,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)
@@ -756,7 +806,7 @@ int arm_checksum_memory(struct target *target,
                return retval;
 
        /* convert code into a buffer in target endianness */
-       for (i = 0; i < DIM(arm_crc_code); i++) {
+       for (i = 0; i < ARRAY_SIZE(arm_crc_code); i++) {
                retval = target_write_u32(target,
                                crc_algorithm->address + i * sizeof(uint32_t),
                                arm_crc_code[i]);
@@ -832,7 +882,7 @@ int arm_blank_check_memory(struct target *target,
                return retval;
 
        /* convert code into a buffer in target endianness */
-       for (i = 0; i < DIM(check_code); i++) {
+       for (i = 0; i < ARRAY_SIZE(check_code); i++) {
                retval = target_write_u32(target,
                                check_algorithm->address
                                                + i * sizeof(uint32_t),