1 /*
2 * Copyright (c) 2019-2023, Arm Limited. All rights reserved.
3 *
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>
13 #include <common/feat_detect.h>
14
15 #define ISOLATE_FIELD(reg, feat) \
16 ((unsigned int)(((reg) >> (feat ## _SHIFT)) & (feat ## _MASK)))
17
is_armv7_gentimer_present(void)18 static 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
read_feat_pan_id_field(void)24 static inline unsigned int read_feat_pan_id_field(void)
25 {
26 return ISOLATE_FIELD(read_id_aa64mmfr1_el1(), ID_AA64MMFR1_EL1_PAN);
27 }
28
is_feat_pan_supported(void)29 static inline bool is_feat_pan_supported(void)
30 {
31 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;
40 }
41
read_feat_vhe_id_field(void)42 static inline unsigned int read_feat_vhe_id_field(void)
43 {
44 return ISOLATE_FIELD(read_id_aa64mmfr1_el1(), ID_AA64MMFR1_EL1_VHE);
45 }
46
is_feat_vhe_supported(void)47 static inline bool is_feat_vhe_supported(void)
48 {
49 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;
58 }
59
is_armv8_2_ttcnp_present(void)60 static 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
is_feat_pacqarma3_present(void)66 static 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
is_armv8_3_pauth_present(void)76 static inline bool is_armv8_3_pauth_present(void)
77 {
78 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);
83
84 /*
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());
90 }
91
is_armv8_4_ttst_present(void)92 static 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
is_armv8_5_bti_present(void)98 static 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
get_armv8_5_mte_support(void)104 static 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
read_feat_sel2_id_field(void)110 static inline unsigned int read_feat_sel2_id_field(void)
111 {
112 return ISOLATE_FIELD(read_id_aa64pfr0_el1(), ID_AA64PFR0_SEL2);
113 }
114
is_feat_sel2_supported(void)115 static inline bool is_feat_sel2_supported(void)
116 {
117 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;
126 }
127
read_feat_twed_id_field(void)128 static inline unsigned int read_feat_twed_id_field(void)
129 {
130 return ISOLATE_FIELD(read_id_aa64mmfr1_el1(), ID_AA64MMFR1_EL1_TWED);
131 }
132
is_feat_twed_supported(void)133 static inline bool is_feat_twed_supported(void)
134 {
135 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;
144 }
145
read_feat_fgt_id_field(void)146 static unsigned int read_feat_fgt_id_field(void)
147 {
148 return ISOLATE_FIELD(read_id_aa64mmfr0_el1(), ID_AA64MMFR0_EL1_FGT);
149 }
150
is_feat_fgt_supported(void)151 static inline bool is_feat_fgt_supported(void)
152 {
153 if (ENABLE_FEAT_FGT == FEAT_STATE_DISABLED) {
154 return false;
155 }
156
157 if (ENABLE_FEAT_FGT == FEAT_STATE_ALWAYS) {
158 return true;
159 }
160
161 return read_feat_fgt_id_field() != 0U;
162 }
163
read_feat_ecv_id_field(void)164 static unsigned int read_feat_ecv_id_field(void)
165 {
166 return ISOLATE_FIELD(read_id_aa64mmfr0_el1(), ID_AA64MMFR0_EL1_ECV);
167 }
168
is_feat_ecv_supported(void)169 static inline bool is_feat_ecv_supported(void)
170 {
171 if (ENABLE_FEAT_ECV == FEAT_STATE_DISABLED) {
172 return false;
173 }
174
175 if (ENABLE_FEAT_ECV == FEAT_STATE_ALWAYS) {
176 return true;
177 }
178
179 return read_feat_ecv_id_field() != 0U;
180 }
181
is_feat_ecv_v2_supported(void)182 static inline bool is_feat_ecv_v2_supported(void)
183 {
184 if (ENABLE_FEAT_ECV == FEAT_STATE_DISABLED) {
185 return false;
186 }
187
188 if (ENABLE_FEAT_ECV == FEAT_STATE_ALWAYS) {
189 return true;
190 }
191
192 return read_feat_ecv_id_field() >= ID_AA64MMFR0_EL1_ECV_SELF_SYNCH;
193 }
194
read_feat_rng_id_field(void)195 static unsigned int read_feat_rng_id_field(void)
196 {
197 return ISOLATE_FIELD(read_id_aa64isar0_el1(), ID_AA64ISAR0_RNDR);
198 }
199
is_feat_rng_supported(void)200 static inline bool is_feat_rng_supported(void)
201 {
202 if (ENABLE_FEAT_RNG == FEAT_STATE_DISABLED) {
203 return false;
204 }
205
206 if (ENABLE_FEAT_RNG == FEAT_STATE_ALWAYS) {
207 return true;
208 }
209
210 return read_feat_rng_id_field() != 0U;
211 }
212
read_feat_tcrx_id_field(void)213 static unsigned int read_feat_tcrx_id_field(void)
214 {
215 return ISOLATE_FIELD(read_id_aa64mmfr3_el1(), ID_AA64MMFR3_EL1_TCRX);
216 }
217
is_feat_tcr2_supported(void)218 static inline bool is_feat_tcr2_supported(void)
219 {
220 if (ENABLE_FEAT_TCR2 == FEAT_STATE_DISABLED) {
221 return false;
222 }
223
224 if (ENABLE_FEAT_TCR2 == FEAT_STATE_ALWAYS) {
225 return true;
226 }
227
228 return read_feat_tcrx_id_field() != 0U;
229 }
230
read_feat_s2poe_id_field(void)231 static unsigned int read_feat_s2poe_id_field(void)
232 {
233 return ISOLATE_FIELD(read_id_aa64mmfr3_el1(), ID_AA64MMFR3_EL1_S2POE);
234 }
235
is_feat_s2poe_supported(void)236 static inline bool is_feat_s2poe_supported(void)
237 {
238 if (ENABLE_FEAT_S2POE == FEAT_STATE_DISABLED) {
239 return false;
240 }
241
242 if (ENABLE_FEAT_S2POE == FEAT_STATE_ALWAYS) {
243 return true;
244 }
245
246 return read_feat_s2poe_id_field() != 0U;
247 }
248
read_feat_s1poe_id_field(void)249 static unsigned int read_feat_s1poe_id_field(void)
250 {
251 return ISOLATE_FIELD(read_id_aa64mmfr3_el1(), ID_AA64MMFR3_EL1_S1POE);
252 }
253
is_feat_s1poe_supported(void)254 static inline bool is_feat_s1poe_supported(void)
255 {
256 if (ENABLE_FEAT_S1POE == FEAT_STATE_DISABLED) {
257 return false;
258 }
259
260 if (ENABLE_FEAT_S1POE == FEAT_STATE_ALWAYS) {
261 return true;
262 }
263
264 return read_feat_s1poe_id_field() != 0U;
265 }
266
is_feat_sxpoe_supported(void)267 static inline bool is_feat_sxpoe_supported(void)
268 {
269 return is_feat_s1poe_supported() || is_feat_s2poe_supported();
270 }
271
read_feat_s2pie_id_field(void)272 static unsigned int read_feat_s2pie_id_field(void)
273 {
274 return ISOLATE_FIELD(read_id_aa64mmfr3_el1(), ID_AA64MMFR3_EL1_S2PIE);
275 }
276
is_feat_s2pie_supported(void)277 static inline bool is_feat_s2pie_supported(void)
278 {
279 if (ENABLE_FEAT_S2PIE == FEAT_STATE_DISABLED) {
280 return false;
281 }
282
283 if (ENABLE_FEAT_S2PIE == FEAT_STATE_ALWAYS) {
284 return true;
285 }
286
287 return read_feat_s2pie_id_field() != 0U;
288 }
289
read_feat_s1pie_id_field(void)290 static unsigned int read_feat_s1pie_id_field(void)
291 {
292 return ISOLATE_FIELD(read_id_aa64mmfr3_el1(), ID_AA64MMFR3_EL1_S1PIE);
293 }
294
is_feat_s1pie_supported(void)295 static inline bool is_feat_s1pie_supported(void)
296 {
297 if (ENABLE_FEAT_S1PIE == FEAT_STATE_DISABLED) {
298 return false;
299 }
300
301 if (ENABLE_FEAT_S1PIE == FEAT_STATE_ALWAYS) {
302 return true;
303 }
304
305 return read_feat_s1pie_id_field() != 0U;
306 }
307
is_feat_sxpie_supported(void)308 static inline bool is_feat_sxpie_supported(void)
309 {
310 return is_feat_s1pie_supported() || is_feat_s2pie_supported();
311 }
312
read_feat_gcs_id_field(void)313 static unsigned int read_feat_gcs_id_field(void)
314 {
315 return ISOLATE_FIELD(read_id_aa64pfr1_el1(), ID_AA64PFR1_EL1_GCS);
316 }
317
is_feat_gcs_supported(void)318 static inline bool is_feat_gcs_supported(void)
319 {
320 if (ENABLE_FEAT_GCS == FEAT_STATE_DISABLED) {
321 return false;
322 }
323
324 if (ENABLE_FEAT_GCS == FEAT_STATE_ALWAYS) {
325 return true;
326 }
327
328 return read_feat_gcs_id_field() != 0U;
329 }
330
331 /*******************************************************************************
332 * Functions to identify the presence of the Activity Monitors Extension
333 ******************************************************************************/
read_feat_amu_id_field(void)334 static unsigned int read_feat_amu_id_field(void)
335 {
336 return ISOLATE_FIELD(read_id_aa64pfr0_el1(), ID_AA64PFR0_AMU);
337 }
338
is_feat_amu_supported(void)339 static inline bool is_feat_amu_supported(void)
340 {
341 if (ENABLE_FEAT_AMU == FEAT_STATE_DISABLED) {
342 return false;
343 }
344
345 if (ENABLE_FEAT_AMU == FEAT_STATE_ALWAYS) {
346 return true;
347 }
348
349 return read_feat_amu_id_field() >= ID_AA64PFR0_AMU_V1;
350 }
351
is_feat_amuv1p1_supported(void)352 static inline bool is_feat_amuv1p1_supported(void)
353 {
354 if (ENABLE_FEAT_AMUv1p1 == FEAT_STATE_DISABLED) {
355 return false;
356 }
357
358 if (ENABLE_FEAT_AMUv1p1 == FEAT_STATE_ALWAYS) {
359 return true;
360 }
361
362 return read_feat_amu_id_field() >= ID_AA64PFR0_AMU_V1P1;
363 }
364
365 /*
366 * Return MPAM version:
367 *
368 * 0x00: None Armv8.0 or later
369 * 0x01: v0.1 Armv8.4 or later
370 * 0x10: v1.0 Armv8.2 or later
371 * 0x11: v1.1 Armv8.4 or later
372 *
373 */
read_feat_mpam_version(void)374 static inline unsigned int read_feat_mpam_version(void)
375 {
376 return (unsigned int)((((read_id_aa64pfr0_el1() >>
377 ID_AA64PFR0_MPAM_SHIFT) & ID_AA64PFR0_MPAM_MASK) << 4) |
378 ((read_id_aa64pfr1_el1() >>
379 ID_AA64PFR1_MPAM_FRAC_SHIFT) & ID_AA64PFR1_MPAM_FRAC_MASK));
380 }
381
is_feat_mpam_supported(void)382 static inline bool is_feat_mpam_supported(void)
383 {
384 if (ENABLE_MPAM_FOR_LOWER_ELS == FEAT_STATE_DISABLED) {
385 return false;
386 }
387
388 if (ENABLE_MPAM_FOR_LOWER_ELS == FEAT_STATE_ALWAYS) {
389 return true;
390 }
391
392 return read_feat_mpam_version() != 0U;
393 }
394
read_feat_hcx_id_field(void)395 static inline unsigned int read_feat_hcx_id_field(void)
396 {
397 return ISOLATE_FIELD(read_id_aa64mmfr1_el1(), ID_AA64MMFR1_EL1_HCX);
398 }
399
is_feat_hcx_supported(void)400 static inline bool is_feat_hcx_supported(void)
401 {
402 if (ENABLE_FEAT_HCX == FEAT_STATE_DISABLED) {
403 return false;
404 }
405
406 if (ENABLE_FEAT_HCX == FEAT_STATE_ALWAYS) {
407 return true;
408 }
409
410 return read_feat_hcx_id_field() != 0U;
411 }
412
is_feat_rng_trap_present(void)413 static inline bool is_feat_rng_trap_present(void)
414 {
415 return (((read_id_aa64pfr1_el1() >> ID_AA64PFR1_EL1_RNDR_TRAP_SHIFT) &
416 ID_AA64PFR1_EL1_RNDR_TRAP_MASK)
417 == ID_AA64PFR1_EL1_RNG_TRAP_SUPPORTED);
418 }
419
get_armv9_2_feat_rme_support(void)420 static inline unsigned int get_armv9_2_feat_rme_support(void)
421 {
422 /*
423 * Return the RME version, zero if not supported. This function can be
424 * used as both an integer value for the RME version or compared to zero
425 * to detect RME presence.
426 */
427 return (unsigned int)(read_id_aa64pfr0_el1() >>
428 ID_AA64PFR0_FEAT_RME_SHIFT) & ID_AA64PFR0_FEAT_RME_MASK;
429 }
430
431 /*********************************************************************************
432 * Function to identify the presence of FEAT_SB (Speculation Barrier Instruction)
433 ********************************************************************************/
read_feat_sb_id_field(void)434 static inline unsigned int read_feat_sb_id_field(void)
435 {
436 return ISOLATE_FIELD(read_id_aa64isar1_el1(), ID_AA64ISAR1_SB);
437 }
438
439 /*********************************************************************************
440 * Function to identify the presence of FEAT_CSV2_2 (Cache Speculation Variant 2)
441 ********************************************************************************/
read_feat_csv2_id_field(void)442 static inline unsigned int read_feat_csv2_id_field(void)
443 {
444 return ISOLATE_FIELD(read_id_aa64pfr0_el1(), ID_AA64PFR0_CSV2);
445 }
446
is_feat_csv2_2_supported(void)447 static inline bool is_feat_csv2_2_supported(void)
448 {
449 if (ENABLE_FEAT_CSV2_2 == FEAT_STATE_DISABLED) {
450 return false;
451 }
452
453 if (ENABLE_FEAT_CSV2_2 == FEAT_STATE_ALWAYS) {
454 return true;
455 }
456
457 return read_feat_csv2_id_field() >= ID_AA64PFR0_CSV2_2_SUPPORTED;
458 }
459
460 /**********************************************************************************
461 * Function to identify the presence of FEAT_SPE (Statistical Profiling Extension)
462 *********************************************************************************/
read_feat_spe_id_field(void)463 static inline unsigned int read_feat_spe_id_field(void)
464 {
465 return ISOLATE_FIELD(read_id_aa64dfr0_el1(), ID_AA64DFR0_PMS);
466 }
467
is_feat_spe_supported(void)468 static inline bool is_feat_spe_supported(void)
469 {
470 if (ENABLE_SPE_FOR_NS == FEAT_STATE_DISABLED) {
471 return false;
472 }
473
474 if (ENABLE_SPE_FOR_NS == FEAT_STATE_ALWAYS) {
475 return true;
476 }
477
478 return read_feat_spe_id_field() != 0U;
479 }
480
481 /*******************************************************************************
482 * Function to identify the presence of FEAT_SVE (Scalable Vector Extension)
483 ******************************************************************************/
read_feat_sve_id_field(void)484 static inline unsigned int read_feat_sve_id_field(void)
485 {
486 return ISOLATE_FIELD(read_id_aa64pfr0_el1(), ID_AA64PFR0_SVE);
487 }
488
is_feat_sve_supported(void)489 static inline bool is_feat_sve_supported(void)
490 {
491 if (ENABLE_SVE_FOR_NS == FEAT_STATE_DISABLED) {
492 return false;
493 }
494
495 if (ENABLE_SVE_FOR_NS == FEAT_STATE_ALWAYS) {
496 return true;
497 }
498
499 return read_feat_sve_id_field() >= ID_AA64PFR0_SVE_SUPPORTED;
500 }
501
read_feat_ras_id_field(void)502 static unsigned int read_feat_ras_id_field(void)
503 {
504 return ISOLATE_FIELD(read_id_aa64pfr0_el1(), ID_AA64PFR0_RAS);
505 }
506
is_feat_ras_supported(void)507 static inline bool is_feat_ras_supported(void)
508 {
509 if (ENABLE_FEAT_RAS == FEAT_STATE_DISABLED) {
510 return false;
511 }
512
513 if (ENABLE_FEAT_RAS == FEAT_STATE_ALWAYS) {
514 return true;
515 }
516
517 return read_feat_ras_id_field() != 0U;
518 }
519
read_feat_dit_id_field(void)520 static unsigned int read_feat_dit_id_field(void)
521 {
522 return ISOLATE_FIELD(read_id_aa64pfr0_el1(), ID_AA64PFR0_DIT);
523 }
524
is_feat_dit_supported(void)525 static inline bool is_feat_dit_supported(void)
526 {
527 if (ENABLE_FEAT_DIT == FEAT_STATE_DISABLED) {
528 return false;
529 }
530
531 if (ENABLE_FEAT_DIT == FEAT_STATE_ALWAYS) {
532 return true;
533 }
534
535 return read_feat_dit_id_field() != 0U;
536 }
537
read_feat_tracever_id_field(void)538 static inline unsigned int read_feat_tracever_id_field(void)
539 {
540 return ISOLATE_FIELD(read_id_aa64dfr0_el1(), ID_AA64DFR0_TRACEVER);
541 }
542
is_feat_sys_reg_trace_supported(void)543 static inline bool is_feat_sys_reg_trace_supported(void)
544 {
545 if (ENABLE_SYS_REG_TRACE_FOR_NS == FEAT_STATE_DISABLED) {
546 return false;
547 }
548
549 if (ENABLE_SYS_REG_TRACE_FOR_NS == FEAT_STATE_ALWAYS) {
550 return true;
551 }
552
553 return read_feat_tracever_id_field() != 0U;
554 }
555
556 /*************************************************************************
557 * Function to identify the presence of FEAT_TRF (TraceLift)
558 ************************************************************************/
read_feat_trf_id_field(void)559 static inline unsigned int read_feat_trf_id_field(void)
560 {
561 return ISOLATE_FIELD(read_id_aa64dfr0_el1(), ID_AA64DFR0_TRACEFILT);
562 }
563
is_feat_trf_supported(void)564 static inline bool is_feat_trf_supported(void)
565 {
566 if (ENABLE_TRF_FOR_NS == FEAT_STATE_DISABLED) {
567 return false;
568 }
569
570 if (ENABLE_TRF_FOR_NS == FEAT_STATE_ALWAYS) {
571 return true;
572 }
573
574 return read_feat_trf_id_field() != 0U;
575 }
576
577 /********************************************************************************
578 * Function to identify the presence of FEAT_NV2 (Enhanced Nested Virtualization
579 * Support)
580 *******************************************************************************/
read_feat_nv_id_field(void)581 static inline unsigned int read_feat_nv_id_field(void)
582 {
583 return ISOLATE_FIELD(read_id_aa64mmfr2_el1(), ID_AA64MMFR2_EL1_NV);
584 }
585
is_feat_nv2_supported(void)586 static inline bool is_feat_nv2_supported(void)
587 {
588 if (CTX_INCLUDE_NEVE_REGS == FEAT_STATE_DISABLED) {
589 return false;
590 }
591
592 if (CTX_INCLUDE_NEVE_REGS == FEAT_STATE_ALWAYS) {
593 return true;
594 }
595
596 return read_feat_nv_id_field() >= ID_AA64MMFR2_EL1_NV2_SUPPORTED;
597 }
598
599 /*******************************************************************************
600 * Function to identify the presence of FEAT_BRBE (Branch Record Buffer
601 * Extension)
602 ******************************************************************************/
read_feat_brbe_id_field(void)603 static inline unsigned int read_feat_brbe_id_field(void)
604 {
605 return ISOLATE_FIELD(read_id_aa64dfr0_el1(), ID_AA64DFR0_BRBE);
606 }
607
is_feat_brbe_supported(void)608 static inline bool is_feat_brbe_supported(void)
609 {
610 if (ENABLE_BRBE_FOR_NS == FEAT_STATE_DISABLED) {
611 return false;
612 }
613
614 if (ENABLE_BRBE_FOR_NS == FEAT_STATE_ALWAYS) {
615 return true;
616 }
617
618 return read_feat_brbe_id_field() != 0U;
619 }
620
621 /*******************************************************************************
622 * Function to identify the presence of FEAT_TRBE (Trace Buffer Extension)
623 ******************************************************************************/
read_feat_trbe_id_field(void)624 static inline unsigned int read_feat_trbe_id_field(void)
625 {
626 return ISOLATE_FIELD(read_id_aa64dfr0_el1(), ID_AA64DFR0_TRACEBUFFER);
627 }
628
is_feat_trbe_supported(void)629 static inline bool is_feat_trbe_supported(void)
630 {
631 if (ENABLE_TRBE_FOR_NS == FEAT_STATE_DISABLED) {
632 return false;
633 }
634
635 if (ENABLE_TRBE_FOR_NS == FEAT_STATE_ALWAYS) {
636 return true;
637 }
638
639 return read_feat_trbe_id_field() != 0U;
640
641 }
642 /*******************************************************************************
643 * Function to identify the presence of FEAT_SMEx (Scalar Matrix Extension)
644 ******************************************************************************/
read_feat_sme_fa64_id_field(void)645 static inline unsigned int read_feat_sme_fa64_id_field(void)
646 {
647 return ISOLATE_FIELD(read_id_aa64smfr0_el1(), ID_AA64SMFR0_EL1_SME_FA64);
648 }
649
read_feat_sme_id_field(void)650 static inline unsigned int read_feat_sme_id_field(void)
651 {
652 return ISOLATE_FIELD(read_id_aa64pfr1_el1(), ID_AA64PFR1_EL1_SME);
653 }
654
is_feat_sme_supported(void)655 static inline bool is_feat_sme_supported(void)
656 {
657 if (ENABLE_SME_FOR_NS == FEAT_STATE_DISABLED) {
658 return false;
659 }
660
661 if (ENABLE_SME_FOR_NS == FEAT_STATE_ALWAYS) {
662 return true;
663 }
664
665 return read_feat_sme_id_field() >= ID_AA64PFR1_EL1_SME_SUPPORTED;
666 }
667
is_feat_sme2_supported(void)668 static inline bool is_feat_sme2_supported(void)
669 {
670 if (ENABLE_SME2_FOR_NS == FEAT_STATE_DISABLED) {
671 return false;
672 }
673
674 if (ENABLE_SME2_FOR_NS == FEAT_STATE_ALWAYS) {
675 return true;
676 }
677
678 return read_feat_sme_id_field() >= ID_AA64PFR1_EL1_SME2_SUPPORTED;
679 }
680
681 #endif /* ARCH_FEATURES_H */
682