jtag: retire jtag_alloc_in_value32 API
[fw/openocd] / src / target / armv7m.c
index 03c9c7ace8812bd467ef9c98d3ed21c4be231a78..d9e63d7f31bef568f45348150a36f5d847118c1a 100644 (file)
@@ -82,7 +82,7 @@ struct reg armv7m_gdb_dummy_cpsr_reg =
  */
 static const struct {
        unsigned id;
-       char *name;
+       const char *name;
        unsigned bits;
 } armv7m_regs[] = {
        { ARMV7M_R0, "r0", 32 },
@@ -287,53 +287,42 @@ int armv7m_get_gdb_reg_list(struct target *target, struct reg **reg_list[], int
        return ERROR_OK;
 }
 
-/* run to exit point. return error if exit point was not reached. */
-static int armv7m_run_and_wait(struct target *target, uint32_t entry_point, int timeout_ms, uint32_t exit_point, struct armv7m_common *armv7m)
+/** Runs a Thumb algorithm in the target. */
+int armv7m_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)
 {
-       uint32_t pc;
        int retval;
-       /* This code relies on the target specific  resume() and  poll()->debug_entry()
-        * sequence to write register values to the processor and the read them back */
-       if ((retval = target_resume(target, 0, entry_point, 1, 1)) != ERROR_OK)
-       {
-               return retval;
-       }
 
-       retval = target_wait_state(target, TARGET_HALTED, timeout_ms);
-       /* If the target fails to halt due to the breakpoint, force a halt */
-       if (retval != ERROR_OK || target->state != TARGET_HALTED)
-       {
-               if ((retval = target_halt(target)) != ERROR_OK)
-                       return retval;
-               if ((retval = target_wait_state(target, TARGET_HALTED, 500)) != ERROR_OK)
-               {
-                       return retval;
-               }
-               return ERROR_TARGET_TIMEOUT;
-       }
+       retval = armv7m_start_algorithm(target,
+                       num_mem_params, mem_params,
+                       num_reg_params, reg_params,
+                       entry_point, exit_point,
+                       arch_info);
 
-       armv7m->load_core_reg_u32(target, ARMV7M_REGISTER_CORE_GP, 15, &pc);
-       if (exit_point && (pc != exit_point))
-       {
-               LOG_DEBUG("failed algoritm halted at 0x%" PRIx32 " ", pc);
-               return ERROR_TARGET_TIMEOUT;
-       }
+       if (retval == ERROR_OK)
+               retval = armv7m_wait_algorithm(target,
+                               num_mem_params, mem_params,
+                               num_reg_params, reg_params,
+                               exit_point, timeout_ms,
+                               arch_info);
 
-       return ERROR_OK;
+       return retval;
 }
 
