armv7m: implement async algorithm functions
[openocd.git] / src / target / armv7m.c
index fff5dd84062d1c8b7850f5f525f443dd82a577f8..39a89b9414ed70790bbd9bd3c1817f3807c30e2a 100644 (file)
@@ -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 algorithm 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;
 }

Linking to existing account procedure

If you already have an account and want to add another login method you MUST first sign in with your existing account and then change URL to read https://review.openocd.org/login/?link to get to this page again but this time it'll work for linking. Thank you.

SSH host keys fingerprints

1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=..              |
|+o..   .         |
|*.o   . .        |
|+B . . .         |
|Bo. = o S        |
|Oo.+ + =         |
|oB=.* = . o      |
| =+=.+   + E     |
|. .=o   . o      |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)