Revert parts of the previous ARMv7-M register patch. It turns out that part of the issue is a documentation problem for the Cortex-M3 r1 parts. So for the rest, simpler fixes are possible (in followup patch). git-svn-id: svn://svn.berlios.de/openocd/trunk@2552 b42882b7-edfa-0310-969c-e2dbd0fdcd60tags/v0.3.0-rc0
@@ -60,8 +60,8 @@ char* armv7m_core_reg_list[] = | |||||
"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", | "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", | ||||
"sp", "lr", "pc", | "sp", "lr", "pc", | ||||
"xPSR", "msp", "psp", | "xPSR", "msp", "psp", | ||||
/* reg 20 has 4 bytes: CONTROL, FAULTMASK, BASEPRI, PRIMASK */ | |||||
"spec20", | |||||
/* Registers accessed through special reg 20 */ | |||||
"primask", "basepri", "faultmask", "control" | |||||
}; | }; | ||||
uint8_t armv7m_gdb_dummy_fp_value[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; | uint8_t armv7m_gdb_dummy_fp_value[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; | ||||
@@ -111,11 +111,11 @@ armv7m_core_reg_t armv7m_core_reg_list_arch_info[] = | |||||
{17, ARMV7M_REGISTER_CORE_GP, ARMV7M_MODE_ANY, NULL, NULL}, /* MSP */ | {17, ARMV7M_REGISTER_CORE_GP, ARMV7M_MODE_ANY, NULL, NULL}, /* MSP */ | ||||
{18, ARMV7M_REGISTER_CORE_GP, ARMV7M_MODE_ANY, NULL, NULL}, /* PSP */ | {18, ARMV7M_REGISTER_CORE_GP, ARMV7M_MODE_ANY, NULL, NULL}, /* PSP */ | ||||
/* FIXME the register numbers here are core-specific. | |||||
* Numbers 0..18 above work for all Cortex-M3 revisions. | |||||
* Number 20 below works for CM3 r2p0 and later. | |||||
*/ | |||||
{20, ARMV7M_REGISTER_CORE_SP, ARMV7M_MODE_ANY, NULL, NULL}, | |||||
/* 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; | int armv7m_core_reg_arch_type = -1; | ||||
@@ -387,21 +387,12 @@ int armv7m_run_algorithm(struct target_s *target, int num_mem_params, mem_param_ | |||||
armv7m_set_core_reg(reg, reg_params[i].value); | armv7m_set_core_reg(reg, reg_params[i].value); | ||||
} | } | ||||
/* NOTE: CONTROL is bits 31:24 of SPEC20 register, if it's present; | |||||
* holding a two-bit field. | |||||
* | |||||
* FIXME need a solution using ARMV7M_T_MSR(). Use it at least for | |||||
* earlier cores. | |||||
*/ | |||||
if (armv7m_algorithm_info->core_mode != ARMV7M_MODE_ANY | |||||
&& armv7m->has_spec20) | |||||
if (armv7m_algorithm_info->core_mode != ARMV7M_MODE_ANY) | |||||
{ | { | ||||
LOG_DEBUG("setting core_mode: 0x%2.2x", armv7m_algorithm_info->core_mode); | LOG_DEBUG("setting core_mode: 0x%2.2x", armv7m_algorithm_info->core_mode); | ||||
buf_set_u32(armv7m->core_cache->reg_list[ARMV7M_SPEC20].value, | |||||
24, 2, armv7m_algorithm_info->core_mode); | |||||
armv7m->core_cache->reg_list[ARMV7M_SPEC20].dirty = 1; | |||||
armv7m->core_cache->reg_list[ARMV7M_SPEC20].valid = 1; | |||||
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 */ | /* ARMV7M always runs in Thumb state */ | ||||
@@ -61,15 +61,10 @@ enum | |||||
ARMV7M_xPSR = 16, | ARMV7M_xPSR = 16, | ||||
ARMV7M_MSP, | ARMV7M_MSP, | ||||
ARMV7M_PSP, | ARMV7M_PSP, | ||||
/* FIXME the register numbers here are core-specific. Cortex-M3 | |||||
* through r1p1 only defines registers up to PSP; see ARM DDI 0337E. | |||||
* | |||||
* It's r2p0 (see ARM DDI 0337G) which defines the register that's | |||||
* called SPEC20 here, with four single-byte fields with CONTROL | |||||
* (highest byte), FAULTMASK, BASEPRI, and PRIMASK (lowest byte). | |||||
*/ | |||||
ARMV7M_SPEC20 = 20, | |||||
ARMV7M_PRIMASK, | |||||
ARMV7M_BASEPRI, | |||||
ARMV7M_FAULTMASK, | |||||
ARMV7M_CONTROL, | |||||
ARMV7NUMCOREREGS | ARMV7NUMCOREREGS | ||||
}; | }; | ||||
@@ -83,7 +78,6 @@ typedef struct armv7m_common_s | |||||
int exception_number; | int exception_number; | ||||
swjdp_common_t swjdp_info; | swjdp_common_t swjdp_info; | ||||
bool has_spec20; | |||||
/* Direct processor core register read and writes */ | /* Direct processor core register read and writes */ | ||||
int (*load_core_reg_u32)(struct target_s *target, enum armv7m_regtype type, uint32_t num, uint32_t *value); | int (*load_core_reg_u32)(struct target_s *target, enum armv7m_regtype type, uint32_t num, uint32_t *value); | ||||
@@ -395,7 +395,7 @@ int cortex_m3_debug_entry(target_t *target) | |||||
/* Examine target state and mode */ | /* Examine target state and mode */ | ||||
/* First load register acessible through core debug port*/ | /* First load register acessible through core debug port*/ | ||||
for (i = 0; i < ARMV7NUMCOREREGS; i++) | |||||
for (i = 0; i < ARMV7M_PRIMASK; i++) | |||||
{ | { | ||||
if (!armv7m->core_cache->reg_list[i].valid) | if (!armv7m->core_cache->reg_list[i].valid) | ||||
armv7m->read_core_reg(target, i); | armv7m->read_core_reg(target, i); | ||||
@@ -418,19 +418,22 @@ int cortex_m3_debug_entry(target_t *target) | |||||
cortex_m3_store_core_reg_u32(target, ARMV7M_REGISTER_CORE_GP, 16, xPSR &~ 0xff); | cortex_m3_store_core_reg_u32(target, ARMV7M_REGISTER_CORE_GP, 16, xPSR &~ 0xff); | ||||
} | } | ||||
/* Now we can load SP core registers */ | |||||
for (i = ARMV7M_PRIMASK; i < ARMV7NUMCOREREGS; i++) | |||||
{ | |||||
if (!armv7m->core_cache->reg_list[i].valid) | |||||
armv7m->read_core_reg(target, i); | |||||
} | |||||
/* Are we in an exception handler */ | /* Are we in an exception handler */ | ||||
if (xPSR & 0x1FF) | if (xPSR & 0x1FF) | ||||
{ | { | ||||
armv7m->core_mode = ARMV7M_MODE_HANDLER; | armv7m->core_mode = ARMV7M_MODE_HANDLER; | ||||
armv7m->exception_number = (xPSR & 0x1FF); | armv7m->exception_number = (xPSR & 0x1FF); | ||||
} | } | ||||
else if (armv7m->has_spec20) | |||||
else | |||||
{ | { | ||||
/* NOTE: CONTROL is bits 31:24 of SPEC20 register, holding | |||||
* a two-bit field. Unavailable before r2p0... | |||||
*/ | |||||
armv7m->core_mode = buf_get_u32( | |||||
armv7m->core_cache->reg_list[ARMV7M_SPEC20].value, 24, 2); | |||||
armv7m->core_mode = buf_get_u32(armv7m->core_cache->reg_list[ARMV7M_CONTROL].value, 0, 1); | |||||
armv7m->exception_number = 0; | armv7m->exception_number = 0; | ||||
} | } | ||||
@@ -633,26 +636,16 @@ int cortex_m3_resume(struct target_s *target, int current, uint32_t address, int | |||||
if (debug_execution) | if (debug_execution) | ||||
{ | { | ||||
/* Disable interrupts */ | /* Disable interrupts */ | ||||
/* We disable interrupts in the PRIMASK register instead | |||||
* of masking with C_MASKINTS, | |||||
/* We disable interrupts in the PRIMASK register instead of masking with C_MASKINTS, | |||||
* This is probably the same issue as Cortex-M3 Errata 377493: | * This is probably the same issue as Cortex-M3 Errata 377493: | ||||
* C_MASKINTS in parallel with disabled interrupts can cause | |||||
* local faults to not be taken. (FIXED in r1p0 and later.) | |||||
* | |||||
* NOTE: PRIMASK is bits 7:0 of SPEC20 register, holding a | |||||
* one bit field. Available this way for r2p0 and later... | |||||
*/ | |||||
if (armv7m->has_spec20) { | |||||
buf_set_u32(armv7m->core_cache->reg_list[ARMV7M_SPEC20] | |||||
.value, 0, 1, 1); | |||||
armv7m->core_cache->reg_list[ARMV7M_SPEC20].dirty = 1; | |||||
armv7m->core_cache->reg_list[ARMV7M_SPEC20].valid = 1; | |||||
} | |||||
* C_MASKINTS in parallel with disabled interrupts can cause local faults to not be taken. */ | |||||
buf_set_u32(armv7m->core_cache->reg_list[ARMV7M_PRIMASK].value, 0, 32, 1); | |||||
armv7m->core_cache->reg_list[ARMV7M_PRIMASK].dirty = 1; | |||||
armv7m->core_cache->reg_list[ARMV7M_PRIMASK].valid = 1; | |||||
/* Make sure we are in Thumb mode */ | /* Make sure we are in Thumb mode */ | ||||
buf_set_u32(armv7m->core_cache->reg_list[ARMV7M_xPSR].value, 0, 32, | buf_set_u32(armv7m->core_cache->reg_list[ARMV7M_xPSR].value, 0, 32, | ||||
buf_get_u32(armv7m->core_cache->reg_list[ARMV7M_xPSR].value, 0, 32) | |||||
| (1 << 24)); | |||||
buf_get_u32(armv7m->core_cache->reg_list[ARMV7M_xPSR].value, 0, 32) | (1 << 24)); | |||||
armv7m->core_cache->reg_list[ARMV7M_xPSR].dirty = 1; | armv7m->core_cache->reg_list[ARMV7M_xPSR].dirty = 1; | ||||
armv7m->core_cache->reg_list[ARMV7M_xPSR].valid = 1; | armv7m->core_cache->reg_list[ARMV7M_xPSR].valid = 1; | ||||
} | } | ||||
@@ -1474,14 +1467,8 @@ int cortex_m3_examine(struct target_s *target) | |||||
if ((retval = target_read_u32(target, CPUID, &cpuid)) != ERROR_OK) | if ((retval = target_read_u32(target, CPUID, &cpuid)) != ERROR_OK) | ||||
return retval; | return retval; | ||||
if (((cpuid >> 4) & 0xc3f) == 0xc23) { | |||||
if (((cpuid >> 4) & 0xc3f) == 0xc23) | |||||
LOG_DEBUG("CORTEX-M3 processor detected"); | LOG_DEBUG("CORTEX-M3 processor detected"); | ||||
if (((cpuid >> 20) & 0xf) >= 2) { | |||||
armv7m->has_spec20 = true; | |||||
LOG_DEBUG("r2p0 or later detected"); | |||||
} | |||||
} else | |||||
LOG_WARNING("not a CORTEX-M3 processor?"); | |||||
LOG_DEBUG("cpuid: 0x%8.8" PRIx32 "", cpuid); | LOG_DEBUG("cpuid: 0x%8.8" PRIx32 "", cpuid); | ||||
target_read_u32(target, NVIC_ICTR, &ictr); | target_read_u32(target, NVIC_ICTR, &ictr); | ||||
@@ -117,21 +117,6 @@ extern char* cortex_m3_state_strings[]; | |||||
#define FPCR_REPLACE_BKPT_HIGH (2 << 30) | #define FPCR_REPLACE_BKPT_HIGH (2 << 30) | ||||
#define FPCR_REPLACE_BKPT_BOTH (3 << 30) | #define FPCR_REPLACE_BKPT_BOTH (3 << 30) | ||||
/* Use MRS/MSR to read/write any of these special registers. Some of | |||||
* them (xPSR, MSP, PSP) are always available using DCRxR. Starting in | |||||
* Cortex-M3 r2p0, some (CONTROL, BASEPRI, and *MASK) are also available | |||||
* through DCRxR. | |||||
* NOTE: this listing omits xPSR components and other mixtures. | |||||
*/ | |||||
#define SR_XPSR 3 | |||||
#define SR_MSP 8 | |||||
#define SR_PSP 9 | |||||
#define SR_PRIMASK 16 | |||||
#define SR_BASEPRI 17 | |||||
#define SR_BASEPRI_MAX 18 | |||||
#define SR_FAULTMASK 19 | |||||
#define SR_CONTROL 20 | |||||
typedef struct cortex_m3_fp_comparator_s | typedef struct cortex_m3_fp_comparator_s | ||||
{ | { | ||||
int used; | int used; | ||||