44 * SPDX-License-Identifier: BSD-3-Clause
55 */
66
7+ #include <arch_features.h>
8+ #include <common/debug.h>
79#include <common/feat_detect.h>
810
11+ static bool tainted ;
12+
913/*******************************************************************************
1014 * 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:
15+ * feature states (FEAT_STATE_ALWAYS and FEAT_STATE_CHECK ) and perform
16+ * necessary action as below:
1317 *
1418 * It verifies whether the FEAT_XXX (eg: FEAT_SB) is supported by the PE or not.
1519 * Without this check an exception would occur during context save/restore
1620 * routines, if the feature is enabled but not supported by PE.
1721 ******************************************************************************/
1822
23+ #define feat_detect_panic (a , b ) ((a) ? (void)0 : feature_panic(b))
24+
25+ /*******************************************************************************
26+ * Function : feature_panic
27+ * Customised panic function with error logging mechanism to list the feature
28+ * not supported by the PE.
29+ ******************************************************************************/
30+ static inline void feature_panic (char * feat_name )
31+ {
32+ ERROR ("FEAT_%s not supported by the PE\n" , feat_name );
33+ panic ();
34+ }
35+
36+ /*******************************************************************************
37+ * Function : check_feature
38+ * Check for a valid combination of build time flags (ENABLE_FEAT_xxx) and
39+ * feature availability on the hardware.
40+ * Panics if a feature is forcefully enabled, but not available on the PE.
41+ *
42+ * We force inlining here to let the compiler optimise away the whole check
43+ * if the feature is disabled at build time (FEAT_STATE_DISABLED).
44+ ******************************************************************************/
45+ static inline void __attribute((__always_inline__ ))
46+ check_feature (int state , unsigned long field , const char * feat_name )
47+ {
48+ if (state == FEAT_STATE_ALWAYS && field == 0U ) {
49+ ERROR ("FEAT_%s not supported by the PE\n" , feat_name );
50+ tainted = true;
51+ }
52+ }
53+
1954/******************************************
2055 * Feature : FEAT_SB (Speculation Barrier)
2156 *****************************************/
2257static void read_feat_sb (void )
2358{
24- #if (ENABLE_FEAT_SB == FEAT_STATE_1 )
59+ #if (ENABLE_FEAT_SB == FEAT_STATE_ALWAYS )
2560 feat_detect_panic (is_armv8_0_feat_sb_present (), "SB" );
2661#endif
2762}
@@ -31,7 +66,7 @@ static void read_feat_sb(void)
3166 *****************************************************/
3267static void read_feat_csv2_2 (void )
3368{
34- #if (ENABLE_FEAT_CSV2_2 == FEAT_STATE_1 )
69+ #if (ENABLE_FEAT_CSV2_2 == FEAT_STATE_ALWAYS )
3570 feat_detect_panic (is_armv8_0_feat_csv2_2_present (), "CSV2_2" );
3671#endif
3772}
@@ -41,7 +76,7 @@ static void read_feat_csv2_2(void)
4176 **********************************************/
4277static void read_feat_pan (void )
4378{
44- #if (ENABLE_FEAT_PAN == FEAT_STATE_1 )
79+ #if (ENABLE_FEAT_PAN == FEAT_STATE_ALWAYS )
4580 feat_detect_panic (is_armv8_1_pan_present (), "PAN" );
4681#endif
4782}
@@ -51,7 +86,7 @@ static void read_feat_pan(void)
5186 *****************************************************/
5287static void read_feat_vhe (void )
5388{
54- #if (ENABLE_FEAT_VHE == FEAT_STATE_1 )
89+ #if (ENABLE_FEAT_VHE == FEAT_STATE_ALWAYS )
5590 feat_detect_panic (is_armv8_1_vhe_present (), "VHE" );
5691#endif
5792}
@@ -61,7 +96,7 @@ static void read_feat_vhe(void)
6196 ******************************************************************************/
6297static void read_feat_ras (void )
6398{
64- #if (RAS_EXTENSION == FEAT_STATE_1 )
99+ #if (RAS_EXTENSION == FEAT_STATE_ALWAYS )
65100 feat_detect_panic (is_armv8_2_feat_ras_present (), "RAS" );
66101#endif
67102}
@@ -71,7 +106,7 @@ static void read_feat_ras(void)
71106 ***********************************************/
72107static void read_feat_pauth (void )
73108{
74- #if (ENABLE_PAUTH == FEAT_STATE_1 ) || (CTX_INCLUDE_PAUTH_REGS == FEAT_STATE_1 )
109+ #if (ENABLE_PAUTH == FEAT_STATE_ALWAYS ) || (CTX_INCLUDE_PAUTH_REGS == FEAT_STATE_ALWAYS )
75110 feat_detect_panic (is_armv8_3_pauth_present (), "PAUTH" );
76111#endif
77112}
@@ -81,27 +116,17 @@ static void read_feat_pauth(void)
81116 ***********************************************************/
82117static void read_feat_dit (void )
83118{
84- #if (ENABLE_FEAT_DIT == FEAT_STATE_1 )
119+ #if (ENABLE_FEAT_DIT == FEAT_STATE_ALWAYS )
85120 feat_detect_panic (is_armv8_4_feat_dit_present (), "DIT" );
86121#endif
87122}
88123
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-
99124/****************************************************************************
100125 * Feature : FEAT_MPAM (Memory Partitioning and Monitoring (MPAM) Extension)
101126 ***************************************************************************/
102127static void read_feat_mpam (void )
103128{
104- #if (ENABLE_MPAM_FOR_LOWER_ELS == FEAT_STATE_1 )
129+ #if (ENABLE_MPAM_FOR_LOWER_ELS == FEAT_STATE_ALWAYS )
105130 feat_detect_panic (get_mpam_version () != 0U , "MPAM" );
106131#endif
107132}
@@ -111,7 +136,7 @@ static void read_feat_mpam(void)
111136 *************************************************************/
112137static void read_feat_nv2 (void )
113138{
114- #if (CTX_INCLUDE_NEVE_REGS == FEAT_STATE_1 )
139+ #if (CTX_INCLUDE_NEVE_REGS == FEAT_STATE_ALWAYS )
115140 unsigned int nv = get_armv8_4_feat_nv_support ();
116141
117142 feat_detect_panic ((nv == ID_AA64MMFR2_EL1_NV2_SUPPORTED ), "NV2" );
@@ -123,7 +148,7 @@ static void read_feat_nv2(void)
123148 **********************************/
124149static void read_feat_sel2 (void )
125150{
126- #if (ENABLE_FEAT_SEL2 == FEAT_STATE_1 )
151+ #if (ENABLE_FEAT_SEL2 == FEAT_STATE_ALWAYS )
127152 feat_detect_panic (is_armv8_4_sel2_present (), "SEL2" );
128153#endif
129154}
@@ -133,7 +158,7 @@ static void read_feat_sel2(void)
133158 ***************************************************/
134159static void read_feat_trf (void )
135160{
136- #if (ENABLE_TRF_FOR_NS == FEAT_STATE_1 )
161+ #if (ENABLE_TRF_FOR_NS == FEAT_STATE_ALWAYS )
137162 feat_detect_panic (is_arm8_4_feat_trf_present (), "TRF" );
138163#endif
139164}
@@ -143,7 +168,7 @@ static void read_feat_trf(void)
143168 ***********************************************/
144169static void read_feat_mte (void )
145170{
146- #if (CTX_INCLUDE_MTE_REGS == FEAT_STATE_1 )
171+ #if (CTX_INCLUDE_MTE_REGS == FEAT_STATE_ALWAYS )
147172 unsigned int mte = get_armv8_5_mte_support ();
148173
149174 feat_detect_panic ((mte != MTE_UNIMPLEMENTED ), "MTE" );
@@ -155,7 +180,7 @@ static void read_feat_mte(void)
155180 **********************************************/
156181static void read_feat_rng (void )
157182{
158- #if (ENABLE_FEAT_RNG == FEAT_STATE_1 )
183+ #if (ENABLE_FEAT_RNG == FEAT_STATE_ALWAYS )
159184 feat_detect_panic (is_armv8_5_rng_present (), "RNG" );
160185#endif
161186}
@@ -165,27 +190,17 @@ static void read_feat_rng(void)
165190 ***************************************************/
166191static void read_feat_bti (void )
167192{
168- #if (ENABLE_BTI == FEAT_STATE_1 )
193+ #if (ENABLE_BTI == FEAT_STATE_ALWAYS )
169194 feat_detect_panic (is_armv8_5_bti_present (), "BTI" );
170195#endif
171196}
172197
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-
183198/***********************************************
184199 * Feature : FEAT_AMUv1p1 (AMU Extensions v1.1)
185200 **********************************************/
186201static void read_feat_amuv1p1 (void )
187202{
188- #if (ENABLE_FEAT_AMUv1p1 == FEAT_STATE_1 )
203+ #if (ENABLE_FEAT_AMUv1p1 == FEAT_STATE_ALWAYS )
189204 feat_detect_panic (is_armv8_6_feat_amuv1p1_present (), "AMUv1p1" );
190205#endif
191206}
@@ -195,7 +210,7 @@ static void read_feat_amuv1p1(void)
195210 ******************************************************/
196211static void read_feat_ecv (void )
197212{
198- #if (ENABLE_FEAT_ECV == FEAT_STATE_1 )
213+ #if (ENABLE_FEAT_ECV == FEAT_STATE_ALWAYS )
199214 unsigned int ecv = get_armv8_6_ecv_support ();
200215
201216 feat_detect_panic (((ecv == ID_AA64MMFR0_EL1_ECV_SUPPORTED ) ||
@@ -208,27 +223,17 @@ static void read_feat_ecv(void)
208223 **********************************************************/
209224static void read_feat_twed (void )
210225{
211- #if (ENABLE_FEAT_TWED == FEAT_STATE_1 )
226+ #if (ENABLE_FEAT_TWED == FEAT_STATE_ALWAYS )
212227 feat_detect_panic (is_armv8_6_twed_present (), "TWED" );
213228#endif
214229}
215230
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-
226231/**************************************************
227232 * Feature : FEAT_RME (Realm Management Extension)
228233 *************************************************/
229234static void read_feat_rme (void )
230235{
231- #if (ENABLE_RME == FEAT_STATE_1 )
236+ #if (ENABLE_RME == FEAT_STATE_ALWAYS )
232237 feat_detect_panic ((get_armv9_2_feat_rme_support () !=
233238 ID_AA64PFR0_FEAT_RME_NOT_SUPPORTED ), "RME" );
234239#endif
@@ -239,7 +244,7 @@ static void read_feat_rme(void)
239244 *****************************************************/
240245static void read_feat_brbe (void )
241246{
242- #if (ENABLE_BRBE_FOR_NS == FEAT_STATE_1 )
247+ #if (ENABLE_BRBE_FOR_NS == FEAT_STATE_ALWAYS )
243248 feat_detect_panic (is_feat_brbe_present (), "BRBE" );
244249#endif
245250}
@@ -249,7 +254,7 @@ static void read_feat_brbe(void)
249254 *****************************************************/
250255static void read_feat_trbe (void )
251256{
252- #if (ENABLE_TRBE_FOR_NS == FEAT_STATE_1 )
257+ #if (ENABLE_TRBE_FOR_NS == FEAT_STATE_ALWAYS )
253258 feat_detect_panic (is_feat_trbe_present (), "TRBE" );
254259#endif
255260}
@@ -259,7 +264,7 @@ static void read_feat_trbe(void)
259264 *****************************************************************/
260265static void read_feat_rng_trap (void )
261266{
262- #if (ENABLE_FEAT_RNG_TRAP == FEAT_STATE_1 )
267+ #if (ENABLE_FEAT_RNG_TRAP == FEAT_STATE_ALWAYS )
263268 feat_detect_panic (is_feat_rng_trap_present (), "RNG_TRAP" );
264269#endif
265270}
@@ -283,11 +288,14 @@ static void read_feat_rng_trap(void)
283288 * ENABLE_FEAT_xxx = 2 : The feature is enabled but dynamically enabled at runtime
284289 * depending on hardware capability.
285290 *
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.
291+ * For better readability, state values are defined with macros, namely:
292+ * { FEAT_STATE_DISABLED, FEAT_STATE_ALWAYS, FEAT_STATE_CHECK }, taking values
293+ * { 0, 1, 2 }, respectively, as their naming.
288294 **********************************************************************************/
289295void detect_arch_features (void )
290296{
297+ tainted = false;
298+
291299 /* v8.0 features */
292300 read_feat_sb ();
293301 read_feat_csv2_2 ();
@@ -304,7 +312,7 @@ void detect_arch_features(void)
304312
305313 /* v8.4 features */
306314 read_feat_dit ();
307- read_feat_amuv1 ( );
315+ check_feature ( ENABLE_FEAT_AMUv1 , read_feat_amu_id_field (), "AMUv1" );
308316 read_feat_mpam ();
309317 read_feat_nv2 ();
310318 read_feat_sel2 ();
@@ -318,17 +326,21 @@ void detect_arch_features(void)
318326
319327 /* v8.6 features */
320328 read_feat_amuv1p1 ();
321- read_feat_fgt ( );
329+ check_feature ( ENABLE_FEAT_FGT , read_feat_fgt_id_field (), "FGT" );
322330 read_feat_ecv ();
323331 read_feat_twed ();
324332
325333 /* v8.7 features */
326- read_feat_hcx ( );
334+ check_feature ( ENABLE_FEAT_HCX , read_feat_hcx_id_field (), "HCX" );
327335
328336 /* v9.0 features */
329337 read_feat_brbe ();
330338 read_feat_trbe ();
331339
332340 /* v9.2 features */
333341 read_feat_rme ();
342+
343+ if (tainted ) {
344+ panic ();
345+ }
334346}
0 commit comments