summaryrefslogtreecommitdiff
path: root/src/target/armv7m.c
diff options
context:
space:
mode:
authorntfreak <ntfreak@b42882b7-edfa-0310-969c-e2dbd0fdcd60>2008-04-10 11:43:48 +0000
committerntfreak <ntfreak@b42882b7-edfa-0310-969c-e2dbd0fdcd60>2008-04-10 11:43:48 +0000
commit9c3dec377eb6eb822b85fa107ade2a62c9e1cfd1 (patch)
tree528bc639688200b05ae27df46046c3544399d121 /src/target/armv7m.c
parent1ade331ba925c506ed4254f31dba5e6f9cf782b4 (diff)
downloadopenocd+libswd-9c3dec377eb6eb822b85fa107ade2a62c9e1cfd1.tar.gz
openocd+libswd-9c3dec377eb6eb822b85fa107ade2a62c9e1cfd1.tar.bz2
openocd+libswd-9c3dec377eb6eb822b85fa107ade2a62c9e1cfd1.tar.xz
openocd+libswd-9c3dec377eb6eb822b85fa107ade2a62c9e1cfd1.zip
- single core context used, removed debug context as thought unnecessary.
- DCRDR now used to access special core registers - info is currently omitted from the cortex_m3 TRM ARM have told me this is the preferred access method and the docs will be updated soon. - now checks for User Thread Mode and Thread mode when halted. - removed repeated function declarations from command.c - cortex_m3_prepare_reset_halt removed, updated cortex_m3_assert_reset to suit git-svn-id: svn://svn.berlios.de/openocd/trunk@558 b42882b7-edfa-0310-969c-e2dbd0fdcd60
Diffstat (limited to 'src/target/armv7m.c')
-rw-r--r--src/target/armv7m.c168
1 files changed, 45 insertions, 123 deletions
diff --git a/src/target/armv7m.c b/src/target/armv7m.c
index f79305f2..81b477a9 100644
--- a/src/target/armv7m.c
+++ b/src/target/armv7m.c
@@ -42,12 +42,7 @@
char* armv7m_mode_strings[] =
{
- "Handler", "Thread"
-};
-
-char* armv7m_state_strings[] =
-{
- "Thumb", "Debug"
+ "Thread", "Thread (User)", "Handler",
};
char* armv7m_exception_strings[] =
@@ -62,22 +57,10 @@ char* armv7m_core_reg_list[] =
"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12",
"sp", "lr", "pc",
"xPSR", "msp", "psp",
- /* Registers accessed through MSR instructions */
- /* "apsr", "iapsr", "ipsr", "epsr", */
+ /* Registers accessed through special reg 20 */
"primask", "basepri", "faultmask", "control"
};
-char* armv7m_core_dbgreg_list[] =
-{
- /* Registers accessed through core debug */
- "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12",
- "sp", "lr", "pc",
- "xPSR", "msp", "psp",
- /* Registers accessed through MSR instructions */
- /* "dbg_apsr", "iapsr", "ipsr", "epsr", */
- "primask", "basepri", "faultmask", "dbg_control"
-};
-
u8 armv7m_gdb_dummy_fp_value[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
reg_t armv7m_gdb_dummy_fp_reg =
@@ -116,74 +99,15 @@ armv7m_core_reg_t armv7m_core_reg_list_arch_info[] =
{17, ARMV7M_REGISTER_CORE_GP, ARMV7M_MODE_ANY, NULL, NULL}, /* MSP */
{18, ARMV7M_REGISTER_CORE_GP, ARMV7M_MODE_ANY, NULL, NULL}, /* PSP */
- /* CORE_SP are accesible using MSR and MRS instructions */
-#if 0
- {0x00, ARMV7M_REGISTER_CORE_SP, ARMV7M_MODE_ANY, NULL, NULL}, /* APSR */
- {0x01, ARMV7M_REGISTER_CORE_SP, ARMV7M_MODE_ANY, NULL, NULL}, /* IAPSR */
- {0x05, ARMV7M_REGISTER_CORE_SP, ARMV7M_MODE_ANY, NULL, NULL}, /* IPSR */
- {0x06, ARMV7M_REGISTER_CORE_SP, ARMV7M_MODE_ANY, NULL, NULL}, /* EPSR */
-#endif
-
- {0x10, ARMV7M_REGISTER_CORE_SP, ARMV7M_MODE_ANY, NULL, NULL}, /* PRIMASK */
- {0x11, ARMV7M_REGISTER_CORE_SP, ARMV7M_MODE_ANY, NULL, NULL}, /* BASEPRI */
- {0x13, ARMV7M_REGISTER_CORE_SP, ARMV7M_MODE_ANY, NULL, NULL}, /* FAULTMASK */
- {0x14, ARMV7M_REGISTER_CORE_SP, ARMV7M_MODE_ANY, NULL, NULL} /* CONTROL */
+ /* CORE_SP are accesible using coreregister 20 */
+ {19, ARMV7M_REGISTER_CORE_SP, ARMV7M_MODE_ANY, NULL, NULL}, /* PRIMASK */
+ {20, ARMV7M_REGISTER_CORE_SP, ARMV7M_MODE_ANY, NULL, NULL}, /* BASEPRI */
+ {21, ARMV7M_REGISTER_CORE_SP, ARMV7M_MODE_ANY, NULL, NULL}, /* FAULTMASK */
+ {22, ARMV7M_REGISTER_CORE_SP, ARMV7M_MODE_ANY, NULL, NULL} /* CONTROL */
};
int armv7m_core_reg_arch_type = -1;
-/* Keep different contexts for the process being debugged and debug algorithms */
-enum armv7m_runcontext armv7m_get_context(target_t *target)
-{
- /* get pointers to arch-specific information */
- armv7m_common_t *armv7m = target->arch_info;
-
- if (armv7m->process_context == armv7m->core_cache)
- return ARMV7M_PROCESS_CONTEXT;
- if (armv7m->debug_context == armv7m->core_cache)
- return ARMV7M_DEBUG_CONTEXT;
-
- LOG_ERROR("Invalid runcontext");
- exit(-1);
-}
-
-int armv7m_use_context(target_t *target, enum armv7m_runcontext new_ctx)
-{
- int i;
- /* get pointers to arch-specific information */
- armv7m_common_t *armv7m = target->arch_info;
-
- if ((target->state != TARGET_HALTED) && (target->state != TARGET_RESET))
- {
- LOG_WARNING("target not halted, switch context ");
- return ERROR_TARGET_NOT_HALTED;
- }
-
- if (new_ctx == armv7m_get_context(target))
- return ERROR_OK;
-
- switch (new_ctx)
- {
- case ARMV7M_PROCESS_CONTEXT:
- armv7m->core_cache = armv7m->process_context;
- break;
- case ARMV7M_DEBUG_CONTEXT:
- armv7m->core_cache = armv7m->debug_context;
- break;
- default:
- LOG_ERROR("Invalid runcontext");
- exit(-1);
- }
- /* Mark registers in new context as dirty to force reload when run */
-
- for (i = 0; i < armv7m->core_cache->num_regs; i++)
- {
- armv7m->core_cache->reg_list[i].dirty = 1;
- }
-
- return ERROR_OK;
-}
-
int armv7m_restore_context(target_t *target)
{
int i;
@@ -333,7 +257,7 @@ int armv7m_get_gdb_reg_list(target_t *target, reg_t **reg_list[], int *reg_list_
for (i = 0; i < 16; i++)
{
- (*reg_list)[i] = &armv7m->process_context->reg_list[i];
+ (*reg_list)[i] = &armv7m->core_cache->reg_list[i];
}
for (i = 16; i < 24; i++)
@@ -345,8 +269,8 @@ int armv7m_get_gdb_reg_list(target_t *target, reg_t **reg_list[], int *reg_list_
/* ARMV7M is always in thumb mode, try to make GDB understand this
* if it does not support this arch */
- armv7m->process_context->reg_list[15].value[0] |= 1;
- (*reg_list)[25] = &armv7m->process_context->reg_list[ARMV7M_xPSR];
+ armv7m->core_cache->reg_list[15].value[0] |= 1;
+ (*reg_list)[25] = &armv7m->core_cache->reg_list[ARMV7M_xPSR];
return ERROR_OK;
}
@@ -355,10 +279,12 @@ int armv7m_run_algorithm(struct target_s *target, int num_mem_params, mem_param_
/* get pointers to arch-specific information */
armv7m_common_t *armv7m = target->arch_info;
armv7m_algorithm_t *armv7m_algorithm_info = arch_info;
+ enum armv7m_mode core_mode = armv7m->core_mode;
int retval = ERROR_OK;
u32 pc;
int i;
-
+ u32 context[ARMV7NUMCOREREGS];
+
if (armv7m_algorithm_info->common_magic != ARMV7M_COMMON_MAGIC)
{
LOG_ERROR("current target isn't an ARMV7M target");
@@ -373,7 +299,12 @@ int armv7m_run_algorithm(struct target_s *target, int num_mem_params, mem_param_
/* refresh core register cache */
/* Not needed if core register cache is always consistent with target process state */
- armv7m_use_context(target, ARMV7M_DEBUG_CONTEXT);
+ for (i = 0; i < ARMV7NUMCOREREGS; i++)
+ {
+ 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);
+ }
for (i = 0; i < num_mem_params; i++)
{
@@ -401,6 +332,14 @@ int armv7m_run_algorithm(struct target_s *target, int num_mem_params, mem_param_
armv7m_set_core_reg(reg, reg_params[i].value);
}
+ if (armv7m_algorithm_info->core_mode != ARMV7M_MODE_ANY)
+ {
+ LOG_DEBUG("setting core_mode: 0x%2.2x", armv7m_algorithm_info->core_mode);
+ buf_set_u32(armv7m->core_cache->reg_list[ARMV7M_CONTROL].value, 0, 1, armv7m_algorithm_info->core_mode);
+ armv7m->core_cache->reg_list[ARMV7M_CONTROL].dirty = 1;
+ armv7m->core_cache->reg_list[ARMV7M_CONTROL].valid = 1;
+ }
+
/* ARMV7M always runs in Thumb state */
if ((retval = breakpoint_add(target, exit_point, 2, BKPT_SOFT)) != ERROR_OK)
{
@@ -452,7 +391,7 @@ int armv7m_run_algorithm(struct target_s *target, int num_mem_params, mem_param_
{
if (reg_params[i].direction != PARAM_OUT)
{
- reg_t *reg = register_get_by_name(armv7m->debug_context, reg_params[i].reg_name, 0);
+ reg_t *reg = register_get_by_name(armv7m->core_cache, reg_params[i].reg_name, 0);
if (!reg)
{
@@ -470,6 +409,16 @@ int armv7m_run_algorithm(struct target_s *target, int num_mem_params, mem_param_
}
}
+ for (i = ARMV7NUMCOREREGS-1; i >= 0; i--)
+ {
+ LOG_DEBUG("restoring register %s with value 0x%8.8x", armv7m->core_cache->reg_list[i].name, context[i]);
+ buf_set_u32(armv7m->core_cache->reg_list[i].value, 0, 32, context[i]);
+ armv7m->core_cache->reg_list[i].valid = 1;
+ armv7m->core_cache->reg_list[i].dirty = 1;
+ }
+
+ armv7m->core_mode = core_mode;
+
return retval;
}
@@ -478,13 +427,12 @@ int armv7m_arch_state(struct target_s *target)
/* get pointers to arch-specific information */
armv7m_common_t *armv7m = target->arch_info;
- LOG_USER("target halted in %s state due to %s, current mode: %s %s\nxPSR: 0x%8.8x pc: 0x%8.8x",
- armv7m_state_strings[armv7m->core_state],
- target_debug_reason_strings[target->debug_reason],
- armv7m_mode_strings[armv7m->core_mode],
- armv7m_exception_string(armv7m->exception_number),
- buf_get_u32(armv7m->core_cache->reg_list[ARMV7M_xPSR].value, 0, 32),
- buf_get_u32(armv7m->core_cache->reg_list[15].value, 0, 32));
+ LOG_USER("target halted due to %s, current mode: %s %s\nxPSR: 0x%8.8x pc: 0x%8.8x",
+ target_debug_reason_strings[target->debug_reason],
+ armv7m_mode_strings[armv7m->core_mode],
+ armv7m_exception_string(armv7m->exception_number),
+ buf_get_u32(armv7m->core_cache->reg_list[ARMV7M_xPSR].value, 0, 32),
+ buf_get_u32(armv7m->core_cache->reg_list[15].value, 0, 32));
return ERROR_OK;
}
@@ -511,7 +459,6 @@ reg_cache_t *armv7m_build_reg_cache(target_t *target)
cache->num_regs = num_regs;
(*cache_p) = cache;
armv7m->core_cache = cache;
- armv7m->process_context = cache;
for (i = 0; i < num_regs; i++)
{
@@ -528,30 +475,6 @@ reg_cache_t *armv7m_build_reg_cache(target_t *target)
reg_list[i].arch_type = armv7m_core_reg_arch_type;
reg_list[i].arch_info = &arch_info[i];
}
-
- /* Build the debug context cache*/
- cache = malloc(sizeof(reg_cache_t));
- reg_list = malloc(sizeof(reg_t) * num_regs);
-
- cache->name = "arm v7m debug registers";
- cache->next = NULL;
- cache->reg_list = reg_list;
- cache->num_regs = num_regs;
- armv7m->debug_context = cache;
- armv7m->process_context->next = cache;
-
- for (i = 0; i < num_regs; i++)
- {
- reg_list[i].name = armv7m_core_dbgreg_list[i];
- reg_list[i].size = 32;
- reg_list[i].value = calloc(1, 4);
- reg_list[i].dirty = 0;
- reg_list[i].valid = 0;
- reg_list[i].bitfield_desc = NULL;
- reg_list[i].num_bitfields = 0;
- reg_list[i].arch_type = armv7m_core_reg_arch_type;
- reg_list[i].arch_info = &arch_info[i];
- }
return cache;
}
@@ -568,7 +491,6 @@ int armv7m_init_arch_info(target_t *target, armv7m_common_t *armv7m)
/* register arch-specific functions */
target->arch_info = armv7m;
- armv7m->core_state = ARMV7M_STATE_THUMB;
armv7m->read_core_reg = armv7m_read_core_reg;
armv7m->write_core_reg = armv7m_write_core_reg;
@@ -631,7 +553,6 @@ int armv7m_checksum_memory(struct target_s *target, u32 address, u32 count, u32*
armv7m_info.common_magic = ARMV7M_COMMON_MAGIC;
armv7m_info.core_mode = ARMV7M_MODE_ANY;
- armv7m_info.core_state = ARMV7M_STATE_THUMB;
init_reg_param(&reg_params[0], "r0", 32, PARAM_IN_OUT);
init_reg_param(&reg_params[1], "r1", 32, PARAM_OUT);
@@ -659,3 +580,4 @@ int armv7m_checksum_memory(struct target_s *target, u32 address, u32 count, u32*
return ERROR_OK;
}
+