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:
Tarek BOCHKATI 2021-05-11 14:03:47 +01:00 committed by Antonio Borneo
parent f69adafb3d
commit 1185760729
2 changed files with 108 additions and 41 deletions

View File

@ -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 */

View File

@ -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;