cortex_m: enhance core and arch detection
Rework core detection by adding cortex_m_partno enum to detect all CPUs using the same method. Instead of checking the core PARTNO then assign the arch, use the stored information within cortex_m parts[] with the flags inside which can help simplifying a bit the cortex_m_examine code. This change fixes: - the Cortex-M1 detection as ARMv6-M Core (was managed as ARMv7-M) - the displayed CPU name for Cortex-M0+ (was displayed Cortex-M0) Change-Id: I40b6e03f7cf3664c85e297adfc25323196dfe90b Signed-off-by: Tarek BOCHKATI <tarek.bouchkati@gmail.com> Reviewed-on: http://openocd.zylin.com/6233 Tested-by: jenkins Reviewed-by: Antonio Borneo <borneo.antonio@gmail.com>
This commit is contained in:
parent
f69adafb3d
commit
1185760729
|
@ -52,6 +52,66 @@
|
||||||
* any longer.
|
* any longer.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/* Supported Cortex-M Cores */
|
||||||
|
static const struct cortex_m_part_info cortex_m_parts[] = {
|
||||||
|
{
|
||||||
|
.partno = CORTEX_M0_PARTNO,
|
||||||
|
.name = "Cortex-M0",
|
||||||
|
.arch = ARM_ARCH_V6M,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.partno = CORTEX_M0P_PARTNO,
|
||||||
|
.name = "Cortex-M0+",
|
||||||
|
.arch = ARM_ARCH_V6M,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.partno = CORTEX_M1_PARTNO,
|
||||||
|
.name = "Cortex-M1",
|
||||||
|
.arch = ARM_ARCH_V6M,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.partno = CORTEX_M3_PARTNO,
|
||||||
|
.name = "Cortex-M3",
|
||||||
|
.arch = ARM_ARCH_V7M,
|
||||||
|
.flags = CORTEX_M_F_TAR_AUTOINCR_BLOCK_4K,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.partno = CORTEX_M4_PARTNO,
|
||||||
|
.name = "Cortex-M4",
|
||||||
|
.arch = ARM_ARCH_V7M,
|
||||||
|
.flags = CORTEX_M_F_HAS_FPV4 | CORTEX_M_F_TAR_AUTOINCR_BLOCK_4K,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.partno = CORTEX_M7_PARTNO,
|
||||||
|
.name = "Cortex-M7",
|
||||||
|
.arch = ARM_ARCH_V7M,
|
||||||
|
.flags = CORTEX_M_F_HAS_FPV5,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.partno = CORTEX_M23_PARTNO,
|
||||||
|
.name = "Cortex-M23",
|
||||||
|
.arch = ARM_ARCH_V8M,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.partno = CORTEX_M33_PARTNO,
|
||||||
|
.name = "Cortex-M33",
|
||||||
|
.arch = ARM_ARCH_V8M,
|
||||||
|
.flags = CORTEX_M_F_HAS_FPV5,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.partno = CORTEX_M35P_PARTNO,
|
||||||
|
.name = "Cortex-M35P",
|
||||||
|
.arch = ARM_ARCH_V8M,
|
||||||
|
.flags = CORTEX_M_F_HAS_FPV5,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.partno = CORTEX_M55_PARTNO,
|
||||||
|
.name = "Cortex-M55",
|
||||||
|
.arch = ARM_ARCH_V8M,
|
||||||
|
.flags = CORTEX_M_F_HAS_FPV5,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
/* forward declarations */
|
/* forward declarations */
|
||||||
static int cortex_m_store_core_reg_u32(struct target *target,
|
static int cortex_m_store_core_reg_u32(struct target *target,
|
||||||
uint32_t num, uint32_t value);
|
uint32_t num, uint32_t value);
|
||||||
|
@ -2001,35 +2061,27 @@ int cortex_m_examine(struct target *target)
|
||||||
if (retval != ERROR_OK)
|
if (retval != ERROR_OK)
|
||||||
return retval;
|
return retval;
|
||||||
|
|
||||||
/* Get CPU Type */
|
/* Get ARCH and CPU types */
|
||||||
unsigned int core = (cpuid >> 4) & 0xf;
|
const enum cortex_m_partno core_partno = (cpuid & ARM_CPUID_PARTNO_MASK) >> ARM_CPUID_PARTNO_POS;
|
||||||
|
|
||||||
/* Check if it is an ARMv8-M core */
|
for (unsigned int n = 0; n < ARRAY_SIZE(cortex_m_parts); n++) {
|
||||||
armv7m->arm.arch = ARM_ARCH_V8M;
|
if (core_partno == cortex_m_parts[n].partno) {
|
||||||
|
cortex_m->core_info = &cortex_m_parts[n];
|
||||||
switch (cpuid & ARM_CPUID_PARTNO_MASK) {
|
|
||||||
case CORTEX_M23_PARTNO:
|
|
||||||
core = 23;
|
|
||||||
break;
|
|
||||||
case CORTEX_M33_PARTNO:
|
|
||||||
core = 33;
|
|
||||||
break;
|
|
||||||
case CORTEX_M35P_PARTNO:
|
|
||||||
core = 35;
|
|
||||||
break;
|
|
||||||
case CORTEX_M55_PARTNO:
|
|
||||||
core = 55;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
armv7m->arm.arch = ARM_ARCH_V7M;
|
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!cortex_m->core_info) {
|
||||||
|
LOG_ERROR("Cortex-M PARTNO 0x%x is unrecognized", core_partno);
|
||||||
|
return ERROR_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
LOG_DEBUG("Cortex-M%d r%" PRId8 "p%" PRId8 " processor detected",
|
armv7m->arm.arch = cortex_m->core_info->arch;
|
||||||
core, (uint8_t)((cpuid >> 20) & 0xf), (uint8_t)((cpuid >> 0) & 0xf));
|
|
||||||
|
LOG_DEBUG("%s r%" PRId8 "p%" PRId8 " processor detected",
|
||||||
|
cortex_m->core_info->name, (uint8_t)((cpuid >> 20) & 0xf), (uint8_t)((cpuid >> 0) & 0xf));
|
||||||
cortex_m->maskints_erratum = false;
|
cortex_m->maskints_erratum = false;
|
||||||
if (core == 7) {
|
if (core_partno == CORTEX_M7_PARTNO) {
|
||||||
uint8_t rev, patch;
|
uint8_t rev, patch;
|
||||||
rev = (cpuid >> 20) & 0xf;
|
rev = (cpuid >> 20) & 0xf;
|
||||||
patch = (cpuid >> 0) & 0xf;
|
patch = (cpuid >> 0) & 0xf;
|
||||||
|
@ -2040,30 +2092,27 @@ int cortex_m_examine(struct target *target)
|
||||||
}
|
}
|
||||||
LOG_DEBUG("cpuid: 0x%8.8" PRIx32 "", cpuid);
|
LOG_DEBUG("cpuid: 0x%8.8" PRIx32 "", cpuid);
|
||||||
|
|
||||||
if (core == 4) {
|
if (cortex_m->core_info->flags & CORTEX_M_F_HAS_FPV4) {
|
||||||
target_read_u32(target, MVFR0, &mvfr0);
|
target_read_u32(target, MVFR0, &mvfr0);
|
||||||
target_read_u32(target, MVFR1, &mvfr1);
|
target_read_u32(target, MVFR1, &mvfr1);
|
||||||
|
|
||||||
/* test for floating point feature on Cortex-M4 */
|
/* test for floating point feature on Cortex-M4 */
|
||||||
if ((mvfr0 == MVFR0_DEFAULT_M4) && (mvfr1 == MVFR1_DEFAULT_M4)) {
|
if ((mvfr0 == MVFR0_DEFAULT_M4) && (mvfr1 == MVFR1_DEFAULT_M4)) {
|
||||||
LOG_DEBUG("Cortex-M%d floating point feature FPv4_SP found", core);
|
LOG_DEBUG("%s floating point feature FPv4_SP found", cortex_m->core_info->name);
|
||||||
armv7m->fp_feature = FPV4_SP;
|
armv7m->fp_feature = FPV4_SP;
|
||||||
}
|
}
|
||||||
} else if (core == 7 || core == 33 || core == 35 || core == 55) {
|
} else if (cortex_m->core_info->flags & CORTEX_M_F_HAS_FPV5) {
|
||||||
target_read_u32(target, MVFR0, &mvfr0);
|
target_read_u32(target, MVFR0, &mvfr0);
|
||||||
target_read_u32(target, MVFR1, &mvfr1);
|
target_read_u32(target, MVFR1, &mvfr1);
|
||||||
|
|
||||||
/* test for floating point features on Cortex-M7 */
|
/* test for floating point features on Cortex-M7 */
|
||||||
if ((mvfr0 == MVFR0_DEFAULT_M7_SP) && (mvfr1 == MVFR1_DEFAULT_M7_SP)) {
|
if ((mvfr0 == MVFR0_DEFAULT_M7_SP) && (mvfr1 == MVFR1_DEFAULT_M7_SP)) {
|
||||||
LOG_DEBUG("Cortex-M%d floating point feature FPv5_SP found", core);
|
LOG_DEBUG("%s floating point feature FPv5_SP found", cortex_m->core_info->name);
|
||||||
armv7m->fp_feature = FPV5_SP;
|
armv7m->fp_feature = FPV5_SP;
|
||||||
} else if ((mvfr0 == MVFR0_DEFAULT_M7_DP) && (mvfr1 == MVFR1_DEFAULT_M7_DP)) {
|
} else if ((mvfr0 == MVFR0_DEFAULT_M7_DP) && (mvfr1 == MVFR1_DEFAULT_M7_DP)) {
|
||||||
LOG_DEBUG("Cortex-M%d floating point feature FPv5_DP found", core);
|
LOG_DEBUG("%s floating point feature FPv5_DP found", cortex_m->core_info->name);
|
||||||
armv7m->fp_feature = FPV5_DP;
|
armv7m->fp_feature = FPV5_DP;
|
||||||
}
|
}
|
||||||
} else if (core == 0) {
|
|
||||||
/* Cortex-M0 does not support unaligned memory access */
|
|
||||||
armv7m->arm.arch = ARM_ARCH_V6M;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* VECTRESET is supported only on ARMv7-M cores */
|
/* VECTRESET is supported only on ARMv7-M cores */
|
||||||
|
@ -2079,13 +2128,10 @@ int cortex_m_examine(struct target *target)
|
||||||
armv7m->arm.core_cache->reg_list[idx].exist = false;
|
armv7m->arm.core_cache->reg_list[idx].exist = false;
|
||||||
|
|
||||||
if (!armv7m->stlink) {
|
if (!armv7m->stlink) {
|
||||||
if (core == 3 || core == 4)
|
if (cortex_m->core_info->flags & CORTEX_M_F_TAR_AUTOINCR_BLOCK_4K)
|
||||||
/* Cortex-M3/M4 have 4096 bytes autoincrement range,
|
/* Cortex-M3/M4 have 4096 bytes autoincrement range,
|
||||||
* s. ARM IHI 0031C: MEM-AP 7.2.2 */
|
* s. ARM IHI 0031C: MEM-AP 7.2.2 */
|
||||||
armv7m->debug_ap->tar_autoincr_block = (1 << 12);
|
armv7m->debug_ap->tar_autoincr_block = (1 << 12);
|
||||||
else if (core == 7)
|
|
||||||
/* Cortex-M7 has only 1024 bytes autoincrement range */
|
|
||||||
armv7m->debug_ap->tar_autoincr_block = (1 << 10);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Enable debug requests */
|
/* Enable debug requests */
|
||||||
|
|
|
@ -42,12 +42,33 @@
|
||||||
|
|
||||||
#define CPUID 0xE000ED00
|
#define CPUID 0xE000ED00
|
||||||
|
|
||||||
#define ARM_CPUID_PARTNO_MASK 0xFFF0
|
#define ARM_CPUID_PARTNO_POS 4
|
||||||
|
#define ARM_CPUID_PARTNO_MASK (0xFFF << ARM_CPUID_PARTNO_POS)
|
||||||
|
|
||||||
#define CORTEX_M23_PARTNO 0xD200
|
enum cortex_m_partno {
|
||||||
#define CORTEX_M33_PARTNO 0xD210
|
CORTEX_M0_PARTNO = 0xC20,
|
||||||
#define CORTEX_M35P_PARTNO 0xD310
|
CORTEX_M1_PARTNO = 0xC21,
|
||||||
#define CORTEX_M55_PARTNO 0xD220
|
CORTEX_M3_PARTNO = 0xC23,
|
||||||
|
CORTEX_M4_PARTNO = 0xC24,
|
||||||
|
CORTEX_M7_PARTNO = 0xC27,
|
||||||
|
CORTEX_M0P_PARTNO = 0xC60,
|
||||||
|
CORTEX_M23_PARTNO = 0xD20,
|
||||||
|
CORTEX_M33_PARTNO = 0xD21,
|
||||||
|
CORTEX_M35P_PARTNO = 0xD31,
|
||||||
|
CORTEX_M55_PARTNO = 0xD22,
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Relevant Cortex-M flags, used in struct cortex_m_part_info.flags */
|
||||||
|
#define CORTEX_M_F_HAS_FPV4 BIT(0)
|
||||||
|
#define CORTEX_M_F_HAS_FPV5 BIT(1)
|
||||||
|
#define CORTEX_M_F_TAR_AUTOINCR_BLOCK_4K BIT(2)
|
||||||
|
|
||||||
|
struct cortex_m_part_info {
|
||||||
|
enum cortex_m_partno partno;
|
||||||
|
const char *name;
|
||||||
|
enum arm_arch arch;
|
||||||
|
uint32_t flags;
|
||||||
|
};
|
||||||
|
|
||||||
/* Debug Control Block */
|
/* Debug Control Block */
|
||||||
#define DCB_DHCSR 0xE000EDF0
|
#define DCB_DHCSR 0xE000EDF0
|
||||||
|
@ -211,9 +232,9 @@ struct cortex_m_common {
|
||||||
|
|
||||||
enum cortex_m_soft_reset_config soft_reset_config;
|
enum cortex_m_soft_reset_config soft_reset_config;
|
||||||
bool vectreset_supported;
|
bool vectreset_supported;
|
||||||
|
|
||||||
enum cortex_m_isrmasking_mode isrmasking_mode;
|
enum cortex_m_isrmasking_mode isrmasking_mode;
|
||||||
|
|
||||||
|
const struct cortex_m_part_info *core_info;
|
||||||
struct armv7m_common armv7m;
|
struct armv7m_common armv7m;
|
||||||
|
|
||||||
int apsel;
|
int apsel;
|
||||||
|
|
Loading…
Reference in New Issue