fixed warning
[fw/openocd] / src / target / armv4_5.c
index 3eab03354bc6ceb3386f5a74d4aad0ef9fe1a27f..3d96961b09270be02e9f6cb5d0762f68c0b3110c 100644 (file)
@@ -70,11 +70,14 @@ char* armv4_5_core_reg_list[] =
        "cpsr", "spsr_fiq", "spsr_irq", "spsr_svc", "spsr_abt", "spsr_und"
 };
 
-char* armv4_5_mode_strings[] =
+char * armv4_5_mode_strings_list[] =
 {
-       "User", "FIQ", "IRQ", "Supervisor", "Abort", "Undefined", "System"
+       "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;
+
 char* armv4_5_state_strings[] =
 {
        "ARM", "Thumb", "Jazelle"
@@ -169,42 +172,6 @@ reg_t armv4_5_gdb_dummy_fps_reg =
        "GDB dummy floating-point status register", armv4_5_gdb_dummy_fps_value, 0, 1, 32, NULL, 0, NULL, 0
 };
 
-/* map psr mode bits to linear number */
-int armv4_5_mode_to_number(enum armv4_5_mode mode)
-{
-       switch (mode)
-       {
-               case 16: return 0; break;
-               case 17: return 1; break;
-               case 18: return 2; break;
-               case 19: return 3; break;
-               case 23: return 4; break;
-               case 27: return 5; break;
-               case 31: return 6; break;
-               case -1: return 0; break;       /* map MODE_ANY to user mode */
-               default: 
-                       ERROR("invalid mode value encountered");
-                       return -1;
-       }
-}
-
-/* map linear number to mode bits */
-enum armv4_5_mode armv4_5_number_to_mode(int number)
-{
-       switch(number)
-       {
-               case 0: return ARMV4_5_MODE_USR; break;
-               case 1: return ARMV4_5_MODE_FIQ; break;
-               case 2: return ARMV4_5_MODE_IRQ; break;
-               case 3: return ARMV4_5_MODE_SVC; break;
-               case 4: return ARMV4_5_MODE_ABT; break;
-               case 5: return ARMV4_5_MODE_UND; break;
-               case 6: return ARMV4_5_MODE_SYS; break;
-               default: 
-                       ERROR("mode index out of bounds");
-                       return -1;
-       }
-};
 
 int armv4_5_get_core_reg(reg_t *reg)
 {
@@ -214,10 +181,11 @@ int armv4_5_get_core_reg(reg_t *reg)
        
        if (target->state != TARGET_HALTED)
        {
+               LOG_ERROR("Target not halted");
                return ERROR_TARGET_NOT_HALTED;
        }
        
-       //retval = armv4_5->armv4_5_common->full_context(target);
+       /* retval = armv4_5->armv4_5_common->full_context(target); */
        retval = armv4_5->armv4_5_common->read_core_reg(target, armv4_5->num, armv4_5->mode);
        
        return retval;
@@ -243,7 +211,7 @@ int armv4_5_set_core_reg(reg_t *reg, u8 *buf)
                        if (armv4_5_target->core_state == ARMV4_5_STATE_ARM)
                        {
                                /* change state to Thumb */
-                               DEBUG("changing to Thumb state");
+                               LOG_DEBUG("changing to Thumb state");
                                armv4_5_target->core_state = ARMV4_5_STATE_THUMB;       
                        }
                }
@@ -253,10 +221,17 @@ int armv4_5_set_core_reg(reg_t *reg, u8 *buf)
                        if (armv4_5_target->core_state == ARMV4_5_STATE_THUMB)
                        {
                                /* change state to ARM */
-                               DEBUG("changing to ARM state");
+                               LOG_DEBUG("changing to ARM state");
                                armv4_5_target->core_state = ARMV4_5_STATE_ARM; 
                        }
                }
+               
+               if (armv4_5_target->core_mode != (value & 0x1f))
+               {
+                       LOG_DEBUG("changing ARM core mode to '%s'", armv4_5_mode_strings[armv4_5_mode_to_number(value & 0x1f)]);
+                       armv4_5_target->core_mode = value & 0x1f;
+                       armv4_5_target->write_core_reg(target, 16, ARMV4_5_MODE_ANY, value);
+               }
        }
        
        buf_set_u32(reg->value, 0, 32, value);
@@ -315,18 +290,17 @@ reg_cache_t* armv4_5_build_reg_cache(target_t *target, armv4_5_common_t *armv4_5
        return cache;
 }
 