-/** Runs a Thumb algorithm in the target. */
-int armv7m_run_algorithm(struct target *target,
+/** Starts a Thumb algorithm in the target. */
+int armv7m_start_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)
+       void *arch_info)
 {
        struct armv7m_common *armv7m = target_to_armv7m(target);
        struct armv7m_algorithm *armv7m_algorithm_info = arch_info;
        enum armv7m_mode core_mode = armv7m->core_mode;
        int retval = ERROR_OK;
-       uint32_t context[ARMV7M_NUM_REGS];
 
        /* NOTE: armv7m_run_algorithm requires that each algorithm uses a software breakpoint
         * at the exit point */
@@ -356,11 +345,12 @@ int armv7m_run_algorithm(struct target *target,
        {
                if (!armv7m->core_cache->reg_list[i].valid)
                        armv7m->read_core_reg(target, i);
-               context[i] = buf_get_u32(armv7m->core_cache->reg_list[i].value, 0, 32);
+               armv7m_algorithm_info->context[i] = buf_get_u32(armv7m->core_cache->reg_list[i].value, 0, 32);
        }
 
        for (int i = 0; i < num_mem_params; i++)
        {
+               // TODO: Write only out params
                if ((retval = target_write_buffer(target, mem_params[i].address, mem_params[i].size, mem_params[i].value)) != ERROR_OK)
                        return retval;
        }
@@ -394,12 +384,52 @@ int armv7m_run_algorithm(struct target *target,
                armv7m->core_cache->reg_list[ARMV7M_CONTROL].dirty = 1;
                armv7m->core_cache->reg_list[ARMV7M_CONTROL].valid = 1;
        }
+       armv7m_algorithm_info->core_mode = core_mode;
 
-       retval = armv7m_run_and_wait(target, entry_point, timeout_ms, exit_point, armv7m);
+       retval = target_resume(target, 0, entry_point, 1, 1);
 
-       if (retval != ERROR_OK)
+       return retval;
+}
+
+/** Waits for an algorithm in the target. */
+int armv7m_wait_algorithm(struct target *target,
+       int num_mem_params, struct mem_param *mem_params,
+       int num_reg_params, struct reg_param *reg_params,
+       uint32_t exit_point, int timeout_ms,
+       void *arch_info)
+{
+       struct armv7m_common *armv7m = target_to_armv7m(target);
+       struct armv7m_algorithm *armv7m_algorithm_info = arch_info;
+       int retval = ERROR_OK;
+       uint32_t pc;
+
+       /* NOTE: armv7m_run_algorithm requires that each algorithm uses a software breakpoint
+        * at the exit point */
+
+       if (armv7m_algorithm_info->common_magic != ARMV7M_COMMON_MAGIC)
        {
-               return retval;
+               LOG_ERROR("current target isn't an ARMV7M target");
+               return ERROR_TARGET_INVALID;
+       }
+
+       retval = target_wait_state(target, TARGET_HALTED, timeout_ms);
+       /* If the target fails to halt due to the breakpoint, force a halt */
+       if (retval != ERROR_OK || target->state != TARGET_HALTED)
+       {
+               if ((retval = target_halt(target)) != ERROR_OK)
+                       return retval;
+               if ((retval = target_wait_state(target, TARGET_HALTED, 500)) != ERROR_OK)
+               {
+                       return retval;
+               }
+               return ERROR_TARGET_TIMEOUT;
+       }
+
+       armv7m->load_core_reg_u32(target, ARMV7M_REGISTER_CORE_GP, 15, &pc);
+       if (exit_point && (pc != exit_point))
+       {
+               LOG_DEBUG("failed algorithm halted at 0x%" PRIx32 ", expected 0x%" PRIx32 , pc, exit_point);
+               return ERROR_TARGET_TIMEOUT;
        }
 
        /* Read memory values to mem_params[] */
@@ -439,18 +469,18 @@ int armv7m_run_algorithm(struct target *target,
        {
                uint32_t regvalue;
                regvalue = buf_get_u32(armv7m->core_cache->reg_list[i].value, 0, 32);
-               if (regvalue != context[i])
+               if (regvalue != armv7m_algorithm_info->context[i])
                {
                        LOG_DEBUG("restoring register %s with value 0x%8.8" PRIx32,
-                               armv7m->core_cache->reg_list[i].name, context[i]);
+                               armv7m->core_cache->reg_list[i].name, armv7m_algorithm_info->context[i]);
                        buf_set_u32(armv7m->core_cache->reg_list[i].value,
-                                       0, 32, context[i]);
+                                       0, 32, armv7m_algorithm_info->context[i]);
                        armv7m->core_cache->reg_list[i].valid = 1;
                        armv7m->core_cache->reg_list[i].dirty = 1;
                }
        }
 
-       armv7m->core_mode = core_mode;
+       armv7m->core_mode = armv7m_algorithm_info->core_mode;
 
        return retval;
 }
