1*6a0da736SJayanth Dodderi Chidanand /* 2*6a0da736SJayanth Dodderi Chidanand * Copyright (c) 2022, Arm Limited and Contributors. All rights reserved. 3*6a0da736SJayanth Dodderi Chidanand * 4*6a0da736SJayanth Dodderi Chidanand * SPDX-License-Identifier: BSD-3-Clause 5*6a0da736SJayanth Dodderi Chidanand */ 6*6a0da736SJayanth Dodderi Chidanand 7*6a0da736SJayanth Dodderi Chidanand #include <common/feat_detect.h> 8*6a0da736SJayanth Dodderi Chidanand 9*6a0da736SJayanth Dodderi Chidanand /******************************************************************************* 10*6a0da736SJayanth Dodderi Chidanand * This section lists the wrapper modules for each feature to evaluate the 11*6a0da736SJayanth Dodderi Chidanand * feature states (FEAT_STATE_1 and FEAT_STATE_2) and perform necessary action 12*6a0da736SJayanth Dodderi Chidanand * as below: 13*6a0da736SJayanth Dodderi Chidanand * 14*6a0da736SJayanth Dodderi Chidanand * It verifies whether the FEAT_XXX (eg: FEAT_SB) is supported by the PE or not. 15*6a0da736SJayanth Dodderi Chidanand * Without this check an exception would occur during context save/restore 16*6a0da736SJayanth Dodderi Chidanand * routines, if the feature is enabled but not supported by PE. 17*6a0da736SJayanth Dodderi Chidanand ******************************************************************************/ 18*6a0da736SJayanth Dodderi Chidanand 19*6a0da736SJayanth Dodderi Chidanand /****************************************** 20*6a0da736SJayanth Dodderi Chidanand * Feature : FEAT_SB (Speculation Barrier) 21*6a0da736SJayanth Dodderi Chidanand *****************************************/ 22*6a0da736SJayanth Dodderi Chidanand static void read_feat_sb(void) 23*6a0da736SJayanth Dodderi Chidanand { 24*6a0da736SJayanth Dodderi Chidanand #if (ENABLE_FEAT_SB == FEAT_STATE_1) 25*6a0da736SJayanth Dodderi Chidanand feat_detect_panic(is_armv8_0_feat_sb_present(), "SB"); 26*6a0da736SJayanth Dodderi Chidanand #endif 27*6a0da736SJayanth Dodderi Chidanand } 28*6a0da736SJayanth Dodderi Chidanand 29*6a0da736SJayanth Dodderi Chidanand /****************************************************** 30*6a0da736SJayanth Dodderi Chidanand * Feature : FEAT_CSV2_2 (Cache Speculation Variant 2) 31*6a0da736SJayanth Dodderi Chidanand *****************************************************/ 32*6a0da736SJayanth Dodderi Chidanand static void read_feat_csv2_2(void) 33*6a0da736SJayanth Dodderi Chidanand { 34*6a0da736SJayanth Dodderi Chidanand #if (ENABLE_FEAT_CSV2_2 == FEAT_STATE_1) 35*6a0da736SJayanth Dodderi Chidanand feat_detect_panic(is_armv8_0_feat_csv2_2_present(), "CSV2_2"); 36*6a0da736SJayanth Dodderi Chidanand #endif 37*6a0da736SJayanth Dodderi Chidanand } 38*6a0da736SJayanth Dodderi Chidanand 39*6a0da736SJayanth Dodderi Chidanand /*********************************************** 40*6a0da736SJayanth Dodderi Chidanand * Feature : FEAT_PAN (Privileged Access Never) 41*6a0da736SJayanth Dodderi Chidanand **********************************************/ 42*6a0da736SJayanth Dodderi Chidanand static void read_feat_pan(void) 43*6a0da736SJayanth Dodderi Chidanand { 44*6a0da736SJayanth Dodderi Chidanand #if (ENABLE_FEAT_PAN == FEAT_STATE_1) 45*6a0da736SJayanth Dodderi Chidanand feat_detect_panic(is_armv8_1_pan_present(), "PAN"); 46*6a0da736SJayanth Dodderi Chidanand #endif 47*6a0da736SJayanth Dodderi Chidanand } 48*6a0da736SJayanth Dodderi Chidanand 49*6a0da736SJayanth Dodderi Chidanand /****************************************************** 50*6a0da736SJayanth Dodderi Chidanand * Feature : FEAT_VHE (Virtualization Host Extensions) 51*6a0da736SJayanth Dodderi Chidanand *****************************************************/ 52*6a0da736SJayanth Dodderi Chidanand static void read_feat_vhe(void) 53*6a0da736SJayanth Dodderi Chidanand { 54*6a0da736SJayanth Dodderi Chidanand #if (ENABLE_FEAT_VHE == FEAT_STATE_1) 55*6a0da736SJayanth Dodderi Chidanand feat_detect_panic(is_armv8_1_vhe_present(), "VHE"); 56*6a0da736SJayanth Dodderi Chidanand #endif 57*6a0da736SJayanth Dodderi Chidanand } 58*6a0da736SJayanth Dodderi Chidanand 59*6a0da736SJayanth Dodderi Chidanand /******************************************************************************* 60*6a0da736SJayanth Dodderi Chidanand * Feature : FEAT_RAS (Reliability, Availability, and Serviceability Extension) 61*6a0da736SJayanth Dodderi Chidanand ******************************************************************************/ 62*6a0da736SJayanth Dodderi Chidanand static void read_feat_ras(void) 63*6a0da736SJayanth Dodderi Chidanand { 64*6a0da736SJayanth Dodderi Chidanand #if (RAS_EXTENSION == FEAT_STATE_1) 65*6a0da736SJayanth Dodderi Chidanand feat_detect_panic(is_armv8_2_feat_ras_present(), "RAS"); 66*6a0da736SJayanth Dodderi Chidanand #endif 67*6a0da736SJayanth Dodderi Chidanand } 68*6a0da736SJayanth Dodderi Chidanand 69*6a0da736SJayanth Dodderi Chidanand /************************************************ 70*6a0da736SJayanth Dodderi Chidanand * Feature : FEAT_PAUTH (Pointer Authentication) 71*6a0da736SJayanth Dodderi Chidanand ***********************************************/ 72*6a0da736SJayanth Dodderi Chidanand static void read_feat_pauth(void) 73*6a0da736SJayanth Dodderi Chidanand { 74*6a0da736SJayanth Dodderi Chidanand #if (ENABLE_PAUTH == FEAT_STATE_1) || (CTX_INCLUDE_PAUTH_REGS == FEAT_STATE_1) 75*6a0da736SJayanth Dodderi Chidanand feat_detect_panic(is_armv8_3_pauth_present(), "PAUTH"); 76*6a0da736SJayanth Dodderi Chidanand #endif 77*6a0da736SJayanth Dodderi Chidanand } 78*6a0da736SJayanth Dodderi Chidanand 79*6a0da736SJayanth Dodderi Chidanand /************************************************************ 80*6a0da736SJayanth Dodderi Chidanand * Feature : FEAT_DIT (Data Independent Timing Instructions) 81*6a0da736SJayanth Dodderi Chidanand ***********************************************************/ 82*6a0da736SJayanth Dodderi Chidanand static void read_feat_dit(void) 83*6a0da736SJayanth Dodderi Chidanand { 84*6a0da736SJayanth Dodderi Chidanand #if (ENABLE_FEAT_DIT == FEAT_STATE_1) 85*6a0da736SJayanth Dodderi Chidanand feat_detect_panic(is_armv8_4_feat_dit_present(), "DIT"); 86*6a0da736SJayanth Dodderi Chidanand #endif 87*6a0da736SJayanth Dodderi Chidanand } 88*6a0da736SJayanth Dodderi Chidanand 89*6a0da736SJayanth Dodderi Chidanand /********************************************************* 90*6a0da736SJayanth Dodderi Chidanand * Feature : FEAT_AMUv1 (Activity Monitors Extensions v1) 91*6a0da736SJayanth Dodderi Chidanand ********************************************************/ 92*6a0da736SJayanth Dodderi Chidanand static void read_feat_amuv1(void) 93*6a0da736SJayanth Dodderi Chidanand { 94*6a0da736SJayanth Dodderi Chidanand #if (ENABLE_FEAT_AMUv1 == FEAT_STATE_1) 95*6a0da736SJayanth Dodderi Chidanand feat_detect_panic(is_armv8_4_feat_amuv1_present(), "AMUv1"); 96*6a0da736SJayanth Dodderi Chidanand #endif 97*6a0da736SJayanth Dodderi Chidanand } 98*6a0da736SJayanth Dodderi Chidanand 99*6a0da736SJayanth Dodderi Chidanand /**************************************************************************** 100*6a0da736SJayanth Dodderi Chidanand * Feature : FEAT_MPAM (Memory Partitioning and Monitoring (MPAM) Extension) 101*6a0da736SJayanth Dodderi Chidanand ***************************************************************************/ 102*6a0da736SJayanth Dodderi Chidanand static void read_feat_mpam(void) 103*6a0da736SJayanth Dodderi Chidanand { 104*6a0da736SJayanth Dodderi Chidanand #if (ENABLE_MPAM_FOR_LOWER_ELS == FEAT_STATE_1) 105*6a0da736SJayanth Dodderi Chidanand feat_detect_panic(get_mpam_version() != 0U, "MPAM"); 106*6a0da736SJayanth Dodderi Chidanand #endif 107*6a0da736SJayanth Dodderi Chidanand } 108*6a0da736SJayanth Dodderi Chidanand 109*6a0da736SJayanth Dodderi Chidanand /************************************************************** 110*6a0da736SJayanth Dodderi Chidanand * Feature : FEAT_NV2 (Enhanced Nested Virtualization Support) 111*6a0da736SJayanth Dodderi Chidanand *************************************************************/ 112*6a0da736SJayanth Dodderi Chidanand static void read_feat_nv2(void) 113*6a0da736SJayanth Dodderi Chidanand { 114*6a0da736SJayanth Dodderi Chidanand #if (CTX_INCLUDE_NEVE_REGS == FEAT_STATE_1) 115*6a0da736SJayanth Dodderi Chidanand unsigned int nv = get_armv8_4_feat_nv_support(); 116*6a0da736SJayanth Dodderi Chidanand 117*6a0da736SJayanth Dodderi Chidanand feat_detect_panic((nv == ID_AA64MMFR2_EL1_NV2_SUPPORTED), "NV2"); 118*6a0da736SJayanth Dodderi Chidanand #endif 119*6a0da736SJayanth Dodderi Chidanand } 120*6a0da736SJayanth Dodderi Chidanand 121*6a0da736SJayanth Dodderi Chidanand /*********************************** 122*6a0da736SJayanth Dodderi Chidanand * Feature : FEAT_SEL2 (Secure EL2) 123*6a0da736SJayanth Dodderi Chidanand **********************************/ 124*6a0da736SJayanth Dodderi Chidanand static void read_feat_sel2(void) 125*6a0da736SJayanth Dodderi Chidanand { 126*6a0da736SJayanth Dodderi Chidanand #if (ENABLE_FEAT_SEL2 == FEAT_STATE_1) 127*6a0da736SJayanth Dodderi Chidanand feat_detect_panic(is_armv8_4_sel2_present(), "SEL2"); 128*6a0da736SJayanth Dodderi Chidanand #endif 129*6a0da736SJayanth Dodderi Chidanand } 130*6a0da736SJayanth Dodderi Chidanand 131*6a0da736SJayanth Dodderi Chidanand /**************************************************** 132*6a0da736SJayanth Dodderi Chidanand * Feature : FEAT_TRF (Self-hosted Trace Extensions) 133*6a0da736SJayanth Dodderi Chidanand ***************************************************/ 134*6a0da736SJayanth Dodderi Chidanand static void read_feat_trf(void) 135*6a0da736SJayanth Dodderi Chidanand { 136*6a0da736SJayanth Dodderi Chidanand #if (ENABLE_TRF_FOR_NS == FEAT_STATE_1) 137*6a0da736SJayanth Dodderi Chidanand feat_detect_panic(is_arm8_4_feat_trf_present(), "TRF"); 138*6a0da736SJayanth Dodderi Chidanand #endif 139*6a0da736SJayanth Dodderi Chidanand } 140*6a0da736SJayanth Dodderi Chidanand 141*6a0da736SJayanth Dodderi Chidanand /************************************************ 142*6a0da736SJayanth Dodderi Chidanand * Feature : FEAT_MTE (Memory Tagging Extension) 143*6a0da736SJayanth Dodderi Chidanand ***********************************************/ 144*6a0da736SJayanth Dodderi Chidanand static void read_feat_mte(void) 145*6a0da736SJayanth Dodderi Chidanand { 146*6a0da736SJayanth Dodderi Chidanand #if (CTX_INCLUDE_MTE_REGS == FEAT_STATE_1) 147*6a0da736SJayanth Dodderi Chidanand unsigned int mte = get_armv8_5_mte_support(); 148*6a0da736SJayanth Dodderi Chidanand 149*6a0da736SJayanth Dodderi Chidanand feat_detect_panic((mte != MTE_UNIMPLEMENTED), "MTE"); 150*6a0da736SJayanth Dodderi Chidanand #endif 151*6a0da736SJayanth Dodderi Chidanand } 152*6a0da736SJayanth Dodderi Chidanand 153*6a0da736SJayanth Dodderi Chidanand /*********************************************** 154*6a0da736SJayanth Dodderi Chidanand * Feature : FEAT_RNG (Random Number Generator) 155*6a0da736SJayanth Dodderi Chidanand **********************************************/ 156*6a0da736SJayanth Dodderi Chidanand static void read_feat_rng(void) 157*6a0da736SJayanth Dodderi Chidanand { 158*6a0da736SJayanth Dodderi Chidanand #if (ENABLE_FEAT_RNG == FEAT_STATE_1) 159*6a0da736SJayanth Dodderi Chidanand feat_detect_panic(is_armv8_5_rng_present(), "RNG"); 160*6a0da736SJayanth Dodderi Chidanand #endif 161*6a0da736SJayanth Dodderi Chidanand } 162*6a0da736SJayanth Dodderi Chidanand 163*6a0da736SJayanth Dodderi Chidanand /**************************************************** 164*6a0da736SJayanth Dodderi Chidanand * Feature : FEAT_BTI (Branch Target Identification) 165*6a0da736SJayanth Dodderi Chidanand ***************************************************/ 166*6a0da736SJayanth Dodderi Chidanand static void read_feat_bti(void) 167*6a0da736SJayanth Dodderi Chidanand { 168*6a0da736SJayanth Dodderi Chidanand #if (ENABLE_BTI == FEAT_STATE_1) 169*6a0da736SJayanth Dodderi Chidanand feat_detect_panic(is_armv8_5_bti_present(), "BTI"); 170*6a0da736SJayanth Dodderi Chidanand #endif 171*6a0da736SJayanth Dodderi Chidanand } 172*6a0da736SJayanth Dodderi Chidanand 173*6a0da736SJayanth Dodderi Chidanand /**************************************** 174*6a0da736SJayanth Dodderi Chidanand * Feature : FEAT_FGT (Fine Grain Traps) 175*6a0da736SJayanth Dodderi Chidanand ***************************************/ 176*6a0da736SJayanth Dodderi Chidanand static void read_feat_fgt(void) 177*6a0da736SJayanth Dodderi Chidanand { 178*6a0da736SJayanth Dodderi Chidanand #if (ENABLE_FEAT_FGT == FEAT_STATE_1) 179*6a0da736SJayanth Dodderi Chidanand feat_detect_panic(is_armv8_6_fgt_present(), "FGT"); 180*6a0da736SJayanth Dodderi Chidanand #endif 181*6a0da736SJayanth Dodderi Chidanand } 182*6a0da736SJayanth Dodderi Chidanand 183*6a0da736SJayanth Dodderi Chidanand /*********************************************** 184*6a0da736SJayanth Dodderi Chidanand * Feature : FEAT_AMUv1p1 (AMU Extensions v1.1) 185*6a0da736SJayanth Dodderi Chidanand **********************************************/ 186*6a0da736SJayanth Dodderi Chidanand static void read_feat_amuv1p1(void) 187*6a0da736SJayanth Dodderi Chidanand { 188*6a0da736SJayanth Dodderi Chidanand #if (ENABLE_FEAT_AMUv1p1 == FEAT_STATE_1) 189*6a0da736SJayanth Dodderi Chidanand feat_detect_panic(is_armv8_6_feat_amuv1p1_present(), "AMUv1p1"); 190*6a0da736SJayanth Dodderi Chidanand #endif 191*6a0da736SJayanth Dodderi Chidanand } 192*6a0da736SJayanth Dodderi Chidanand 193*6a0da736SJayanth Dodderi Chidanand /******************************************************* 194*6a0da736SJayanth Dodderi Chidanand * Feature : FEAT_ECV (Enhanced Counter Virtualization) 195*6a0da736SJayanth Dodderi Chidanand ******************************************************/ 196*6a0da736SJayanth Dodderi Chidanand static void read_feat_ecv(void) 197*6a0da736SJayanth Dodderi Chidanand { 198*6a0da736SJayanth Dodderi Chidanand #if (ENABLE_FEAT_ECV == FEAT_STATE_1) 199*6a0da736SJayanth Dodderi Chidanand unsigned int ecv = get_armv8_6_ecv_support(); 200*6a0da736SJayanth Dodderi Chidanand 201*6a0da736SJayanth Dodderi Chidanand feat_detect_panic(((ecv == ID_AA64MMFR0_EL1_ECV_SUPPORTED) || 202*6a0da736SJayanth Dodderi Chidanand (ecv == ID_AA64MMFR0_EL1_ECV_SELF_SYNCH)), "ECV"); 203*6a0da736SJayanth Dodderi Chidanand #endif 204*6a0da736SJayanth Dodderi Chidanand } 205*6a0da736SJayanth Dodderi Chidanand 206*6a0da736SJayanth Dodderi Chidanand /****************************************************************** 207*6a0da736SJayanth Dodderi Chidanand * Feature : FEAT_HCX (Extended Hypervisor Configuration Register) 208*6a0da736SJayanth Dodderi Chidanand *****************************************************************/ 209*6a0da736SJayanth Dodderi Chidanand static void read_feat_hcx(void) 210*6a0da736SJayanth Dodderi Chidanand { 211*6a0da736SJayanth Dodderi Chidanand #if (ENABLE_FEAT_HCX == FEAT_STATE_1) 212*6a0da736SJayanth Dodderi Chidanand feat_detect_panic(is_feat_hcx_present(), "HCX"); 213*6a0da736SJayanth Dodderi Chidanand #endif 214*6a0da736SJayanth Dodderi Chidanand } 215*6a0da736SJayanth Dodderi Chidanand 216*6a0da736SJayanth Dodderi Chidanand /************************************************** 217*6a0da736SJayanth Dodderi Chidanand * Feature : FEAT_RME (Realm Management Extension) 218*6a0da736SJayanth Dodderi Chidanand *************************************************/ 219*6a0da736SJayanth Dodderi Chidanand static void read_feat_rme(void) 220*6a0da736SJayanth Dodderi Chidanand { 221*6a0da736SJayanth Dodderi Chidanand #if (ENABLE_RME == FEAT_STATE_1) 222*6a0da736SJayanth Dodderi Chidanand feat_detect_panic((get_armv9_2_feat_rme_support() != 223*6a0da736SJayanth Dodderi Chidanand ID_AA64PFR0_FEAT_RME_NOT_SUPPORTED), "RME"); 224*6a0da736SJayanth Dodderi Chidanand #endif 225*6a0da736SJayanth Dodderi Chidanand } 226*6a0da736SJayanth Dodderi Chidanand 227*6a0da736SJayanth Dodderi Chidanand /*********************************************************************************** 228*6a0da736SJayanth Dodderi Chidanand * TF-A supports many Arm architectural features starting from arch version 229*6a0da736SJayanth Dodderi Chidanand * (8.0 till 8.7+). These features are mostly enabled through build flags. This 230*6a0da736SJayanth Dodderi Chidanand * mechanism helps in validating these build flags in the early boot phase 231*6a0da736SJayanth Dodderi Chidanand * either in BL1 or BL31 depending on the platform and assists in identifying 232*6a0da736SJayanth Dodderi Chidanand * and notifying the features which are enabled but not supported by the PE. 233*6a0da736SJayanth Dodderi Chidanand * 234*6a0da736SJayanth Dodderi Chidanand * It reads all the enabled features ID-registers and ensures the features 235*6a0da736SJayanth Dodderi Chidanand * are supported by the PE. 236*6a0da736SJayanth Dodderi Chidanand * In case if they aren't it stops booting at an early phase and logs the error 237*6a0da736SJayanth Dodderi Chidanand * messages, notifying the platforms about the features that are not supported. 238*6a0da736SJayanth Dodderi Chidanand * 239*6a0da736SJayanth Dodderi Chidanand * Further the procedure is implemented with a tri-state approach for each feature: 240*6a0da736SJayanth Dodderi Chidanand * ENABLE_FEAT_xxx = 0 : The feature is disabled statically at compile time 241*6a0da736SJayanth Dodderi Chidanand * ENABLE_FEAT_xxx = 1 : The feature is enabled and must be present in hardware. 242*6a0da736SJayanth Dodderi Chidanand * There will be panic if feature is not present at cold boot. 243*6a0da736SJayanth Dodderi Chidanand * ENABLE_FEAT_xxx = 2 : The feature is enabled but dynamically enabled at runtime 244*6a0da736SJayanth Dodderi Chidanand * depending on hardware capability. 245*6a0da736SJayanth Dodderi Chidanand * 246*6a0da736SJayanth Dodderi Chidanand * For better readability, state values are defined with macros namely: 247*6a0da736SJayanth Dodderi Chidanand * { FEAT_STATE_0, FEAT_STATE_1, FEAT_STATE_2 } taking values as their naming. 248*6a0da736SJayanth Dodderi Chidanand **********************************************************************************/ 249*6a0da736SJayanth Dodderi Chidanand void detect_arch_features(void) 250*6a0da736SJayanth Dodderi Chidanand { 251*6a0da736SJayanth Dodderi Chidanand /* v8.0 features */ 252*6a0da736SJayanth Dodderi Chidanand read_feat_sb(); 253*6a0da736SJayanth Dodderi Chidanand read_feat_csv2_2(); 254*6a0da736SJayanth Dodderi Chidanand 255*6a0da736SJayanth Dodderi Chidanand /* v8.1 features */ 256*6a0da736SJayanth Dodderi Chidanand read_feat_pan(); 257*6a0da736SJayanth Dodderi Chidanand read_feat_vhe(); 258*6a0da736SJayanth Dodderi Chidanand 259*6a0da736SJayanth Dodderi Chidanand /* v8.2 features */ 260*6a0da736SJayanth Dodderi Chidanand read_feat_ras(); 261*6a0da736SJayanth Dodderi Chidanand 262*6a0da736SJayanth Dodderi Chidanand /* v8.3 features */ 263*6a0da736SJayanth Dodderi Chidanand read_feat_pauth(); 264*6a0da736SJayanth Dodderi Chidanand 265*6a0da736SJayanth Dodderi Chidanand /* v8.4 features */ 266*6a0da736SJayanth Dodderi Chidanand read_feat_dit(); 267*6a0da736SJayanth Dodderi Chidanand read_feat_amuv1(); 268*6a0da736SJayanth Dodderi Chidanand read_feat_mpam(); 269*6a0da736SJayanth Dodderi Chidanand read_feat_nv2(); 270*6a0da736SJayanth Dodderi Chidanand read_feat_sel2(); 271*6a0da736SJayanth Dodderi Chidanand read_feat_trf(); 272*6a0da736SJayanth Dodderi Chidanand 273*6a0da736SJayanth Dodderi Chidanand /* v8.5 features */ 274*6a0da736SJayanth Dodderi Chidanand read_feat_mte(); 275*6a0da736SJayanth Dodderi Chidanand read_feat_rng(); 276*6a0da736SJayanth Dodderi Chidanand read_feat_bti(); 277*6a0da736SJayanth Dodderi Chidanand 278*6a0da736SJayanth Dodderi Chidanand /* v8.6 features */ 279*6a0da736SJayanth Dodderi Chidanand read_feat_amuv1p1(); 280*6a0da736SJayanth Dodderi Chidanand read_feat_fgt(); 281*6a0da736SJayanth Dodderi Chidanand read_feat_ecv(); 282*6a0da736SJayanth Dodderi Chidanand 283*6a0da736SJayanth Dodderi Chidanand /* v8.7 features */ 284*6a0da736SJayanth Dodderi Chidanand read_feat_hcx(); 285*6a0da736SJayanth Dodderi Chidanand 286*6a0da736SJayanth Dodderi Chidanand /* v9.2 features */ 287*6a0da736SJayanth Dodderi Chidanand read_feat_rme(); 288*6a0da736SJayanth Dodderi Chidanand } 289