blob: 9f11f1561ff20b6aeee716f42b5b1749a8cf9985 [file] [log] [blame]
Antonio Nino Diazc326c342019-01-11 11:20:10 +00001/*
Andre Przywarabb0db3b2023-01-25 12:26:14 +00002 * Copyright (c) 2019-2023, Arm Limited. All rights reserved.
Antonio Nino Diazc326c342019-01-11 11:20:10 +00003 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7#ifndef ARCH_FEATURES_H
8#define ARCH_FEATURES_H
9
10#include <stdbool.h>
11
12#include <arch_helpers.h>
Andre Przywarae8920f62022-11-10 14:28:01 +000013#include <common/feat_detect.h>
Antonio Nino Diazc326c342019-01-11 11:20:10 +000014
Andre Przywarabb0db3b2023-01-25 12:26:14 +000015#define ISOLATE_FIELD(reg, feat) \
16 ((unsigned int)(((reg) >> (feat ## _SHIFT)) & (feat ## _MASK)))
17
Antonio Nino Diazd29d21e2019-02-06 09:23:04 +000018static inline bool is_armv7_gentimer_present(void)
19{
20 /* The Generic Timer is always present in an ARMv8-A implementation */
21 return true;
22}
23
Andre Przywara97272942023-01-26 15:27:38 +000024static inline unsigned int read_feat_pan_id_field(void)
25{
26 return ISOLATE_FIELD(read_id_aa64mmfr1_el1(), ID_AA64MMFR1_EL1_PAN);
27}
28
29static inline bool is_feat_pan_supported(void)
Daniel Boulby44b43332020-11-25 16:36:46 +000030{
Andre Przywara97272942023-01-26 15:27:38 +000031 if (ENABLE_FEAT_PAN == FEAT_STATE_DISABLED) {
32 return false;
33 }
34
35 if (ENABLE_FEAT_PAN == FEAT_STATE_ALWAYS) {
36 return true;
37 }
38
39 return read_feat_pan_id_field() != 0U;
Daniel Boulby44b43332020-11-25 16:36:46 +000040}
41
Andre Przywara98908b32022-11-17 16:42:09 +000042static inline unsigned int read_feat_vhe_id_field(void)
43{
44 return ISOLATE_FIELD(read_id_aa64mmfr1_el1(), ID_AA64MMFR1_EL1_VHE);
45}
46
47static inline bool is_feat_vhe_supported(void)
Daniel Boulby44b43332020-11-25 16:36:46 +000048{
Andre Przywara98908b32022-11-17 16:42:09 +000049 if (ENABLE_FEAT_VHE == FEAT_STATE_DISABLED) {
50 return false;
51 }
52
53 if (ENABLE_FEAT_VHE == FEAT_STATE_ALWAYS) {
54 return true;
55 }
56
57 return read_feat_vhe_id_field() != 0U;
Daniel Boulby44b43332020-11-25 16:36:46 +000058}
59
Antonio Nino Diazc326c342019-01-11 11:20:10 +000060static inline bool is_armv8_2_ttcnp_present(void)
61{
62 return ((read_id_aa64mmfr2_el1() >> ID_AA64MMFR2_EL1_CNP_SHIFT) &
63 ID_AA64MMFR2_EL1_CNP_MASK) != 0U;
64}
65
Juan Pablo Condee089a172022-06-29 17:44:43 -040066static inline bool is_feat_pacqarma3_present(void)
67{
68 uint64_t mask_id_aa64isar2 =
69 (ID_AA64ISAR2_GPA3_MASK << ID_AA64ISAR2_GPA3_SHIFT) |
70 (ID_AA64ISAR2_APA3_MASK << ID_AA64ISAR2_APA3_SHIFT);
71
72 /* If any of the fields is not zero, QARMA3 algorithm is present */
73 return (read_id_aa64isar2_el1() & mask_id_aa64isar2) != 0U;
74}
75
Antonio Nino Diaz25cda672019-02-19 11:53:51 +000076static inline bool is_armv8_3_pauth_present(void)
77{
Juan Pablo Condee089a172022-06-29 17:44:43 -040078 uint64_t mask_id_aa64isar1 =
79 (ID_AA64ISAR1_GPI_MASK << ID_AA64ISAR1_GPI_SHIFT) |
80 (ID_AA64ISAR1_GPA_MASK << ID_AA64ISAR1_GPA_SHIFT) |
81 (ID_AA64ISAR1_API_MASK << ID_AA64ISAR1_API_SHIFT) |
82 (ID_AA64ISAR1_APA_MASK << ID_AA64ISAR1_APA_SHIFT);
Antonio Nino Diaz25cda672019-02-19 11:53:51 +000083
Juan Pablo Condee089a172022-06-29 17:44:43 -040084 /*
85 * If any of the fields is not zero or QARMA3 is present,
86 * PAuth is present
87 */
88 return ((read_id_aa64isar1_el1() & mask_id_aa64isar1) != 0U ||
89 is_feat_pacqarma3_present());
Antonio Nino Diaz25cda672019-02-19 11:53:51 +000090}
91
Sathees Balya74155972019-01-25 11:36:01 +000092static inline bool is_armv8_4_ttst_present(void)
93{
94 return ((read_id_aa64mmfr2_el1() >> ID_AA64MMFR2_EL1_ST_SHIFT) &
95 ID_AA64MMFR2_EL1_ST_MASK) == 1U;
96}
97
Alexei Fedorov90f2e882019-05-24 12:17:09 +010098static inline bool is_armv8_5_bti_present(void)
99{
100 return ((read_id_aa64pfr1_el1() >> ID_AA64PFR1_EL1_BT_SHIFT) &
101 ID_AA64PFR1_EL1_BT_MASK) == BTI_IMPLEMENTED;
102}
103
Soby Mathew830f0ad2019-07-12 09:23:38 +0100104static inline unsigned int get_armv8_5_mte_support(void)
105{
106 return ((read_id_aa64pfr1_el1() >> ID_AA64PFR1_EL1_MTE_SHIFT) &
107 ID_AA64PFR1_EL1_MTE_MASK);
108}
109
Andre Przywara6dd2d062023-02-22 16:53:50 +0000110static inline unsigned int read_feat_sel2_id_field(void)
111{
112 return ISOLATE_FIELD(read_id_aa64pfr0_el1(), ID_AA64PFR0_SEL2);
113}
114
115static inline bool is_feat_sel2_supported(void)
Olivier Deprez2bae35f2020-04-16 13:39:06 +0200116{
Andre Przywara6dd2d062023-02-22 16:53:50 +0000117 if (ENABLE_FEAT_SEL2 == FEAT_STATE_DISABLED) {
118 return false;
119 }
120
121 if (ENABLE_FEAT_SEL2 == FEAT_STATE_ALWAYS) {
122 return true;
123 }
124
125 return read_feat_sel2_id_field() != 0U;
Olivier Deprez2bae35f2020-04-16 13:39:06 +0200126}
127
Andre Przywara0cf77402023-01-27 12:25:49 +0000128static inline unsigned int read_feat_twed_id_field(void)
129{
130 return ISOLATE_FIELD(read_id_aa64mmfr1_el1(), ID_AA64MMFR1_EL1_TWED);
131}
132
133static inline bool is_feat_twed_supported(void)
johpow013e24c162020-04-22 14:05:13 -0500134{
Andre Przywara0cf77402023-01-27 12:25:49 +0000135 if (ENABLE_FEAT_TWED == FEAT_STATE_DISABLED) {
136 return false;
137 }
138
139 if (ENABLE_FEAT_TWED == FEAT_STATE_ALWAYS) {
140 return true;
141 }
142
143 return read_feat_twed_id_field() != 0U;
johpow013e24c162020-04-22 14:05:13 -0500144}
145
Andre Przywarae8920f62022-11-10 14:28:01 +0000146static unsigned int read_feat_fgt_id_field(void)
Jimmy Brissonecc3c672020-04-16 10:47:56 -0500147{
Andre Przywarabb0db3b2023-01-25 12:26:14 +0000148 return ISOLATE_FIELD(read_id_aa64mmfr0_el1(), ID_AA64MMFR0_EL1_FGT);
Andre Przywarae8920f62022-11-10 14:28:01 +0000149}
150
Maksims Svecovsdf4ad842023-03-24 13:05:09 +0000151static unsigned int read_feat_mte_perm_id_field(void)
152{
153 return ISOLATE_FIELD(read_id_aa64pfr2_el1(), ID_AA64PFR2_EL1_MTEPERM);
154}
155
Andre Przywarae8920f62022-11-10 14:28:01 +0000156static inline bool is_feat_fgt_supported(void)
157{
158 if (ENABLE_FEAT_FGT == FEAT_STATE_DISABLED) {
159 return false;
160 }
161
162 if (ENABLE_FEAT_FGT == FEAT_STATE_ALWAYS) {
163 return true;
164 }
165
166 return read_feat_fgt_id_field() != 0U;
Jimmy Brissonecc3c672020-04-16 10:47:56 -0500167}
168
Maksims Svecovsdf4ad842023-03-24 13:05:09 +0000169static inline bool is_feat_mte_perm_supported(void)
170{
171 if (ENABLE_FEAT_MTE_PERM == FEAT_STATE_DISABLED) {
172 return false;
173 }
174
175 if (ENABLE_FEAT_MTE_PERM == FEAT_STATE_ALWAYS) {
176 return true;
177 }
178
179 return read_feat_mte_perm_id_field() != 0U;
180}
181
Andre Przywarac3464182022-11-17 17:30:43 +0000182static unsigned int read_feat_ecv_id_field(void)
183{
184 return ISOLATE_FIELD(read_id_aa64mmfr0_el1(), ID_AA64MMFR0_EL1_ECV);
185}
186
187static inline bool is_feat_ecv_supported(void)
188{
189 if (ENABLE_FEAT_ECV == FEAT_STATE_DISABLED) {
190 return false;
191 }
192
193 if (ENABLE_FEAT_ECV == FEAT_STATE_ALWAYS) {
194 return true;
195 }
196
197 return read_feat_ecv_id_field() != 0U;
198}
199
200static inline bool is_feat_ecv_v2_supported(void)
Jimmy Brisson83573892020-04-16 10:48:02 -0500201{
Andre Przywarac3464182022-11-17 17:30:43 +0000202 if (ENABLE_FEAT_ECV == FEAT_STATE_DISABLED) {
203 return false;
204 }
205
206 if (ENABLE_FEAT_ECV == FEAT_STATE_ALWAYS) {
207 return true;
208 }
209
210 return read_feat_ecv_id_field() >= ID_AA64MMFR0_EL1_ECV_SELF_SYNCH;
Jimmy Brisson83573892020-04-16 10:48:02 -0500211}
212
Andre Przywara436b4bb2023-02-22 17:55:59 +0000213static unsigned int read_feat_rng_id_field(void)
214{
215 return ISOLATE_FIELD(read_id_aa64isar0_el1(), ID_AA64ISAR0_RNDR);
216}
217
218static inline bool is_feat_rng_supported(void)
Tomas Pilar6fd816e2020-10-28 15:34:12 +0000219{
Andre Przywara436b4bb2023-02-22 17:55:59 +0000220 if (ENABLE_FEAT_RNG == FEAT_STATE_DISABLED) {
221 return false;
222 }
223
224 if (ENABLE_FEAT_RNG == FEAT_STATE_ALWAYS) {
225 return true;
226 }
227
228 return read_feat_rng_id_field() != 0U;
Tomas Pilar6fd816e2020-10-28 15:34:12 +0000229}
230
Mark Brownc37eee72023-03-14 20:13:03 +0000231static unsigned int read_feat_tcrx_id_field(void)
232{
233 return ISOLATE_FIELD(read_id_aa64mmfr3_el1(), ID_AA64MMFR3_EL1_TCRX);
234}
235
236static inline bool is_feat_tcr2_supported(void)
237{
238 if (ENABLE_FEAT_TCR2 == FEAT_STATE_DISABLED) {
239 return false;
240 }
241
242 if (ENABLE_FEAT_TCR2 == FEAT_STATE_ALWAYS) {
243 return true;
244 }
245
246 return read_feat_tcrx_id_field() != 0U;
247}
248
Mark Brown293a6612023-03-14 20:48:43 +0000249static unsigned int read_feat_s2poe_id_field(void)
250{
251 return ISOLATE_FIELD(read_id_aa64mmfr3_el1(), ID_AA64MMFR3_EL1_S2POE);
252}
253
254static inline bool is_feat_s2poe_supported(void)
255{
256 if (ENABLE_FEAT_S2POE == FEAT_STATE_DISABLED) {
257 return false;
258 }
259
260 if (ENABLE_FEAT_S2POE == FEAT_STATE_ALWAYS) {
261 return true;
262 }
263
264 return read_feat_s2poe_id_field() != 0U;
265}
266
267static unsigned int read_feat_s1poe_id_field(void)
268{
269 return ISOLATE_FIELD(read_id_aa64mmfr3_el1(), ID_AA64MMFR3_EL1_S1POE);
270}
271
272static inline bool is_feat_s1poe_supported(void)
273{
274 if (ENABLE_FEAT_S1POE == FEAT_STATE_DISABLED) {
275 return false;
276 }
277
278 if (ENABLE_FEAT_S1POE == FEAT_STATE_ALWAYS) {
279 return true;
280 }
281
282 return read_feat_s1poe_id_field() != 0U;
283}
284
285static inline bool is_feat_sxpoe_supported(void)
286{
287 return is_feat_s1poe_supported() || is_feat_s2poe_supported();
288}
289
290static unsigned int read_feat_s2pie_id_field(void)
291{
292 return ISOLATE_FIELD(read_id_aa64mmfr3_el1(), ID_AA64MMFR3_EL1_S2PIE);
293}
294
295static inline bool is_feat_s2pie_supported(void)
296{
297 if (ENABLE_FEAT_S2PIE == FEAT_STATE_DISABLED) {
298 return false;
299 }
300
301 if (ENABLE_FEAT_S2PIE == FEAT_STATE_ALWAYS) {
302 return true;
303 }
304
305 return read_feat_s2pie_id_field() != 0U;
306}
307
308static unsigned int read_feat_s1pie_id_field(void)
309{
310 return ISOLATE_FIELD(read_id_aa64mmfr3_el1(), ID_AA64MMFR3_EL1_S1PIE);
311}
312
313static inline bool is_feat_s1pie_supported(void)
314{
315 if (ENABLE_FEAT_S1PIE == FEAT_STATE_DISABLED) {
316 return false;
317 }
318
319 if (ENABLE_FEAT_S1PIE == FEAT_STATE_ALWAYS) {
320 return true;
321 }
322
323 return read_feat_s1pie_id_field() != 0U;
324}
325
326static inline bool is_feat_sxpie_supported(void)
327{
328 return is_feat_s1pie_supported() || is_feat_s2pie_supported();
329}
330
Mark Brown326f2952023-03-14 21:33:04 +0000331static unsigned int read_feat_gcs_id_field(void)
332{
333 return ISOLATE_FIELD(read_id_aa64pfr1_el1(), ID_AA64PFR1_EL1_GCS);
334}
335
336static inline bool is_feat_gcs_supported(void)
337{
338 if (ENABLE_FEAT_GCS == FEAT_STATE_DISABLED) {
339 return false;
340 }
341
342 if (ENABLE_FEAT_GCS == FEAT_STATE_ALWAYS) {
343 return true;
344 }
345
346 return read_feat_gcs_id_field() != 0U;
347}
348
Andre Przywara2c550e32022-11-10 14:41:07 +0000349/*******************************************************************************
350 * Functions to identify the presence of the Activity Monitors Extension
351 ******************************************************************************/
352static unsigned int read_feat_amu_id_field(void)
353{
Andre Przywarabb0db3b2023-01-25 12:26:14 +0000354 return ISOLATE_FIELD(read_id_aa64pfr0_el1(), ID_AA64PFR0_AMU);
Andre Przywara2c550e32022-11-10 14:41:07 +0000355}
356
357static inline bool is_feat_amu_supported(void)
358{
Andre Przywara0b7f1b02023-03-21 13:53:19 +0000359 if (ENABLE_FEAT_AMU == FEAT_STATE_DISABLED) {
Andre Przywara2c550e32022-11-10 14:41:07 +0000360 return false;
361 }
362
Andre Przywara0b7f1b02023-03-21 13:53:19 +0000363 if (ENABLE_FEAT_AMU == FEAT_STATE_ALWAYS) {
Andre Przywara2c550e32022-11-10 14:41:07 +0000364 return true;
365 }
366
367 return read_feat_amu_id_field() >= ID_AA64PFR0_AMU_V1;
368}
369
Andre Przywara906776e2023-03-03 10:30:06 +0000370static inline bool is_feat_amuv1p1_supported(void)
johpow01fa59c6f2020-10-02 13:41:11 -0500371{
Andre Przywara906776e2023-03-03 10:30:06 +0000372 if (ENABLE_FEAT_AMUv1p1 == FEAT_STATE_DISABLED) {
373 return false;
374 }
375
376 if (ENABLE_FEAT_AMUv1p1 == FEAT_STATE_ALWAYS) {
377 return true;
378 }
379
Andre Przywara2c550e32022-11-10 14:41:07 +0000380 return read_feat_amu_id_field() >= ID_AA64PFR0_AMU_V1P1;
johpow01fa59c6f2020-10-02 13:41:11 -0500381}
382
Alexei Fedorov19933552020-05-26 13:16:41 +0100383/*
384 * Return MPAM version:
385 *
386 * 0x00: None Armv8.0 or later
387 * 0x01: v0.1 Armv8.4 or later
388 * 0x10: v1.0 Armv8.2 or later
389 * 0x11: v1.1 Armv8.4 or later
390 *
391 */
Andre Przywara84b86532022-11-17 16:42:09 +0000392static inline unsigned int read_feat_mpam_version(void)
Alexei Fedorov19933552020-05-26 13:16:41 +0100393{
394 return (unsigned int)((((read_id_aa64pfr0_el1() >>
395 ID_AA64PFR0_MPAM_SHIFT) & ID_AA64PFR0_MPAM_MASK) << 4) |
396 ((read_id_aa64pfr1_el1() >>
397 ID_AA64PFR1_MPAM_FRAC_SHIFT) & ID_AA64PFR1_MPAM_FRAC_MASK));
398}
399
Andre Przywara84b86532022-11-17 16:42:09 +0000400static inline bool is_feat_mpam_supported(void)
401{
402 if (ENABLE_MPAM_FOR_LOWER_ELS == FEAT_STATE_DISABLED) {
403 return false;
404 }
405
406 if (ENABLE_MPAM_FOR_LOWER_ELS == FEAT_STATE_ALWAYS) {
407 return true;
408 }
409
410 return read_feat_mpam_version() != 0U;
411}
412
Andre Przywaraf20ad902022-11-15 11:45:19 +0000413static inline unsigned int read_feat_hcx_id_field(void)
414{
Andre Przywarabb0db3b2023-01-25 12:26:14 +0000415 return ISOLATE_FIELD(read_id_aa64mmfr1_el1(), ID_AA64MMFR1_EL1_HCX);
Andre Przywaraf20ad902022-11-15 11:45:19 +0000416}
417
418static inline bool is_feat_hcx_supported(void)
johpow01f91e59f2021-08-04 19:38:18 -0500419{
Andre Przywaraf20ad902022-11-15 11:45:19 +0000420 if (ENABLE_FEAT_HCX == FEAT_STATE_DISABLED) {
421 return false;
422 }
423
424 if (ENABLE_FEAT_HCX == FEAT_STATE_ALWAYS) {
425 return true;
426 }
427
428 return read_feat_hcx_id_field() != 0U;
johpow01f91e59f2021-08-04 19:38:18 -0500429}
430
Juan Pablo Conde42305f22022-07-12 16:40:29 -0400431static inline bool is_feat_rng_trap_present(void)
432{
433 return (((read_id_aa64pfr1_el1() >> ID_AA64PFR1_EL1_RNDR_TRAP_SHIFT) &
434 ID_AA64PFR1_EL1_RNDR_TRAP_MASK)
435 == ID_AA64PFR1_EL1_RNG_TRAP_SUPPORTED);
436}
437
Zelalem Aweke79e3d292021-07-08 16:51:14 -0500438static inline unsigned int get_armv9_2_feat_rme_support(void)
439{
440 /*
441 * Return the RME version, zero if not supported. This function can be
442 * used as both an integer value for the RME version or compared to zero
443 * to detect RME presence.
444 */
445 return (unsigned int)(read_id_aa64pfr0_el1() >>
446 ID_AA64PFR0_FEAT_RME_SHIFT) & ID_AA64PFR0_FEAT_RME_MASK;
447}
448
Jayanth Dodderi Chidanand9461a892022-01-17 18:57:17 +0000449/*********************************************************************************
450 * Function to identify the presence of FEAT_SB (Speculation Barrier Instruction)
451 ********************************************************************************/
Andre Przywara46880dc2022-11-17 16:42:09 +0000452static inline unsigned int read_feat_sb_id_field(void)
Jayanth Dodderi Chidanand9461a892022-01-17 18:57:17 +0000453{
Andre Przywara46880dc2022-11-17 16:42:09 +0000454 return ISOLATE_FIELD(read_id_aa64isar1_el1(), ID_AA64ISAR1_SB);
Jayanth Dodderi Chidanand9461a892022-01-17 18:57:17 +0000455}
456
457/*********************************************************************************
458 * Function to identify the presence of FEAT_CSV2_2 (Cache Speculation Variant 2)
459 ********************************************************************************/
Andre Przywara902c9022022-11-17 17:30:43 +0000460static inline unsigned int read_feat_csv2_id_field(void)
461{
462 return ISOLATE_FIELD(read_id_aa64pfr0_el1(), ID_AA64PFR0_CSV2);
463}
464
465static inline bool is_feat_csv2_2_supported(void)
Jayanth Dodderi Chidanand9461a892022-01-17 18:57:17 +0000466{
Andre Przywara902c9022022-11-17 17:30:43 +0000467 if (ENABLE_FEAT_CSV2_2 == FEAT_STATE_DISABLED) {
468 return false;
469 }
470
471 if (ENABLE_FEAT_CSV2_2 == FEAT_STATE_ALWAYS) {
472 return true;
473 }
474
475 return read_feat_csv2_id_field() >= ID_AA64PFR0_CSV2_2_SUPPORTED;
Jayanth Dodderi Chidanand9461a892022-01-17 18:57:17 +0000476}
477
478/**********************************************************************************
479 * Function to identify the presence of FEAT_SPE (Statistical Profiling Extension)
480 *********************************************************************************/
Andre Przywaraf3e8cfc2022-11-17 16:42:09 +0000481static inline unsigned int read_feat_spe_id_field(void)
482{
483 return ISOLATE_FIELD(read_id_aa64dfr0_el1(), ID_AA64DFR0_PMS);
484}
485
486static inline bool is_feat_spe_supported(void)
Jayanth Dodderi Chidanand9461a892022-01-17 18:57:17 +0000487{
Andre Przywaraf3e8cfc2022-11-17 16:42:09 +0000488 if (ENABLE_SPE_FOR_NS == FEAT_STATE_DISABLED) {
489 return false;
490 }
491
492 if (ENABLE_SPE_FOR_NS == FEAT_STATE_ALWAYS) {
493 return true;
494 }
495
496 return read_feat_spe_id_field() != 0U;
Jayanth Dodderi Chidanand9461a892022-01-17 18:57:17 +0000497}
498
499/*******************************************************************************
500 * Function to identify the presence of FEAT_SVE (Scalable Vector Extension)
501 ******************************************************************************/
Jayanth Dodderi Chidanandd62c6812023-03-07 10:43:19 +0000502static inline unsigned int read_feat_sve_id_field(void)
503{
504 return ISOLATE_FIELD(read_id_aa64pfr0_el1(), ID_AA64PFR0_SVE);
505}
506
507static inline bool is_feat_sve_supported(void)
Jayanth Dodderi Chidanand9461a892022-01-17 18:57:17 +0000508{
Jayanth Dodderi Chidanandd62c6812023-03-07 10:43:19 +0000509 if (ENABLE_SVE_FOR_NS == FEAT_STATE_DISABLED) {
510 return false;
511 }
512
513 if (ENABLE_SVE_FOR_NS == FEAT_STATE_ALWAYS) {
514 return true;
515 }
516
517 return read_feat_sve_id_field() >= ID_AA64PFR0_SVE_SUPPORTED;
Jayanth Dodderi Chidanand9461a892022-01-17 18:57:17 +0000518}
519
Andre Przywara870627e2023-01-27 12:25:49 +0000520static unsigned int read_feat_ras_id_field(void)
521{
522 return ISOLATE_FIELD(read_id_aa64pfr0_el1(), ID_AA64PFR0_RAS);
523}
524
525static inline bool is_feat_ras_supported(void)
Jayanth Dodderi Chidanand9461a892022-01-17 18:57:17 +0000526{
Andre Przywara870627e2023-01-27 12:25:49 +0000527 if (ENABLE_FEAT_RAS == FEAT_STATE_DISABLED) {
528 return false;
529 }
530
531 if (ENABLE_FEAT_RAS == FEAT_STATE_ALWAYS) {
532 return true;
533 }
534
535 return read_feat_ras_id_field() != 0U;
Jayanth Dodderi Chidanand9461a892022-01-17 18:57:17 +0000536}
537
Andre Przywara1f55c412023-01-26 16:47:52 +0000538static unsigned int read_feat_dit_id_field(void)
539{
540 return ISOLATE_FIELD(read_id_aa64pfr0_el1(), ID_AA64PFR0_DIT);
541}
542
543static inline bool is_feat_dit_supported(void)
Jayanth Dodderi Chidanand9461a892022-01-17 18:57:17 +0000544{
Andre Przywara1f55c412023-01-26 16:47:52 +0000545 if (ENABLE_FEAT_DIT == FEAT_STATE_DISABLED) {
546 return false;
547 }
548
549 if (ENABLE_FEAT_DIT == FEAT_STATE_ALWAYS) {
550 return true;
551 }
552
553 return read_feat_dit_id_field() != 0U;
Jayanth Dodderi Chidanand9461a892022-01-17 18:57:17 +0000554}
555
Andre Przywara44e33e02022-11-17 16:42:09 +0000556static inline unsigned int read_feat_tracever_id_field(void)
557{
558 return ISOLATE_FIELD(read_id_aa64dfr0_el1(), ID_AA64DFR0_TRACEVER);
559}
560
561static inline bool is_feat_sys_reg_trace_supported(void)
562{
563 if (ENABLE_SYS_REG_TRACE_FOR_NS == FEAT_STATE_DISABLED) {
564 return false;
565 }
566
567 if (ENABLE_SYS_REG_TRACE_FOR_NS == FEAT_STATE_ALWAYS) {
568 return true;
569 }
570
571 return read_feat_tracever_id_field() != 0U;
572}
573
Jayanth Dodderi Chidanand9461a892022-01-17 18:57:17 +0000574/*************************************************************************
575 * Function to identify the presence of FEAT_TRF (TraceLift)
576 ************************************************************************/
Andre Przywara06ea44e2022-11-17 17:30:43 +0000577static inline unsigned int read_feat_trf_id_field(void)
578{
579 return ISOLATE_FIELD(read_id_aa64dfr0_el1(), ID_AA64DFR0_TRACEFILT);
580}
581
582static inline bool is_feat_trf_supported(void)
Jayanth Dodderi Chidanand9461a892022-01-17 18:57:17 +0000583{
Andre Przywara06ea44e2022-11-17 17:30:43 +0000584 if (ENABLE_TRF_FOR_NS == FEAT_STATE_DISABLED) {
585 return false;
586 }
587
588 if (ENABLE_TRF_FOR_NS == FEAT_STATE_ALWAYS) {
589 return true;
590 }
591
592 return read_feat_trf_id_field() != 0U;
Jayanth Dodderi Chidanand9461a892022-01-17 18:57:17 +0000593}
594
Jayanth Dodderi Chidanand9461a892022-01-17 18:57:17 +0000595/********************************************************************************
596 * Function to identify the presence of FEAT_NV2 (Enhanced Nested Virtualization
597 * Support)
598 *******************************************************************************/
Andre Przywaraedc449d2023-01-27 14:09:20 +0000599static inline unsigned int read_feat_nv_id_field(void)
600{
601 return ISOLATE_FIELD(read_id_aa64mmfr2_el1(), ID_AA64MMFR2_EL1_NV);
602}
603
604static inline bool is_feat_nv2_supported(void)
Jayanth Dodderi Chidanand9461a892022-01-17 18:57:17 +0000605{
Andre Przywaraedc449d2023-01-27 14:09:20 +0000606 if (CTX_INCLUDE_NEVE_REGS == FEAT_STATE_DISABLED) {
607 return false;
608 }
609
610 if (CTX_INCLUDE_NEVE_REGS == FEAT_STATE_ALWAYS) {
611 return true;
612 }
613
614 return read_feat_nv_id_field() >= ID_AA64MMFR2_EL1_NV2_SUPPORTED;
Jayanth Dodderi Chidanand9461a892022-01-17 18:57:17 +0000615}
616
Jayanth Dodderi Chidanand69316752022-05-09 12:33:03 +0100617/*******************************************************************************
618 * Function to identify the presence of FEAT_BRBE (Branch Record Buffer
619 * Extension)
620 ******************************************************************************/
Andre Przywarac97c5512022-11-17 16:42:09 +0000621static inline unsigned int read_feat_brbe_id_field(void)
622{
623 return ISOLATE_FIELD(read_id_aa64dfr0_el1(), ID_AA64DFR0_BRBE);
624}
625
626static inline bool is_feat_brbe_supported(void)
Jayanth Dodderi Chidanand69316752022-05-09 12:33:03 +0100627{
Andre Przywarac97c5512022-11-17 16:42:09 +0000628 if (ENABLE_BRBE_FOR_NS == FEAT_STATE_DISABLED) {
629 return false;
630 }
631
632 if (ENABLE_BRBE_FOR_NS == FEAT_STATE_ALWAYS) {
633 return true;
634 }
635
636 return read_feat_brbe_id_field() != 0U;
Jayanth Dodderi Chidanand69316752022-05-09 12:33:03 +0100637}
638
Jayanth Dodderi Chidananda793ccc2022-05-19 14:08:28 +0100639/*******************************************************************************
640 * Function to identify the presence of FEAT_TRBE (Trace Buffer Extension)
641 ******************************************************************************/
Andre Przywara191eff62022-11-17 16:42:09 +0000642static inline unsigned int read_feat_trbe_id_field(void)
Jayanth Dodderi Chidananda793ccc2022-05-19 14:08:28 +0100643{
Andre Przywara191eff62022-11-17 16:42:09 +0000644 return ISOLATE_FIELD(read_id_aa64dfr0_el1(), ID_AA64DFR0_TRACEBUFFER);
Jayanth Dodderi Chidananda793ccc2022-05-19 14:08:28 +0100645}
Jayanth Dodderi Chidanand69316752022-05-09 12:33:03 +0100646
Andre Przywara191eff62022-11-17 16:42:09 +0000647static inline bool is_feat_trbe_supported(void)
648{
649 if (ENABLE_TRBE_FOR_NS == FEAT_STATE_DISABLED) {
650 return false;
651 }
652
653 if (ENABLE_TRBE_FOR_NS == FEAT_STATE_ALWAYS) {
654 return true;
655 }
656
657 return read_feat_trbe_id_field() != 0U;
658
659}
Boyan Karatotev05504ba2023-02-15 13:21:50 +0000660
Jayanth Dodderi Chidanand605419a2023-03-06 23:56:14 +0000661/*******************************************************************************
662 * Function to identify the presence of FEAT_SMEx (Scalar Matrix Extension)
663 ******************************************************************************/
664static inline unsigned int read_feat_sme_fa64_id_field(void)
665{
666 return ISOLATE_FIELD(read_id_aa64smfr0_el1(), ID_AA64SMFR0_EL1_SME_FA64);
667}
668
669static inline unsigned int read_feat_sme_id_field(void)
670{
671 return ISOLATE_FIELD(read_id_aa64pfr1_el1(), ID_AA64PFR1_EL1_SME);
672}
673
674static inline bool is_feat_sme_supported(void)
675{
676 if (ENABLE_SME_FOR_NS == FEAT_STATE_DISABLED) {
677 return false;
678 }
679
680 if (ENABLE_SME_FOR_NS == FEAT_STATE_ALWAYS) {
681 return true;
682 }
683
684 return read_feat_sme_id_field() >= ID_AA64PFR1_EL1_SME_SUPPORTED;
685}
686
Jayanth Dodderi Chidanandcfe053a2022-11-08 10:31:07 +0000687static inline bool is_feat_sme2_supported(void)
688{
689 if (ENABLE_SME2_FOR_NS == FEAT_STATE_DISABLED) {
690 return false;
691 }
692
693 if (ENABLE_SME2_FOR_NS == FEAT_STATE_ALWAYS) {
694 return true;
695 }
696
697 return read_feat_sme_id_field() >= ID_AA64PFR1_EL1_SME2_SUPPORTED;
698}
699
Javier Almansa Sobrino8c8107e2023-05-03 12:16:11 +0100700/*******************************************************************************
701 * Function to get hardware granularity support
702 ******************************************************************************/
703
704static inline unsigned int read_id_aa64mmfr0_el0_tgran4_field(void)
705{
706 return ISOLATE_FIELD(read_id_aa64mmfr0_el1(), ID_AA64MMFR0_EL1_TGRAN4);
707}
708
709static inline unsigned int read_id_aa64mmfr0_el0_tgran16_field(void)
710{
711 return ISOLATE_FIELD(read_id_aa64mmfr0_el1(),
712 ID_AA64MMFR0_EL1_TGRAN16);
713}
714
715static inline unsigned int read_id_aa64mmfr0_el0_tgran64_field(void)
716{
717 return ISOLATE_FIELD(read_id_aa64mmfr0_el1(),
718 ID_AA64MMFR0_EL1_TGRAN64);
719}
720
Boyan Karatotev05504ba2023-02-15 13:21:50 +0000721static inline unsigned int read_feat_pmuv3_id_field(void)
722{
723 return ISOLATE_FIELD(read_id_aa64dfr0_el1(), ID_AA64DFR0_PMUVER);
724}
725
Boyan Karatotev677ed8a2023-02-16 09:45:29 +0000726static inline unsigned int read_feat_mtpmu_id_field(void)
727{
728 return ISOLATE_FIELD(read_id_aa64dfr0_el1(), ID_AA64DFR0_MTPMU);
729}
730
731static inline bool is_feat_mtpmu_supported(void)
732{
733 if (DISABLE_MTPMU == FEAT_STATE_DISABLED) {
734 return false;
735 }
736
737 if (DISABLE_MTPMU == FEAT_STATE_ALWAYS) {
738 return true;
739 }
740
741 unsigned int mtpmu = read_feat_mtpmu_id_field();
742
743 return (mtpmu != 0U) && (mtpmu != ID_AA64DFR0_MTPMU_DISABLED);
744}
745
Antonio Nino Diazc326c342019-01-11 11:20:10 +0000746#endif /* ARCH_FEATURES_H */