diff --git a/src/target/armv7m.c b/src/target/armv7m.c index 02a664aa6..584944301 100644 --- a/src/target/armv7m.c +++ b/src/target/armv7m.c @@ -60,8 +60,8 @@ char* armv7m_core_reg_list[] = "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "sp", "lr", "pc", "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}; @@ -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 */ {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; @@ -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); } - /* 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); - - 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 */ diff --git a/src/target/armv7m.h b/src/target/armv7m.h index 17e3ff382..ec90b7150 100644 --- a/src/target/armv7m.h +++ b/src/target/armv7m.h @@ -61,15 +61,10 @@ enum ARMV7M_xPSR = 16, ARMV7M_MSP, 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 }; @@ -83,7 +78,6 @@ typedef struct armv7m_common_s int exception_number; swjdp_common_t swjdp_info; - bool has_spec20; /* 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); diff --git a/src/target/cortex_m3.c b/src/target/cortex_m3.c index 8cb1bd4e7..94d420468 100644 --- a/src/target/cortex_m3.c +++ b/src/target/cortex_m3.c @@ -395,7 +395,7 @@ int cortex_m3_debug_entry(target_t *target) /* Examine target state and mode */ /* 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) 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); } + /* 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 */ if (xPSR & 0x1FF) { armv7m->core_mode = ARMV7M_MODE_HANDLER; 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; } @@ -633,26 +636,16 @@ int cortex_m3_resume(struct target_s *target, int current, uint32_t address, int if (debug_execution) { /* 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: - * 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 */ 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].valid = 1; } @@ -1474,14 +1467,8 @@ int cortex_m3_examine(struct target_s *target) if ((retval = target_read_u32(target, CPUID, &cpuid)) != ERROR_OK) return retval; - if (((cpuid >> 4) & 0xc3f) == 0xc23) { + if (((cpuid >> 4) & 0xc3f) == 0xc23) 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); target_read_u32(target, NVIC_ICTR, &ictr); diff --git a/src/target/cortex_m3.h b/src/target/cortex_m3.h index ba61b1cba..e6714d007 100644 --- a/src/target/cortex_m3.h +++ b/src/target/cortex_m3.h @@ -117,21 +117,6 @@ extern char* cortex_m3_state_strings[]; #define FPCR_REPLACE_BKPT_HIGH (2 << 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 { int used;