cortex_m: enhance core and arch detection
authorTarek BOCHKATI <tarek.bouchkati@gmail.com>
Tue, 11 May 2021 13:03:47 +0000 (14:03 +0100)
committerAntonio Borneo <borneo.antonio@gmail.com>
Fri, 18 Jun 2021 22:13:18 +0000 (23:13 +0100)
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>
src/target/cortex_m.c
src/target/cortex_m.h

index e442fc3b66ef4da8a6f7a22f2aacb50fa13f013c..d0256b1343b6926dc0ea09e3d188404523e98ea5 100644 (file)
  * 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 */
index 0f221ffff455b535e32b532485e9a3ca5f691498..3ba8a016dc141fed7765f4a552156b67f4219811 100644 (file)
 
 #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;