xref: /rk3399_ARM-atf/include/arch/aarch64/arch_features.h (revision a8d5d3d540dce6e231133b0eb6d6a68a11f9d6be)
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)					\
16*a8d5d3d5SAndre Przywara 	((unsigned int)(((reg) >> (feat)) & ID_REG_FIELD_MASK))
17*a8d5d3d5SAndre Przywara 
18*a8d5d3d5SAndre Przywara #define CREATE_FEATURE_FUNCS_VER(name, read_func, idvalue, guard)	\
19*a8d5d3d5SAndre Przywara static inline bool is_ ## name ## _supported(void)			\
20*a8d5d3d5SAndre Przywara {									\
21*a8d5d3d5SAndre Przywara 	if ((guard) == FEAT_STATE_DISABLED) {				\
22*a8d5d3d5SAndre Przywara 		return false;						\
23*a8d5d3d5SAndre Przywara 	}								\
24*a8d5d3d5SAndre Przywara 	if ((guard) == FEAT_STATE_ALWAYS) {				\
25*a8d5d3d5SAndre Przywara 		return true;						\
26*a8d5d3d5SAndre Przywara 	}								\
27*a8d5d3d5SAndre Przywara 	return read_func() >= (idvalue);				\
28*a8d5d3d5SAndre Przywara }
29*a8d5d3d5SAndre Przywara 
30*a8d5d3d5SAndre Przywara #define CREATE_FEATURE_FUNCS(name, idreg, idfield, guard)		\
31*a8d5d3d5SAndre Przywara static unsigned int read_ ## name ## _id_field(void)			\
32*a8d5d3d5SAndre Przywara {									\
33*a8d5d3d5SAndre Przywara 	return ISOLATE_FIELD(read_ ## idreg(), idfield);		\
34*a8d5d3d5SAndre Przywara }									\
35*a8d5d3d5SAndre 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 
43*a8d5d3d5SAndre Przywara CREATE_FEATURE_FUNCS(feat_pan, id_aa64mmfr1_el1, ID_AA64MMFR1_EL1_PAN_SHIFT,
44*a8d5d3d5SAndre Przywara 		     ENABLE_FEAT_PAN)
45*a8d5d3d5SAndre Przywara CREATE_FEATURE_FUNCS(feat_vhe, id_aa64mmfr1_el1, ID_AA64MMFR1_EL1_VHE_SHIFT,
46*a8d5d3d5SAndre 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 
92b7e398d6SSoby Mathew static inline unsigned int get_armv8_5_mte_support(void)
93b7e398d6SSoby Mathew {
94b7e398d6SSoby Mathew 	return ((read_id_aa64pfr1_el1() >> ID_AA64PFR1_EL1_MTE_SHIFT) &
95b7e398d6SSoby Mathew 		ID_AA64PFR1_EL1_MTE_MASK);
96b7e398d6SSoby Mathew }
97b7e398d6SSoby Mathew 
98*a8d5d3d5SAndre Przywara CREATE_FEATURE_FUNCS(feat_sel2, id_aa64pfr0_el1, ID_AA64PFR0_SEL2_SHIFT,
99*a8d5d3d5SAndre Przywara 		     ENABLE_FEAT_SEL2)
100*a8d5d3d5SAndre Przywara CREATE_FEATURE_FUNCS(feat_twed, id_aa64mmfr1_el1, ID_AA64MMFR1_EL1_TWED_SHIFT,
101*a8d5d3d5SAndre Przywara 		     ENABLE_FEAT_TWED)
102*a8d5d3d5SAndre Przywara CREATE_FEATURE_FUNCS(feat_fgt, id_aa64mmfr0_el1, ID_AA64MMFR0_EL1_FGT_SHIFT,
103*a8d5d3d5SAndre Przywara 		     ENABLE_FEAT_FGT)
104*a8d5d3d5SAndre Przywara CREATE_FEATURE_FUNCS(feat_mte_perm, id_aa64pfr2_el1,
105*a8d5d3d5SAndre Przywara 		     ID_AA64PFR2_EL1_MTEPERM_SHIFT, ENABLE_FEAT_MTE_PERM)
106*a8d5d3d5SAndre Przywara CREATE_FEATURE_FUNCS(feat_ecv, id_aa64mmfr0_el1, ID_AA64MMFR0_EL1_ECV_SHIFT,
107*a8d5d3d5SAndre Przywara 		     ENABLE_FEAT_ECV)
108*a8d5d3d5SAndre Przywara CREATE_FEATURE_FUNCS_VER(feat_ecv_v2, read_feat_ecv_id_field,
109*a8d5d3d5SAndre Przywara 			 ID_AA64MMFR0_EL1_ECV_SELF_SYNCH, ENABLE_FEAT_ECV)
110623f6140SAndre Przywara 
111*a8d5d3d5SAndre Przywara CREATE_FEATURE_FUNCS(feat_rng, id_aa64isar0_el1, ID_AA64ISAR0_RNDR_SHIFT,
112*a8d5d3d5SAndre Przywara 		     ENABLE_FEAT_RNG)
113*a8d5d3d5SAndre Przywara CREATE_FEATURE_FUNCS(feat_tcr2, id_aa64mmfr3_el1, ID_AA64MMFR3_EL1_TCRX_SHIFT,
114*a8d5d3d5SAndre Przywara 		     ENABLE_FEAT_TCR2)
115623f6140SAndre Przywara 
116*a8d5d3d5SAndre Przywara CREATE_FEATURE_FUNCS(feat_s2poe, id_aa64mmfr3_el1, ID_AA64MMFR3_EL1_S2POE_SHIFT,
117*a8d5d3d5SAndre Przywara 		     ENABLE_FEAT_S2POE)
118*a8d5d3d5SAndre Przywara CREATE_FEATURE_FUNCS(feat_s1poe, id_aa64mmfr3_el1, ID_AA64MMFR3_EL1_S1POE_SHIFT,
119*a8d5d3d5SAndre Przywara 		     ENABLE_FEAT_S1POE)
120062b6c6bSMark Brown static inline bool is_feat_sxpoe_supported(void)
121062b6c6bSMark Brown {
122062b6c6bSMark Brown 	return is_feat_s1poe_supported() || is_feat_s2poe_supported();
123062b6c6bSMark Brown }
124062b6c6bSMark Brown 
125*a8d5d3d5SAndre Przywara CREATE_FEATURE_FUNCS(feat_s2pie, id_aa64mmfr3_el1, ID_AA64MMFR3_EL1_S2PIE_SHIFT,
126*a8d5d3d5SAndre Przywara 		     ENABLE_FEAT_S2PIE)
127*a8d5d3d5SAndre Przywara CREATE_FEATURE_FUNCS(feat_s1pie, id_aa64mmfr3_el1, ID_AA64MMFR3_EL1_S1PIE_SHIFT,
128*a8d5d3d5SAndre Przywara 		     ENABLE_FEAT_S1PIE)
129062b6c6bSMark Brown static inline bool is_feat_sxpie_supported(void)
130062b6c6bSMark Brown {
131062b6c6bSMark Brown 	return is_feat_s1pie_supported() || is_feat_s2pie_supported();
132062b6c6bSMark Brown }
133062b6c6bSMark Brown 
134*a8d5d3d5SAndre Przywara /* FEAT_GCS: Guarded Control Stack */
135*a8d5d3d5SAndre Przywara CREATE_FEATURE_FUNCS(feat_gcs, id_aa64pfr1_el1, ID_AA64PFR1_EL1_GCS_SHIFT,
136*a8d5d3d5SAndre Przywara 		     ENABLE_FEAT_GCS)
137688ab57bSMark Brown 
138*a8d5d3d5SAndre Przywara /* FEAT_AMU: Activity Monitors Extension */
139*a8d5d3d5SAndre Przywara CREATE_FEATURE_FUNCS(feat_amu, id_aa64pfr0_el1, ID_AA64PFR0_AMU_SHIFT,
140*a8d5d3d5SAndre Przywara 		     ENABLE_FEAT_AMU)
141*a8d5d3d5SAndre Przywara CREATE_FEATURE_FUNCS_VER(feat_amuv1p1, read_feat_amu_id_field,
142*a8d5d3d5SAndre Przywara 			 ID_AA64PFR0_AMU_V1P1, ENABLE_FEAT_AMUv1p1)
143873d4241Sjohpow01 
144dbcc44a1SAlexei Fedorov /*
145dbcc44a1SAlexei Fedorov  * Return MPAM version:
146dbcc44a1SAlexei Fedorov  *
147dbcc44a1SAlexei Fedorov  * 0x00: None Armv8.0 or later
148dbcc44a1SAlexei Fedorov  * 0x01: v0.1 Armv8.4 or later
149dbcc44a1SAlexei Fedorov  * 0x10: v1.0 Armv8.2 or later
150dbcc44a1SAlexei Fedorov  * 0x11: v1.1 Armv8.4 or later
151dbcc44a1SAlexei Fedorov  *
152dbcc44a1SAlexei Fedorov  */
1539448f2b8SAndre Przywara static inline unsigned int read_feat_mpam_version(void)
154dbcc44a1SAlexei Fedorov {
155dbcc44a1SAlexei Fedorov 	return (unsigned int)((((read_id_aa64pfr0_el1() >>
156dbcc44a1SAlexei Fedorov 		ID_AA64PFR0_MPAM_SHIFT) & ID_AA64PFR0_MPAM_MASK) << 4) |
157dbcc44a1SAlexei Fedorov 				((read_id_aa64pfr1_el1() >>
158dbcc44a1SAlexei Fedorov 		ID_AA64PFR1_MPAM_FRAC_SHIFT) & ID_AA64PFR1_MPAM_FRAC_MASK));
159dbcc44a1SAlexei Fedorov }
160dbcc44a1SAlexei Fedorov 
161*a8d5d3d5SAndre Przywara CREATE_FEATURE_FUNCS_VER(feat_mpam, read_feat_mpam_version, 1U,
162*a8d5d3d5SAndre Przywara 			 ENABLE_MPAM_FOR_LOWER_ELS)
1639448f2b8SAndre Przywara 
164*a8d5d3d5SAndre Przywara /* FEAT_HCX: Extended Hypervisor Configuration Register */
165*a8d5d3d5SAndre Przywara CREATE_FEATURE_FUNCS(feat_hcx, id_aa64mmfr1_el1, ID_AA64MMFR1_EL1_HCX_SHIFT,
166*a8d5d3d5SAndre Przywara 		     ENABLE_FEAT_HCX)
167cb4ec47bSjohpow01 
168ff86e0b4SJuan Pablo Conde static inline bool is_feat_rng_trap_present(void)
169ff86e0b4SJuan Pablo Conde {
170ff86e0b4SJuan Pablo Conde 	return (((read_id_aa64pfr1_el1() >> ID_AA64PFR1_EL1_RNDR_TRAP_SHIFT) &
171ff86e0b4SJuan Pablo Conde 			ID_AA64PFR1_EL1_RNDR_TRAP_MASK)
172ff86e0b4SJuan Pablo Conde 			== ID_AA64PFR1_EL1_RNG_TRAP_SUPPORTED);
173ff86e0b4SJuan Pablo Conde }
174ff86e0b4SJuan Pablo Conde 
17581c272b3SZelalem Aweke static inline unsigned int get_armv9_2_feat_rme_support(void)
17681c272b3SZelalem Aweke {
17781c272b3SZelalem Aweke 	/*
17881c272b3SZelalem Aweke 	 * Return the RME version, zero if not supported.  This function can be
17981c272b3SZelalem Aweke 	 * used as both an integer value for the RME version or compared to zero
18081c272b3SZelalem Aweke 	 * to detect RME presence.
18181c272b3SZelalem Aweke 	 */
18281c272b3SZelalem Aweke 	return (unsigned int)(read_id_aa64pfr0_el1() >>
18381c272b3SZelalem Aweke 		ID_AA64PFR0_FEAT_RME_SHIFT) & ID_AA64PFR0_FEAT_RME_MASK;
18481c272b3SZelalem Aweke }
18581c272b3SZelalem Aweke 
1866a0da736SJayanth Dodderi Chidanand /*********************************************************************************
1876a0da736SJayanth Dodderi Chidanand  * Function to identify the presence of FEAT_SB (Speculation Barrier Instruction)
1886a0da736SJayanth Dodderi Chidanand  ********************************************************************************/
18924077098SAndre Przywara static inline unsigned int read_feat_sb_id_field(void)
1906a0da736SJayanth Dodderi Chidanand {
191*a8d5d3d5SAndre Przywara 	return ISOLATE_FIELD(read_id_aa64isar1_el1(), ID_AA64ISAR1_SB_SHIFT);
1926a0da736SJayanth Dodderi Chidanand }
1936a0da736SJayanth Dodderi Chidanand 
194*a8d5d3d5SAndre Przywara /* FEAT_CSV2_2: Cache Speculation Variant 2 */
195*a8d5d3d5SAndre Przywara CREATE_FEATURE_FUNCS(feat_csv2, id_aa64pfr0_el1, ID_AA64PFR0_CSV2_SHIFT, 0)
196*a8d5d3d5SAndre Przywara CREATE_FEATURE_FUNCS_VER(feat_csv2_2, read_feat_csv2_id_field,
197*a8d5d3d5SAndre Przywara 			 ID_AA64PFR0_CSV2_2_SUPPORTED, ENABLE_FEAT_CSV2_2)
1987db710f0SAndre Przywara 
199*a8d5d3d5SAndre Przywara /* FEAT_SPE: Statistical Profiling Extension */
200*a8d5d3d5SAndre Przywara CREATE_FEATURE_FUNCS(feat_spe, id_aa64dfr0_el1, ID_AA64DFR0_PMS_SHIFT,
201*a8d5d3d5SAndre Przywara 		     ENABLE_SPE_FOR_NS)
2027db710f0SAndre Przywara 
203*a8d5d3d5SAndre Przywara /* FEAT_SVE: Scalable Vector Extension */
204*a8d5d3d5SAndre Przywara CREATE_FEATURE_FUNCS(feat_sve, id_aa64pfr0_el1, ID_AA64PFR0_SVE_SHIFT,
205*a8d5d3d5SAndre Przywara 		     ENABLE_SVE_FOR_NS)
2067db710f0SAndre Przywara 
207*a8d5d3d5SAndre Przywara /* FEAT_RAS: Reliability, Accessibility, Serviceability */
208*a8d5d3d5SAndre Przywara CREATE_FEATURE_FUNCS(feat_ras, id_aa64pfr0_el1,
209*a8d5d3d5SAndre Przywara 		     ID_AA64PFR0_RAS_SHIFT, ENABLE_FEAT_RAS)
2106a0da736SJayanth Dodderi Chidanand 
211*a8d5d3d5SAndre Przywara /* FEAT_DIT: Data Independent Timing instructions */
212*a8d5d3d5SAndre Przywara CREATE_FEATURE_FUNCS(feat_dit, id_aa64pfr0_el1,
213*a8d5d3d5SAndre Przywara 		     ID_AA64PFR0_DIT_SHIFT, ENABLE_FEAT_DIT)
2146437a09aSAndre Przywara 
215*a8d5d3d5SAndre Przywara CREATE_FEATURE_FUNCS(feat_sys_reg_trace, id_aa64dfr0_el1,
216*a8d5d3d5SAndre Przywara 		     ID_AA64DFR0_TRACEVER_SHIFT, ENABLE_SYS_REG_TRACE_FOR_NS)
2176437a09aSAndre Przywara 
218*a8d5d3d5SAndre Przywara /* FEAT_TRF: TraceFilter */
219*a8d5d3d5SAndre Przywara CREATE_FEATURE_FUNCS(feat_trf, id_aa64dfr0_el1, ID_AA64DFR0_TRACEFILT_SHIFT,
220*a8d5d3d5SAndre Przywara 		     ENABLE_TRF_FOR_NS)
2216437a09aSAndre Przywara 
222*a8d5d3d5SAndre Przywara /* FEAT_NV2: Enhanced Nested Virtualization */
223*a8d5d3d5SAndre Przywara CREATE_FEATURE_FUNCS(feat_nv, id_aa64mmfr2_el1, ID_AA64MMFR2_EL1_NV_SHIFT, 0)
224*a8d5d3d5SAndre Przywara CREATE_FEATURE_FUNCS_VER(feat_nv2, read_feat_nv_id_field,
225*a8d5d3d5SAndre Przywara 			 ID_AA64MMFR2_EL1_NV2_SUPPORTED, CTX_INCLUDE_NEVE_REGS)
2266a0da736SJayanth Dodderi Chidanand 
227*a8d5d3d5SAndre Przywara /* FEAT_BRBE: Branch Record Buffer Extension */
228*a8d5d3d5SAndre Przywara CREATE_FEATURE_FUNCS(feat_brbe, id_aa64dfr0_el1, ID_AA64DFR0_BRBE_SHIFT,
229*a8d5d3d5SAndre Przywara 		     ENABLE_BRBE_FOR_NS)
2302b0bc4e0SJayanth Dodderi Chidanand 
231*a8d5d3d5SAndre Przywara /* FEAT_TRBE: Trace Buffer Extension */
232*a8d5d3d5SAndre Przywara CREATE_FEATURE_FUNCS(feat_trbe, id_aa64dfr0_el1, ID_AA64DFR0_TRACEBUFFER_SHIFT,
233*a8d5d3d5SAndre Przywara 		     ENABLE_TRBE_FOR_NS)
2342b0bc4e0SJayanth Dodderi Chidanand 
23545007acdSJayanth Dodderi Chidanand static inline unsigned int read_feat_sme_fa64_id_field(void)
23645007acdSJayanth Dodderi Chidanand {
237*a8d5d3d5SAndre Przywara 	return ISOLATE_FIELD(read_id_aa64smfr0_el1(),
238*a8d5d3d5SAndre Przywara 			     ID_AA64SMFR0_EL1_SME_FA64_SHIFT);
23945007acdSJayanth Dodderi Chidanand }
240*a8d5d3d5SAndre Przywara /* FEAT_SMEx: Scalar Matrix Extension */
241*a8d5d3d5SAndre Przywara CREATE_FEATURE_FUNCS(feat_sme, id_aa64pfr1_el1, ID_AA64PFR1_EL1_SME_SHIFT,
242*a8d5d3d5SAndre Przywara 		     ENABLE_SME_FOR_NS)
243*a8d5d3d5SAndre Przywara CREATE_FEATURE_FUNCS_VER(feat_sme2, read_feat_sme_id_field,
244*a8d5d3d5SAndre Przywara 			 ID_AA64PFR1_EL1_SME2_SUPPORTED, ENABLE_SME2_FOR_NS)
24503d3c0d7SJayanth Dodderi Chidanand 
246bff074ddSJavier Almansa Sobrino /*******************************************************************************
247bff074ddSJavier Almansa Sobrino  * Function to get hardware granularity support
248bff074ddSJavier Almansa Sobrino  ******************************************************************************/
249bff074ddSJavier Almansa Sobrino 
250bff074ddSJavier Almansa Sobrino static inline unsigned int read_id_aa64mmfr0_el0_tgran4_field(void)
251bff074ddSJavier Almansa Sobrino {
252*a8d5d3d5SAndre Przywara 	return ISOLATE_FIELD(read_id_aa64mmfr0_el1(),
253*a8d5d3d5SAndre Przywara 			     ID_AA64MMFR0_EL1_TGRAN4_SHIFT);
254bff074ddSJavier Almansa Sobrino }
255bff074ddSJavier Almansa Sobrino 
256bff074ddSJavier Almansa Sobrino static inline unsigned int read_id_aa64mmfr0_el0_tgran16_field(void)
257bff074ddSJavier Almansa Sobrino {
258bff074ddSJavier Almansa Sobrino 	return ISOLATE_FIELD(read_id_aa64mmfr0_el1(),
259*a8d5d3d5SAndre Przywara 			     ID_AA64MMFR0_EL1_TGRAN16_SHIFT);
260bff074ddSJavier Almansa Sobrino }
261bff074ddSJavier Almansa Sobrino 
262bff074ddSJavier Almansa Sobrino static inline unsigned int read_id_aa64mmfr0_el0_tgran64_field(void)
263bff074ddSJavier Almansa Sobrino {
264bff074ddSJavier Almansa Sobrino 	return ISOLATE_FIELD(read_id_aa64mmfr0_el1(),
265*a8d5d3d5SAndre Przywara 			     ID_AA64MMFR0_EL1_TGRAN64_SHIFT);
266bff074ddSJavier Almansa Sobrino }
267bff074ddSJavier Almansa Sobrino 
268c73686a1SBoyan Karatotev static inline unsigned int read_feat_pmuv3_id_field(void)
269c73686a1SBoyan Karatotev {
270*a8d5d3d5SAndre Przywara 	return ISOLATE_FIELD(read_id_aa64dfr0_el1(), ID_AA64DFR0_PMUVER_SHIFT);
271c73686a1SBoyan Karatotev }
272c73686a1SBoyan Karatotev 
27383a4dae1SBoyan Karatotev static inline unsigned int read_feat_mtpmu_id_field(void)
27483a4dae1SBoyan Karatotev {
275*a8d5d3d5SAndre Przywara 	return ISOLATE_FIELD(read_id_aa64dfr0_el1(), ID_AA64DFR0_MTPMU_SHIFT);
27683a4dae1SBoyan Karatotev }
27783a4dae1SBoyan Karatotev 
27883a4dae1SBoyan Karatotev static inline bool is_feat_mtpmu_supported(void)
27983a4dae1SBoyan Karatotev {
28083a4dae1SBoyan Karatotev 	if (DISABLE_MTPMU == FEAT_STATE_DISABLED) {
28183a4dae1SBoyan Karatotev 		return false;
28283a4dae1SBoyan Karatotev 	}
28383a4dae1SBoyan Karatotev 
28483a4dae1SBoyan Karatotev 	if (DISABLE_MTPMU == FEAT_STATE_ALWAYS) {
28583a4dae1SBoyan Karatotev 		return true;
28683a4dae1SBoyan Karatotev 	}
28783a4dae1SBoyan Karatotev 
28883a4dae1SBoyan Karatotev 	unsigned int mtpmu = read_feat_mtpmu_id_field();
28983a4dae1SBoyan Karatotev 
29083a4dae1SBoyan Karatotev 	return (mtpmu != 0U) && (mtpmu != ID_AA64DFR0_MTPMU_DISABLED);
29183a4dae1SBoyan Karatotev }
29283a4dae1SBoyan Karatotev 
2932559b2c8SAntonio Nino Diaz #endif /* ARCH_FEATURES_H */
294