xref: /rk3399_ARM-atf/include/arch/aarch64/arch_features.h (revision 0a33adc058080433f73bde73895266068990245c)
12559b2c8SAntonio Nino Diaz /*
2*0a33adc0SGovindraj Raja  * Copyright (c) 2019-2024, 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)					\
16a8d5d3d5SAndre Przywara 	((unsigned int)(((reg) >> (feat)) & ID_REG_FIELD_MASK))
17a8d5d3d5SAndre Przywara 
18a8d5d3d5SAndre Przywara #define CREATE_FEATURE_FUNCS_VER(name, read_func, idvalue, guard)	\
19a8d5d3d5SAndre Przywara static inline bool is_ ## name ## _supported(void)			\
20a8d5d3d5SAndre Przywara {									\
21a8d5d3d5SAndre Przywara 	if ((guard) == FEAT_STATE_DISABLED) {				\
22a8d5d3d5SAndre Przywara 		return false;						\
23a8d5d3d5SAndre Przywara 	}								\
24a8d5d3d5SAndre Przywara 	if ((guard) == FEAT_STATE_ALWAYS) {				\
25a8d5d3d5SAndre Przywara 		return true;						\
26a8d5d3d5SAndre Przywara 	}								\
27a8d5d3d5SAndre Przywara 	return read_func() >= (idvalue);				\
28a8d5d3d5SAndre Przywara }
29a8d5d3d5SAndre Przywara 
30a8d5d3d5SAndre Przywara #define CREATE_FEATURE_FUNCS(name, idreg, idfield, guard)		\
31a8d5d3d5SAndre Przywara static unsigned int read_ ## name ## _id_field(void)			\
32a8d5d3d5SAndre Przywara {									\
33a8d5d3d5SAndre Przywara 	return ISOLATE_FIELD(read_ ## idreg(), idfield);		\
34a8d5d3d5SAndre Przywara }									\
35a8d5d3d5SAndre Przywara CREATE_FEATURE_FUNCS_VER(name, read_ ## name ## _id_field, 1U, guard)
36fd1dd4cbSAndre Przywara 
3729a24134SAntonio Nino Diaz static inline bool is_armv7_gentimer_present(void)
3829a24134SAntonio Nino Diaz {
3929a24134SAntonio Nino Diaz 	/* The Generic Timer is always present in an ARMv8-A implementation */
4029a24134SAntonio Nino Diaz 	return true;
4129a24134SAntonio Nino Diaz }
4229a24134SAntonio Nino Diaz 
43a8d5d3d5SAndre Przywara CREATE_FEATURE_FUNCS(feat_pan, id_aa64mmfr1_el1, ID_AA64MMFR1_EL1_PAN_SHIFT,
44a8d5d3d5SAndre Przywara 		     ENABLE_FEAT_PAN)
45a8d5d3d5SAndre Przywara CREATE_FEATURE_FUNCS(feat_vhe, id_aa64mmfr1_el1, ID_AA64MMFR1_EL1_VHE_SHIFT,
46a8d5d3d5SAndre Przywara 		     ENABLE_FEAT_VHE)
4737596fcbSDaniel Boulby 
482559b2c8SAntonio Nino Diaz static inline bool is_armv8_2_ttcnp_present(void)
492559b2c8SAntonio Nino Diaz {
502559b2c8SAntonio Nino Diaz 	return ((read_id_aa64mmfr2_el1() >> ID_AA64MMFR2_EL1_CNP_SHIFT) &
512559b2c8SAntonio Nino Diaz 		ID_AA64MMFR2_EL1_CNP_MASK) != 0U;
522559b2c8SAntonio Nino Diaz }
532559b2c8SAntonio Nino Diaz 
549ff5f754SJuan Pablo Conde static inline bool is_feat_pacqarma3_present(void)
559ff5f754SJuan Pablo Conde {
569ff5f754SJuan Pablo Conde 	uint64_t mask_id_aa64isar2 =
579ff5f754SJuan Pablo Conde 			(ID_AA64ISAR2_GPA3_MASK << ID_AA64ISAR2_GPA3_SHIFT) |
589ff5f754SJuan Pablo Conde 			(ID_AA64ISAR2_APA3_MASK << ID_AA64ISAR2_APA3_SHIFT);
599ff5f754SJuan Pablo Conde 
609ff5f754SJuan Pablo Conde 	/* If any of the fields is not zero, QARMA3 algorithm is present */
619ff5f754SJuan Pablo Conde 	return (read_id_aa64isar2_el1() & mask_id_aa64isar2) != 0U;
629ff5f754SJuan Pablo Conde }
639ff5f754SJuan Pablo Conde 
64b86048c4SAntonio Nino Diaz static inline bool is_armv8_3_pauth_present(void)
65b86048c4SAntonio Nino Diaz {
669ff5f754SJuan Pablo Conde 	uint64_t mask_id_aa64isar1 =
679ff5f754SJuan Pablo Conde 		(ID_AA64ISAR1_GPI_MASK << ID_AA64ISAR1_GPI_SHIFT) |
68b86048c4SAntonio Nino Diaz 		(ID_AA64ISAR1_GPA_MASK << ID_AA64ISAR1_GPA_SHIFT) |
69b86048c4SAntonio Nino Diaz 		(ID_AA64ISAR1_API_MASK << ID_AA64ISAR1_API_SHIFT) |
70b86048c4SAntonio Nino Diaz 		(ID_AA64ISAR1_APA_MASK << ID_AA64ISAR1_APA_SHIFT);
71b86048c4SAntonio Nino Diaz 
729ff5f754SJuan Pablo Conde 	/*
739ff5f754SJuan Pablo Conde 	 * If any of the fields is not zero or QARMA3 is present,
749ff5f754SJuan Pablo Conde 	 * PAuth is present
759ff5f754SJuan Pablo Conde 	 */
769ff5f754SJuan Pablo Conde 	return ((read_id_aa64isar1_el1() & mask_id_aa64isar1) != 0U ||
779ff5f754SJuan Pablo Conde 		is_feat_pacqarma3_present());
78b86048c4SAntonio Nino Diaz }
79b86048c4SAntonio Nino Diaz 
80cedfa04bSSathees Balya static inline bool is_armv8_4_ttst_present(void)
81cedfa04bSSathees Balya {
82cedfa04bSSathees Balya 	return ((read_id_aa64mmfr2_el1() >> ID_AA64MMFR2_EL1_ST_SHIFT) &
83cedfa04bSSathees Balya 		ID_AA64MMFR2_EL1_ST_MASK) == 1U;
84cedfa04bSSathees Balya }
85cedfa04bSSathees Balya 
869fc59639SAlexei Fedorov static inline bool is_armv8_5_bti_present(void)
879fc59639SAlexei Fedorov {
889fc59639SAlexei Fedorov 	return ((read_id_aa64pfr1_el1() >> ID_AA64PFR1_EL1_BT_SHIFT) &
899fc59639SAlexei Fedorov 		ID_AA64PFR1_EL1_BT_MASK) == BTI_IMPLEMENTED;
909fc59639SAlexei Fedorov }
919fc59639SAlexei Fedorov 
92*0a33adc0SGovindraj Raja CREATE_FEATURE_FUNCS(feat_mte, id_aa64pfr1_el1, ID_AA64PFR1_EL1_MTE_SHIFT,
93*0a33adc0SGovindraj Raja 		     ENABLE_FEAT_MTE)
94a8d5d3d5SAndre Przywara CREATE_FEATURE_FUNCS(feat_sel2, id_aa64pfr0_el1, ID_AA64PFR0_SEL2_SHIFT,
95a8d5d3d5SAndre Przywara 		     ENABLE_FEAT_SEL2)
96a8d5d3d5SAndre Przywara CREATE_FEATURE_FUNCS(feat_twed, id_aa64mmfr1_el1, ID_AA64MMFR1_EL1_TWED_SHIFT,
97a8d5d3d5SAndre Przywara 		     ENABLE_FEAT_TWED)
98a8d5d3d5SAndre Przywara CREATE_FEATURE_FUNCS(feat_fgt, id_aa64mmfr0_el1, ID_AA64MMFR0_EL1_FGT_SHIFT,
99a8d5d3d5SAndre Przywara 		     ENABLE_FEAT_FGT)
100a8d5d3d5SAndre Przywara CREATE_FEATURE_FUNCS(feat_mte_perm, id_aa64pfr2_el1,
101a8d5d3d5SAndre Przywara 		     ID_AA64PFR2_EL1_MTEPERM_SHIFT, ENABLE_FEAT_MTE_PERM)
102a8d5d3d5SAndre Przywara CREATE_FEATURE_FUNCS(feat_ecv, id_aa64mmfr0_el1, ID_AA64MMFR0_EL1_ECV_SHIFT,
103a8d5d3d5SAndre Przywara 		     ENABLE_FEAT_ECV)
104a8d5d3d5SAndre Przywara CREATE_FEATURE_FUNCS_VER(feat_ecv_v2, read_feat_ecv_id_field,
105a8d5d3d5SAndre Przywara 			 ID_AA64MMFR0_EL1_ECV_SELF_SYNCH, ENABLE_FEAT_ECV)
106623f6140SAndre Przywara 
107a8d5d3d5SAndre Przywara CREATE_FEATURE_FUNCS(feat_rng, id_aa64isar0_el1, ID_AA64ISAR0_RNDR_SHIFT,
108a8d5d3d5SAndre Przywara 		     ENABLE_FEAT_RNG)
109a8d5d3d5SAndre Przywara CREATE_FEATURE_FUNCS(feat_tcr2, id_aa64mmfr3_el1, ID_AA64MMFR3_EL1_TCRX_SHIFT,
110a8d5d3d5SAndre Przywara 		     ENABLE_FEAT_TCR2)
111623f6140SAndre Przywara 
112a8d5d3d5SAndre Przywara CREATE_FEATURE_FUNCS(feat_s2poe, id_aa64mmfr3_el1, ID_AA64MMFR3_EL1_S2POE_SHIFT,
113a8d5d3d5SAndre Przywara 		     ENABLE_FEAT_S2POE)
114a8d5d3d5SAndre Przywara CREATE_FEATURE_FUNCS(feat_s1poe, id_aa64mmfr3_el1, ID_AA64MMFR3_EL1_S1POE_SHIFT,
115a8d5d3d5SAndre Przywara 		     ENABLE_FEAT_S1POE)
116062b6c6bSMark Brown static inline bool is_feat_sxpoe_supported(void)
117062b6c6bSMark Brown {
118062b6c6bSMark Brown 	return is_feat_s1poe_supported() || is_feat_s2poe_supported();
119062b6c6bSMark Brown }
120062b6c6bSMark Brown 
121a8d5d3d5SAndre Przywara CREATE_FEATURE_FUNCS(feat_s2pie, id_aa64mmfr3_el1, ID_AA64MMFR3_EL1_S2PIE_SHIFT,
122a8d5d3d5SAndre Przywara 		     ENABLE_FEAT_S2PIE)
123a8d5d3d5SAndre Przywara CREATE_FEATURE_FUNCS(feat_s1pie, id_aa64mmfr3_el1, ID_AA64MMFR3_EL1_S1PIE_SHIFT,
124a8d5d3d5SAndre Przywara 		     ENABLE_FEAT_S1PIE)
125062b6c6bSMark Brown static inline bool is_feat_sxpie_supported(void)
126062b6c6bSMark Brown {
127062b6c6bSMark Brown 	return is_feat_s1pie_supported() || is_feat_s2pie_supported();
128062b6c6bSMark Brown }
129062b6c6bSMark Brown 
130a8d5d3d5SAndre Przywara /* FEAT_GCS: Guarded Control Stack */
131a8d5d3d5SAndre Przywara CREATE_FEATURE_FUNCS(feat_gcs, id_aa64pfr1_el1, ID_AA64PFR1_EL1_GCS_SHIFT,
132a8d5d3d5SAndre Przywara 		     ENABLE_FEAT_GCS)
133688ab57bSMark Brown 
134a8d5d3d5SAndre Przywara /* FEAT_AMU: Activity Monitors Extension */
135a8d5d3d5SAndre Przywara CREATE_FEATURE_FUNCS(feat_amu, id_aa64pfr0_el1, ID_AA64PFR0_AMU_SHIFT,
136a8d5d3d5SAndre Przywara 		     ENABLE_FEAT_AMU)
137a8d5d3d5SAndre Przywara CREATE_FEATURE_FUNCS_VER(feat_amuv1p1, read_feat_amu_id_field,
138a8d5d3d5SAndre Przywara 			 ID_AA64PFR0_AMU_V1P1, ENABLE_FEAT_AMUv1p1)
139873d4241Sjohpow01 
140dbcc44a1SAlexei Fedorov /*
141dbcc44a1SAlexei Fedorov  * Return MPAM version:
142dbcc44a1SAlexei Fedorov  *
143dbcc44a1SAlexei Fedorov  * 0x00: None Armv8.0 or later
144dbcc44a1SAlexei Fedorov  * 0x01: v0.1 Armv8.4 or later
145dbcc44a1SAlexei Fedorov  * 0x10: v1.0 Armv8.2 or later
146dbcc44a1SAlexei Fedorov  * 0x11: v1.1 Armv8.4 or later
147dbcc44a1SAlexei Fedorov  *
148dbcc44a1SAlexei Fedorov  */
1499448f2b8SAndre Przywara static inline unsigned int read_feat_mpam_version(void)
150dbcc44a1SAlexei Fedorov {
151dbcc44a1SAlexei Fedorov 	return (unsigned int)((((read_id_aa64pfr0_el1() >>
152dbcc44a1SAlexei Fedorov 		ID_AA64PFR0_MPAM_SHIFT) & ID_AA64PFR0_MPAM_MASK) << 4) |
153dbcc44a1SAlexei Fedorov 				((read_id_aa64pfr1_el1() >>
154dbcc44a1SAlexei Fedorov 		ID_AA64PFR1_MPAM_FRAC_SHIFT) & ID_AA64PFR1_MPAM_FRAC_MASK));
155dbcc44a1SAlexei Fedorov }
156dbcc44a1SAlexei Fedorov 
157a8d5d3d5SAndre Przywara CREATE_FEATURE_FUNCS_VER(feat_mpam, read_feat_mpam_version, 1U,
158edebefbcSArvind Ram Prakash 			 ENABLE_FEAT_MPAM)
1599448f2b8SAndre Przywara 
160a8d5d3d5SAndre Przywara /* FEAT_HCX: Extended Hypervisor Configuration Register */
161a8d5d3d5SAndre Przywara CREATE_FEATURE_FUNCS(feat_hcx, id_aa64mmfr1_el1, ID_AA64MMFR1_EL1_HCX_SHIFT,
162a8d5d3d5SAndre Przywara 		     ENABLE_FEAT_HCX)
163cb4ec47bSjohpow01 
164ff86e0b4SJuan Pablo Conde static inline bool is_feat_rng_trap_present(void)
165ff86e0b4SJuan Pablo Conde {
166ff86e0b4SJuan Pablo Conde 	return (((read_id_aa64pfr1_el1() >> ID_AA64PFR1_EL1_RNDR_TRAP_SHIFT) &
167ff86e0b4SJuan Pablo Conde 			ID_AA64PFR1_EL1_RNDR_TRAP_MASK)
168ff86e0b4SJuan Pablo Conde 			== ID_AA64PFR1_EL1_RNG_TRAP_SUPPORTED);
169ff86e0b4SJuan Pablo Conde }
170ff86e0b4SJuan Pablo Conde 
17181c272b3SZelalem Aweke static inline unsigned int get_armv9_2_feat_rme_support(void)
17281c272b3SZelalem Aweke {
17381c272b3SZelalem Aweke 	/*
17481c272b3SZelalem Aweke 	 * Return the RME version, zero if not supported.  This function can be
17581c272b3SZelalem Aweke 	 * used as both an integer value for the RME version or compared to zero
17681c272b3SZelalem Aweke 	 * to detect RME presence.
17781c272b3SZelalem Aweke 	 */
17881c272b3SZelalem Aweke 	return (unsigned int)(read_id_aa64pfr0_el1() >>
17981c272b3SZelalem Aweke 		ID_AA64PFR0_FEAT_RME_SHIFT) & ID_AA64PFR0_FEAT_RME_MASK;
18081c272b3SZelalem Aweke }
18181c272b3SZelalem Aweke 
1826a0da736SJayanth Dodderi Chidanand /*********************************************************************************
1836a0da736SJayanth Dodderi Chidanand  * Function to identify the presence of FEAT_SB (Speculation Barrier Instruction)
1846a0da736SJayanth Dodderi Chidanand  ********************************************************************************/
18524077098SAndre Przywara static inline unsigned int read_feat_sb_id_field(void)
1866a0da736SJayanth Dodderi Chidanand {
187a8d5d3d5SAndre Przywara 	return ISOLATE_FIELD(read_id_aa64isar1_el1(), ID_AA64ISAR1_SB_SHIFT);
1886a0da736SJayanth Dodderi Chidanand }
1896a0da736SJayanth Dodderi Chidanand 
190a8d5d3d5SAndre Przywara /* FEAT_CSV2_2: Cache Speculation Variant 2 */
191a8d5d3d5SAndre Przywara CREATE_FEATURE_FUNCS(feat_csv2, id_aa64pfr0_el1, ID_AA64PFR0_CSV2_SHIFT, 0)
192a8d5d3d5SAndre Przywara CREATE_FEATURE_FUNCS_VER(feat_csv2_2, read_feat_csv2_id_field,
193a8d5d3d5SAndre Przywara 			 ID_AA64PFR0_CSV2_2_SUPPORTED, ENABLE_FEAT_CSV2_2)
1947db710f0SAndre Przywara 
195a8d5d3d5SAndre Przywara /* FEAT_SPE: Statistical Profiling Extension */
196a8d5d3d5SAndre Przywara CREATE_FEATURE_FUNCS(feat_spe, id_aa64dfr0_el1, ID_AA64DFR0_PMS_SHIFT,
197a8d5d3d5SAndre Przywara 		     ENABLE_SPE_FOR_NS)
1987db710f0SAndre Przywara 
199a8d5d3d5SAndre Przywara /* FEAT_SVE: Scalable Vector Extension */
200a8d5d3d5SAndre Przywara CREATE_FEATURE_FUNCS(feat_sve, id_aa64pfr0_el1, ID_AA64PFR0_SVE_SHIFT,
201a8d5d3d5SAndre Przywara 		     ENABLE_SVE_FOR_NS)
2027db710f0SAndre Przywara 
203a8d5d3d5SAndre Przywara /* FEAT_RAS: Reliability, Accessibility, Serviceability */
204a8d5d3d5SAndre Przywara CREATE_FEATURE_FUNCS(feat_ras, id_aa64pfr0_el1,
205a8d5d3d5SAndre Przywara 		     ID_AA64PFR0_RAS_SHIFT, ENABLE_FEAT_RAS)
2066a0da736SJayanth Dodderi Chidanand 
207a8d5d3d5SAndre Przywara /* FEAT_DIT: Data Independent Timing instructions */
208a8d5d3d5SAndre Przywara CREATE_FEATURE_FUNCS(feat_dit, id_aa64pfr0_el1,
209a8d5d3d5SAndre Przywara 		     ID_AA64PFR0_DIT_SHIFT, ENABLE_FEAT_DIT)
2106437a09aSAndre Przywara 
211a8d5d3d5SAndre Przywara CREATE_FEATURE_FUNCS(feat_sys_reg_trace, id_aa64dfr0_el1,
212a8d5d3d5SAndre Przywara 		     ID_AA64DFR0_TRACEVER_SHIFT, ENABLE_SYS_REG_TRACE_FOR_NS)
2136437a09aSAndre Przywara 
214a8d5d3d5SAndre Przywara /* FEAT_TRF: TraceFilter */
215a8d5d3d5SAndre Przywara CREATE_FEATURE_FUNCS(feat_trf, id_aa64dfr0_el1, ID_AA64DFR0_TRACEFILT_SHIFT,
216a8d5d3d5SAndre Przywara 		     ENABLE_TRF_FOR_NS)
2176437a09aSAndre Przywara 
218a8d5d3d5SAndre Przywara /* FEAT_NV2: Enhanced Nested Virtualization */
219a8d5d3d5SAndre Przywara CREATE_FEATURE_FUNCS(feat_nv, id_aa64mmfr2_el1, ID_AA64MMFR2_EL1_NV_SHIFT, 0)
220a8d5d3d5SAndre Przywara CREATE_FEATURE_FUNCS_VER(feat_nv2, read_feat_nv_id_field,
221a8d5d3d5SAndre Przywara 			 ID_AA64MMFR2_EL1_NV2_SUPPORTED, CTX_INCLUDE_NEVE_REGS)
2226a0da736SJayanth Dodderi Chidanand 
223a8d5d3d5SAndre Przywara /* FEAT_BRBE: Branch Record Buffer Extension */
224a8d5d3d5SAndre Przywara CREATE_FEATURE_FUNCS(feat_brbe, id_aa64dfr0_el1, ID_AA64DFR0_BRBE_SHIFT,
225a8d5d3d5SAndre Przywara 		     ENABLE_BRBE_FOR_NS)
2262b0bc4e0SJayanth Dodderi Chidanand 
227a8d5d3d5SAndre Przywara /* FEAT_TRBE: Trace Buffer Extension */
228a8d5d3d5SAndre Przywara CREATE_FEATURE_FUNCS(feat_trbe, id_aa64dfr0_el1, ID_AA64DFR0_TRACEBUFFER_SHIFT,
229a8d5d3d5SAndre Przywara 		     ENABLE_TRBE_FOR_NS)
2302b0bc4e0SJayanth Dodderi Chidanand 
23145007acdSJayanth Dodderi Chidanand static inline unsigned int read_feat_sme_fa64_id_field(void)
23245007acdSJayanth Dodderi Chidanand {
233a8d5d3d5SAndre Przywara 	return ISOLATE_FIELD(read_id_aa64smfr0_el1(),
234a8d5d3d5SAndre Przywara 			     ID_AA64SMFR0_EL1_SME_FA64_SHIFT);
23545007acdSJayanth Dodderi Chidanand }
236a8d5d3d5SAndre Przywara /* FEAT_SMEx: Scalar Matrix Extension */
237a8d5d3d5SAndre Przywara CREATE_FEATURE_FUNCS(feat_sme, id_aa64pfr1_el1, ID_AA64PFR1_EL1_SME_SHIFT,
238a8d5d3d5SAndre Przywara 		     ENABLE_SME_FOR_NS)
239a8d5d3d5SAndre Przywara CREATE_FEATURE_FUNCS_VER(feat_sme2, read_feat_sme_id_field,
240a8d5d3d5SAndre Przywara 			 ID_AA64PFR1_EL1_SME2_SUPPORTED, ENABLE_SME2_FOR_NS)
24103d3c0d7SJayanth Dodderi Chidanand 
242bff074ddSJavier Almansa Sobrino /*******************************************************************************
243bff074ddSJavier Almansa Sobrino  * Function to get hardware granularity support
244bff074ddSJavier Almansa Sobrino  ******************************************************************************/
245bff074ddSJavier Almansa Sobrino 
246bff074ddSJavier Almansa Sobrino static inline unsigned int read_id_aa64mmfr0_el0_tgran4_field(void)
247bff074ddSJavier Almansa Sobrino {
248a8d5d3d5SAndre Przywara 	return ISOLATE_FIELD(read_id_aa64mmfr0_el1(),
249a8d5d3d5SAndre Przywara 			     ID_AA64MMFR0_EL1_TGRAN4_SHIFT);
250bff074ddSJavier Almansa Sobrino }
251bff074ddSJavier Almansa Sobrino 
252bff074ddSJavier Almansa Sobrino static inline unsigned int read_id_aa64mmfr0_el0_tgran16_field(void)
253bff074ddSJavier Almansa Sobrino {
254bff074ddSJavier Almansa Sobrino 	return ISOLATE_FIELD(read_id_aa64mmfr0_el1(),
255a8d5d3d5SAndre Przywara 			     ID_AA64MMFR0_EL1_TGRAN16_SHIFT);
256bff074ddSJavier Almansa Sobrino }
257bff074ddSJavier Almansa Sobrino 
258bff074ddSJavier Almansa Sobrino static inline unsigned int read_id_aa64mmfr0_el0_tgran64_field(void)
259bff074ddSJavier Almansa Sobrino {
260bff074ddSJavier Almansa Sobrino 	return ISOLATE_FIELD(read_id_aa64mmfr0_el1(),
261a8d5d3d5SAndre Przywara 			     ID_AA64MMFR0_EL1_TGRAN64_SHIFT);
262bff074ddSJavier Almansa Sobrino }
263bff074ddSJavier Almansa Sobrino 
264c73686a1SBoyan Karatotev static inline unsigned int read_feat_pmuv3_id_field(void)
265c73686a1SBoyan Karatotev {
266a8d5d3d5SAndre Przywara 	return ISOLATE_FIELD(read_id_aa64dfr0_el1(), ID_AA64DFR0_PMUVER_SHIFT);
267c73686a1SBoyan Karatotev }
268c73686a1SBoyan Karatotev 
26983a4dae1SBoyan Karatotev static inline unsigned int read_feat_mtpmu_id_field(void)
27083a4dae1SBoyan Karatotev {
271a8d5d3d5SAndre Przywara 	return ISOLATE_FIELD(read_id_aa64dfr0_el1(), ID_AA64DFR0_MTPMU_SHIFT);
27283a4dae1SBoyan Karatotev }
27383a4dae1SBoyan Karatotev 
27483a4dae1SBoyan Karatotev static inline bool is_feat_mtpmu_supported(void)
27583a4dae1SBoyan Karatotev {
27683a4dae1SBoyan Karatotev 	if (DISABLE_MTPMU == FEAT_STATE_DISABLED) {
27783a4dae1SBoyan Karatotev 		return false;
27883a4dae1SBoyan Karatotev 	}
27983a4dae1SBoyan Karatotev 
28083a4dae1SBoyan Karatotev 	if (DISABLE_MTPMU == FEAT_STATE_ALWAYS) {
28183a4dae1SBoyan Karatotev 		return true;
28283a4dae1SBoyan Karatotev 	}
28383a4dae1SBoyan Karatotev 
28483a4dae1SBoyan Karatotev 	unsigned int mtpmu = read_feat_mtpmu_id_field();
28583a4dae1SBoyan Karatotev 
28683a4dae1SBoyan Karatotev 	return (mtpmu != 0U) && (mtpmu != ID_AA64DFR0_MTPMU_DISABLED);
28783a4dae1SBoyan Karatotev }
28883a4dae1SBoyan Karatotev 
2892559b2c8SAntonio Nino Diaz #endif /* ARCH_FEATURES_H */
290