diff --git a/Makefile b/Makefile index 95c9075ee..f91699c44 100644 --- a/Makefile +++ b/Makefile @@ -263,24 +263,6 @@ ENABLE_FEAT_RNG = $(if $(findstring rng,${arch-features}),1,0) # Determine if FEAT_SB is supported ENABLE_FEAT_SB = $(if $(findstring sb,${arch-features}),1,0) -ifeq "8.5" "$(word 1, $(sort 8.5 $(ARM_ARCH_MAJOR).$(ARM_ARCH_MINOR)))" -ENABLE_FEAT_SB = 1 -endif - -# Determine and enable FEAT_FGT to access HDFGRTR_EL2 register for v8.6 and higher versions. -ifeq "8.6" "$(word 1, $(sort 8.6 $(ARM_ARCH_MAJOR).$(ARM_ARCH_MINOR)))" -ENABLE_FEAT_FGT = 1 -endif - -# Determine and enable FEAT_ECV to access CNTPOFF_EL2 register for v8.6 and higher versions. -ifeq "8.6" "$(word 1, $(sort 8.6 $(ARM_ARCH_MAJOR).$(ARM_ARCH_MINOR)))" -ENABLE_FEAT_ECV = 1 -endif - -ifeq "8.4" "$(word 1, $(sort 8.4 $(ARM_ARCH_MAJOR).$(ARM_ARCH_MINOR)))" -ENABLE_FEAT_DIT = 1 -endif - ifneq ($(findstring armclang,$(notdir $(CC))),) TF_CFLAGS_aarch32 = -target arm-arm-none-eabi $(march32-directive) TF_CFLAGS_aarch64 = -target aarch64-arm-none-eabi $(march64-directive) @@ -474,6 +456,7 @@ endif ################################################################################ # Common sources and include directories ################################################################################ +include ${MAKE_HELPERS_DIRECTORY}arch_features.mk include lib/compiler-rt/compiler-rt.mk BL_COMMON_SOURCES += common/bl_common.c \ @@ -776,6 +759,10 @@ ifeq ($(PSA_FWU_SUPPORT),1) $(info PSA_FWU_SUPPORT is an experimental feature) endif +ifeq ($(FEATURE_DETECTION),1) + $(info FEATURE_DETECTION is an experimental feature) +endif + ifeq (${ARM_XLAT_TABLES_LIB_V1}, 1) ifeq (${ALLOW_RO_XLAT_TABLES}, 1) $(error "ALLOW_RO_XLAT_TABLES requires translation tables library v2") @@ -980,10 +967,7 @@ $(eval $(call assert_booleans,\ CREATE_KEYS \ CTX_INCLUDE_AARCH32_REGS \ CTX_INCLUDE_FPREGS \ - CTX_INCLUDE_PAUTH_REGS \ - CTX_INCLUDE_MTE_REGS \ CTX_INCLUDE_EL2_REGS \ - CTX_INCLUDE_NEVE_REGS \ DEBUG \ DISABLE_MTPMU \ DYN_DISABLE_AUTH \ @@ -993,11 +977,9 @@ $(eval $(call assert_booleans,\ ENABLE_AMU_FCONF \ AMU_RESTRICT_COUNTERS \ ENABLE_ASSERTIONS \ - ENABLE_MPAM_FOR_LOWER_ELS \ ENABLE_PIE \ ENABLE_PMF \ ENABLE_PSCI_STAT \ - ENABLE_RME \ ENABLE_RUNTIME_INSTRUMENTATION \ ENABLE_SME_FOR_NS \ ENABLE_SME_FOR_SWD \ @@ -1017,7 +999,6 @@ $(eval $(call assert_booleans,\ PL011_GENERIC_UART \ PROGRAMMABLE_RESET_ADDRESS \ PSCI_EXTENDED_STATE_ID \ - RAS_EXTENSION \ RESET_TO_BL31 \ SAVE_KEYS \ SEPARATE_CODE_AND_RODATA \ @@ -1046,20 +1027,13 @@ $(eval $(call assert_booleans,\ RAS_TRAP_LOWER_EL_ERR_ACCESS \ COT_DESC_IN_DTB \ USE_SP804_TIMER \ - ENABLE_FEAT_RNG \ - ENABLE_FEAT_SB \ - ENABLE_FEAT_DIT \ PSA_FWU_SUPPORT \ ENABLE_TRBE_FOR_NS \ ENABLE_SYS_REG_TRACE_FOR_NS \ - ENABLE_TRF_FOR_NS \ - ENABLE_FEAT_HCX \ ENABLE_MPMM \ ENABLE_MPMM_FCONF \ - ENABLE_FEAT_FGT \ - ENABLE_FEAT_AMUv1 \ - ENABLE_FEAT_ECV \ SIMICS_BUILD \ + FEATURE_DETECTION \ ))) $(eval $(call assert_numerics,\ @@ -1067,9 +1041,30 @@ $(eval $(call assert_numerics,\ ARM_ARCH_MAJOR \ ARM_ARCH_MINOR \ BRANCH_PROTECTION \ + CTX_INCLUDE_PAUTH_REGS \ + CTX_INCLUDE_MTE_REGS \ + CTX_INCLUDE_NEVE_REGS \ + ENABLE_BTI \ + ENABLE_PAUTH \ + ENABLE_FEAT_AMUv1 \ + ENABLE_FEAT_AMUv1p1 \ + ENABLE_FEAT_CSV2_2 \ + ENABLE_FEAT_DIT \ + ENABLE_FEAT_ECV \ + ENABLE_FEAT_FGT \ + ENABLE_FEAT_HCX \ + ENABLE_FEAT_PAN \ + ENABLE_FEAT_RNG \ + ENABLE_FEAT_SB \ + ENABLE_FEAT_SEL2 \ + ENABLE_FEAT_VHE \ + ENABLE_MPAM_FOR_LOWER_ELS \ + ENABLE_RME \ + ENABLE_TRF_FOR_NS \ FW_ENC_STATUS \ NR_OF_FW_BANKS \ NR_OF_IMAGES_IN_FW_BANK \ + RAS_EXTENSION \ ))) ifdef KEY_SIZE @@ -1179,6 +1174,12 @@ $(eval $(call add_defines,\ ENABLE_FEAT_AMUv1 \ ENABLE_FEAT_ECV \ SIMICS_BUILD \ + ENABLE_FEAT_AMUv1p1 \ + ENABLE_FEAT_SEL2 \ + ENABLE_FEAT_VHE \ + ENABLE_FEAT_CSV2_2 \ + ENABLE_FEAT_PAN \ + FEATURE_DETECTION \ ))) ifeq (${SANITIZE_UB},trap) diff --git a/bl31/bl31.mk b/bl31/bl31.mk index e751824bb..25c7964a1 100644 --- a/bl31/bl31.mk +++ b/bl31/bl31.mk @@ -1,5 +1,5 @@ # -# Copyright (c) 2013-2021, ARM Limited and Contributors. All rights reserved. +# Copyright (c) 2013-2022, ARM Limited and Contributors. All rights reserved. # # SPDX-License-Identifier: BSD-3-Clause # @@ -128,6 +128,10 @@ BL31_SOURCES += ${GPT_LIB_SRCS} \ ${RMMD_SOURCES} endif +ifeq ($(FEATURE_DETECTION),1) +BL31_SOURCES += common/feat_detect.c +endif + BL31_LINKERFILE := bl31/bl31.ld.S # Flag used to indicate if Crash reporting via console should be included diff --git a/bl31/bl31_main.c b/bl31/bl31_main.c index 9ac10e240..797093e15 100644 --- a/bl31/bl31_main.c +++ b/bl31/bl31_main.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2021, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2013-2022, Arm Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -123,6 +124,11 @@ void bl31_main(void) NOTICE("BL31: %s\n", version_string); NOTICE("BL31: %s\n", build_message); +#if FEATURE_DETECTION + /* Detect if features enabled during compilation are supported by PE. */ + detect_arch_features(); +#endif /* FEATURE_DETECTION */ + #ifdef SUPPORT_UNKNOWN_MPID if (unsupported_mpid_flag == 0) { NOTICE("Unsupported MPID detected!\n"); diff --git a/common/feat_detect.c b/common/feat_detect.c new file mode 100644 index 000000000..ef09b8657 --- /dev/null +++ b/common/feat_detect.c @@ -0,0 +1,288 @@ +/* + * Copyright (c) 2022, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +/******************************************************************************* + * This section lists the wrapper modules for each feature to evaluate the + * feature states (FEAT_STATE_1 and FEAT_STATE_2) and perform necessary action + * as below: + * + * It verifies whether the FEAT_XXX (eg: FEAT_SB) is supported by the PE or not. + * Without this check an exception would occur during context save/restore + * routines, if the feature is enabled but not supported by PE. + ******************************************************************************/ + +/****************************************** + * Feature : FEAT_SB (Speculation Barrier) + *****************************************/ +static void read_feat_sb(void) +{ +#if (ENABLE_FEAT_SB == FEAT_STATE_1) + feat_detect_panic(is_armv8_0_feat_sb_present(), "SB"); +#endif +} + +/****************************************************** + * Feature : FEAT_CSV2_2 (Cache Speculation Variant 2) + *****************************************************/ +static void read_feat_csv2_2(void) +{ +#if (ENABLE_FEAT_CSV2_2 == FEAT_STATE_1) + feat_detect_panic(is_armv8_0_feat_csv2_2_present(), "CSV2_2"); +#endif +} + +/*********************************************** + * Feature : FEAT_PAN (Privileged Access Never) + **********************************************/ +static void read_feat_pan(void) +{ +#if (ENABLE_FEAT_PAN == FEAT_STATE_1) + feat_detect_panic(is_armv8_1_pan_present(), "PAN"); +#endif +} + +/****************************************************** + * Feature : FEAT_VHE (Virtualization Host Extensions) + *****************************************************/ +static void read_feat_vhe(void) +{ +#if (ENABLE_FEAT_VHE == FEAT_STATE_1) + feat_detect_panic(is_armv8_1_vhe_present(), "VHE"); +#endif +} + +/******************************************************************************* + * Feature : FEAT_RAS (Reliability, Availability, and Serviceability Extension) + ******************************************************************************/ +static void read_feat_ras(void) +{ +#if (RAS_EXTENSION == FEAT_STATE_1) + feat_detect_panic(is_armv8_2_feat_ras_present(), "RAS"); +#endif +} + +/************************************************ + * Feature : FEAT_PAUTH (Pointer Authentication) + ***********************************************/ +static void read_feat_pauth(void) +{ +#if (ENABLE_PAUTH == FEAT_STATE_1) || (CTX_INCLUDE_PAUTH_REGS == FEAT_STATE_1) + feat_detect_panic(is_armv8_3_pauth_present(), "PAUTH"); +#endif +} + +/************************************************************ + * Feature : FEAT_DIT (Data Independent Timing Instructions) + ***********************************************************/ +static void read_feat_dit(void) +{ +#if (ENABLE_FEAT_DIT == FEAT_STATE_1) + feat_detect_panic(is_armv8_4_feat_dit_present(), "DIT"); +#endif +} + +/********************************************************* + * Feature : FEAT_AMUv1 (Activity Monitors Extensions v1) + ********************************************************/ +static void read_feat_amuv1(void) +{ +#if (ENABLE_FEAT_AMUv1 == FEAT_STATE_1) + feat_detect_panic(is_armv8_4_feat_amuv1_present(), "AMUv1"); +#endif +} + +/**************************************************************************** + * Feature : FEAT_MPAM (Memory Partitioning and Monitoring (MPAM) Extension) + ***************************************************************************/ +static void read_feat_mpam(void) +{ +#if (ENABLE_MPAM_FOR_LOWER_ELS == FEAT_STATE_1) + feat_detect_panic(get_mpam_version() != 0U, "MPAM"); +#endif +} + +/************************************************************** + * Feature : FEAT_NV2 (Enhanced Nested Virtualization Support) + *************************************************************/ +static void read_feat_nv2(void) +{ +#if (CTX_INCLUDE_NEVE_REGS == FEAT_STATE_1) + unsigned int nv = get_armv8_4_feat_nv_support(); + + feat_detect_panic((nv == ID_AA64MMFR2_EL1_NV2_SUPPORTED), "NV2"); +#endif +} + +/*********************************** + * Feature : FEAT_SEL2 (Secure EL2) + **********************************/ +static void read_feat_sel2(void) +{ +#if (ENABLE_FEAT_SEL2 == FEAT_STATE_1) + feat_detect_panic(is_armv8_4_sel2_present(), "SEL2"); +#endif +} + +/**************************************************** + * Feature : FEAT_TRF (Self-hosted Trace Extensions) + ***************************************************/ +static void read_feat_trf(void) +{ +#if (ENABLE_TRF_FOR_NS == FEAT_STATE_1) + feat_detect_panic(is_arm8_4_feat_trf_present(), "TRF"); +#endif +} + +/************************************************ + * Feature : FEAT_MTE (Memory Tagging Extension) + ***********************************************/ +static void read_feat_mte(void) +{ +#if (CTX_INCLUDE_MTE_REGS == FEAT_STATE_1) + unsigned int mte = get_armv8_5_mte_support(); + + feat_detect_panic((mte != MTE_UNIMPLEMENTED), "MTE"); +#endif +} + +/*********************************************** + * Feature : FEAT_RNG (Random Number Generator) + **********************************************/ +static void read_feat_rng(void) +{ +#if (ENABLE_FEAT_RNG == FEAT_STATE_1) + feat_detect_panic(is_armv8_5_rng_present(), "RNG"); +#endif +} + +/**************************************************** + * Feature : FEAT_BTI (Branch Target Identification) + ***************************************************/ +static void read_feat_bti(void) +{ +#if (ENABLE_BTI == FEAT_STATE_1) + feat_detect_panic(is_armv8_5_bti_present(), "BTI"); +#endif +} + +/**************************************** + * Feature : FEAT_FGT (Fine Grain Traps) + ***************************************/ +static void read_feat_fgt(void) +{ +#if (ENABLE_FEAT_FGT == FEAT_STATE_1) + feat_detect_panic(is_armv8_6_fgt_present(), "FGT"); +#endif +} + +/*********************************************** + * Feature : FEAT_AMUv1p1 (AMU Extensions v1.1) + **********************************************/ +static void read_feat_amuv1p1(void) +{ +#if (ENABLE_FEAT_AMUv1p1 == FEAT_STATE_1) + feat_detect_panic(is_armv8_6_feat_amuv1p1_present(), "AMUv1p1"); +#endif +} + +/******************************************************* + * Feature : FEAT_ECV (Enhanced Counter Virtualization) + ******************************************************/ +static void read_feat_ecv(void) +{ +#if (ENABLE_FEAT_ECV == FEAT_STATE_1) + unsigned int ecv = get_armv8_6_ecv_support(); + + feat_detect_panic(((ecv == ID_AA64MMFR0_EL1_ECV_SUPPORTED) || + (ecv == ID_AA64MMFR0_EL1_ECV_SELF_SYNCH)), "ECV"); +#endif +} + +/****************************************************************** + * Feature : FEAT_HCX (Extended Hypervisor Configuration Register) + *****************************************************************/ +static void read_feat_hcx(void) +{ +#if (ENABLE_FEAT_HCX == FEAT_STATE_1) + feat_detect_panic(is_feat_hcx_present(), "HCX"); +#endif +} + +/************************************************** + * Feature : FEAT_RME (Realm Management Extension) + *************************************************/ +static void read_feat_rme(void) +{ +#if (ENABLE_RME == FEAT_STATE_1) + feat_detect_panic((get_armv9_2_feat_rme_support() != + ID_AA64PFR0_FEAT_RME_NOT_SUPPORTED), "RME"); +#endif +} + +/*********************************************************************************** + * TF-A supports many Arm architectural features starting from arch version + * (8.0 till 8.7+). These features are mostly enabled through build flags. This + * mechanism helps in validating these build flags in the early boot phase + * either in BL1 or BL31 depending on the platform and assists in identifying + * and notifying the features which are enabled but not supported by the PE. + * + * It reads all the enabled features ID-registers and ensures the features + * are supported by the PE. + * In case if they aren't it stops booting at an early phase and logs the error + * messages, notifying the platforms about the features that are not supported. + * + * Further the procedure is implemented with a tri-state approach for each feature: + * ENABLE_FEAT_xxx = 0 : The feature is disabled statically at compile time + * ENABLE_FEAT_xxx = 1 : The feature is enabled and must be present in hardware. + * There will be panic if feature is not present at cold boot. + * ENABLE_FEAT_xxx = 2 : The feature is enabled but dynamically enabled at runtime + * depending on hardware capability. + * + * For better readability, state values are defined with macros namely: + * { FEAT_STATE_0, FEAT_STATE_1, FEAT_STATE_2 } taking values as their naming. + **********************************************************************************/ +void detect_arch_features(void) +{ + /* v8.0 features */ + read_feat_sb(); + read_feat_csv2_2(); + + /* v8.1 features */ + read_feat_pan(); + read_feat_vhe(); + + /* v8.2 features */ + read_feat_ras(); + + /* v8.3 features */ + read_feat_pauth(); + + /* v8.4 features */ + read_feat_dit(); + read_feat_amuv1(); + read_feat_mpam(); + read_feat_nv2(); + read_feat_sel2(); + read_feat_trf(); + + /* v8.5 features */ + read_feat_mte(); + read_feat_rng(); + read_feat_bti(); + + /* v8.6 features */ + read_feat_amuv1p1(); + read_feat_fgt(); + read_feat_ecv(); + + /* v8.7 features */ + read_feat_hcx(); + + /* v9.2 features */ + read_feat_rme(); +} diff --git a/include/arch/aarch64/arch.h b/include/arch/aarch64/arch.h index 29da33cbd..b4608ae41 100644 --- a/include/arch/aarch64/arch.h +++ b/include/arch/aarch64/arch.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2021, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2013-2022, Arm Limited and Contributors. All rights reserved. * Copyright (c) 2020, NVIDIA Corporation. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause @@ -99,7 +99,6 @@ /******************************************************************************* * Definitions for EL2 system registers for save/restore routine ******************************************************************************/ - #define CNTPOFF_EL2 S3_4_C14_C0_6 #define HAFGRTR_EL2 S3_4_C3_C1_6 #define HDFGRTR_EL2 S3_4_C3_C1_4 @@ -155,39 +154,55 @@ #endif /* ID_AA64PFR0_EL1 definitions */ -#define ID_AA64PFR0_EL0_SHIFT U(0) -#define ID_AA64PFR0_EL1_SHIFT U(4) -#define ID_AA64PFR0_EL2_SHIFT U(8) -#define ID_AA64PFR0_EL3_SHIFT U(12) -#define ID_AA64PFR0_AMU_SHIFT U(44) -#define ID_AA64PFR0_AMU_MASK ULL(0xf) -#define ID_AA64PFR0_AMU_NOT_SUPPORTED U(0x0) -#define ID_AA64PFR0_AMU_V1 U(0x1) -#define ID_AA64PFR0_AMU_V1P1 U(0x2) -#define ID_AA64PFR0_ELX_MASK ULL(0xf) -#define ID_AA64PFR0_GIC_SHIFT U(24) -#define ID_AA64PFR0_GIC_WIDTH U(4) -#define ID_AA64PFR0_GIC_MASK ULL(0xf) -#define ID_AA64PFR0_SVE_SHIFT U(32) -#define ID_AA64PFR0_SVE_MASK ULL(0xf) -#define ID_AA64PFR0_SVE_LENGTH U(4) -#define ID_AA64PFR0_SEL2_SHIFT U(36) -#define ID_AA64PFR0_SEL2_MASK ULL(0xf) -#define ID_AA64PFR0_MPAM_SHIFT U(40) -#define ID_AA64PFR0_MPAM_MASK ULL(0xf) -#define ID_AA64PFR0_DIT_SHIFT U(48) -#define ID_AA64PFR0_DIT_MASK ULL(0xf) -#define ID_AA64PFR0_DIT_LENGTH U(4) -#define ID_AA64PFR0_DIT_SUPPORTED U(1) -#define ID_AA64PFR0_CSV2_SHIFT U(56) -#define ID_AA64PFR0_CSV2_MASK ULL(0xf) -#define ID_AA64PFR0_CSV2_LENGTH U(4) +#define ID_AA64PFR0_EL0_SHIFT U(0) +#define ID_AA64PFR0_EL1_SHIFT U(4) +#define ID_AA64PFR0_EL2_SHIFT U(8) +#define ID_AA64PFR0_EL3_SHIFT U(12) + +#define ID_AA64PFR0_AMU_SHIFT U(44) +#define ID_AA64PFR0_AMU_MASK ULL(0xf) +#define ID_AA64PFR0_AMU_NOT_SUPPORTED U(0x0) +#define ID_AA64PFR0_AMU_V1 ULL(0x1) +#define ID_AA64PFR0_AMU_V1P1 U(0x2) + +#define ID_AA64PFR0_ELX_MASK ULL(0xf) + +#define ID_AA64PFR0_GIC_SHIFT U(24) +#define ID_AA64PFR0_GIC_WIDTH U(4) +#define ID_AA64PFR0_GIC_MASK ULL(0xf) + +#define ID_AA64PFR0_SVE_SHIFT U(32) +#define ID_AA64PFR0_SVE_MASK ULL(0xf) +#define ID_AA64PFR0_SVE_SUPPORTED ULL(0x1) +#define ID_AA64PFR0_SVE_LENGTH U(4) + +#define ID_AA64PFR0_SEL2_SHIFT U(36) +#define ID_AA64PFR0_SEL2_MASK ULL(0xf) + +#define ID_AA64PFR0_MPAM_SHIFT U(40) +#define ID_AA64PFR0_MPAM_MASK ULL(0xf) + +#define ID_AA64PFR0_DIT_SHIFT U(48) +#define ID_AA64PFR0_DIT_MASK ULL(0xf) +#define ID_AA64PFR0_DIT_LENGTH U(4) +#define ID_AA64PFR0_DIT_SUPPORTED U(1) + +#define ID_AA64PFR0_CSV2_SHIFT U(56) +#define ID_AA64PFR0_CSV2_MASK ULL(0xf) +#define ID_AA64PFR0_CSV2_LENGTH U(4) +#define ID_AA64PFR0_CSV2_2_SUPPORTED ULL(0x2) + #define ID_AA64PFR0_FEAT_RME_SHIFT U(52) #define ID_AA64PFR0_FEAT_RME_MASK ULL(0xf) #define ID_AA64PFR0_FEAT_RME_LENGTH U(4) #define ID_AA64PFR0_FEAT_RME_NOT_SUPPORTED U(0) #define ID_AA64PFR0_FEAT_RME_V1 U(1) +#define ID_AA64PFR0_RAS_SHIFT U(28) +#define ID_AA64PFR0_RAS_MASK ULL(0xf) +#define ID_AA64PFR0_RAS_NOT_SUPPORTED ULL(0x0) +#define ID_AA64PFR0_RAS_LENGTH U(4) + /* Exception level handling */ #define EL_IMPL_NONE ULL(0) #define EL_IMPL_A64ONLY ULL(1) @@ -204,8 +219,10 @@ #define ID_AA64DFR0_TRACEFILT_LENGTH U(4) /* ID_AA64DFR0_EL1.PMS definitions (for ARMv8.2+) */ -#define ID_AA64DFR0_PMS_SHIFT U(32) -#define ID_AA64DFR0_PMS_MASK ULL(0xf) +#define ID_AA64DFR0_PMS_SHIFT U(32) +#define ID_AA64DFR0_PMS_MASK ULL(0xf) +#define ID_AA64DFR0_SPE_SUPPORTED ULL(0x1) +#define ID_AA64DFR0_SPE_NOT_SUPPORTED ULL(0x0) /* ID_AA64DFR0_EL1.TraceBuffer definitions */ #define ID_AA64DFR0_TRACEBUFFER_SHIFT U(44) @@ -222,15 +239,22 @@ #define ID_AA64ISAR0_RNDR_MASK ULL(0xf) /* ID_AA64ISAR1_EL1 definitions */ -#define ID_AA64ISAR1_EL1 S3_0_C0_C6_1 -#define ID_AA64ISAR1_GPI_SHIFT U(28) -#define ID_AA64ISAR1_GPI_MASK ULL(0xf) -#define ID_AA64ISAR1_GPA_SHIFT U(24) -#define ID_AA64ISAR1_GPA_MASK ULL(0xf) -#define ID_AA64ISAR1_API_SHIFT U(8) -#define ID_AA64ISAR1_API_MASK ULL(0xf) -#define ID_AA64ISAR1_APA_SHIFT U(4) -#define ID_AA64ISAR1_APA_MASK ULL(0xf) +#define ID_AA64ISAR1_EL1 S3_0_C0_C6_1 + +#define ID_AA64ISAR1_GPI_SHIFT U(28) +#define ID_AA64ISAR1_GPI_MASK ULL(0xf) +#define ID_AA64ISAR1_GPA_SHIFT U(24) +#define ID_AA64ISAR1_GPA_MASK ULL(0xf) + +#define ID_AA64ISAR1_API_SHIFT U(8) +#define ID_AA64ISAR1_API_MASK ULL(0xf) +#define ID_AA64ISAR1_APA_SHIFT U(4) +#define ID_AA64ISAR1_APA_MASK ULL(0xf) + +#define ID_AA64ISAR1_SB_SHIFT U(36) +#define ID_AA64ISAR1_SB_MASK ULL(0xf) +#define ID_AA64ISAR1_SB_SUPPORTED ULL(0x1) +#define ID_AA64ISAR1_SB_NOT_SUPPORTED ULL(0x0) /* ID_AA64MMFR0_EL1 definitions */ #define ID_AA64MMFR0_EL1_PARANGE_SHIFT U(0) @@ -292,17 +316,23 @@ #define ID_AA64MMFR1_EL1_HCX_NOT_SUPPORTED ULL(0x0) /* ID_AA64MMFR2_EL1 definitions */ -#define ID_AA64MMFR2_EL1 S3_0_C0_C7_2 +#define ID_AA64MMFR2_EL1 S3_0_C0_C7_2 -#define ID_AA64MMFR2_EL1_ST_SHIFT U(28) -#define ID_AA64MMFR2_EL1_ST_MASK ULL(0xf) +#define ID_AA64MMFR2_EL1_ST_SHIFT U(28) +#define ID_AA64MMFR2_EL1_ST_MASK ULL(0xf) -#define ID_AA64MMFR2_EL1_CCIDX_SHIFT U(20) -#define ID_AA64MMFR2_EL1_CCIDX_MASK ULL(0xf) -#define ID_AA64MMFR2_EL1_CCIDX_LENGTH U(4) +#define ID_AA64MMFR2_EL1_CCIDX_SHIFT U(20) +#define ID_AA64MMFR2_EL1_CCIDX_MASK ULL(0xf) +#define ID_AA64MMFR2_EL1_CCIDX_LENGTH U(4) -#define ID_AA64MMFR2_EL1_CNP_SHIFT U(0) -#define ID_AA64MMFR2_EL1_CNP_MASK ULL(0xf) +#define ID_AA64MMFR2_EL1_CNP_SHIFT U(0) +#define ID_AA64MMFR2_EL1_CNP_MASK ULL(0xf) + +#define ID_AA64MMFR2_EL1_NV_SHIFT U(24) +#define ID_AA64MMFR2_EL1_NV_MASK ULL(0xf) +#define ID_AA64MMFR2_EL1_NV_NOT_SUPPORTED ULL(0x0) +#define ID_AA64MMFR2_EL1_NV_SUPPORTED ULL(0x1) +#define ID_AA64MMFR2_EL1_NV2_SUPPORTED ULL(0x2) /* ID_AA64PFR1_EL1 definitions */ #define ID_AA64PFR1_EL1_SSBS_SHIFT U(4) diff --git a/include/arch/aarch64/arch_features.h b/include/arch/aarch64/arch_features.h index a260f0316..29710e736 100644 --- a/include/arch/aarch64/arch_features.h +++ b/include/arch/aarch64/arch_features.h @@ -140,4 +140,88 @@ static inline unsigned int get_armv9_2_feat_rme_support(void) ID_AA64PFR0_FEAT_RME_SHIFT) & ID_AA64PFR0_FEAT_RME_MASK; } +/********************************************************************************* + * Function to identify the presence of FEAT_SB (Speculation Barrier Instruction) + ********************************************************************************/ +static inline bool is_armv8_0_feat_sb_present(void) +{ + return (((read_id_aa64isar1_el1() >> ID_AA64ISAR1_SB_SHIFT) & + ID_AA64ISAR1_SB_MASK) == ID_AA64ISAR1_SB_SUPPORTED); +} + +/********************************************************************************* + * Function to identify the presence of FEAT_CSV2_2 (Cache Speculation Variant 2) + ********************************************************************************/ +static inline bool is_armv8_0_feat_csv2_2_present(void) +{ + return (((read_id_aa64pfr0_el1() >> ID_AA64PFR0_CSV2_SHIFT) & + ID_AA64PFR0_CSV2_MASK) == ID_AA64PFR0_CSV2_2_SUPPORTED); +} + +/********************************************************************************** + * Function to identify the presence of FEAT_SPE (Statistical Profiling Extension) + *********************************************************************************/ +static inline bool is_armv8_2_feat_spe_present(void) +{ + return (((read_id_aa64dfr0_el1() >> ID_AA64DFR0_PMS_SHIFT) & + ID_AA64DFR0_PMS_MASK) != ID_AA64DFR0_SPE_NOT_SUPPORTED); +} + +/******************************************************************************* + * Function to identify the presence of FEAT_SVE (Scalable Vector Extension) + ******************************************************************************/ +static inline bool is_armv8_2_feat_sve_present(void) +{ + return (((read_id_aa64pfr0_el1() >> ID_AA64PFR0_SVE_SHIFT) & + ID_AA64PFR0_SVE_MASK) == ID_AA64PFR0_SVE_SUPPORTED); +} + +/******************************************************************************* + * Function to identify the presence of FEAT_RAS (Reliability,Availability, + * and Serviceability Extension) + ******************************************************************************/ +static inline bool is_armv8_2_feat_ras_present(void) +{ + return (((read_id_aa64pfr0_el1() >> ID_AA64PFR0_RAS_SHIFT) & + ID_AA64PFR0_RAS_MASK) != ID_AA64PFR0_RAS_NOT_SUPPORTED); +} + +/************************************************************************** + * Function to identify the presence of FEAT_DIT (Data Independent Timing) + *************************************************************************/ +static inline bool is_armv8_4_feat_dit_present(void) +{ + return (((read_id_aa64pfr0_el1() >> ID_AA64PFR0_DIT_SHIFT) & + ID_AA64PFR0_DIT_MASK) == ID_AA64PFR0_DIT_SUPPORTED); +} + +/************************************************************************* + * Function to identify the presence of FEAT_TRF (TraceLift) + ************************************************************************/ +static inline bool is_arm8_4_feat_trf_present(void) +{ + return (((read_id_aa64dfr0_el1() >> ID_AA64DFR0_TRACEFILT_SHIFT) & + ID_AA64DFR0_TRACEFILT_MASK) == ID_AA64DFR0_TRACEFILT_SUPPORTED); +} + +/******************************************************************************* + * Function to identify the presence of FEAT_AMUv1 (Activity Monitors- + * Extension v1) + ******************************************************************************/ +static inline bool is_armv8_4_feat_amuv1_present(void) +{ + return (((read_id_aa64pfr0_el1() >> ID_AA64PFR0_AMU_SHIFT) & + ID_AA64PFR0_AMU_MASK) >= ID_AA64PFR0_AMU_V1); +} + +/******************************************************************************** + * Function to identify the presence of FEAT_NV2 (Enhanced Nested Virtualization + * Support) + *******************************************************************************/ +static inline unsigned int get_armv8_4_feat_nv_support(void) +{ + return (((read_id_aa64mmfr2_el1() >> ID_AA64MMFR2_EL1_NV_SHIFT) & + ID_AA64MMFR2_EL1_NV_MASK)); +} + #endif /* ARCH_FEATURES_H */ diff --git a/include/common/feat_detect.h b/include/common/feat_detect.h new file mode 100644 index 000000000..0f0f10596 --- /dev/null +++ b/include/common/feat_detect.h @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2022, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef FEAT_DETECT_H +#define FEAT_DETECT_H + +#include +#include + +/* Function Prototypes */ +void detect_arch_features(void); + +/* Macro Definitions */ +#define FEAT_STATE_1 1 +#define FEAT_STATE_2 2 +#define feat_detect_panic(a, b) ((a) ? (void)0 : feature_panic(b)) + +/******************************************************************************* + * Function : feature_panic + * Customised panic module with error logging mechanism to list the feature + * not supported by the PE. + ******************************************************************************/ +static inline void feature_panic(char *feat_name) +{ + ERROR("FEAT_%s not supported by the PE\n", feat_name); + panic(); +} + +#endif /* FEAT_DETECT_H */ diff --git a/make_helpers/arch_features.mk b/make_helpers/arch_features.mk new file mode 100644 index 000000000..01e3e096d --- /dev/null +++ b/make_helpers/arch_features.mk @@ -0,0 +1,36 @@ +# +# Copyright (c) 2022, Arm Limited. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# + +# This file lists all the checks related to the Architectural Feature +# Enablement flags, based on the Architectural version. + +# Enable the features which are mandatory from ARCH version 8.1 and upwards. +ifeq "8.1" "$(word 1, $(sort 8.1 $(ARM_ARCH_MAJOR).$(ARM_ARCH_MINOR)))" +ENABLE_FEAT_PAN = 1 +ENABLE_FEAT_VHE = 1 +endif + +# Enable the features which are mandatory from ARCH version 8.4 and upwards. +ifeq "8.4" "$(word 1, $(sort 8.4 $(ARM_ARCH_MAJOR).$(ARM_ARCH_MINOR)))" +ENABLE_FEAT_DIT = 1 +ENABLE_FEAT_SEL2 = 1 +endif + +# Enable the features which are mandatory from ARCH version 8.5 and upwards. +ifeq "8.5" "$(word 1, $(sort 8.5 $(ARM_ARCH_MAJOR).$(ARM_ARCH_MINOR)))" +ENABLE_FEAT_SB = 1 +endif + +# Enable the features which are mandatory from ARCH version 8.6 and upwards. +ifeq "8.6" "$(word 1, $(sort 8.6 $(ARM_ARCH_MAJOR).$(ARM_ARCH_MINOR)))" +ENABLE_FEAT_FGT = 1 +ENABLE_FEAT_ECV = 1 +endif + +# Enable the features which are mandatory from ARCH version 8.7 and upwards. +ifeq "8.7" "$(word 1, $(sort 8.7 $(ARM_ARCH_MAJOR).$(ARM_ARCH_MINOR)))" +ENABLE_FEAT_HCX = 1 +endif diff --git a/make_helpers/defaults.mk b/make_helpers/defaults.mk index 910ffdf54..99f44a4ec 100644 --- a/make_helpers/defaults.mk +++ b/make_helpers/defaults.mk @@ -133,12 +133,18 @@ ENABLE_BTI := 0 # Use BRANCH_PROTECTION to enable PAUTH. ENABLE_PAUTH := 0 -# Flag to enable access to the HCRX_EL2 register by setting SCR_EL3.HXEn. -ENABLE_FEAT_HCX := 0 - # Flag to enable access to the HAFGRTR_EL2 register ENABLE_FEAT_AMUv1 := 0 +# Flag to enable AMUv1p1 extension. +ENABLE_FEAT_AMUv1p1 := 0 + +# Flag to enable CSV2_2 extension. +ENABLE_FEAT_CSV2_2 := 0 + +# Flag to enable access to the HCRX_EL2 register by setting SCR_EL3.HXEn. +ENABLE_FEAT_HCX := 0 + # Flag to enable access to the HDFGRTR_EL2 register ENABLE_FEAT_FGT := 0 @@ -148,6 +154,21 @@ ENABLE_FEAT_ECV := 0 # Flag to enable use of the DIT feature. ENABLE_FEAT_DIT := 0 +# Flag to enable access to Privileged Access Never bit of PSTATE. +ENABLE_FEAT_PAN := 0 + +# Flag to enable access to the Random Number Generator registers +ENABLE_FEAT_RNG := 0 + +# Flag to enable Speculation Barrier Instruction +ENABLE_FEAT_SB := 0 + +# Flag to enable Secure EL-2 feature. +ENABLE_FEAT_SEL2 := 0 + +# Flag to enable Virtualization Host Extensions +ENABLE_FEAT_VHE := 0 + # By default BL31 encryption disabled ENCRYPT_BL31 := 0 @@ -166,6 +187,9 @@ ERROR_DEPRECATED := 0 # Fault injection support FAULT_INJECTION_SUPPORT := 0 +# Flag to enable architectural features detection mechanism +FEATURE_DETECTION := 0 + # Byte alignment that each component in FIP is aligned to FIP_ALIGN := 0