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/docs/getting_started/build-options.rst b/docs/getting_started/build-options.rst index adc05e6dd..4dbf5cb9f 100644 --- a/docs/getting_started/build-options.rst +++ b/docs/getting_started/build-options.rst @@ -174,14 +174,23 @@ Common build options registers to be included when saving and restoring the CPU context. Default is 0. -- ``CTX_INCLUDE_NEVE_REGS``: Boolean option that, when set to 1, will cause the - Armv8.4-NV registers to be saved/restored when entering/exiting an EL2 - execution context. Default value is 0. +- ``CTX_INCLUDE_MTE_REGS``: Numeric value to include Memory Tagging Extension + registers in cpu context. This must be enabled, if the platform wants to use + this feature in the Secure world and MTE is enabled at ELX. This flag can + take values 0 to 2, to align with the ``FEATURE_DETECTION`` mechanism. + Default value is 0. + +- ``CTX_INCLUDE_NEVE_REGS``: Numeric value, when set will cause the Armv8.4-NV + registers to be saved/restored when entering/exiting an EL2 execution + context. This flag can take values 0 to 2, to align with the + ``FEATURE_DETECTION`` mechanism. Default value is 0. + +- ``CTX_INCLUDE_PAUTH_REGS``: Numeric value to enable the Pointer + Authentication for Secure world. This will cause the ARMv8.3-PAuth registers + to be included when saving and restoring the CPU context as part of world + switch. This flag can take values 0 to 2, to align with ``FEATURE_DETECTION`` + mechanism. Default value is 0. -- ``CTX_INCLUDE_PAUTH_REGS``: Boolean option that, when set to 1, enables - Pointer Authentication for Secure world. This will cause the ARMv8.3-PAuth - registers to be included when saving and restoring the CPU context as - part of world switch. Default value is 0. Note that Pointer Authentication is enabled for Non-secure world irrespective of the value of this flag if the CPU supports it. @@ -246,42 +255,101 @@ Common build options builds, but this behaviour can be overridden in each platform's Makefile or in the build command line. -- ``ENABLE_FEAT_AMUv1``: Boolean option to enable access to the HAFGRTR_EL2 +- ``ENABLE_FEAT_AMUv1``: Numeric value to enable access to the HAFGRTR_EL2 (Hypervisor Activity Monitors Fine-Grained Read Trap Register) during EL2 - to EL3 context save/restore operations. It is an optional feature available - on v8.4 and onwards and must be set to 1 alongside ``ENABLE_FEAT_FGT``, to - access the HAFGRTR_EL2 register. Defaults to ``0``. + to EL3 context save/restore operations. This flag can take the values 0 to 2, + to align with the ``FEATURE_DETECTION`` mechanism. It is an optional feature + available on v8.4 and onwards and must be set to either 1 or 2 alongside + ``ENABLE_FEAT_FGT``, to access the HAFGRTR_EL2 register. + Default value is ``0``. -- ``ENABLE_FEAT_ECV``: Boolean option to enable support for the Enhanced Counter +- ``ENABLE_FEAT_AMUv1p1``: Numeric value to enable the ``FEAT_AMUv1p1`` + extension. ``FEAT_AMUv1p1`` is an optional feature available on Arm v8.6 + onwards. This flag can take the values 0 to 2, to align with the + ``FEATURE_DETECTION`` mechanism. Default value is ``0``. + +- ``ENABLE_FEAT_CSV2_2``: Numeric value to enable the ``FEAT_CSV2_2`` + extension. It allows access to the SCXTNUM_EL2 (Software Context Number) + register during EL2 context save/restore operations. ``FEAT_CSV2_2`` is an + optional feature available on Arm v8.0 onwards. This flag can take values + 0 to 2, to align with the ``FEATURE_DETECTION`` mechanism. + Default value is ``0``. + +- ``ENABLE_FEAT_DIT``: Numeric value to enable ``FEAT_DIT`` (Data Independent + Timing) extension. It allows setting the ``DIT`` bit of PSTATE in EL3. + ``FEAT_DIT`` is a mandatory architectural feature and is enabled from v8.4 + and upwards. This flag can take the values 0 to 2, to align with the + ``FEATURE_DETECTION`` mechanism. Default value is ``0``. + +- ``ENABLE_FEAT_ECV``: Numeric value to enable support for the Enhanced Counter Virtualization feature, allowing for access to the CNTPOFF_EL2 (Counter-timer Physical Offset register) during EL2 to EL3 context save/restore operations. - Its a mandatory architectural feature in Armv8.6 and defaults to ``1`` for - v8.6 or later CPUs. + Its a mandatory architectural feature and is enabled from v8.6 and upwards. + This flag can take the values 0 to 2, to align with the ``FEATURE_DETECTION`` + mechanism. Default value is ``0``. -- ``ENABLE_FEAT_FGT``: Boolean option to enable support for FGT (Fine Grain Traps) +- ``ENABLE_FEAT_FGT``: Numeric value to enable support for FGT (Fine Grain Traps) feature allowing for access to the HDFGRTR_EL2 (Hypervisor Debug Fine-Grained - Read Trap Register) during EL2 to EL3 context save/restore operations. - Its a mandatory architectural feature in Armv8.6 and defaults to ``1`` for - v8.6 or later CPUs. + Read Trap Register) during EL2 to EL3 context save/restore operations. + Its a mandatory architectural feature and is enabled from v8.6 and upwards. + This flag can take the values 0 to 2, to align with the ``FEATURE_DETECTION`` + mechanism. Default value is ``0``. -- ``ENABLE_FEAT_HCX``: This option sets the bit SCR_EL3.HXEn in EL3 to allow - access to HCRX_EL2 (extended hypervisor control register) from EL2 as well as - adding HCRX_EL2 to the EL2 context save/restore operations. +- ``ENABLE_FEAT_HCX``: Numeric value to set the bit SCR_EL3.HXEn in EL3 to + allow access to HCRX_EL2 (extended hypervisor control register) from EL2 as + well as adding HCRX_EL2 to the EL2 context save/restore operations. Its a + mandatory architectural feature and is enabled from v8.7 and upwards. This + flag can take the values 0 to 2, to align with the ``FEATURE_DETECTION`` + mechanism. Default value is ``0``. + +- ``ENABLE_FEAT_PAN``: Numeric value to enable the ``FEAT_PAN`` (Privileged + Access Never) extension. ``FEAT_PAN`` adds a bit to PSTATE, generating a + permission fault for any privileged data access from EL1/EL2 to virtual + memory address, accessible at EL0, provided (HCR_EL2.E2H=1). It is a + mandatory architectural feature and is enabled from v8.1 and upwards. This + flag can take values 0 to 2, to align with the ``FEATURE_DETECTION`` + mechanism. Default value is ``0``. + +- ``ENABLE_FEAT_RNG``: Numeric value to enable the ``FEAT_RNG`` extension. + ``FEAT_RNG`` is an optional feature available on Arm v8.5 onwards. This + flag can take the values 0 to 2, to align with the ``FEATURE_DETECTION`` + mechanism. Default is ``0``. + +- ``ENABLE_FEAT_SB``: Numeric value to enable the ``FEAT_SB`` (Speculation + Barrier) extension allowing access to ``sb`` instruction. ``FEAT_SB`` is an + optional feature and defaults to ``0`` for pre-Armv8.5 CPUs but are mandatory + for Armv8.5 or later CPUs. This flag can take values 0 to 2, to align with + ``FEATURE_DETECTION`` mechanism. It is enabled from v8.5 and upwards and if + needed could be overidden from platforms explicitly. Default value is ``0``. + +- ``ENABLE_FEAT_SEL2``: Numeric value to enable the ``FEAT_SEL2`` (Secure EL2) + extension. ``FEAT_SEL2`` is a mandatory feature available on Arm v8.4. + This flag can take values 0 to 2, to align with the ``FEATURE_DETECTION`` + mechanism. Default is ``0``. + +- ``ENABLE_FEAT_VHE``: Numeric value to enable the ``FEAT_VHE`` (Virtualization + Host Extensions) extension. It allows access to CONTEXTIDR_EL2 register + during EL2 context save/restore operations.``FEAT_VHE`` is a mandatory + architectural feature and is enabled from v8.1 and upwards. It can take + values 0 to 2, to align with the ``FEATURE_DETECTION`` mechanism. + Default value is ``0``. - ``ENABLE_LTO``: Boolean option to enable Link Time Optimization (LTO) support in GCC for TF-A. This option is currently only supported for AArch64. Default is 0. -- ``ENABLE_MPAM_FOR_LOWER_ELS``: Boolean option to enable lower ELs to use MPAM +- ``ENABLE_MPAM_FOR_LOWER_ELS``: Numeric value to enable lower ELs to use MPAM feature. MPAM is an optional Armv8.4 extension that enables various memory system components and resources to define partitions; software running at various ELs can assign themselves to desired partition to control their performance aspects. - When this option is set to ``1``, EL3 allows lower ELs to access their own - MPAM registers without trapping into EL3. This option doesn't make use of - partitioning in EL3, however. Platform initialisation code should configure - and use partitions in EL3 as required. This option defaults to ``0``. + This flag can take values 0 to 2, to align with the ``FEATURE_DETECTION`` + mechanism. When this option is set to ``1`` or ``2``, EL3 allows lower ELs to + access their own MPAM registers without trapping into EL3. This option + doesn't make use of partitioning in EL3, however. Platform initialisation + code should configure and use partitions in EL3 as required. This option + defaults to ``0``. - ``ENABLE_MPMM``: Boolean option to enable support for the Maximum Power Mitigation Mechanism supported by certain Arm cores, which allows the SoC @@ -307,9 +375,10 @@ Common build options be enabled. If ``ENABLE_PMF`` is set, the residency statistics are tracked in software. -- ``ENABLE_RME``: Boolean option to enable support for the ARMv9 Realm - Management Extension. Default value is 0. This is currently an experimental - feature. +- ``ENABLE_RME``: Numeric value to enable support for the ARMv9 Realm + Management Extension. This flag can take the values 0 to 2, to align with + the ``FEATURE_DETECTION`` mechanism. Default value is 0. This is currently + an experimental feature. - ``ENABLE_RUNTIME_INSTRUMENTATION``: Boolean option to enable runtime instrumentation which injects timestamp collection points into TF-A to @@ -352,8 +421,8 @@ Common build options - ``ENABLE_SVE_FOR_SWD``: Boolean option to enable SVE for the Secure world. SVE is an optional architectural feature for AArch64. Note that this option - requires ENABLE_SVE_FOR_NS to be enabled. The default is 0 and it is - automatically disabled when the target architecture is AArch32. + requires ENABLE_SVE_FOR_NS to be enabled. The default is 0 and it + is automatically disabled when the target architecture is AArch32. - ``ENABLE_STACK_PROTECTOR``: String option to enable the stack protection checks in GCC. Allowed values are "all", "strong", "default" and "none". The @@ -399,6 +468,43 @@ Common build options This feature is intended for testing purposes only, and is advisable to keep disabled for production images. +- ``FEATURE_DETECTION``: Boolean option to enable the architectural features + detection mechanism. It detects whether the Architectural features enabled + through feature specific build flags are supported by the PE or not by + validating them either at boot phase or at runtime based on the value + possessed by the feature flag (0 to 2) and report error messages at an early + stage. + + This prevents and benefits us from EL3 runtime exceptions during context save + and restore routines guarded by these build flags. Henceforth validating them + before their usage provides more control on the actions taken under them. + + The mechanism permits the build flags to take values 0, 1 or 2 and + evaluates them accordingly. + + Lets consider ``ENABLE_FEAT_HCX``, build flag for ``FEAT_HCX`` as an example: + + :: + + ENABLE_FEAT_HCX = 0: Feature disabled statically at compile time. + ENABLE_FEAT_HCX = 1: Feature Enabled and the flag is validated at boottime. + ENABLE_FEAT_HCX = 2: Feature Enabled and the flag is validated at runtime. + + In the above example, if the feature build flag, ``ENABLE_FEAT_HCX`` set to + 0, feature is disabled statically during compilation. If it is defined as 1, + feature is validated, wherein FEAT_HCX is detected at boot time. In case not + implemented by the PE, a hard panic is generated. Finally, if the flag is set + to 2, feature is validated at runtime. + + Note that the entire implementation is divided into two phases, wherein as + as part of phase-1 we are supporting the values 0,1. Value 2 is currently not + supported and is planned to be handled explicilty in phase-2 implementation. + + FEATURE_DETECTION macro is disabled by default, and is currently an + experimental procedure. Platforms can explicitly make use of this by + mechanism, by enabling it to validate whether they have set their build flags + properly at an early phase. + - ``FIP_NAME``: This is an optional build option which specifies the FIP filename for the ``fip`` target. Default is ``fip.bin``. @@ -588,9 +694,10 @@ Common build options enabled on Arm platforms, the option ``ARM_RECOM_STATE_ID_ENC`` needs to be set to 1 as well. -- ``RAS_EXTENSION``: When set to ``1``, enable Armv8.2 RAS features. RAS features +- ``RAS_EXTENSION``: Numeric value to enable Armv8.2 RAS features. RAS features are an optional extension for pre-Armv8.2 CPUs, but are mandatory for Armv8.2 - or later CPUs. + or later CPUs. This flag can take the values 0 to 2, to align with the + ``FEATURE_DETECTION`` mechanism. When ``RAS_EXTENSION`` is set to ``1``, ``HANDLE_EA_EL3_FIRST`` must also be set to ``1``. @@ -673,7 +780,7 @@ Common build options firmware images have been loaded in memory, and the MMU and caches are turned off. Refer to the "Debugging options" section for more details. -- ``SPMD_SPM_AT_SEL2`` : this boolean option is used jointly with the SPM +- ``SPMD_SPM_AT_SEL2`` : This boolean option is used jointly with the SPM Dispatcher option (``SPD=spmd``). When enabled (1) it indicates the SPMC component runs at the S-EL2 execution state provided by the Armv8.4-SecEL2 extension. This is the default when enabling the SPM Dispatcher. When @@ -851,9 +958,10 @@ Common build options but unused). This feature is available if trace unit such as ETMv4.x, and ETE(extending ETM feature) is implemented. This flag is disabled by default. -- ``ENABLE_TRF_FOR_NS``: Boolean option to enable trace filter control registers +- ``ENABLE_TRF_FOR_NS``: Numeric value to enable trace filter control registers access from NS ELs, NS-EL2 or NS-EL1 (when NS-EL2 is implemented but unused), - if FEAT_TRF is implemented. This flag is disabled by default. + if FEAT_TRF is implemented. This flag can take the values 0 to 2, to align + with the ``FEATURE_DETECTION`` mechanism. This flag is disabled by default. GICv3 driver options -------------------- 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/include/lib/el3_runtime/aarch64/context.h b/include/lib/el3_runtime/aarch64/context.h index 512d19671..d2d12e51d 100644 --- a/include/lib/el3_runtime/aarch64/context.h +++ b/include/lib/el3_runtime/aarch64/context.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. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -217,13 +217,13 @@ // Starting with Armv8.4 #define CTX_CONTEXTIDR_EL2 U(0x198) -#define CTX_SDER32_EL2 U(0x1a0) -#define CTX_TTBR1_EL2 U(0x1a8) -#define CTX_VDISR_EL2 U(0x1b0) -#define CTX_VNCR_EL2 U(0x1b8) -#define CTX_VSESR_EL2 U(0x1c0) -#define CTX_VSTCR_EL2 U(0x1c8) -#define CTX_VSTTBR_EL2 U(0x1d0) +#define CTX_TTBR1_EL2 U(0x1a0) +#define CTX_VDISR_EL2 U(0x1a8) +#define CTX_VSESR_EL2 U(0x1b0) +#define CTX_VSTCR_EL2 U(0x1b8) +#define CTX_VSTTBR_EL2 U(0x1c0) +#define CTX_SDER32_EL2 U(0x1c8) +#define CTX_VNCR_EL2 U(0x1d0) #define CTX_TRFCR_EL2 U(0x1d8) // Starting with Armv8.5 diff --git a/lib/el3_runtime/aarch64/context.S b/lib/el3_runtime/aarch64/context.S index c1c061237..0432d96b1 100644 --- a/lib/el3_runtime/aarch64/context.S +++ b/lib/el3_runtime/aarch64/context.S @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2022, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2013-2022, Arm Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -13,14 +13,14 @@ #if CTX_INCLUDE_EL2_REGS .global el2_sysregs_context_save .global el2_sysregs_context_restore -#endif +#endif /* CTX_INCLUDE_EL2_REGS */ .global el1_sysregs_context_save .global el1_sysregs_context_restore #if CTX_INCLUDE_FPREGS .global fpregs_context_save .global fpregs_context_restore -#endif +#endif /* CTX_INCLUDE_FPREGS */ .global prepare_el3_entry .global restore_gp_pmcr_pauth_regs .global save_and_update_ptw_el1_sys_regs @@ -62,7 +62,7 @@ func el2_sysregs_context_save #if CTX_INCLUDE_AARCH32_REGS mrs x16, dbgvcr32_el2 str x16, [x0, #CTX_DBGVCR32_EL2] -#endif +#endif /* CTX_INCLUDE_AARCH32_REGS */ mrs x9, elr_el2 mrs x10, esr_el2 @@ -91,7 +91,8 @@ func el2_sysregs_context_save #if ENABLE_SPE_FOR_LOWER_ELS mrs x13, PMSCR_EL2 str x13, [x0, #CTX_PMSCR_EL2] -#endif +#endif /* ENABLE_SPE_FOR_LOWER_ELS */ + mrs x14, sctlr_el2 str x14, [x0, #CTX_SCTLR_EL2] @@ -118,7 +119,7 @@ func el2_sysregs_context_save #if CTX_INCLUDE_MTE_REGS mrs x9, TFSR_EL2 str x9, [x0, #CTX_TFSR_EL2] -#endif +#endif /* CTX_INCLUDE_MTE_REGS */ #if ENABLE_MPAM_FOR_LOWER_ELS mrs x10, MPAM2_EL2 @@ -143,7 +144,7 @@ func el2_sysregs_context_save mrs x11, MPAMVPM7_EL2 mrs x12, MPAMVPMV_EL2 stp x11, x12, [x0, #CTX_MPAMVPM7_EL2] -#endif +#endif /* ENABLE_MPAM_FOR_LOWER_ELS */ #if ENABLE_FEAT_FGT mrs x13, HDFGRTR_EL2 @@ -152,7 +153,7 @@ func el2_sysregs_context_save stp x13, x14, [x0, #CTX_HDFGRTR_EL2] #else str x13, [x0, #CTX_HDFGRTR_EL2] -#endif +#endif /* ENABLE_FEAT_AMUv1 */ mrs x15, HDFGWTR_EL2 mrs x16, HFGITR_EL2 stp x15, x16, [x0, #CTX_HDFGWTR_EL2] @@ -160,48 +161,80 @@ func el2_sysregs_context_save mrs x9, HFGRTR_EL2 mrs x10, HFGWTR_EL2 stp x9, x10, [x0, #CTX_HFGRTR_EL2] -#endif +#endif /* ENABLE_FEAT_FGT */ #if ENABLE_FEAT_ECV mrs x11, CNTPOFF_EL2 str x11, [x0, #CTX_CNTPOFF_EL2] -#endif +#endif /* ENABLE_FEAT_ECV */ -#if ARM_ARCH_AT_LEAST(8, 4) - mrs x12, contextidr_el2 - str x12, [x0, #CTX_CONTEXTIDR_EL2] +#if ENABLE_FEAT_VHE + /* + * CONTEXTIDR_EL2 register is saved only when FEAT_VHE or + * FEAT_Debugv8p2 (currently not in TF-A) is supported. + */ + mrs x9, contextidr_el2 + mrs x10, ttbr1_el2 + stp x9, x10, [x0, #CTX_CONTEXTIDR_EL2] +#endif /* ENABLE_FEAT_VHE */ -#if CTX_INCLUDE_AARCH32_REGS - mrs x13, sder32_el2 - str x13, [x0, #CTX_SDER32_EL2] -#endif - mrs x14, ttbr1_el2 - mrs x15, vdisr_el2 - stp x14, x15, [x0, #CTX_TTBR1_EL2] +#if RAS_EXTENSION + /* + * VDISR_EL2 and VSESR_EL2 registers are saved only when + * FEAT_RAS is supported. + */ + mrs x11, vdisr_el2 + mrs x12, vsesr_el2 + stp x11, x12, [x0, #CTX_VDISR_EL2] +#endif /* RAS_EXTENSION */ + +#if ENABLE_FEAT_SEL2 + /* + * VSTCR_EL2 and VSTTBR_EL2 registers are saved only + * when FEAT_SEL2 is supported. + */ + mrs x13, vstcr_el2 + mrs x14, vsttbr_el2 + stp x13, x14, [x0, #CTX_VSTCR_EL2] +#endif /* ENABLE_FEAT_SEL2 */ + +#if CTX_INCLUDE_AARCH32_REGS && ENABLE_FEAT_SEL2 + /* + * SDER32_EL2 register is saved only when EL2 and EL1 + * capable of using Aarch32 and FEAT_SEL2 is supported. + */ + mrs x15, sder32_el2 + str x15, [x0, #CTX_SDER32_EL2] +#endif /* CTX_INCLUDE_AARCH32_REGS && ENABLE_FEAT_SEL2 */ #if CTX_INCLUDE_NEVE_REGS + /* + * VNCR_EL2 register is saved only when FEAT_NV2 is supported. + */ mrs x16, vncr_el2 str x16, [x0, #CTX_VNCR_EL2] -#endif +#endif /* CTX_INCLUDE_NEVE_REGS */ - mrs x9, vsesr_el2 - mrs x10, vstcr_el2 - stp x9, x10, [x0, #CTX_VSESR_EL2] - - mrs x11, vsttbr_el2 +#if ENABLE_TRF_FOR_NS + /* + * TRFCR_EL2 register is saved only when FEAT_TRF is supported. + */ mrs x12, TRFCR_EL2 - stp x11, x12, [x0, #CTX_VSTTBR_EL2] -#endif + str x12, [x0, #CTX_TRFCR_EL2] +#endif /* ENABLE_TRF_FOR_NS */ -#if ARM_ARCH_AT_LEAST(8, 5) +#if ENABLE_FEAT_CSV2_2 + /* + * SCXTNUM_EL2 register is saved only when FEAT_CSV2_2 is supported. + */ mrs x13, scxtnum_el2 str x13, [x0, #CTX_SCXTNUM_EL2] -#endif +#endif /* ENABLE_FEAT_CSV2_2 */ #if ENABLE_FEAT_HCX mrs x14, hcrx_el2 str x14, [x0, #CTX_HCRX_EL2] -#endif +#endif /* ENABLE_FEAT_HCX */ ret endfunc el2_sysregs_context_save @@ -241,7 +274,7 @@ func el2_sysregs_context_restore #if CTX_INCLUDE_AARCH32_REGS ldr x16, [x0, #CTX_DBGVCR32_EL2] msr dbgvcr32_el2, x16 -#endif +#endif /* CTX_INCLUDE_AARCH32_REGS */ ldp x9, x10, [x0, #CTX_ELR_EL2] msr elr_el2, x9 @@ -270,7 +303,8 @@ func el2_sysregs_context_restore #if ENABLE_SPE_FOR_LOWER_ELS ldr x13, [x0, #CTX_PMSCR_EL2] msr PMSCR_EL2, x13 -#endif +#endif /* ENABLE_SPE_FOR_LOWER_ELS */ + ldr x14, [x0, #CTX_SCTLR_EL2] msr sctlr_el2, x14 @@ -297,7 +331,7 @@ func el2_sysregs_context_restore #if CTX_INCLUDE_MTE_REGS ldr x9, [x0, #CTX_TFSR_EL2] msr TFSR_EL2, x9 -#endif +#endif /* CTX_INCLUDE_MTE_REGS */ #if ENABLE_MPAM_FOR_LOWER_ELS ldr x10, [x0, #CTX_MPAM2_EL2] @@ -322,7 +356,7 @@ func el2_sysregs_context_restore ldp x11, x12, [x0, #CTX_MPAMVPM7_EL2] msr MPAMVPM7_EL2, x11 msr MPAMVPMV_EL2, x12 -#endif +#endif /* ENABLE_MPAM_FOR_LOWER_ELS */ #if ENABLE_FEAT_FGT #if ENABLE_FEAT_AMUv1 @@ -330,7 +364,7 @@ func el2_sysregs_context_restore msr HAFGRTR_EL2, x14 #else ldr x13, [x0, #CTX_HDFGRTR_EL2] -#endif +#endif /* ENABLE_FEAT_AMUv1 */ msr HDFGRTR_EL2, x13 ldp x15, x16, [x0, #CTX_HDFGWTR_EL2] @@ -340,48 +374,80 @@ func el2_sysregs_context_restore ldp x9, x10, [x0, #CTX_HFGRTR_EL2] msr HFGRTR_EL2, x9 msr HFGWTR_EL2, x10 -#endif +#endif /* ENABLE_FEAT_FGT */ #if ENABLE_FEAT_ECV ldr x11, [x0, #CTX_CNTPOFF_EL2] msr CNTPOFF_EL2, x11 -#endif +#endif /* ENABLE_FEAT_ECV */ -#if ARM_ARCH_AT_LEAST(8, 4) - ldr x12, [x0, #CTX_CONTEXTIDR_EL2] - msr contextidr_el2, x12 +#if ENABLE_FEAT_VHE + /* + * CONTEXTIDR_EL2 register is restored only when FEAT_VHE or + * FEAT_Debugv8p2 (currently not in TF-A) is supported. + */ + ldp x9, x10, [x0, #CTX_CONTEXTIDR_EL2] + msr contextidr_el2, x9 + msr ttbr1_el2, x10 +#endif /* ENABLE_FEAT_VHE */ -#if CTX_INCLUDE_AARCH32_REGS - ldr x13, [x0, #CTX_SDER32_EL2] - msr sder32_el2, x13 -#endif - ldp x14, x15, [x0, #CTX_TTBR1_EL2] - msr ttbr1_el2, x14 - msr vdisr_el2, x15 +#if RAS_EXTENSION + /* + * VDISR_EL2 and VSESR_EL2 registers are restored only when FEAT_RAS + * is supported. + */ + ldp x11, x12, [x0, #CTX_VDISR_EL2] + msr vdisr_el2, x11 + msr vsesr_el2, x12 +#endif /* RAS_EXTENSION */ + +#if ENABLE_FEAT_SEL2 + /* + * VSTCR_EL2 and VSTTBR_EL2 registers are restored only when FEAT_SEL2 + * is supported. + */ + ldp x13, x14, [x0, #CTX_VSTCR_EL2] + msr vstcr_el2, x13 + msr vsttbr_el2, x14 +#endif /* ENABLE_FEAT_SEL2 */ + +#if CTX_INCLUDE_AARCH32_REGS && ENABLE_FEAT_SEL2 + /* + * SDER32_EL2 register is restored only when EL2 and EL1 capable of using + * Aarch32 and FEAT_SEL2 is supported. + */ + ldr x15, [x0, #CTX_SDER32_EL2] + msr sder32_el2, x15 +#endif /* CTX_INCLUDE_AARCH32_REGS && ENABLE_FEAT_SEL2 */ #if CTX_INCLUDE_NEVE_REGS + /* + * VNCR_EL2 register is restored only when FEAT_NV2 is supported. + */ ldr x16, [x0, #CTX_VNCR_EL2] msr vncr_el2, x16 -#endif +#endif /* CTX_INCLUDE_NEVE_REGS */ - ldp x9, x10, [x0, #CTX_VSESR_EL2] - msr vsesr_el2, x9 - msr vstcr_el2, x10 - - ldp x11, x12, [x0, #CTX_VSTTBR_EL2] - msr vsttbr_el2, x11 +#if ENABLE_TRF_FOR_NS + /* + * TRFCR_EL2 register is restored only when FEAT_TRF is supported. + */ + ldr x12, [x0, #CTX_TRFCR_EL2] msr TRFCR_EL2, x12 -#endif +#endif /* ENABLE_TRF_FOR_NS */ -#if ARM_ARCH_AT_LEAST(8, 5) +#if ENABLE_FEAT_CSV2_2 + /* + * SCXTNUM_EL2 register is restored only when FEAT_CSV2_2 is supported. + */ ldr x13, [x0, #CTX_SCXTNUM_EL2] msr scxtnum_el2, x13 -#endif +#endif /* ENABLE_FEAT_CSV2_2 */ #if ENABLE_FEAT_HCX ldr x14, [x0, #CTX_HCRX_EL2] msr hcrx_el2, x14 -#endif +#endif /* ENABLE_FEAT_HCX */ ret endfunc el2_sysregs_context_restore @@ -405,7 +471,7 @@ func el1_sysregs_context_save mrs x15, sctlr_el1 mrs x16, tcr_el1 stp x15, x16, [x0, #CTX_SCTLR_EL1] -#endif +#endif /* ERRATA_SPECULATIVE_AT */ mrs x17, cpacr_el1 mrs x9, csselr_el1 @@ -456,7 +522,7 @@ func el1_sysregs_context_save mrs x15, dacr32_el2 mrs x16, ifsr32_el2 stp x15, x16, [x0, #CTX_DACR32_EL2] -#endif +#endif /* CTX_INCLUDE_AARCH32_REGS */ /* Save NS timer registers if the build has instructed so */ #if NS_TIMER_SWITCH @@ -470,7 +536,7 @@ func el1_sysregs_context_save mrs x14, cntkctl_el1 str x14, [x0, #CTX_CNTKCTL_EL1] -#endif +#endif /* NS_TIMER_SWITCH */ /* Save MTE system registers if the build has instructed so */ #if CTX_INCLUDE_MTE_REGS @@ -481,7 +547,7 @@ func el1_sysregs_context_save mrs x9, RGSR_EL1 mrs x10, GCR_EL1 stp x9, x10, [x0, #CTX_RGSR_EL1] -#endif +#endif /* CTX_INCLUDE_MTE_REGS */ ret endfunc el1_sysregs_context_save @@ -504,7 +570,7 @@ func el1_sysregs_context_restore ldp x15, x16, [x0, #CTX_SCTLR_EL1] msr sctlr_el1, x15 msr tcr_el1, x16 -#endif +#endif /* ERRATA_SPECULATIVE_AT */ ldp x17, x9, [x0, #CTX_CPACR_EL1] msr cpacr_el1, x17 @@ -555,7 +621,8 @@ func el1_sysregs_context_restore ldp x15, x16, [x0, #CTX_DACR32_EL2] msr dacr32_el2, x15 msr ifsr32_el2, x16 -#endif +#endif /* CTX_INCLUDE_AARCH32_REGS */ + /* Restore NS timer registers if the build has instructed so */ #if NS_TIMER_SWITCH ldp x10, x11, [x0, #CTX_CNTP_CTL_EL0] @@ -568,7 +635,8 @@ func el1_sysregs_context_restore ldr x14, [x0, #CTX_CNTKCTL_EL1] msr cntkctl_el1, x14 -#endif +#endif /* NS_TIMER_SWITCH */ + /* Restore MTE system registers if the build has instructed so */ #if CTX_INCLUDE_MTE_REGS ldp x11, x12, [x0, #CTX_TFSRE0_EL1] @@ -578,7 +646,7 @@ func el1_sysregs_context_restore ldp x13, x14, [x0, #CTX_RGSR_EL1] msr RGSR_EL1, x13 msr GCR_EL1, x14 -#endif +#endif /* CTX_INCLUDE_MTE_REGS */ /* No explict ISB required here as ERET covers it */ ret @@ -626,7 +694,7 @@ func fpregs_context_save #if CTX_INCLUDE_AARCH32_REGS mrs x11, fpexc32_el2 str x11, [x0, #CTX_FP_FPEXC32_EL2] -#endif +#endif /* CTX_INCLUDE_AARCH32_REGS */ ret endfunc fpregs_context_save @@ -671,7 +739,8 @@ func fpregs_context_restore #if CTX_INCLUDE_AARCH32_REGS ldr x11, [x0, #CTX_FP_FPEXC32_EL2] msr fpexc32_el2, x11 -#endif +#endif /* CTX_INCLUDE_AARCH32_REGS */ + /* * No explict ISB required here as ERET to * switch to secure EL1 or non-secure world @@ -688,13 +757,13 @@ endfunc fpregs_context_restore * in ARM DDI 0487F.c page J1-7635 to a default value. */ .macro set_unset_pstate_bits - /* - * If Data Independent Timing (DIT) functionality is implemented, - * always enable DIT in EL3 - */ + /* + * If Data Independent Timing (DIT) functionality is implemented, + * always enable DIT in EL3 + */ #if ENABLE_FEAT_DIT - mov x8, #DIT_BIT - msr DIT, x8 + mov x8, #DIT_BIT + msr DIT, x8 #endif /* ENABLE_FEAT_DIT */ .endm /* set_unset_pstate_bits */ @@ -933,7 +1002,7 @@ func el3_exit mrs x17, spsel cmp x17, #MODE_SP_EL0 ASM_ASSERT(eq) -#endif +#endif /* ENABLE_ASSERTIONS */ /* ---------------------------------------------------------- * Save the current SP_EL0 i.e. the EL3 runtime stack which @@ -971,7 +1040,7 @@ func el3_exit isb msr S3_6_C1_C2_0, x20 /* zcr_el3 */ sve_not_enabled: -#endif +#endif /* IMAGE_BL31 */ #if IMAGE_BL31 && DYNAMIC_WORKAROUND_CVE_2018_3639 /* ---------------------------------------------------------- @@ -982,7 +1051,8 @@ sve_not_enabled: cbz x17, 1f blr x17 1: -#endif +#endif /* IMAGE_BL31 && DYNAMIC_WORKAROUND_CVE_2018_3639 */ + restore_ptw_el1_sys_regs /* ---------------------------------------------------------- @@ -1005,10 +1075,12 @@ sve_not_enabled: esb #else dsb sy -#endif +#endif /* IMAGE_BL31 && RAS_EXTENSION */ + #ifdef IMAGE_BL31 str xzr, [sp, #CTX_EL3STATE_OFFSET + CTX_IS_IN_EL3] -#endif +#endif /* IMAGE_BL31 */ + exception_return endfunc el3_exit 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