xref: /rk3399_ARM-atf/include/arch/aarch64/arch_features.h (revision 4f5ef849c184313a2ba124ff0dd0b1545ddee217)
12559b2c8SAntonio Nino Diaz /*
2fd1dd4cbSAndre Przywara  * Copyright (c) 2019-2023, Arm Limited. All rights reserved.
32559b2c8SAntonio Nino Diaz  *
42559b2c8SAntonio Nino Diaz  * SPDX-License-Identifier: BSD-3-Clause
52559b2c8SAntonio Nino Diaz  */
62559b2c8SAntonio Nino Diaz 
72559b2c8SAntonio Nino Diaz #ifndef ARCH_FEATURES_H
82559b2c8SAntonio Nino Diaz #define ARCH_FEATURES_H
92559b2c8SAntonio Nino Diaz 
102559b2c8SAntonio Nino Diaz #include <stdbool.h>
112559b2c8SAntonio Nino Diaz 
122559b2c8SAntonio Nino Diaz #include <arch_helpers.h>
13ce485955SAndre Przywara #include <common/feat_detect.h>
142559b2c8SAntonio Nino Diaz 
15fd1dd4cbSAndre Przywara #define ISOLATE_FIELD(reg, feat)					\
16fd1dd4cbSAndre Przywara 	((unsigned int)(((reg) >> (feat ## _SHIFT)) & (feat ## _MASK)))
17fd1dd4cbSAndre Przywara 
1829a24134SAntonio Nino Diaz static inline bool is_armv7_gentimer_present(void)
1929a24134SAntonio Nino Diaz {
2029a24134SAntonio Nino Diaz 	/* The Generic Timer is always present in an ARMv8-A implementation */
2129a24134SAntonio Nino Diaz 	return true;
2229a24134SAntonio Nino Diaz }
2329a24134SAntonio Nino Diaz 
24*4f5ef849SAndre Przywara static inline unsigned int read_feat_pan_id_field(void)
2537596fcbSDaniel Boulby {
26*4f5ef849SAndre Przywara 	return ISOLATE_FIELD(read_id_aa64mmfr1_el1(), ID_AA64MMFR1_EL1_PAN);
27*4f5ef849SAndre Przywara }
28*4f5ef849SAndre Przywara 
29*4f5ef849SAndre Przywara static inline bool is_feat_pan_supported(void)
30*4f5ef849SAndre Przywara {
31*4f5ef849SAndre Przywara 	if (ENABLE_FEAT_PAN == FEAT_STATE_DISABLED) {
32*4f5ef849SAndre Przywara 		return false;
33*4f5ef849SAndre Przywara 	}
34*4f5ef849SAndre Przywara 
35*4f5ef849SAndre Przywara 	if (ENABLE_FEAT_PAN == FEAT_STATE_ALWAYS) {
36*4f5ef849SAndre Przywara 		return true;
37*4f5ef849SAndre Przywara 	}
38*4f5ef849SAndre Przywara 
39*4f5ef849SAndre Przywara 	return read_feat_pan_id_field() != 0U;
4037596fcbSDaniel Boulby }
4137596fcbSDaniel Boulby 
42ea735bf5SAndre Przywara static inline unsigned int read_feat_vhe_id_field(void)
4337596fcbSDaniel Boulby {
44ea735bf5SAndre Przywara 	return ISOLATE_FIELD(read_id_aa64mmfr1_el1(), ID_AA64MMFR1_EL1_VHE);
45ea735bf5SAndre Przywara }
46ea735bf5SAndre Przywara 
47ea735bf5SAndre Przywara static inline bool is_feat_vhe_supported(void)
48ea735bf5SAndre Przywara {
49ea735bf5SAndre Przywara 	if (ENABLE_FEAT_VHE == FEAT_STATE_DISABLED) {
50ea735bf5SAndre Przywara 		return false;
51ea735bf5SAndre Przywara 	}
52ea735bf5SAndre Przywara 
53ea735bf5SAndre Przywara 	if (ENABLE_FEAT_VHE == FEAT_STATE_ALWAYS) {
54ea735bf5SAndre Przywara 		return true;
55ea735bf5SAndre Przywara 	}
56ea735bf5SAndre Przywara 
57ea735bf5SAndre Przywara 	return read_feat_vhe_id_field() != 0U;
5837596fcbSDaniel Boulby }
5937596fcbSDaniel Boulby 
602559b2c8SAntonio Nino Diaz static inline bool is_armv8_2_ttcnp_present(void)
612559b2c8SAntonio Nino Diaz {
622559b2c8SAntonio Nino Diaz 	return ((read_id_aa64mmfr2_el1() >> ID_AA64MMFR2_EL1_CNP_SHIFT) &
632559b2c8SAntonio Nino Diaz 		ID_AA64MMFR2_EL1_CNP_MASK) != 0U;
642559b2c8SAntonio Nino Diaz }
652559b2c8SAntonio Nino Diaz 
669ff5f754SJuan Pablo Conde static inline bool is_feat_pacqarma3_present(void)
679ff5f754SJuan Pablo Conde {
689ff5f754SJuan Pablo Conde 	uint64_t mask_id_aa64isar2 =
699ff5f754SJuan Pablo Conde 			(ID_AA64ISAR2_GPA3_MASK << ID_AA64ISAR2_GPA3_SHIFT) |
709ff5f754SJuan Pablo Conde 			(ID_AA64ISAR2_APA3_MASK << ID_AA64ISAR2_APA3_SHIFT);
719ff5f754SJuan Pablo Conde 
729ff5f754SJuan Pablo Conde 	/* If any of the fields is not zero, QARMA3 algorithm is present */
739ff5f754SJuan Pablo Conde 	return (read_id_aa64isar2_el1() & mask_id_aa64isar2) != 0U;
749ff5f754SJuan Pablo Conde }
759ff5f754SJuan Pablo Conde 
76b86048c4SAntonio Nino Diaz static inline bool is_armv8_3_pauth_present(void)
77b86048c4SAntonio Nino Diaz {
789ff5f754SJuan Pablo Conde 	uint64_t mask_id_aa64isar1 =
799ff5f754SJuan Pablo Conde 		(ID_AA64ISAR1_GPI_MASK << ID_AA64ISAR1_GPI_SHIFT) |
80b86048c4SAntonio Nino Diaz 		(ID_AA64ISAR1_GPA_MASK << ID_AA64ISAR1_GPA_SHIFT) |
81b86048c4SAntonio Nino Diaz 		(ID_AA64ISAR1_API_MASK << ID_AA64ISAR1_API_SHIFT) |
82b86048c4SAntonio Nino Diaz 		(ID_AA64ISAR1_APA_MASK << ID_AA64ISAR1_APA_SHIFT);
83b86048c4SAntonio Nino Diaz 
849ff5f754SJuan Pablo Conde 	/*
859ff5f754SJuan Pablo Conde 	 * If any of the fields is not zero or QARMA3 is present,
869ff5f754SJuan Pablo Conde 	 * PAuth is present
879ff5f754SJuan Pablo Conde 	 */
889ff5f754SJuan Pablo Conde 	return ((read_id_aa64isar1_el1() & mask_id_aa64isar1) != 0U ||
899ff5f754SJuan Pablo Conde 		is_feat_pacqarma3_present());
90b86048c4SAntonio Nino Diaz }
91b86048c4SAntonio Nino Diaz 
924d482156SDaniel Boulby static inline bool is_armv8_4_dit_present(void)
934d482156SDaniel Boulby {
944d482156SDaniel Boulby 	return ((read_id_aa64pfr0_el1() >> ID_AA64PFR0_DIT_SHIFT) &
954d482156SDaniel Boulby 		ID_AA64PFR0_DIT_MASK) == 1U;
964d482156SDaniel Boulby }
974d482156SDaniel Boulby 
98cedfa04bSSathees Balya static inline bool is_armv8_4_ttst_present(void)
99cedfa04bSSathees Balya {
100cedfa04bSSathees Balya 	return ((read_id_aa64mmfr2_el1() >> ID_AA64MMFR2_EL1_ST_SHIFT) &
101cedfa04bSSathees Balya 		ID_AA64MMFR2_EL1_ST_MASK) == 1U;
102cedfa04bSSathees Balya }
103cedfa04bSSathees Balya 
1049fc59639SAlexei Fedorov static inline bool is_armv8_5_bti_present(void)
1059fc59639SAlexei Fedorov {
1069fc59639SAlexei Fedorov 	return ((read_id_aa64pfr1_el1() >> ID_AA64PFR1_EL1_BT_SHIFT) &
1079fc59639SAlexei Fedorov 		ID_AA64PFR1_EL1_BT_MASK) == BTI_IMPLEMENTED;
1089fc59639SAlexei Fedorov }
1099fc59639SAlexei Fedorov 
110b7e398d6SSoby Mathew static inline unsigned int get_armv8_5_mte_support(void)
111b7e398d6SSoby Mathew {
112b7e398d6SSoby Mathew 	return ((read_id_aa64pfr1_el1() >> ID_AA64PFR1_EL1_MTE_SHIFT) &
113b7e398d6SSoby Mathew 		ID_AA64PFR1_EL1_MTE_MASK);
114b7e398d6SSoby Mathew }
115b7e398d6SSoby Mathew 
11652696946SOlivier Deprez static inline bool is_armv8_4_sel2_present(void)
11752696946SOlivier Deprez {
11852696946SOlivier Deprez 	return ((read_id_aa64pfr0_el1() >> ID_AA64PFR0_SEL2_SHIFT) &
11952696946SOlivier Deprez 		ID_AA64PFR0_SEL2_MASK) == 1ULL;
12052696946SOlivier Deprez }
12152696946SOlivier Deprez 
1226cac724dSjohpow01 static inline bool is_armv8_6_twed_present(void)
1236cac724dSjohpow01 {
1246cac724dSjohpow01 	return (((read_id_aa64mmfr1_el1() >> ID_AA64MMFR1_EL1_TWED_SHIFT) &
1256cac724dSjohpow01 		ID_AA64MMFR1_EL1_TWED_MASK) == ID_AA64MMFR1_EL1_TWED_SUPPORTED);
1266cac724dSjohpow01 }
1276cac724dSjohpow01 
128ce485955SAndre Przywara static unsigned int read_feat_fgt_id_field(void)
129110ee433SJimmy Brisson {
130fd1dd4cbSAndre Przywara 	return ISOLATE_FIELD(read_id_aa64mmfr0_el1(), ID_AA64MMFR0_EL1_FGT);
131ce485955SAndre Przywara }
132ce485955SAndre Przywara 
133ce485955SAndre Przywara static inline bool is_feat_fgt_supported(void)
134ce485955SAndre Przywara {
135ce485955SAndre Przywara 	if (ENABLE_FEAT_FGT == FEAT_STATE_DISABLED) {
136ce485955SAndre Przywara 		return false;
137ce485955SAndre Przywara 	}
138ce485955SAndre Przywara 
139ce485955SAndre Przywara 	if (ENABLE_FEAT_FGT == FEAT_STATE_ALWAYS) {
140ce485955SAndre Przywara 		return true;
141ce485955SAndre Przywara 	}
142ce485955SAndre Przywara 
143ce485955SAndre Przywara 	return read_feat_fgt_id_field() != 0U;
144110ee433SJimmy Brisson }
145110ee433SJimmy Brisson 
14629d0ee54SJimmy Brisson static inline unsigned long int get_armv8_6_ecv_support(void)
14729d0ee54SJimmy Brisson {
14829d0ee54SJimmy Brisson 	return ((read_id_aa64mmfr0_el1() >> ID_AA64MMFR0_EL1_ECV_SHIFT) &
14929d0ee54SJimmy Brisson 		ID_AA64MMFR0_EL1_ECV_MASK);
15029d0ee54SJimmy Brisson }
15129d0ee54SJimmy Brisson 
1527c802c71STomas Pilar static inline bool is_armv8_5_rng_present(void)
1537c802c71STomas Pilar {
1547c802c71STomas Pilar 	return ((read_id_aa64isar0_el1() >> ID_AA64ISAR0_RNDR_SHIFT) &
1557c802c71STomas Pilar 		ID_AA64ISAR0_RNDR_MASK);
1567c802c71STomas Pilar }
1577c802c71STomas Pilar 
158d3331603SMark Brown static unsigned int read_feat_tcrx_id_field(void)
159d3331603SMark Brown {
160d3331603SMark Brown 	return ISOLATE_FIELD(read_id_aa64mmfr3_el1(), ID_AA64MMFR3_EL1_TCRX);
161d3331603SMark Brown }
162d3331603SMark Brown 
163d3331603SMark Brown static inline bool is_feat_tcr2_supported(void)
164d3331603SMark Brown {
165d3331603SMark Brown 	if (ENABLE_FEAT_TCR2 == FEAT_STATE_DISABLED) {
166d3331603SMark Brown 		return false;
167d3331603SMark Brown 	}
168d3331603SMark Brown 
169d3331603SMark Brown 	if (ENABLE_FEAT_TCR2 == FEAT_STATE_ALWAYS) {
170d3331603SMark Brown 		return true;
171d3331603SMark Brown 	}
172d3331603SMark Brown 
173d3331603SMark Brown 	return read_feat_tcrx_id_field() != 0U;
174d3331603SMark Brown }
175d3331603SMark Brown 
176f0deb4c8SAndre Przywara /*******************************************************************************
177f0deb4c8SAndre Przywara  * Functions to identify the presence of the Activity Monitors Extension
178f0deb4c8SAndre Przywara  ******************************************************************************/
179f0deb4c8SAndre Przywara static unsigned int read_feat_amu_id_field(void)
180f0deb4c8SAndre Przywara {
181fd1dd4cbSAndre Przywara 	return ISOLATE_FIELD(read_id_aa64pfr0_el1(), ID_AA64PFR0_AMU);
182f0deb4c8SAndre Przywara }
183f0deb4c8SAndre Przywara 
184f0deb4c8SAndre Przywara static inline bool is_feat_amu_supported(void)
185f0deb4c8SAndre Przywara {
186f0deb4c8SAndre Przywara 	if (ENABLE_FEAT_AMUv1 == FEAT_STATE_DISABLED) {
187f0deb4c8SAndre Przywara 		return false;
188f0deb4c8SAndre Przywara 	}
189f0deb4c8SAndre Przywara 
190f0deb4c8SAndre Przywara 	if (ENABLE_FEAT_AMUv1 == FEAT_STATE_ALWAYS) {
191f0deb4c8SAndre Przywara 		return true;
192f0deb4c8SAndre Przywara 	}
193f0deb4c8SAndre Przywara 
194f0deb4c8SAndre Przywara 	return read_feat_amu_id_field() >= ID_AA64PFR0_AMU_V1;
195f0deb4c8SAndre Przywara }
196f0deb4c8SAndre Przywara 
197873d4241Sjohpow01 static inline bool is_armv8_6_feat_amuv1p1_present(void)
198873d4241Sjohpow01 {
199f0deb4c8SAndre Przywara 	return read_feat_amu_id_field() >= ID_AA64PFR0_AMU_V1P1;
200873d4241Sjohpow01 }
201873d4241Sjohpow01 
202dbcc44a1SAlexei Fedorov /*
203dbcc44a1SAlexei Fedorov  * Return MPAM version:
204dbcc44a1SAlexei Fedorov  *
205dbcc44a1SAlexei Fedorov  * 0x00: None Armv8.0 or later
206dbcc44a1SAlexei Fedorov  * 0x01: v0.1 Armv8.4 or later
207dbcc44a1SAlexei Fedorov  * 0x10: v1.0 Armv8.2 or later
208dbcc44a1SAlexei Fedorov  * 0x11: v1.1 Armv8.4 or later
209dbcc44a1SAlexei Fedorov  *
210dbcc44a1SAlexei Fedorov  */
2119448f2b8SAndre Przywara static inline unsigned int read_feat_mpam_version(void)
212dbcc44a1SAlexei Fedorov {
213dbcc44a1SAlexei Fedorov 	return (unsigned int)((((read_id_aa64pfr0_el1() >>
214dbcc44a1SAlexei Fedorov 		ID_AA64PFR0_MPAM_SHIFT) & ID_AA64PFR0_MPAM_MASK) << 4) |
215dbcc44a1SAlexei Fedorov 				((read_id_aa64pfr1_el1() >>
216dbcc44a1SAlexei Fedorov 		ID_AA64PFR1_MPAM_FRAC_SHIFT) & ID_AA64PFR1_MPAM_FRAC_MASK));
217dbcc44a1SAlexei Fedorov }
218dbcc44a1SAlexei Fedorov 
2199448f2b8SAndre Przywara static inline bool is_feat_mpam_supported(void)
2209448f2b8SAndre Przywara {
2219448f2b8SAndre Przywara 	if (ENABLE_MPAM_FOR_LOWER_ELS == FEAT_STATE_DISABLED) {
2229448f2b8SAndre Przywara 		return false;
2239448f2b8SAndre Przywara 	}
2249448f2b8SAndre Przywara 
2259448f2b8SAndre Przywara 	if (ENABLE_MPAM_FOR_LOWER_ELS == FEAT_STATE_ALWAYS) {
2269448f2b8SAndre Przywara 		return true;
2279448f2b8SAndre Przywara 	}
2289448f2b8SAndre Przywara 
2299448f2b8SAndre Przywara 	return read_feat_mpam_version() != 0U;
2309448f2b8SAndre Przywara }
2319448f2b8SAndre Przywara 
232d242128cSAndre Przywara static inline unsigned int read_feat_hcx_id_field(void)
233cb4ec47bSjohpow01 {
234fd1dd4cbSAndre Przywara 	return ISOLATE_FIELD(read_id_aa64mmfr1_el1(), ID_AA64MMFR1_EL1_HCX);
235d242128cSAndre Przywara }
236d242128cSAndre Przywara 
237d242128cSAndre Przywara static inline bool is_feat_hcx_supported(void)
238d242128cSAndre Przywara {
239d242128cSAndre Przywara 	if (ENABLE_FEAT_HCX == FEAT_STATE_DISABLED) {
240d242128cSAndre Przywara 		return false;
241d242128cSAndre Przywara 	}
242d242128cSAndre Przywara 
243d242128cSAndre Przywara 	if (ENABLE_FEAT_HCX == FEAT_STATE_ALWAYS) {
244d242128cSAndre Przywara 		return true;
245d242128cSAndre Przywara 	}
246d242128cSAndre Przywara 
247d242128cSAndre Przywara 	return read_feat_hcx_id_field() != 0U;
248cb4ec47bSjohpow01 }
249cb4ec47bSjohpow01 
250ff86e0b4SJuan Pablo Conde static inline bool is_feat_rng_trap_present(void)
251ff86e0b4SJuan Pablo Conde {
252ff86e0b4SJuan Pablo Conde 	return (((read_id_aa64pfr1_el1() >> ID_AA64PFR1_EL1_RNDR_TRAP_SHIFT) &
253ff86e0b4SJuan Pablo Conde 			ID_AA64PFR1_EL1_RNDR_TRAP_MASK)
254ff86e0b4SJuan Pablo Conde 			== ID_AA64PFR1_EL1_RNG_TRAP_SUPPORTED);
255ff86e0b4SJuan Pablo Conde }
256ff86e0b4SJuan Pablo Conde 
25781c272b3SZelalem Aweke static inline unsigned int get_armv9_2_feat_rme_support(void)
25881c272b3SZelalem Aweke {
25981c272b3SZelalem Aweke 	/*
26081c272b3SZelalem Aweke 	 * Return the RME version, zero if not supported.  This function can be
26181c272b3SZelalem Aweke 	 * used as both an integer value for the RME version or compared to zero
26281c272b3SZelalem Aweke 	 * to detect RME presence.
26381c272b3SZelalem Aweke 	 */
26481c272b3SZelalem Aweke 	return (unsigned int)(read_id_aa64pfr0_el1() >>
26581c272b3SZelalem Aweke 		ID_AA64PFR0_FEAT_RME_SHIFT) & ID_AA64PFR0_FEAT_RME_MASK;
26681c272b3SZelalem Aweke }
26781c272b3SZelalem Aweke 
2686a0da736SJayanth Dodderi Chidanand /*********************************************************************************
2696a0da736SJayanth Dodderi Chidanand  * Function to identify the presence of FEAT_SB (Speculation Barrier Instruction)
2706a0da736SJayanth Dodderi Chidanand  ********************************************************************************/
27124077098SAndre Przywara static inline unsigned int read_feat_sb_id_field(void)
2726a0da736SJayanth Dodderi Chidanand {
27324077098SAndre Przywara 	return ISOLATE_FIELD(read_id_aa64isar1_el1(), ID_AA64ISAR1_SB);
2746a0da736SJayanth Dodderi Chidanand }
2756a0da736SJayanth Dodderi Chidanand 
2766a0da736SJayanth Dodderi Chidanand /*********************************************************************************
2776a0da736SJayanth Dodderi Chidanand  * Function to identify the presence of FEAT_CSV2_2 (Cache Speculation Variant 2)
2786a0da736SJayanth Dodderi Chidanand  ********************************************************************************/
2796a0da736SJayanth Dodderi Chidanand static inline bool is_armv8_0_feat_csv2_2_present(void)
2806a0da736SJayanth Dodderi Chidanand {
2816a0da736SJayanth Dodderi Chidanand 	return (((read_id_aa64pfr0_el1() >> ID_AA64PFR0_CSV2_SHIFT) &
2826a0da736SJayanth Dodderi Chidanand 		ID_AA64PFR0_CSV2_MASK) == ID_AA64PFR0_CSV2_2_SUPPORTED);
2836a0da736SJayanth Dodderi Chidanand }
2846a0da736SJayanth Dodderi Chidanand 
2856a0da736SJayanth Dodderi Chidanand /**********************************************************************************
2866a0da736SJayanth Dodderi Chidanand  * Function to identify the presence of FEAT_SPE (Statistical Profiling Extension)
2876a0da736SJayanth Dodderi Chidanand  *********************************************************************************/
2886437a09aSAndre Przywara static inline unsigned int read_feat_spe_id_field(void)
2896a0da736SJayanth Dodderi Chidanand {
2906437a09aSAndre Przywara 	return ISOLATE_FIELD(read_id_aa64dfr0_el1(), ID_AA64DFR0_PMS);
2916437a09aSAndre Przywara }
2926437a09aSAndre Przywara 
2936437a09aSAndre Przywara static inline bool is_feat_spe_supported(void)
2946437a09aSAndre Przywara {
2956437a09aSAndre Przywara 	if (ENABLE_SPE_FOR_NS == FEAT_STATE_DISABLED) {
2966437a09aSAndre Przywara 		return false;
2976437a09aSAndre Przywara 	}
2986437a09aSAndre Przywara 
2996437a09aSAndre Przywara 	if (ENABLE_SPE_FOR_NS == FEAT_STATE_ALWAYS) {
3006437a09aSAndre Przywara 		return true;
3016437a09aSAndre Przywara 	}
3026437a09aSAndre Przywara 
3036437a09aSAndre Przywara 	return read_feat_spe_id_field() != 0U;
3046a0da736SJayanth Dodderi Chidanand }
3056a0da736SJayanth Dodderi Chidanand 
3066a0da736SJayanth Dodderi Chidanand /*******************************************************************************
3076a0da736SJayanth Dodderi Chidanand  * Function to identify the presence of FEAT_SVE (Scalable Vector Extension)
3086a0da736SJayanth Dodderi Chidanand  ******************************************************************************/
3096a0da736SJayanth Dodderi Chidanand static inline bool is_armv8_2_feat_sve_present(void)
3106a0da736SJayanth Dodderi Chidanand {
3116a0da736SJayanth Dodderi Chidanand 	return (((read_id_aa64pfr0_el1() >> ID_AA64PFR0_SVE_SHIFT) &
3126a0da736SJayanth Dodderi Chidanand 		ID_AA64PFR0_SVE_MASK) == ID_AA64PFR0_SVE_SUPPORTED);
3136a0da736SJayanth Dodderi Chidanand }
3146a0da736SJayanth Dodderi Chidanand 
3156a0da736SJayanth Dodderi Chidanand /*******************************************************************************
3166a0da736SJayanth Dodderi Chidanand  * Function to identify the presence of FEAT_RAS (Reliability,Availability,
3176a0da736SJayanth Dodderi Chidanand  * and Serviceability Extension)
3186a0da736SJayanth Dodderi Chidanand  ******************************************************************************/
3196a0da736SJayanth Dodderi Chidanand static inline bool is_armv8_2_feat_ras_present(void)
3206a0da736SJayanth Dodderi Chidanand {
3216a0da736SJayanth Dodderi Chidanand 	return (((read_id_aa64pfr0_el1() >> ID_AA64PFR0_RAS_SHIFT) &
3226a0da736SJayanth Dodderi Chidanand 		ID_AA64PFR0_RAS_MASK) != ID_AA64PFR0_RAS_NOT_SUPPORTED);
3236a0da736SJayanth Dodderi Chidanand }
3246a0da736SJayanth Dodderi Chidanand 
3256a0da736SJayanth Dodderi Chidanand /**************************************************************************
3266a0da736SJayanth Dodderi Chidanand  * Function to identify the presence of FEAT_DIT (Data Independent Timing)
3276a0da736SJayanth Dodderi Chidanand  *************************************************************************/
3286a0da736SJayanth Dodderi Chidanand static inline bool is_armv8_4_feat_dit_present(void)
3296a0da736SJayanth Dodderi Chidanand {
3306a0da736SJayanth Dodderi Chidanand 	return (((read_id_aa64pfr0_el1() >> ID_AA64PFR0_DIT_SHIFT) &
3316a0da736SJayanth Dodderi Chidanand 		ID_AA64PFR0_DIT_MASK) == ID_AA64PFR0_DIT_SUPPORTED);
3326a0da736SJayanth Dodderi Chidanand }
3336a0da736SJayanth Dodderi Chidanand 
334603a0c6fSAndre Przywara static inline unsigned int read_feat_tracever_id_field(void)
335603a0c6fSAndre Przywara {
336603a0c6fSAndre Przywara 	return ISOLATE_FIELD(read_id_aa64dfr0_el1(), ID_AA64DFR0_TRACEVER);
337603a0c6fSAndre Przywara }
338603a0c6fSAndre Przywara 
339603a0c6fSAndre Przywara static inline bool is_feat_sys_reg_trace_supported(void)
340603a0c6fSAndre Przywara {
341603a0c6fSAndre Przywara 	if (ENABLE_SYS_REG_TRACE_FOR_NS == FEAT_STATE_DISABLED) {
342603a0c6fSAndre Przywara 		return false;
343603a0c6fSAndre Przywara 	}
344603a0c6fSAndre Przywara 
345603a0c6fSAndre Przywara 	if (ENABLE_SYS_REG_TRACE_FOR_NS == FEAT_STATE_ALWAYS) {
346603a0c6fSAndre Przywara 		return true;
347603a0c6fSAndre Przywara 	}
348603a0c6fSAndre Przywara 
349603a0c6fSAndre Przywara 	return read_feat_tracever_id_field() != 0U;
350603a0c6fSAndre Przywara }
351603a0c6fSAndre Przywara 
3526a0da736SJayanth Dodderi Chidanand /*************************************************************************
3536a0da736SJayanth Dodderi Chidanand  * Function to identify the presence of FEAT_TRF (TraceLift)
3546a0da736SJayanth Dodderi Chidanand  ************************************************************************/
355fc8d2d39SAndre Przywara static inline unsigned int read_feat_trf_id_field(void)
3566a0da736SJayanth Dodderi Chidanand {
357fc8d2d39SAndre Przywara 	return ISOLATE_FIELD(read_id_aa64dfr0_el1(), ID_AA64DFR0_TRACEFILT);
358fc8d2d39SAndre Przywara }
359fc8d2d39SAndre Przywara 
360fc8d2d39SAndre Przywara static inline bool is_feat_trf_supported(void)
361fc8d2d39SAndre Przywara {
362fc8d2d39SAndre Przywara 	if (ENABLE_TRF_FOR_NS == FEAT_STATE_DISABLED) {
363fc8d2d39SAndre Przywara 		return false;
364fc8d2d39SAndre Przywara 	}
365fc8d2d39SAndre Przywara 
366fc8d2d39SAndre Przywara 	if (ENABLE_TRF_FOR_NS == FEAT_STATE_ALWAYS) {
367fc8d2d39SAndre Przywara 		return true;
368fc8d2d39SAndre Przywara 	}
369fc8d2d39SAndre Przywara 
370fc8d2d39SAndre Przywara 	return read_feat_trf_id_field() != 0U;
3716a0da736SJayanth Dodderi Chidanand }
3726a0da736SJayanth Dodderi Chidanand 
3736a0da736SJayanth Dodderi Chidanand /********************************************************************************
3746a0da736SJayanth Dodderi Chidanand  * Function to identify the presence of FEAT_NV2 (Enhanced Nested Virtualization
3756a0da736SJayanth Dodderi Chidanand  * Support)
3766a0da736SJayanth Dodderi Chidanand  *******************************************************************************/
3776a0da736SJayanth Dodderi Chidanand static inline unsigned int get_armv8_4_feat_nv_support(void)
3786a0da736SJayanth Dodderi Chidanand {
3796a0da736SJayanth Dodderi Chidanand 	return (((read_id_aa64mmfr2_el1() >> ID_AA64MMFR2_EL1_NV_SHIFT) &
3806a0da736SJayanth Dodderi Chidanand 		ID_AA64MMFR2_EL1_NV_MASK));
3816a0da736SJayanth Dodderi Chidanand }
3826a0da736SJayanth Dodderi Chidanand 
3831298f2f1SJayanth Dodderi Chidanand /*******************************************************************************
3841298f2f1SJayanth Dodderi Chidanand  * Function to identify the presence of FEAT_BRBE (Branch Record Buffer
3851298f2f1SJayanth Dodderi Chidanand  * Extension)
3861298f2f1SJayanth Dodderi Chidanand  ******************************************************************************/
387ff491036SAndre Przywara static inline unsigned int read_feat_brbe_id_field(void)
3881298f2f1SJayanth Dodderi Chidanand {
389ff491036SAndre Przywara 	return ISOLATE_FIELD(read_id_aa64dfr0_el1(), ID_AA64DFR0_BRBE);
390ff491036SAndre Przywara }
391ff491036SAndre Przywara 
392ff491036SAndre Przywara static inline bool is_feat_brbe_supported(void)
393ff491036SAndre Przywara {
394ff491036SAndre Przywara 	if (ENABLE_BRBE_FOR_NS == FEAT_STATE_DISABLED) {
395ff491036SAndre Przywara 		return false;
396ff491036SAndre Przywara 	}
397ff491036SAndre Przywara 
398ff491036SAndre Przywara 	if (ENABLE_BRBE_FOR_NS == FEAT_STATE_ALWAYS) {
399ff491036SAndre Przywara 		return true;
400ff491036SAndre Przywara 	}
401ff491036SAndre Przywara 
402ff491036SAndre Przywara 	return read_feat_brbe_id_field() != 0U;
4031298f2f1SJayanth Dodderi Chidanand }
4041298f2f1SJayanth Dodderi Chidanand 
40547c681b7SJayanth Dodderi Chidanand /*******************************************************************************
40647c681b7SJayanth Dodderi Chidanand  * Function to identify the presence of FEAT_TRBE (Trace Buffer Extension)
40747c681b7SJayanth Dodderi Chidanand  ******************************************************************************/
408f5360cfaSAndre Przywara static inline unsigned int read_feat_trbe_id_field(void)
40947c681b7SJayanth Dodderi Chidanand {
410f5360cfaSAndre Przywara 	return ISOLATE_FIELD(read_id_aa64dfr0_el1(), ID_AA64DFR0_TRACEBUFFER);
41147c681b7SJayanth Dodderi Chidanand }
4121298f2f1SJayanth Dodderi Chidanand 
413f5360cfaSAndre Przywara static inline bool is_feat_trbe_supported(void)
414f5360cfaSAndre Przywara {
415f5360cfaSAndre Przywara 	if (ENABLE_TRBE_FOR_NS == FEAT_STATE_DISABLED) {
416f5360cfaSAndre Przywara 		return false;
417f5360cfaSAndre Przywara 	}
418f5360cfaSAndre Przywara 
419f5360cfaSAndre Przywara 	if (ENABLE_TRBE_FOR_NS == FEAT_STATE_ALWAYS) {
420f5360cfaSAndre Przywara 		return true;
421f5360cfaSAndre Przywara 	}
422f5360cfaSAndre Przywara 
423f5360cfaSAndre Przywara 	return read_feat_trbe_id_field() != 0U;
424f5360cfaSAndre Przywara 
425f5360cfaSAndre Przywara }
4262559b2c8SAntonio Nino Diaz #endif /* ARCH_FEATURES_H */
427