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