@@ -596,17 +626,16 @@ int armv7m_checksum_memory(struct target *target,
 
        uint32_t i;
 
-       if (target_alloc_working_area(target, sizeof(cortex_m3_crc_code), &crc_algorithm) != ERROR_OK)
-       {
-               return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
-       }
+       retval = target_alloc_working_area(target, sizeof(cortex_m3_crc_code), &crc_algorithm);
+       if (retval != ERROR_OK)
+               return retval;
 
        /* convert flash writing code into a buffer in target endianness */
-       for (i = 0; i < ARRAY_SIZE(cortex_m3_crc_code); i++)
-               if ((retval = target_write_u16(target, crc_algorithm->address + i*sizeof(uint16_t), cortex_m3_crc_code[i])) != ERROR_OK)
-               {
-                       return retval;
-               }
+       for (i = 0; i < ARRAY_SIZE(cortex_m3_crc_code); i++) {
+               retval = target_write_u16(target, crc_algorithm->address + i*sizeof(uint16_t), cortex_m3_crc_code[i]);
+               if (retval != ERROR_OK)
+                       goto cleanup;
+       }
 
        armv7m_info.common_magic = ARMV7M_COMMON_MAGIC;
        armv7m_info.core_mode = ARMV7M_MODE_ANY;
@@ -619,24 +648,22 @@ int armv7m_checksum_memory(struct target *target,
 
        int timeout = 20000 * (1 + (count / (1024 * 1024)));
 
-       if ((retval = target_run_algorithm(target, 0, NULL, 2, reg_params,
-               crc_algorithm->address, crc_algorithm->address + (sizeof(cortex_m3_crc_code)-6), timeout, &armv7m_info)) != ERROR_OK)
-       {
-               LOG_ERROR("error executing cortex_m3 crc algorithm");
-               destroy_reg_param(&reg_params[0]);
-               destroy_reg_param(&reg_params[1]);
-               target_free_working_area(target, crc_algorithm);
-               return retval;
-       }
+       retval = target_run_algorithm(target, 0, NULL, 2, reg_params, crc_algorithm->address,
+                                     crc_algorithm->address + (sizeof(cortex_m3_crc_code) - 6),
+                                     timeout, &armv7m_info);
 
-       *checksum = buf_get_u32(reg_params[0].value, 0, 32);
+       if (retval == ERROR_OK)
+               *checksum = buf_get_u32(reg_params[0].value, 0, 32);
+       else
+               LOG_ERROR("error executing cortex_m3 crc algorithm");
 
        destroy_reg_param(&reg_params[0]);
        destroy_reg_param(&reg_params[1]);
 
+cleanup:
        target_free_working_area(target, crc_algorithm);
 
-       return ERROR_OK;
+       return retval;
 }
 
 /** Checks whether a memory region is zeroed. */
@@ -681,17 +708,12 @@ int armv7m_blank_check_memory(struct target *target,
        init_reg_param(&reg_params[2], "r2", 32, PARAM_IN_OUT);
        buf_set_u32(reg_params[2].value, 0, 32, 0xff);
 
-       if ((retval = target_run_algorithm(target, 0, NULL, 3, reg_params,
-                       erase_check_algorithm->address, erase_check_algorithm->address + (sizeof(erase_check_code)-2), 10000, &armv7m_info)) != ERROR_OK)
-       {
-               destroy_reg_param(&reg_params[0]);
-               destroy_reg_param(&reg_params[1]);
-               destroy_reg_param(&reg_params[2]);
-               target_free_working_area(target, erase_check_algorithm);
-               return 0;
-       }
+       retval = target_run_algorithm(target, 0, NULL, 3, reg_params, erase_check_algorithm->address,
+                                     erase_check_algorithm->address + (sizeof(erase_check_code) - 2),
+                                     10000, &armv7m_info);
 
-       *blank = buf_get_u32(reg_params[2].value, 0, 32);
+       if (retval == ERROR_OK)
+               *blank = buf_get_u32(reg_params[2].value, 0, 32);
 
        destroy_reg_param(&reg_params[0]);
        destroy_reg_param(&reg_params[1]);
@@ -699,7 +721,7 @@ int armv7m_blank_check_memory(struct target *target,
 
        target_free_working_area(target, erase_check_algorithm);
 
-       return ERROR_OK;
+       return retval;
 }
 
 int armv7m_maybe_skip_bkpt_inst(struct target *target, bool *inst_found)