-int armv4_5_arch_state(struct target_s *target, char *buf, int buf_size)
+int armv4_5_arch_state(struct target_s *target)
 {
        armv4_5_common_t *armv4_5 = target->arch_info;
        
        if (armv4_5->common_magic != ARMV4_5_COMMON_MAGIC)
        {
-               ERROR("BUG: called for a non-ARMv4/5 target");
+               LOG_ERROR("BUG: called for a non-ARMv4/5 target");
                exit(-1);
        }
        
-       snprintf(buf, buf_size,
-                        "target halted in %s state due to %s, current mode: %s\ncpsr: 0x%8.8x pc: 0x%8.8x",
+       LOG_USER("target halted in %s state due to %s, current mode: %s\ncpsr: 0x%8.8x pc: 0x%8.8x",
                         armv4_5_state_strings[armv4_5->core_state],
                         target_debug_reason_strings[target->debug_reason],
                         armv4_5_mode_strings[armv4_5_mode_to_number(armv4_5->core_mode)],
@@ -356,6 +330,9 @@ int handle_armv4_5_reg_command(struct command_context_s *cmd_ctx, char *cmd, cha
                return ERROR_OK;
        }
        
+       if (armv4_5_mode_to_number(armv4_5->core_mode)==-1)
+               return ERROR_FAIL;
+
        for (num = 0; num <= 15; num++)
        {
                output_len = 0;
@@ -442,7 +419,7 @@ int handle_armv4_5_disassemble_command(struct command_context_s *cmd_ctx, char *
        for (i = 0; i < count; i++)
        {
                target_read_u32(target, address, &opcode);
-               evaluate_opcode(opcode, address, &cur_instruction);
+               arm_evaluate_opcode(opcode, address, &cur_instruction);
                command_print(cmd_ctx, "%s", cur_instruction.text);
                address += (thumb) ? 2 : 4;
        }
@@ -468,10 +445,8 @@ int armv4_5_get_gdb_reg_list(target_t *target, reg_t **reg_list[], int *reg_list
        armv4_5_common_t *armv4_5 = target->arch_info;
        int i;
        
-       if (target->state != TARGET_HALTED)
-       {
-               return ERROR_TARGET_NOT_HALTED;
-       }
+       if (armv4_5_mode_to_number(armv4_5->core_mode)==-1)
+               return ERROR_FAIL;
        
        *reg_list_size = 26;
        *reg_list = malloc(sizeof(reg_t*) * (*reg_list_size));
@@ -503,19 +478,23 @@ int armv4_5_run_algorithm(struct target_s *target, int num_mem_params, mem_param
        int exit_breakpoint_size = 0;
        int i;
        int retval = ERROR_OK;
+       LOG_DEBUG("Running algorithm");
        
        if (armv4_5_algorithm_info->common_magic != ARMV4_5_COMMON_MAGIC)
        {
-               ERROR("current target isn't an ARMV4/5 target");
+               LOG_ERROR("current target isn't an ARMV4/5 target");
                return ERROR_TARGET_INVALID;
        }
        
        if (target->state != TARGET_HALTED)
        {
-               WARNING("target not halted");
+               LOG_WARNING("target not halted");
                return ERROR_TARGET_NOT_HALTED;
        }
        
+       if (armv4_5_mode_to_number(armv4_5->core_mode)==-1)
+               return ERROR_FAIL;
+
        for (i = 0; i <= 16; i++)
        {
                if (!ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5_algorithm_info->core_mode, i).valid)
@@ -534,13 +513,13 @@ int armv4_5_run_algorithm(struct target_s *target, int num_mem_params, mem_param
                reg_t *reg = register_get_by_name(armv4_5->core_cache, reg_params[i].reg_name, 0);
                if (!reg)
                {
-                       ERROR("BUG: register '%s' not found", reg_params[i].reg_name);
+                       LOG_ERROR("BUG: register '%s' not found", reg_params[i].reg_name);
                        exit(-1);
                }
                
                if (reg->size != reg_params[i].size)
                {
-                       ERROR("BUG: register '%s' size doesn't match reg_params[i].size", reg_params[i].reg_name);
+                       LOG_ERROR("BUG: register '%s' size doesn't match reg_params[i].size", reg_params[i].reg_name);
                        exit(-1);
                }
                
@@ -554,13 +533,13 @@ int armv4_5_run_algorithm(struct target_s *target, int num_mem_params, mem_param
                exit_breakpoint_size = 2;
        else
        {
-               ERROR("BUG: can't execute algorithms when not in ARM or Thumb state");
+               LOG_ERROR("BUG: can't execute algorithms when not in ARM or Thumb state");
                exit(-1);
        }
        
        if (armv4_5_algorithm_info->core_mode != ARMV4_5_MODE_ANY)
        {
-               DEBUG("setting core_mode: 0x%2.2x", armv4_5_algorithm_info->core_mode);
+               LOG_DEBUG("setting core_mode: 0x%2.2x", armv4_5_algorithm_info->core_mode);
                buf_set_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 5, armv4_5_algorithm_info->core_mode);
                armv4_5->core_cache->reg_list[ARMV4_5_CPSR].dirty = 1;
                armv4_5->core_cache->reg_list[ARMV4_5_CPSR].valid = 1;
@@ -568,29 +547,29 @@ int armv4_5_run_algorithm(struct target_s *target, int num_mem_params, mem_param
 
        if ((retval = breakpoint_add(target, exit_point, exit_breakpoint_size, BKPT_HARD)) != ERROR_OK)
        {
-               ERROR("can't add breakpoint to finish algorithm execution");
+               LOG_ERROR("can't add breakpoint to finish algorithm execution");
                return ERROR_TARGET_FAILURE;
        }
        
-       target->type->resume(target, 0, entry_point, 1, 1);
-       target->type->poll(target);
+       target_resume(target, 0, entry_point, 1, 1);
+       target_poll(target);
        
        while (target->state != TARGET_HALTED)
        {
-               usleep(10000);
-               target->type->poll(target);
+               alive_sleep(10);
+               target_poll(target);
                if ((timeout_ms -= 10) <= 0)
                {
-                       ERROR("timeout waiting for algorithm to complete, trying to halt target");
-                       target->type->halt(target);
+                       LOG_ERROR("timeout waiting for algorithm to complete, trying to halt target");
+                       target_halt(target);
                        timeout_ms = 1000;
                        while (target->state != TARGET_HALTED)
                        {
-                               usleep(10000);
-                               target->type->poll(target);
+                               alive_sleep(10);
+                               target_poll(target);
                                if ((timeout_ms -= 10) <= 0)
                                {
-                                       ERROR("target didn't reenter debug state, exiting");
+                                       LOG_ERROR("target didn't reenter debug state, exiting");
                                        exit(-1);
                                }
                        }
@@ -598,6 +577,13 @@ int armv4_5_run_algorithm(struct target_s *target, int num_mem_params, mem_param
                }
        }
        
+       if ((retval != ERROR_TARGET_TIMEOUT) && 
+               (buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32) != exit_point))
+       {
+               LOG_WARNING("target reentered debug state, but not at the desired exit point: 0x%4.4x",
+                       buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32)); 
+       }
+       
        breakpoint_remove(target, exit_point);
        
        for (i = 0; i < num_mem_params; i++)
@@ -614,13 +600,13 @@ int armv4_5_run_algorithm(struct target_s *target, int num_mem_params, mem_param
                        reg_t *reg = register_get_by_name(armv4_5->core_cache, reg_params[i].reg_name, 0);
                        if (!reg)
                        {
-                               ERROR("BUG: register '%s' not found", reg_params[i].reg_name);
+                               LOG_ERROR("BUG: register '%s' not found", reg_params[i].reg_name);
                                exit(-1);
                        }
                        
                        if (reg->size != reg_params[i].size)
                        {
-                               ERROR("BUG: register '%s' size doesn't match reg_params[i].size", reg_params[i].reg_name);
+                               LOG_ERROR("BUG: register '%s' size doesn't match reg_params[i].size", reg_params[i].reg_name);
                                exit(-1);
                        }
                        
@@ -630,7 +616,7 @@ int armv4_5_run_algorithm(struct target_s *target, int num_mem_params, mem_param
        
        for (i = 0; i <= 16; i++)
        {
-               DEBUG("restoring register %s with value 0x%8.8x", ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5_algorithm_info->core_mode, i).name, context[i]);
+               LOG_DEBUG("restoring register %s with value 0x%8.8x", ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5_algorithm_info->core_mode, i).name, context[i]);
                buf_set_u32(ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5_algorithm_info->core_mode, i).value, 0, 32, context[i]);
                ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5_algorithm_info->core_mode, i).valid = 1;
                ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5_algorithm_info->core_mode, i).dirty = 1;