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