blob: 85f8952cfff6ba203cd3028b463d7e5bddb6bf40 [file] [log] [blame]
Antonio Nino Diaz69068db2019-01-11 13:01:45 +00001/*
Javier Almansa Sobrino2a32ff72023-05-25 17:51:48 +01002 * Copyright (c) 2020-2023, Arm Limited. All rights reserved.
Antonio Nino Diaz69068db2019-01-11 13:01:45 +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>
Javier Almansa Sobrino2a32ff72023-05-25 17:51:48 +010011#include <stdint.h>
12
13#include <arch_features.h>
Antonio Nino Diaz69068db2019-01-11 13:01:45 +000014#include <arch_helpers.h>
Javier Almansa Sobrino2a32ff72023-05-25 17:51:48 +010015#include <utils_def.h>
Antonio Nino Diaz69068db2019-01-11 13:01:45 +000016
Antonio Nino Diazffdfd162019-02-11 15:34:32 +000017static inline bool is_armv7_gentimer_present(void)
18{
19 /* The Generic Timer is always present in an ARMv8-A implementation */
20 return true;
21}
22
Daniel Boulby39e4df22021-02-02 19:27:41 +000023static inline bool is_armv8_1_pan_present(void)
24{
Juan Pablo Condec94fb402023-07-21 17:19:42 -050025 u_register_t id_aa64mmfr1_pan =
26 EXTRACT(ID_AA64MMFR1_EL1_PAN, read_id_aa64mmfr1_el1());
27 return (id_aa64mmfr1_pan >= ID_AA64MMFR1_EL1_PAN_SUPPORTED) &&
28 (id_aa64mmfr1_pan <= ID_AA64MMFR1_EL1_PAN3_SUPPORTED);
29}
30
31static inline bool is_armv8_2_pan2_present(void)
32{
33 u_register_t id_aa64mmfr1_pan =
34 EXTRACT(ID_AA64MMFR1_EL1_PAN, read_id_aa64mmfr1_el1());
35 return (id_aa64mmfr1_pan >= ID_AA64MMFR1_EL1_PAN2_SUPPORTED) &&
36 (id_aa64mmfr1_pan <= ID_AA64MMFR1_EL1_PAN3_SUPPORTED);
Daniel Boulby39e4df22021-02-02 19:27:41 +000037}
38
Ambroise Vincentfae77722019-03-07 10:17:15 +000039static inline bool is_armv8_2_sve_present(void)
40{
41 return ((read_id_aa64pfr0_el1() >> ID_AA64PFR0_SVE_SHIFT) &
42 ID_AA64PFR0_SVE_MASK) == 1U;
43}
44
Antonio Nino Diaz69068db2019-01-11 13:01:45 +000045static inline bool is_armv8_2_ttcnp_present(void)
46{
47 return ((read_id_aa64mmfr2_el1() >> ID_AA64MMFR2_EL1_CNP_SHIFT) &
48 ID_AA64MMFR2_EL1_CNP_MASK) != 0U;
49}
50
Juan Pablo Condeebd1b692022-06-30 17:47:35 -040051static inline bool is_feat_pacqarma3_present(void)
52{
53 uint64_t mask_id_aa64isar2 =
54 (ID_AA64ISAR2_GPA3_MASK << ID_AA64ISAR2_GPA3_SHIFT) |
55 (ID_AA64ISAR2_APA3_MASK << ID_AA64ISAR2_APA3_SHIFT);
56
57 /* If any of the fields is not zero, QARMA3 algorithm is present */
58 return (read_id_aa64isar2_el1() & mask_id_aa64isar2) != 0U;
59}
60
Antonio Nino Diaz9c9f92c2019-03-13 13:57:39 +000061static inline bool is_armv8_3_pauth_present(void)
62{
Juan Pablo Condeebd1b692022-06-30 17:47:35 -040063 uint64_t mask_id_aa64isar1 =
64 (ID_AA64ISAR1_GPI_MASK << ID_AA64ISAR1_GPI_SHIFT) |
65 (ID_AA64ISAR1_GPA_MASK << ID_AA64ISAR1_GPA_SHIFT) |
66 (ID_AA64ISAR1_API_MASK << ID_AA64ISAR1_API_SHIFT) |
67 (ID_AA64ISAR1_APA_MASK << ID_AA64ISAR1_APA_SHIFT);
Antonio Nino Diaz9c9f92c2019-03-13 13:57:39 +000068
Juan Pablo Condeebd1b692022-06-30 17:47:35 -040069 /*
70 * If any of the fields is not zero or QARMA3 is present,
71 * PAuth is present.
72 */
73 return ((read_id_aa64isar1_el1() & mask_id_aa64isar1) != 0U ||
74 is_feat_pacqarma3_present());
Antonio Nino Diaz9c9f92c2019-03-13 13:57:39 +000075}
76
Juan Pablo Condeebd1b692022-06-30 17:47:35 -040077static inline bool is_armv8_3_pauth_apa_api_apa3_present(void)
Antonio Nino Diaz9c9f92c2019-03-13 13:57:39 +000078{
Juan Pablo Condeebd1b692022-06-30 17:47:35 -040079 uint64_t mask_id_aa64isar1 =
80 (ID_AA64ISAR1_API_MASK << ID_AA64ISAR1_API_SHIFT) |
81 (ID_AA64ISAR1_APA_MASK << ID_AA64ISAR1_APA_SHIFT);
Antonio Nino Diaz9c9f92c2019-03-13 13:57:39 +000082
Juan Pablo Condeebd1b692022-06-30 17:47:35 -040083 uint64_t mask_id_aa64isar2 =
84 (ID_AA64ISAR2_APA3_MASK << ID_AA64ISAR2_APA3_SHIFT);
85
86 return ((read_id_aa64isar1_el1() & mask_id_aa64isar1) |
87 (read_id_aa64isar2_el1() & mask_id_aa64isar2)) != 0U;
Antonio Nino Diaz9c9f92c2019-03-13 13:57:39 +000088}
89
Juan Pablo Condeebd1b692022-06-30 17:47:35 -040090static inline bool is_armv8_3_pauth_gpa_gpi_gpa3_present(void)
Joel Hutton8790f022019-03-15 14:47:02 +000091{
Juan Pablo Condeebd1b692022-06-30 17:47:35 -040092 uint64_t mask_id_aa64isar1 =
93 (ID_AA64ISAR1_GPI_MASK << ID_AA64ISAR1_GPI_SHIFT) |
94 (ID_AA64ISAR1_GPA_MASK << ID_AA64ISAR1_GPA_SHIFT);
Joel Hutton8790f022019-03-15 14:47:02 +000095
Juan Pablo Condeebd1b692022-06-30 17:47:35 -040096 uint64_t mask_id_aa64isar2 =
97 (ID_AA64ISAR2_GPA3_MASK << ID_AA64ISAR2_GPA3_SHIFT);
98
99 return ((read_id_aa64isar1_el1() & mask_id_aa64isar1) |
100 (read_id_aa64isar2_el1() & mask_id_aa64isar2)) != 0U;
Joel Hutton8790f022019-03-15 14:47:02 +0000101}
102
Daniel Boulby39e4df22021-02-02 19:27:41 +0000103static inline bool is_armv8_4_dit_present(void)
104{
105 return ((read_id_aa64pfr0_el1() >> ID_AA64PFR0_DIT_SHIFT) &
106 ID_AA64PFR0_DIT_MASK) == 1U;
107}
108
Antonio Nino Diazffdfd162019-02-11 15:34:32 +0000109static inline bool is_armv8_4_ttst_present(void)
110{
111 return ((read_id_aa64mmfr2_el1() >> ID_AA64MMFR2_EL1_ST_SHIFT) &
112 ID_AA64MMFR2_EL1_ST_MASK) == 1U;
113}
114
Alexei Fedorov9cd75022020-06-17 18:54:20 +0100115static inline bool is_armv8_5_bti_present(void)
116{
117 return ((read_id_aa64pfr1_el1() >> ID_AA64PFR1_EL1_BT_SHIFT) &
118 ID_AA64PFR1_EL1_BT_MASK) == BTI_IMPLEMENTED;
119}
120
Sandrine Bailleux277fb762019-10-08 12:10:45 +0200121static inline unsigned int get_armv8_5_mte_support(void)
122{
123 return ((read_id_aa64pfr1_el1() >> ID_AA64PFR1_EL1_MTE_SHIFT) &
124 ID_AA64PFR1_EL1_MTE_MASK);
125}
126
Jimmy Brisson90f1d5c2020-04-16 10:54:51 -0500127static inline bool is_armv8_6_fgt_present(void)
128{
129 return ((read_id_aa64mmfr0_el1() >> ID_AA64MMFR0_EL1_FGT_SHIFT) &
130 ID_AA64MMFR0_EL1_FGT_MASK) == ID_AA64MMFR0_EL1_FGT_SUPPORTED;
131}
132
Jimmy Brisson945095a2020-04-16 10:54:59 -0500133static inline unsigned long int get_armv8_6_ecv_support(void)
134{
135 return ((read_id_aa64mmfr0_el1() >> ID_AA64MMFR0_EL1_ECV_SHIFT) &
136 ID_AA64MMFR0_EL1_ECV_MASK);
137}
138
Federico Recanatid3749b02022-01-14 15:44:45 +0100139static inline unsigned long int get_pa_range(void)
140{
141 return ((read_id_aa64mmfr0_el1() >> ID_AA64MMFR0_EL1_PARANGE_SHIFT) &
142 ID_AA64MMFR0_EL1_PARANGE_MASK);
143}
144
Petre-Ionut Tudorf1a45f72019-10-08 16:51:45 +0100145static inline uint32_t arch_get_debug_version(void)
146{
147 return ((read_id_aa64dfr0_el1() & ID_AA64DFR0_DEBUG_BITS) >>
148 ID_AA64DFR0_DEBUG_SHIFT);
149}
150
Manish V Badarkhe87c03d12021-07-06 22:57:11 +0100151static inline bool get_armv9_0_trbe_support(void)
152{
Manish V Badarkheb31bc752021-12-24 08:52:52 +0000153 return ((read_id_aa64dfr0_el1() >> ID_AA64DFR0_TRACEBUFFER_SHIFT) &
Manish V Badarkhe87c03d12021-07-06 22:57:11 +0100154 ID_AA64DFR0_TRACEBUFFER_MASK) ==
155 ID_AA64DFR0_TRACEBUFFER_SUPPORTED;
156}
157
Manish V Badarkhe2c518e52021-07-08 16:36:57 +0100158static inline bool get_armv8_4_trf_support(void)
159{
Manish V Badarkheb31bc752021-12-24 08:52:52 +0000160 return ((read_id_aa64dfr0_el1() >> ID_AA64DFR0_TRACEFILT_SHIFT) &
Manish V Badarkhe2c518e52021-07-08 16:36:57 +0100161 ID_AA64DFR0_TRACEFILT_MASK) ==
162 ID_AA64DFR0_TRACEFILT_SUPPORTED;
163}
164
Manish V Badarkhe6d0e1b62021-07-09 13:58:28 +0100165static inline bool get_armv8_0_sys_reg_trace_support(void)
166{
Manish V Badarkheb31bc752021-12-24 08:52:52 +0000167 return ((read_id_aa64dfr0_el1() >> ID_AA64DFR0_TRACEVER_SHIFT) &
Manish V Badarkhe6d0e1b62021-07-09 13:58:28 +0100168 ID_AA64DFR0_TRACEVER_MASK) ==
169 ID_AA64DFR0_TRACEVER_SUPPORTED;
170}
171
Mark Dykes16b71692021-09-15 14:13:55 -0500172static inline unsigned int get_armv9_2_feat_rme_support(void)
173{
174 /*
175 * Return the RME version, zero if not supported. This function can be
176 * used as both an integer value for the RME version or compared to zero
177 * to detect RME presence.
178 */
179 return (unsigned int)(read_id_aa64pfr0_el1() >>
180 ID_AA64PFR0_FEAT_RME_SHIFT) & ID_AA64PFR0_FEAT_RME_MASK;
181}
182
johpow01d0bbe6e2021-11-11 16:13:32 -0600183static inline bool get_feat_hcx_support(void)
184{
185 return (((read_id_aa64mmfr1_el1() >> ID_AA64MMFR1_EL1_HCX_SHIFT) &
186 ID_AA64MMFR1_EL1_HCX_MASK) == ID_AA64MMFR1_EL1_HCX_SUPPORTED);
187}
188
Manish V Badarkhe82e1a252022-01-04 13:45:31 +0000189static inline bool get_feat_afp_present(void)
190{
191 return (((read_id_aa64mmfr1_el1() >> ID_AA64MMFR1_EL1_AFP_SHIFT) &
192 ID_AA64MMFR1_EL1_AFP_MASK) == ID_AA64MMFR1_EL1_AFP_SUPPORTED);
193}
194
johpow018c3da8b2022-01-31 18:14:41 -0600195static inline bool get_feat_brbe_support(void)
196{
197 return ((read_id_aa64dfr0_el1() >> ID_AA64DFR0_BRBE_SHIFT) &
198 ID_AA64DFR0_BRBE_MASK) ==
199 ID_AA64DFR0_BRBE_SUPPORTED;
200}
201
Manish V Badarkheb31bc752021-12-24 08:52:52 +0000202static inline bool get_feat_wfxt_present(void)
203{
204 return (((read_id_aa64isar2_el1() >> ID_AA64ISAR2_WFXT_SHIFT) &
205 ID_AA64ISAR2_WFXT_MASK) == ID_AA64ISAR2_WFXT_SUPPORTED);
206}
207
Juan Pablo Conde9303f4d2022-07-25 16:38:01 -0400208static inline bool is_feat_rng_trap_present(void)
209{
210 return (((read_id_aa64pfr1_el1() >> ID_AA64PFR1_EL1_RNDR_TRAP_SHIFT) &
211 ID_AA64PFR1_EL1_RNDR_TRAP_MASK)
212 == ID_AA64PFR1_EL1_RNG_TRAP_SUPPORTED);
213}
214
Manish V Badarkhe41bce212022-11-17 12:34:40 +0000215static inline unsigned int spe_get_version(void)
216{
217 return (unsigned int)((read_id_aa64dfr0_el1() >> ID_AA64DFR0_PMS_SHIFT) &
218 ID_AA64DFR0_PMS_MASK);
219}
220
Boyan Karatotev35e3ca02022-10-10 16:39:45 +0100221static inline bool get_feat_pmuv3_supported(void)
222{
223 return (((read_id_aa64dfr0_el1() >> ID_AA64DFR0_PMUVER_SHIFT) &
224 ID_AA64DFR0_PMUVER_MASK) != ID_AA64DFR0_PMUVER_NOT_SUPPORTED);
225}
226
227static inline bool get_feat_hpmn0_supported(void)
228{
229 return (((read_id_aa64dfr0_el1() >> ID_AA64DFR0_HPMN0_SHIFT) &
230 ID_AA64DFR0_HPMN0_MASK) == ID_AA64DFR0_HPMN0_SUPPORTED);
231}
Jayanth Dodderi Chidanandb3ffd3c2023-02-13 12:15:11 +0000232
233static inline bool is_feat_sme_supported(void)
234{
235 uint64_t features;
236
237 features = read_id_aa64pfr1_el1() >> ID_AA64PFR1_EL1_SME_SHIFT;
238 return (features & ID_AA64PFR1_EL1_SME_MASK) >= ID_AA64PFR1_EL1_SME_SUPPORTED;
239}
240
241static inline bool is_feat_sme_fa64_supported(void)
242{
243 uint64_t features;
244
245 features = read_id_aa64smfr0_el1();
246 return (features & ID_AA64SMFR0_EL1_FA64_BIT) != 0U;
247}
248
Jayanth Dodderi Chidanand95d5d272023-01-16 17:58:47 +0000249static inline bool is_feat_sme2_supported(void)
250{
251 uint64_t features;
252
253 features = read_id_aa64pfr1_el1() >> ID_AA64PFR1_EL1_SME_SHIFT;
254 return (features & ID_AA64PFR1_EL1_SME_MASK) >= ID_AA64PFR1_EL1_SME2_SUPPORTED;
255}
256
Javier Almansa Sobrino2a32ff72023-05-25 17:51:48 +0100257static inline u_register_t get_id_aa64mmfr0_el0_tgran4(void)
258{
259 return EXTRACT(ID_AA64MMFR0_EL1_TGRAN4, read_id_aa64mmfr0_el1());
260}
261
262static inline u_register_t get_id_aa64mmfr0_el0_tgran4_2(void)
263{
264 return EXTRACT(ID_AA64MMFR0_EL1_TGRAN4_2, read_id_aa64mmfr0_el1());
265}
266
267static inline u_register_t get_id_aa64mmfr0_el0_tgran16(void)
268{
269 return EXTRACT(ID_AA64MMFR0_EL1_TGRAN16, read_id_aa64mmfr0_el1());
270}
271
272static inline u_register_t get_id_aa64mmfr0_el0_tgran16_2(void)
273{
274 return EXTRACT(ID_AA64MMFR0_EL1_TGRAN16_2, read_id_aa64mmfr0_el1());
275}
276
277static inline u_register_t get_id_aa64mmfr0_el0_tgran64(void)
278{
279 return EXTRACT(ID_AA64MMFR0_EL1_TGRAN64, read_id_aa64mmfr0_el1());
280}
281
282static inline u_register_t get_id_aa64mmfr0_el0_tgran64_2(void)
283{
284 return EXTRACT(ID_AA64MMFR0_EL1_TGRAN64_2, read_id_aa64mmfr0_el1());
285}
286
287static inline bool is_feat_52b_on_4k_supported(void)
288{
289 return (get_id_aa64mmfr0_el0_tgran4() ==
290 ID_AA64MMFR0_EL1_TGRAN4_52B_SUPPORTED);
291}
292
293static inline bool is_feat_52b_on_4k_2_supported(void)
294{
295 u_register_t tgran4_2 = get_id_aa64mmfr0_el0_tgran4_2();
296
297 return ((tgran4_2 == ID_AA64MMFR0_EL1_TGRAN4_2_52B_SUPPORTED) ||
298 ((tgran4_2 == ID_AA64MMFR0_EL1_TGRAN4_2_AS_1)
299 && (is_feat_52b_on_4k_supported() == true)));
300}
301
Juan Pablo Condec94fb402023-07-21 17:19:42 -0500302static inline bool is_feat_specres_present(void)
303{
304 return EXTRACT(ID_AA64ISAR1_SPECRES, read_id_aa64isar1_el1())
305 == ID_AA64ISAR1_SPECRES_SUPPORTED;
306}
307
308static inline bool is_feat_tlbirange_present(void)
309{
310 return EXTRACT(ID_AA64ISAR0_TLB, read_id_aa64isar0_el1())
311 == ID_AA64ISAR0_TLBIRANGE_SUPPORTED;
312}
313
314static inline bool is_feat_tlbios_present(void)
315{
316 return EXTRACT(ID_AA64ISAR0_TLB, read_id_aa64isar0_el1())
317 != ID_AA64ISAR0_TLB_NOT_SUPPORTED;
318}
319
320static inline bool is_feat_dpb_present(void)
321{
322 return EXTRACT(ID_AA64ISAR1_DPB, read_id_aa64isar1_el1())
323 >= ID_AA64ISAR1_DPB_SUPPORTED;
324}
325
326static inline bool is_feat_dpb2_present(void)
327{
328 return EXTRACT(ID_AA64ISAR1_DPB, read_id_aa64isar1_el1())
329 >= ID_AA64ISAR1_DPB2_SUPPORTED;
330}
331
332static inline bool is_feat_ls64_present(void)
333{
334 return EXTRACT(ID_AA64ISAR1_LS64, read_id_aa64isar1_el1())
335 >= ID_AA64ISAR1_LS64_SUPPORTED;
336}
337
338static inline bool is_feat_ls64_v_present(void)
339{
340 return EXTRACT(ID_AA64ISAR1_LS64, read_id_aa64isar1_el1())
341 >= ID_AA64ISAR1_LS64_V_SUPPORTED;
342}
343
344static inline bool is_feat_ls64_accdata_present(void)
345{
346 return EXTRACT(ID_AA64ISAR1_LS64, read_id_aa64isar1_el1())
347 >= ID_AA64ISAR1_LS64_ACCDATA_SUPPORTED;
348}
349
350static inline bool is_feat_ras_present(void)
351{
352 return EXTRACT(ID_AA64PFR0_RAS, read_id_aa64pfr0_el1())
353 == ID_AA64PFR0_RAS_SUPPORTED;
354}
355
356static inline bool is_feat_rasv1p1_present(void)
357{
358 return (EXTRACT(ID_AA64PFR0_RAS, read_id_aa64pfr0_el1())
359 == ID_AA64PFR0_RASV1P1_SUPPORTED)
360 || (is_feat_ras_present() &&
361 (EXTRACT(ID_AA64PFR1_RAS_FRAC, read_id_aa64pfr1_el1())
362 == ID_AA64PFR1_RASV1P1_SUPPORTED))
363 || (EXTRACT(ID_PFR0_EL1_RAS, read_id_pfr0_el1())
364 == ID_PFR0_EL1_RASV1P1_SUPPORTED)
365 || ((EXTRACT(ID_PFR0_EL1_RAS, read_id_pfr0_el1())
366 == ID_PFR0_EL1_RAS_SUPPORTED) &&
367 (EXTRACT(ID_PFR2_EL1_RAS_FRAC, read_id_pfr2_el1())
368 == ID_PFR2_EL1_RASV1P1_SUPPORTED));
369}
370
371static inline bool is_feat_gicv3_gicv4_present(void)
372{
373 return EXTRACT(ID_AA64PFR0_GIC, read_id_aa64pfr0_el1())
374 == ID_AA64PFR0_GICV3_GICV4_SUPPORTED;
375}
376
377static inline bool is_feat_csv2_present(void)
378{
379 return EXTRACT(ID_AA64PFR0_CSV2, read_id_aa64pfr0_el1())
380 == ID_AA64PFR0_CSV2_SUPPORTED;
381}
382
383static inline bool is_feat_csv2_2_present(void)
384{
385 return EXTRACT(ID_AA64PFR0_CSV2, read_id_aa64pfr0_el1())
386 == ID_AA64PFR0_CSV2_2_SUPPORTED;
387}
388
389static inline bool is_feat_csv2_1p1_present(void)
390{
391 return is_feat_csv2_present() &&
392 (EXTRACT(ID_AA64PFR1_CSV2_FRAC, read_id_aa64pfr1_el1())
393 == ID_AA64PFR1_CSV2_1P1_SUPPORTED);
394}
395
396static inline bool is_feat_csv2_1p2_present(void)
397{
398 return is_feat_csv2_present() &&
399 (EXTRACT(ID_AA64PFR1_CSV2_FRAC, read_id_aa64pfr1_el1())
400 == ID_AA64PFR1_CSV2_1P2_SUPPORTED);
401}
402
403static inline bool is_feat_lor_present(void)
404{
405 return EXTRACT(ID_AA64MMFR1_EL1_LO, read_id_aa64mmfr1_el1())
406 != ID_AA64MMFR1_EL1_LOR_NOT_SUPPORTED;
407}
408
Antonio Nino Diaz69068db2019-01-11 13:01:45 +0000409#endif /* ARCH_FEATURES_H */