From 11857607293e1b27b43c307c3f6fba6ebbce90a8 Mon Sep 17 00:00:00 2001 From: Tarek BOCHKATI Date: Tue, 11 May 2021 14:03:47 +0100 Subject: [PATCH] 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 Reviewed-on: http://openocd.zylin.com/6233 Tested-by: jenkins Reviewed-by: Antonio Borneo --- src/target/cortex_m.c | 116 +++++++++++++++++++++++++++++------------- src/target/cortex_m.h | 33 +++++++++--- 2 files changed, 108 insertions(+), 41 deletions(-) diff --git a/src/target/cortex_m.c b/src/target/cortex_m.c index e442fc3b6..d0256b134 100644 --- a/src/target/cortex_m.c +++ b/src/target/cortex_m.c @@ -52,6 +52,66 @@ * 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 */ static int cortex_m_store_core_reg_u32(struct target *target, uint32_t num, uint32_t value); @@ -2001,35 +2061,27 @@ int cortex_m_examine(struct target *target) if (retval != ERROR_OK) return retval; - /* Get CPU Type */ - unsigned int core = (cpuid >> 4) & 0xf; + /* Get ARCH and CPU types */ + const enum cortex_m_partno core_partno = (cpuid & ARM_CPUID_PARTNO_MASK) >> ARM_CPUID_PARTNO_POS; - /* Check if it is an ARMv8-M core */ - armv7m->arm.arch = ARM_ARCH_V8M; - - 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; + for (unsigned int n = 0; n < ARRAY_SIZE(cortex_m_parts); n++) { + if (core_partno == cortex_m_parts[n].partno) { + cortex_m->core_info = &cortex_m_parts[n]; break; + } + } + + if (!cortex_m->core_info) { + LOG_ERROR("Cortex-M PARTNO 0x%x is unrecognized", core_partno); + return ERROR_FAIL; } + armv7m->arm.arch = cortex_m->core_info->arch; - LOG_DEBUG("Cortex-M%d r%" PRId8 "p%" PRId8 " processor detected", - 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; - if (core == 7) { + if (core_partno == CORTEX_M7_PARTNO) { uint8_t rev, patch; rev = (cpuid >> 20) & 0xf; patch = (cpuid >> 0) & 0xf; @@ -2040,30 +2092,27 @@ int cortex_m_examine(struct target *target) } 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, MVFR1, &mvfr1); /* test for floating point feature on Cortex-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; } - } 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, MVFR1, &mvfr1); /* test for floating point features on Cortex-M7 */ 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; } 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; } - } 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 */ @@ -2079,13 +2128,10 @@ int cortex_m_examine(struct target *target) armv7m->arm.core_cache->reg_list[idx].exist = false; 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, * s. ARM IHI 0031C: MEM-AP 7.2.2 */ 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 */ diff --git a/src/target/cortex_m.h b/src/target/cortex_m.h index 0f221ffff..3ba8a016d 100644 --- a/src/target/cortex_m.h +++ b/src/target/cortex_m.h @@ -42,12 +42,33 @@ #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) + +enum cortex_m_partno { + CORTEX_M0_PARTNO = 0xC20, + CORTEX_M1_PARTNO = 0xC21, + 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) -#define CORTEX_M23_PARTNO 0xD200 -#define CORTEX_M33_PARTNO 0xD210 -#define CORTEX_M35P_PARTNO 0xD310 -#define CORTEX_M55_PARTNO 0xD220 +struct cortex_m_part_info { + enum cortex_m_partno partno; + const char *name; + enum arm_arch arch; + uint32_t flags; +}; /* Debug Control Block */ #define DCB_DHCSR 0xE000EDF0 @@ -211,9 +232,9 @@ struct cortex_m_common { enum cortex_m_soft_reset_config soft_reset_config; bool vectreset_supported; - enum cortex_m_isrmasking_mode isrmasking_mode; + const struct cortex_m_part_info *core_info; struct armv7m_common armv7m; int apsel; -- 2.30.2