blob: ee14d676146b6828a51dff3be1f17443595553b3 [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{
25 return ((read_id_aa64mmfr1_el1() >> ID_AA64MMFR1_EL1_PAN_SHIFT) &
26 ID_AA64MMFR1_EL1_PAN_MASK) != 0U;
27}
28
Ambroise Vincentfae77722019-03-07 10:17:15 +000029static inline bool is_armv8_2_sve_present(void)
30{
31 return ((read_id_aa64pfr0_el1() >> ID_AA64PFR0_SVE_SHIFT) &
32 ID_AA64PFR0_SVE_MASK) == 1U;
33}
34
Antonio Nino Diaz69068db2019-01-11 13:01:45 +000035static inline bool is_armv8_2_ttcnp_present(void)
36{
37 return ((read_id_aa64mmfr2_el1() >> ID_AA64MMFR2_EL1_CNP_SHIFT) &
38 ID_AA64MMFR2_EL1_CNP_MASK) != 0U;
39}
40
Juan Pablo Condeebd1b692022-06-30 17:47:35 -040041static inline bool is_feat_pacqarma3_present(void)
42{
43 uint64_t mask_id_aa64isar2 =
44 (ID_AA64ISAR2_GPA3_MASK << ID_AA64ISAR2_GPA3_SHIFT) |
45 (ID_AA64ISAR2_APA3_MASK << ID_AA64ISAR2_APA3_SHIFT);
46
47 /* If any of the fields is not zero, QARMA3 algorithm is present */
48 return (read_id_aa64isar2_el1() & mask_id_aa64isar2) != 0U;
49}
50
Antonio Nino Diaz9c9f92c2019-03-13 13:57:39 +000051static inline bool is_armv8_3_pauth_present(void)
52{
Juan Pablo Condeebd1b692022-06-30 17:47:35 -040053 uint64_t mask_id_aa64isar1 =
54 (ID_AA64ISAR1_GPI_MASK << ID_AA64ISAR1_GPI_SHIFT) |
55 (ID_AA64ISAR1_GPA_MASK << ID_AA64ISAR1_GPA_SHIFT) |
56 (ID_AA64ISAR1_API_MASK << ID_AA64ISAR1_API_SHIFT) |
57 (ID_AA64ISAR1_APA_MASK << ID_AA64ISAR1_APA_SHIFT);
Antonio Nino Diaz9c9f92c2019-03-13 13:57:39 +000058
Juan Pablo Condeebd1b692022-06-30 17:47:35 -040059 /*
60 * If any of the fields is not zero or QARMA3 is present,
61 * PAuth is present.
62 */
63 return ((read_id_aa64isar1_el1() & mask_id_aa64isar1) != 0U ||
64 is_feat_pacqarma3_present());
Antonio Nino Diaz9c9f92c2019-03-13 13:57:39 +000065}
66
Juan Pablo Condeebd1b692022-06-30 17:47:35 -040067static inline bool is_armv8_3_pauth_apa_api_apa3_present(void)
Antonio Nino Diaz9c9f92c2019-03-13 13:57:39 +000068{
Juan Pablo Condeebd1b692022-06-30 17:47:35 -040069 uint64_t mask_id_aa64isar1 =
70 (ID_AA64ISAR1_API_MASK << ID_AA64ISAR1_API_SHIFT) |
71 (ID_AA64ISAR1_APA_MASK << ID_AA64ISAR1_APA_SHIFT);
Antonio Nino Diaz9c9f92c2019-03-13 13:57:39 +000072
Juan Pablo Condeebd1b692022-06-30 17:47:35 -040073 uint64_t mask_id_aa64isar2 =
74 (ID_AA64ISAR2_APA3_MASK << ID_AA64ISAR2_APA3_SHIFT);
75
76 return ((read_id_aa64isar1_el1() & mask_id_aa64isar1) |
77 (read_id_aa64isar2_el1() & mask_id_aa64isar2)) != 0U;
Antonio Nino Diaz9c9f92c2019-03-13 13:57:39 +000078}
79
Juan Pablo Condeebd1b692022-06-30 17:47:35 -040080static inline bool is_armv8_3_pauth_gpa_gpi_gpa3_present(void)
Joel Hutton8790f022019-03-15 14:47:02 +000081{
Juan Pablo Condeebd1b692022-06-30 17:47:35 -040082 uint64_t mask_id_aa64isar1 =
83 (ID_AA64ISAR1_GPI_MASK << ID_AA64ISAR1_GPI_SHIFT) |
84 (ID_AA64ISAR1_GPA_MASK << ID_AA64ISAR1_GPA_SHIFT);
Joel Hutton8790f022019-03-15 14:47:02 +000085
Juan Pablo Condeebd1b692022-06-30 17:47:35 -040086 uint64_t mask_id_aa64isar2 =
87 (ID_AA64ISAR2_GPA3_MASK << ID_AA64ISAR2_GPA3_SHIFT);
88
89 return ((read_id_aa64isar1_el1() & mask_id_aa64isar1) |
90 (read_id_aa64isar2_el1() & mask_id_aa64isar2)) != 0U;
Joel Hutton8790f022019-03-15 14:47:02 +000091}
92
Daniel Boulby39e4df22021-02-02 19:27:41 +000093static inline bool is_armv8_4_dit_present(void)
94{
95 return ((read_id_aa64pfr0_el1() >> ID_AA64PFR0_DIT_SHIFT) &
96 ID_AA64PFR0_DIT_MASK) == 1U;
97}
98
Antonio Nino Diazffdfd162019-02-11 15:34:32 +000099static inline bool is_armv8_4_ttst_present(void)
100{
101 return ((read_id_aa64mmfr2_el1() >> ID_AA64MMFR2_EL1_ST_SHIFT) &
102 ID_AA64MMFR2_EL1_ST_MASK) == 1U;
103}
104
Alexei Fedorov9cd75022020-06-17 18:54:20 +0100105static inline bool is_armv8_5_bti_present(void)
106{
107 return ((read_id_aa64pfr1_el1() >> ID_AA64PFR1_EL1_BT_SHIFT) &
108 ID_AA64PFR1_EL1_BT_MASK) == BTI_IMPLEMENTED;
109}
110
Sandrine Bailleux277fb762019-10-08 12:10:45 +0200111static inline unsigned int get_armv8_5_mte_support(void)
112{
113 return ((read_id_aa64pfr1_el1() >> ID_AA64PFR1_EL1_MTE_SHIFT) &
114 ID_AA64PFR1_EL1_MTE_MASK);
115}
116
Jimmy Brisson90f1d5c2020-04-16 10:54:51 -0500117static inline bool is_armv8_6_fgt_present(void)
118{
119 return ((read_id_aa64mmfr0_el1() >> ID_AA64MMFR0_EL1_FGT_SHIFT) &
120 ID_AA64MMFR0_EL1_FGT_MASK) == ID_AA64MMFR0_EL1_FGT_SUPPORTED;
121}
122
Jimmy Brisson945095a2020-04-16 10:54:59 -0500123static inline unsigned long int get_armv8_6_ecv_support(void)
124{
125 return ((read_id_aa64mmfr0_el1() >> ID_AA64MMFR0_EL1_ECV_SHIFT) &
126 ID_AA64MMFR0_EL1_ECV_MASK);
127}
128
Federico Recanatid3749b02022-01-14 15:44:45 +0100129static inline unsigned long int get_pa_range(void)
130{
131 return ((read_id_aa64mmfr0_el1() >> ID_AA64MMFR0_EL1_PARANGE_SHIFT) &
132 ID_AA64MMFR0_EL1_PARANGE_MASK);
133}
134
Petre-Ionut Tudorf1a45f72019-10-08 16:51:45 +0100135static inline uint32_t arch_get_debug_version(void)
136{
137 return ((read_id_aa64dfr0_el1() & ID_AA64DFR0_DEBUG_BITS) >>
138 ID_AA64DFR0_DEBUG_SHIFT);
139}
140
Manish V Badarkhe87c03d12021-07-06 22:57:11 +0100141static inline bool get_armv9_0_trbe_support(void)
142{
Manish V Badarkheb31bc752021-12-24 08:52:52 +0000143 return ((read_id_aa64dfr0_el1() >> ID_AA64DFR0_TRACEBUFFER_SHIFT) &
Manish V Badarkhe87c03d12021-07-06 22:57:11 +0100144 ID_AA64DFR0_TRACEBUFFER_MASK) ==
145 ID_AA64DFR0_TRACEBUFFER_SUPPORTED;
146}
147
Manish V Badarkhe2c518e52021-07-08 16:36:57 +0100148static inline bool get_armv8_4_trf_support(void)
149{
Manish V Badarkheb31bc752021-12-24 08:52:52 +0000150 return ((read_id_aa64dfr0_el1() >> ID_AA64DFR0_TRACEFILT_SHIFT) &
Manish V Badarkhe2c518e52021-07-08 16:36:57 +0100151 ID_AA64DFR0_TRACEFILT_MASK) ==
152 ID_AA64DFR0_TRACEFILT_SUPPORTED;
153}
154
Manish V Badarkhe6d0e1b62021-07-09 13:58:28 +0100155static inline bool get_armv8_0_sys_reg_trace_support(void)
156{
Manish V Badarkheb31bc752021-12-24 08:52:52 +0000157 return ((read_id_aa64dfr0_el1() >> ID_AA64DFR0_TRACEVER_SHIFT) &
Manish V Badarkhe6d0e1b62021-07-09 13:58:28 +0100158 ID_AA64DFR0_TRACEVER_MASK) ==
159 ID_AA64DFR0_TRACEVER_SUPPORTED;
160}
161
Mark Dykes16b71692021-09-15 14:13:55 -0500162static inline unsigned int get_armv9_2_feat_rme_support(void)
163{
164 /*
165 * Return the RME version, zero if not supported. This function can be
166 * used as both an integer value for the RME version or compared to zero
167 * to detect RME presence.
168 */
169 return (unsigned int)(read_id_aa64pfr0_el1() >>
170 ID_AA64PFR0_FEAT_RME_SHIFT) & ID_AA64PFR0_FEAT_RME_MASK;
171}
172
johpow01d0bbe6e2021-11-11 16:13:32 -0600173static inline bool get_feat_hcx_support(void)
174{
175 return (((read_id_aa64mmfr1_el1() >> ID_AA64MMFR1_EL1_HCX_SHIFT) &
176 ID_AA64MMFR1_EL1_HCX_MASK) == ID_AA64MMFR1_EL1_HCX_SUPPORTED);
177}
178
Manish V Badarkhe82e1a252022-01-04 13:45:31 +0000179static inline bool get_feat_afp_present(void)
180{
181 return (((read_id_aa64mmfr1_el1() >> ID_AA64MMFR1_EL1_AFP_SHIFT) &
182 ID_AA64MMFR1_EL1_AFP_MASK) == ID_AA64MMFR1_EL1_AFP_SUPPORTED);
183}
184
johpow018c3da8b2022-01-31 18:14:41 -0600185static inline bool get_feat_brbe_support(void)
186{
187 return ((read_id_aa64dfr0_el1() >> ID_AA64DFR0_BRBE_SHIFT) &
188 ID_AA64DFR0_BRBE_MASK) ==
189 ID_AA64DFR0_BRBE_SUPPORTED;
190}
191
Manish V Badarkheb31bc752021-12-24 08:52:52 +0000192static inline bool get_feat_wfxt_present(void)
193{
194 return (((read_id_aa64isar2_el1() >> ID_AA64ISAR2_WFXT_SHIFT) &
195 ID_AA64ISAR2_WFXT_MASK) == ID_AA64ISAR2_WFXT_SUPPORTED);
196}
197
Juan Pablo Conde9303f4d2022-07-25 16:38:01 -0400198static inline bool is_feat_rng_trap_present(void)
199{
200 return (((read_id_aa64pfr1_el1() >> ID_AA64PFR1_EL1_RNDR_TRAP_SHIFT) &
201 ID_AA64PFR1_EL1_RNDR_TRAP_MASK)
202 == ID_AA64PFR1_EL1_RNG_TRAP_SUPPORTED);
203}
204
Manish V Badarkhe41bce212022-11-17 12:34:40 +0000205static inline unsigned int spe_get_version(void)
206{
207 return (unsigned int)((read_id_aa64dfr0_el1() >> ID_AA64DFR0_PMS_SHIFT) &
208 ID_AA64DFR0_PMS_MASK);
209}
210
Boyan Karatotev35e3ca02022-10-10 16:39:45 +0100211static inline bool get_feat_pmuv3_supported(void)
212{
213 return (((read_id_aa64dfr0_el1() >> ID_AA64DFR0_PMUVER_SHIFT) &
214 ID_AA64DFR0_PMUVER_MASK) != ID_AA64DFR0_PMUVER_NOT_SUPPORTED);
215}
216
217static inline bool get_feat_hpmn0_supported(void)
218{
219 return (((read_id_aa64dfr0_el1() >> ID_AA64DFR0_HPMN0_SHIFT) &
220 ID_AA64DFR0_HPMN0_MASK) == ID_AA64DFR0_HPMN0_SUPPORTED);
221}
Jayanth Dodderi Chidanandb3ffd3c2023-02-13 12:15:11 +0000222
223static inline bool is_feat_sme_supported(void)
224{
225 uint64_t features;
226
227 features = read_id_aa64pfr1_el1() >> ID_AA64PFR1_EL1_SME_SHIFT;
228 return (features & ID_AA64PFR1_EL1_SME_MASK) >= ID_AA64PFR1_EL1_SME_SUPPORTED;
229}
230
231static inline bool is_feat_sme_fa64_supported(void)
232{
233 uint64_t features;
234
235 features = read_id_aa64smfr0_el1();
236 return (features & ID_AA64SMFR0_EL1_FA64_BIT) != 0U;
237}
238
Jayanth Dodderi Chidanand95d5d272023-01-16 17:58:47 +0000239static inline bool is_feat_sme2_supported(void)
240{
241 uint64_t features;
242
243 features = read_id_aa64pfr1_el1() >> ID_AA64PFR1_EL1_SME_SHIFT;
244 return (features & ID_AA64PFR1_EL1_SME_MASK) >= ID_AA64PFR1_EL1_SME2_SUPPORTED;
245}
246
Javier Almansa Sobrino2a32ff72023-05-25 17:51:48 +0100247static inline u_register_t get_id_aa64mmfr0_el0_tgran4(void)
248{
249 return EXTRACT(ID_AA64MMFR0_EL1_TGRAN4, read_id_aa64mmfr0_el1());
250}
251
252static inline u_register_t get_id_aa64mmfr0_el0_tgran4_2(void)
253{
254 return EXTRACT(ID_AA64MMFR0_EL1_TGRAN4_2, read_id_aa64mmfr0_el1());
255}
256
257static inline u_register_t get_id_aa64mmfr0_el0_tgran16(void)
258{
259 return EXTRACT(ID_AA64MMFR0_EL1_TGRAN16, read_id_aa64mmfr0_el1());
260}
261
262static inline u_register_t get_id_aa64mmfr0_el0_tgran16_2(void)
263{
264 return EXTRACT(ID_AA64MMFR0_EL1_TGRAN16_2, read_id_aa64mmfr0_el1());
265}
266
267static inline u_register_t get_id_aa64mmfr0_el0_tgran64(void)
268{
269 return EXTRACT(ID_AA64MMFR0_EL1_TGRAN64, read_id_aa64mmfr0_el1());
270}
271
272static inline u_register_t get_id_aa64mmfr0_el0_tgran64_2(void)
273{
274 return EXTRACT(ID_AA64MMFR0_EL1_TGRAN64_2, read_id_aa64mmfr0_el1());
275}
276
277static inline bool is_feat_52b_on_4k_supported(void)
278{
279 return (get_id_aa64mmfr0_el0_tgran4() ==
280 ID_AA64MMFR0_EL1_TGRAN4_52B_SUPPORTED);
281}
282
283static inline bool is_feat_52b_on_4k_2_supported(void)
284{
285 u_register_t tgran4_2 = get_id_aa64mmfr0_el0_tgran4_2();
286
287 return ((tgran4_2 == ID_AA64MMFR0_EL1_TGRAN4_2_52B_SUPPORTED) ||
288 ((tgran4_2 == ID_AA64MMFR0_EL1_TGRAN4_2_AS_1)
289 && (is_feat_52b_on_4k_supported() == true)));
290}
291
Antonio Nino Diaz69068db2019-01-11 13:01:45 +0000292#endif /* ARCH_FEATURES_H */