blob: 0342d2f7cf0f6447b3d22282a1f03823efad3e4d [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
Daniel Boulby60786e72021-10-22 11:37:34 +010092static inline bool is_armv8_4_dit_present(void)
93{
94 return ((read_id_aa64pfr0_el1() >> ID_AA64PFR0_DIT_SHIFT) &
95 ID_AA64PFR0_DIT_MASK) == 1U;
96}
97
Sathees Balya74155972019-01-25 11:36:01 +000098static inline bool is_armv8_4_ttst_present(void)
99{
100 return ((read_id_aa64mmfr2_el1() >> ID_AA64MMFR2_EL1_ST_SHIFT) &
101 ID_AA64MMFR2_EL1_ST_MASK) == 1U;
102}
103
Alexei Fedorov90f2e882019-05-24 12:17:09 +0100104static inline bool is_armv8_5_bti_present(void)
105{
106 return ((read_id_aa64pfr1_el1() >> ID_AA64PFR1_EL1_BT_SHIFT) &
107 ID_AA64PFR1_EL1_BT_MASK) == BTI_IMPLEMENTED;
108}
109
Soby Mathew830f0ad2019-07-12 09:23:38 +0100110static inline unsigned int get_armv8_5_mte_support(void)
111{
112 return ((read_id_aa64pfr1_el1() >> ID_AA64PFR1_EL1_MTE_SHIFT) &
113 ID_AA64PFR1_EL1_MTE_MASK);
114}
115
Olivier Deprez2bae35f2020-04-16 13:39:06 +0200116static inline bool is_armv8_4_sel2_present(void)
117{
118 return ((read_id_aa64pfr0_el1() >> ID_AA64PFR0_SEL2_SHIFT) &
119 ID_AA64PFR0_SEL2_MASK) == 1ULL;
120}
121
johpow013e24c162020-04-22 14:05:13 -0500122static inline bool is_armv8_6_twed_present(void)
123{
124 return (((read_id_aa64mmfr1_el1() >> ID_AA64MMFR1_EL1_TWED_SHIFT) &
125 ID_AA64MMFR1_EL1_TWED_MASK) == ID_AA64MMFR1_EL1_TWED_SUPPORTED);
126}
127
Andre Przywarae8920f62022-11-10 14:28:01 +0000128static unsigned int read_feat_fgt_id_field(void)
Jimmy Brissonecc3c672020-04-16 10:47:56 -0500129{
Andre Przywarabb0db3b2023-01-25 12:26:14 +0000130 return ISOLATE_FIELD(read_id_aa64mmfr0_el1(), ID_AA64MMFR0_EL1_FGT);
Andre Przywarae8920f62022-11-10 14:28:01 +0000131}
132
133static inline bool is_feat_fgt_supported(void)
134{
135 if (ENABLE_FEAT_FGT == FEAT_STATE_DISABLED) {
136 return false;
137 }
138
139 if (ENABLE_FEAT_FGT == FEAT_STATE_ALWAYS) {
140 return true;
141 }
142
143 return read_feat_fgt_id_field() != 0U;
Jimmy Brissonecc3c672020-04-16 10:47:56 -0500144}
145
Andre Przywarac3464182022-11-17 17:30:43 +0000146static unsigned int read_feat_ecv_id_field(void)
147{
148 return ISOLATE_FIELD(read_id_aa64mmfr0_el1(), ID_AA64MMFR0_EL1_ECV);
149}
150
151static inline bool is_feat_ecv_supported(void)
152{
153 if (ENABLE_FEAT_ECV == FEAT_STATE_DISABLED) {
154 return false;
155 }
156
157 if (ENABLE_FEAT_ECV == FEAT_STATE_ALWAYS) {
158 return true;
159 }
160
161 return read_feat_ecv_id_field() != 0U;
162}
163
164static inline bool is_feat_ecv_v2_supported(void)
Jimmy Brisson83573892020-04-16 10:48:02 -0500165{
Andre Przywarac3464182022-11-17 17:30:43 +0000166 if (ENABLE_FEAT_ECV == FEAT_STATE_DISABLED) {
167 return false;
168 }
169
170 if (ENABLE_FEAT_ECV == FEAT_STATE_ALWAYS) {
171 return true;
172 }
173
174 return read_feat_ecv_id_field() >= ID_AA64MMFR0_EL1_ECV_SELF_SYNCH;
Jimmy Brisson83573892020-04-16 10:48:02 -0500175}
176
Tomas Pilar6fd816e2020-10-28 15:34:12 +0000177static inline bool is_armv8_5_rng_present(void)
178{
179 return ((read_id_aa64isar0_el1() >> ID_AA64ISAR0_RNDR_SHIFT) &
180 ID_AA64ISAR0_RNDR_MASK);
181}
182
Mark Brownc37eee72023-03-14 20:13:03 +0000183static unsigned int read_feat_tcrx_id_field(void)
184{
185 return ISOLATE_FIELD(read_id_aa64mmfr3_el1(), ID_AA64MMFR3_EL1_TCRX);
186}
187
188static inline bool is_feat_tcr2_supported(void)
189{
190 if (ENABLE_FEAT_TCR2 == FEAT_STATE_DISABLED) {
191 return false;
192 }
193
194 if (ENABLE_FEAT_TCR2 == FEAT_STATE_ALWAYS) {
195 return true;
196 }
197
198 return read_feat_tcrx_id_field() != 0U;
199}
200
Andre Przywara2c550e32022-11-10 14:41:07 +0000201/*******************************************************************************
202 * Functions to identify the presence of the Activity Monitors Extension
203 ******************************************************************************/
204static unsigned int read_feat_amu_id_field(void)
205{
Andre Przywarabb0db3b2023-01-25 12:26:14 +0000206 return ISOLATE_FIELD(read_id_aa64pfr0_el1(), ID_AA64PFR0_AMU);
Andre Przywara2c550e32022-11-10 14:41:07 +0000207}
208
209static inline bool is_feat_amu_supported(void)
210{
211 if (ENABLE_FEAT_AMUv1 == FEAT_STATE_DISABLED) {
212 return false;
213 }
214
215 if (ENABLE_FEAT_AMUv1 == FEAT_STATE_ALWAYS) {
216 return true;
217 }
218
219 return read_feat_amu_id_field() >= ID_AA64PFR0_AMU_V1;
220}
221
johpow01fa59c6f2020-10-02 13:41:11 -0500222static inline bool is_armv8_6_feat_amuv1p1_present(void)
223{
Andre Przywara2c550e32022-11-10 14:41:07 +0000224 return read_feat_amu_id_field() >= ID_AA64PFR0_AMU_V1P1;
johpow01fa59c6f2020-10-02 13:41:11 -0500225}
226
Alexei Fedorov19933552020-05-26 13:16:41 +0100227/*
228 * Return MPAM version:
229 *
230 * 0x00: None Armv8.0 or later
231 * 0x01: v0.1 Armv8.4 or later
232 * 0x10: v1.0 Armv8.2 or later
233 * 0x11: v1.1 Armv8.4 or later
234 *
235 */
Andre Przywara84b86532022-11-17 16:42:09 +0000236static inline unsigned int read_feat_mpam_version(void)
Alexei Fedorov19933552020-05-26 13:16:41 +0100237{
238 return (unsigned int)((((read_id_aa64pfr0_el1() >>
239 ID_AA64PFR0_MPAM_SHIFT) & ID_AA64PFR0_MPAM_MASK) << 4) |
240 ((read_id_aa64pfr1_el1() >>
241 ID_AA64PFR1_MPAM_FRAC_SHIFT) & ID_AA64PFR1_MPAM_FRAC_MASK));
242}
243
Andre Przywara84b86532022-11-17 16:42:09 +0000244static inline bool is_feat_mpam_supported(void)
245{
246 if (ENABLE_MPAM_FOR_LOWER_ELS == FEAT_STATE_DISABLED) {
247 return false;
248 }
249
250 if (ENABLE_MPAM_FOR_LOWER_ELS == FEAT_STATE_ALWAYS) {
251 return true;
252 }
253
254 return read_feat_mpam_version() != 0U;
255}
256
Andre Przywaraf20ad902022-11-15 11:45:19 +0000257static inline unsigned int read_feat_hcx_id_field(void)
258{
Andre Przywarabb0db3b2023-01-25 12:26:14 +0000259 return ISOLATE_FIELD(read_id_aa64mmfr1_el1(), ID_AA64MMFR1_EL1_HCX);
Andre Przywaraf20ad902022-11-15 11:45:19 +0000260}
261
262static inline bool is_feat_hcx_supported(void)
johpow01f91e59f2021-08-04 19:38:18 -0500263{
Andre Przywaraf20ad902022-11-15 11:45:19 +0000264 if (ENABLE_FEAT_HCX == FEAT_STATE_DISABLED) {
265 return false;
266 }
267
268 if (ENABLE_FEAT_HCX == FEAT_STATE_ALWAYS) {
269 return true;
270 }
271
272 return read_feat_hcx_id_field() != 0U;
johpow01f91e59f2021-08-04 19:38:18 -0500273}
274
Juan Pablo Conde42305f22022-07-12 16:40:29 -0400275static inline bool is_feat_rng_trap_present(void)
276{
277 return (((read_id_aa64pfr1_el1() >> ID_AA64PFR1_EL1_RNDR_TRAP_SHIFT) &
278 ID_AA64PFR1_EL1_RNDR_TRAP_MASK)
279 == ID_AA64PFR1_EL1_RNG_TRAP_SUPPORTED);
280}
281
Zelalem Aweke79e3d292021-07-08 16:51:14 -0500282static inline unsigned int get_armv9_2_feat_rme_support(void)
283{
284 /*
285 * Return the RME version, zero if not supported. This function can be
286 * used as both an integer value for the RME version or compared to zero
287 * to detect RME presence.
288 */
289 return (unsigned int)(read_id_aa64pfr0_el1() >>
290 ID_AA64PFR0_FEAT_RME_SHIFT) & ID_AA64PFR0_FEAT_RME_MASK;
291}
292
Jayanth Dodderi Chidanand9461a892022-01-17 18:57:17 +0000293/*********************************************************************************
294 * Function to identify the presence of FEAT_SB (Speculation Barrier Instruction)
295 ********************************************************************************/
Andre Przywara46880dc2022-11-17 16:42:09 +0000296static inline unsigned int read_feat_sb_id_field(void)
Jayanth Dodderi Chidanand9461a892022-01-17 18:57:17 +0000297{
Andre Przywara46880dc2022-11-17 16:42:09 +0000298 return ISOLATE_FIELD(read_id_aa64isar1_el1(), ID_AA64ISAR1_SB);
Jayanth Dodderi Chidanand9461a892022-01-17 18:57:17 +0000299}
300
301/*********************************************************************************
302 * Function to identify the presence of FEAT_CSV2_2 (Cache Speculation Variant 2)
303 ********************************************************************************/
Andre Przywara902c9022022-11-17 17:30:43 +0000304static inline unsigned int read_feat_csv2_id_field(void)
305{
306 return ISOLATE_FIELD(read_id_aa64pfr0_el1(), ID_AA64PFR0_CSV2);
307}
308
309static inline bool is_feat_csv2_2_supported(void)
Jayanth Dodderi Chidanand9461a892022-01-17 18:57:17 +0000310{
Andre Przywara902c9022022-11-17 17:30:43 +0000311 if (ENABLE_FEAT_CSV2_2 == FEAT_STATE_DISABLED) {
312 return false;
313 }
314
315 if (ENABLE_FEAT_CSV2_2 == FEAT_STATE_ALWAYS) {
316 return true;
317 }
318
319 return read_feat_csv2_id_field() >= ID_AA64PFR0_CSV2_2_SUPPORTED;
Jayanth Dodderi Chidanand9461a892022-01-17 18:57:17 +0000320}
321
322/**********************************************************************************
323 * Function to identify the presence of FEAT_SPE (Statistical Profiling Extension)
324 *********************************************************************************/
Andre Przywaraf3e8cfc2022-11-17 16:42:09 +0000325static inline unsigned int read_feat_spe_id_field(void)
326{
327 return ISOLATE_FIELD(read_id_aa64dfr0_el1(), ID_AA64DFR0_PMS);
328}
329
330static inline bool is_feat_spe_supported(void)
Jayanth Dodderi Chidanand9461a892022-01-17 18:57:17 +0000331{
Andre Przywaraf3e8cfc2022-11-17 16:42:09 +0000332 if (ENABLE_SPE_FOR_NS == FEAT_STATE_DISABLED) {
333 return false;
334 }
335
336 if (ENABLE_SPE_FOR_NS == FEAT_STATE_ALWAYS) {
337 return true;
338 }
339
340 return read_feat_spe_id_field() != 0U;
Jayanth Dodderi Chidanand9461a892022-01-17 18:57:17 +0000341}
342
343/*******************************************************************************
344 * Function to identify the presence of FEAT_SVE (Scalable Vector Extension)
345 ******************************************************************************/
346static inline bool is_armv8_2_feat_sve_present(void)
347{
348 return (((read_id_aa64pfr0_el1() >> ID_AA64PFR0_SVE_SHIFT) &
349 ID_AA64PFR0_SVE_MASK) == ID_AA64PFR0_SVE_SUPPORTED);
350}
351
352/*******************************************************************************
353 * Function to identify the presence of FEAT_RAS (Reliability,Availability,
354 * and Serviceability Extension)
355 ******************************************************************************/
356static inline bool is_armv8_2_feat_ras_present(void)
357{
358 return (((read_id_aa64pfr0_el1() >> ID_AA64PFR0_RAS_SHIFT) &
359 ID_AA64PFR0_RAS_MASK) != ID_AA64PFR0_RAS_NOT_SUPPORTED);
360}
361
362/**************************************************************************
363 * Function to identify the presence of FEAT_DIT (Data Independent Timing)
364 *************************************************************************/
365static inline bool is_armv8_4_feat_dit_present(void)
366{
367 return (((read_id_aa64pfr0_el1() >> ID_AA64PFR0_DIT_SHIFT) &
368 ID_AA64PFR0_DIT_MASK) == ID_AA64PFR0_DIT_SUPPORTED);
369}
370
Andre Przywara44e33e02022-11-17 16:42:09 +0000371static inline unsigned int read_feat_tracever_id_field(void)
372{
373 return ISOLATE_FIELD(read_id_aa64dfr0_el1(), ID_AA64DFR0_TRACEVER);
374}
375
376static inline bool is_feat_sys_reg_trace_supported(void)
377{
378 if (ENABLE_SYS_REG_TRACE_FOR_NS == FEAT_STATE_DISABLED) {
379 return false;
380 }
381
382 if (ENABLE_SYS_REG_TRACE_FOR_NS == FEAT_STATE_ALWAYS) {
383 return true;
384 }
385
386 return read_feat_tracever_id_field() != 0U;
387}
388
Jayanth Dodderi Chidanand9461a892022-01-17 18:57:17 +0000389/*************************************************************************
390 * Function to identify the presence of FEAT_TRF (TraceLift)
391 ************************************************************************/
Andre Przywara06ea44e2022-11-17 17:30:43 +0000392static inline unsigned int read_feat_trf_id_field(void)
393{
394 return ISOLATE_FIELD(read_id_aa64dfr0_el1(), ID_AA64DFR0_TRACEFILT);
395}
396
397static inline bool is_feat_trf_supported(void)
Jayanth Dodderi Chidanand9461a892022-01-17 18:57:17 +0000398{
Andre Przywara06ea44e2022-11-17 17:30:43 +0000399 if (ENABLE_TRF_FOR_NS == FEAT_STATE_DISABLED) {
400 return false;
401 }
402
403 if (ENABLE_TRF_FOR_NS == FEAT_STATE_ALWAYS) {
404 return true;
405 }
406
407 return read_feat_trf_id_field() != 0U;
Jayanth Dodderi Chidanand9461a892022-01-17 18:57:17 +0000408}
409
Jayanth Dodderi Chidanand9461a892022-01-17 18:57:17 +0000410/********************************************************************************
411 * Function to identify the presence of FEAT_NV2 (Enhanced Nested Virtualization
412 * Support)
413 *******************************************************************************/
414static inline unsigned int get_armv8_4_feat_nv_support(void)
415{
416 return (((read_id_aa64mmfr2_el1() >> ID_AA64MMFR2_EL1_NV_SHIFT) &
417 ID_AA64MMFR2_EL1_NV_MASK));
418}
419
Jayanth Dodderi Chidanand69316752022-05-09 12:33:03 +0100420/*******************************************************************************
421 * Function to identify the presence of FEAT_BRBE (Branch Record Buffer
422 * Extension)
423 ******************************************************************************/
Andre Przywarac97c5512022-11-17 16:42:09 +0000424static inline unsigned int read_feat_brbe_id_field(void)
425{
426 return ISOLATE_FIELD(read_id_aa64dfr0_el1(), ID_AA64DFR0_BRBE);
427}
428
429static inline bool is_feat_brbe_supported(void)
Jayanth Dodderi Chidanand69316752022-05-09 12:33:03 +0100430{
Andre Przywarac97c5512022-11-17 16:42:09 +0000431 if (ENABLE_BRBE_FOR_NS == FEAT_STATE_DISABLED) {
432 return false;
433 }
434
435 if (ENABLE_BRBE_FOR_NS == FEAT_STATE_ALWAYS) {
436 return true;
437 }
438
439 return read_feat_brbe_id_field() != 0U;
Jayanth Dodderi Chidanand69316752022-05-09 12:33:03 +0100440}
441
Jayanth Dodderi Chidananda793ccc2022-05-19 14:08:28 +0100442/*******************************************************************************
443 * Function to identify the presence of FEAT_TRBE (Trace Buffer Extension)
444 ******************************************************************************/
Andre Przywara191eff62022-11-17 16:42:09 +0000445static inline unsigned int read_feat_trbe_id_field(void)
Jayanth Dodderi Chidananda793ccc2022-05-19 14:08:28 +0100446{
Andre Przywara191eff62022-11-17 16:42:09 +0000447 return ISOLATE_FIELD(read_id_aa64dfr0_el1(), ID_AA64DFR0_TRACEBUFFER);
Jayanth Dodderi Chidananda793ccc2022-05-19 14:08:28 +0100448}
Jayanth Dodderi Chidanand69316752022-05-09 12:33:03 +0100449
Andre Przywara191eff62022-11-17 16:42:09 +0000450static inline bool is_feat_trbe_supported(void)
451{
452 if (ENABLE_TRBE_FOR_NS == FEAT_STATE_DISABLED) {
453 return false;
454 }
455
456 if (ENABLE_TRBE_FOR_NS == FEAT_STATE_ALWAYS) {
457 return true;
458 }
459
460 return read_feat_trbe_id_field() != 0U;
461
462}
Antonio Nino Diazc326c342019-01-11 11:20:10 +0000463#endif /* ARCH_FEATURES_H */