aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/target/armv7m.c110
-rw-r--r--src/target/armv7m.h14
2 files changed, 84 insertions, 40 deletions
diff --git a/src/target/armv7m.c b/src/target/armv7m.c
index fff5dd84..39a89b94 100644
--- a/src/target/armv7m.c
+++ b/src/target/armv7m.c
@@ -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;
}
diff --git a/src/target/armv7m.h b/src/target/armv7m.h
index 8ef38008..ca921468 100644
--- a/src/target/armv7m.h
+++ b/src/target/armv7m.h
@@ -142,6 +142,8 @@ struct armv7m_algorithm
int common_magic;
enum armv7m_mode core_mode;
+
+ uint32_t context[ARMV7M_CONTROL + 1]; //ARMV7M_NUM_REGS
};
struct armv7m_core_reg
@@ -168,6 +170,18 @@ int armv7m_run_algorithm(struct target *target,
uint32_t entry_point, uint32_t exit_point,
int timeout_ms, void *arch_info);
+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,
+ void *arch_info);
+
+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);
+
int armv7m_invalidate_core_regs(struct target *target);
int armv7m_restore_context(struct target *target);