cortex_m: add detection of MVE feature for Armv8.1-M cores

For Armv8.1-M based cores, detect if the core implements the optional
M-profile vector extension (MVE), using MVFR1 register.

While at there rework armv7m->fp_feature detection based on MVFR0
and MVFR1 registers.

Change-Id: I92d5b1759aea9f7561d285f46acdec51d6efb7b4
Signed-off-by: Tarek BOCHKATI <tarek.bouchkati@gmail.com>
Reviewed-on: https://review.openocd.org/c/openocd/+/6950
Reviewed-by: Antonio Borneo <borneo.antonio@gmail.com>
Tested-by: jenkins
This commit is contained in:
Tarek BOCHKATI 2022-04-28 03:46:35 +01:00 committed by Antonio Borneo
parent d2b2ac28d9
commit 22ebb693b6
2 changed files with 34 additions and 19 deletions

View File

@ -211,6 +211,8 @@ enum {
FPV4_SP, FPV4_SP,
FPV5_SP, FPV5_SP,
FPV5_DP, FPV5_DP,
FPV5_MVE_I,
FPV5_MVE_F,
}; };
#define ARMV7M_NUM_CORE_REGS (ARMV7M_CORE_LAST_REG - ARMV7M_CORE_FIRST_REG + 1) #define ARMV7M_NUM_CORE_REGS (ARMV7M_CORE_LAST_REG - ARMV7M_CORE_FIRST_REG + 1)

View File

@ -2486,16 +2486,17 @@ static bool cortex_m_has_tz(struct target *target)
return (dauthstatus & DAUTHSTATUS_SID_MASK) != 0; return (dauthstatus & DAUTHSTATUS_SID_MASK) != 0;
} }
#define MVFR0 0xe000ef40
#define MVFR1 0xe000ef44
#define MVFR0_DEFAULT_M4 0x10110021 #define MVFR0 0xE000EF40
#define MVFR1_DEFAULT_M4 0x11000011 #define MVFR0_SP_MASK 0x000000F0
#define MVFR0_SP 0x00000020
#define MVFR0_DP_MASK 0x00000F00
#define MVFR0_DP 0x00000200
#define MVFR0_DEFAULT_M7_SP 0x10110021 #define MVFR1 0xE000EF44
#define MVFR0_DEFAULT_M7_DP 0x10110221 #define MVFR1_MVE_MASK 0x00000F00
#define MVFR1_DEFAULT_M7_SP 0x11000011 #define MVFR1_MVE_I 0x00000100
#define MVFR1_DEFAULT_M7_DP 0x12000011 #define MVFR1_MVE_F 0x00000200
static int cortex_m_find_mem_ap(struct adiv5_dap *swjdp, static int cortex_m_find_mem_ap(struct adiv5_dap *swjdp,
struct adiv5_ap **debug_ap) struct adiv5_ap **debug_ap)
@ -2509,7 +2510,7 @@ static int cortex_m_find_mem_ap(struct adiv5_dap *swjdp,
int cortex_m_examine(struct target *target) int cortex_m_examine(struct target *target)
{ {
int retval; int retval;
uint32_t cpuid, fpcr, mvfr0, mvfr1; uint32_t cpuid, fpcr;
struct cortex_m_common *cortex_m = target_to_cm(target); struct cortex_m_common *cortex_m = target_to_cm(target);
struct adiv5_dap *swjdp = cortex_m->armv7m.arm.dap; struct adiv5_dap *swjdp = cortex_m->armv7m.arm.dap;
struct armv7m_common *armv7m = target_to_armv7m(target); struct armv7m_common *armv7m = target_to_armv7m(target);
@ -2584,25 +2585,37 @@ int cortex_m_examine(struct target *target)
LOG_TARGET_DEBUG(target, "cpuid: 0x%8.8" PRIx32 "", cpuid); LOG_TARGET_DEBUG(target, "cpuid: 0x%8.8" PRIx32 "", cpuid);
if (cortex_m->core_info->flags & CORTEX_M_F_HAS_FPV4) { if (cortex_m->core_info->flags & CORTEX_M_F_HAS_FPV4) {
uint32_t mvfr0;
target_read_u32(target, MVFR0, &mvfr0); target_read_u32(target, MVFR0, &mvfr0);
target_read_u32(target, MVFR1, &mvfr1);
/* test for floating point feature on Cortex-M4 */ if ((mvfr0 & MVFR0_SP_MASK) == MVFR0_SP) {
if ((mvfr0 == MVFR0_DEFAULT_M4) && (mvfr1 == MVFR1_DEFAULT_M4)) { LOG_TARGET_DEBUG(target, "%s floating point feature FPv4_SP found",
LOG_TARGET_DEBUG(target, "%s floating point feature FPv4_SP found", cortex_m->core_info->name); cortex_m->core_info->name);
armv7m->fp_feature = FPV4_SP; armv7m->fp_feature = FPV4_SP;
} }
} else if (cortex_m->core_info->flags & CORTEX_M_F_HAS_FPV5) { } else if (cortex_m->core_info->flags & CORTEX_M_F_HAS_FPV5) {
uint32_t mvfr0, mvfr1;
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 */ if ((mvfr0 & MVFR0_DP_MASK) == MVFR0_DP) {
if ((mvfr0 == MVFR0_DEFAULT_M7_SP) && (mvfr1 == MVFR1_DEFAULT_M7_SP)) { if ((mvfr1 & MVFR1_MVE_MASK) == MVFR1_MVE_F) {
LOG_TARGET_DEBUG(target, "%s floating point feature FPv5_SP found", cortex_m->core_info->name); LOG_TARGET_DEBUG(target, "%s floating point feature FPv5_DP + MVE-F found",
cortex_m->core_info->name);
armv7m->fp_feature = FPV5_MVE_F;
} else {
LOG_TARGET_DEBUG(target, "%s floating point feature FPv5_DP found",
cortex_m->core_info->name);
armv7m->fp_feature = FPV5_DP;
}
} else if ((mvfr0 & MVFR0_SP_MASK) == MVFR0_SP) {
LOG_TARGET_DEBUG(target, "%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 ((mvfr1 & MVFR1_MVE_MASK) == MVFR1_MVE_I) {
LOG_TARGET_DEBUG(target, "%s floating point feature FPv5_DP found", cortex_m->core_info->name); LOG_TARGET_DEBUG(target, "%s floating point feature MVE-I found",
armv7m->fp_feature = FPV5_DP; cortex_m->core_info->name);
armv7m->fp_feature = FPV5_MVE_I;
} }
} }