xref: /rk3399_ARM-atf/include/arch/aarch32/arch_features.h (revision ed0c801fc69f55103c597dcc29cadf4c7cb7d575)
1 /*
2  * Copyright (c) 2019-2025, Arm Limited. All rights reserved.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 #ifndef ARCH_FEATURES_H
8 #define ARCH_FEATURES_H
9 
10 #include <stdbool.h>
11 
12 #include <arch_helpers.h>
13 #include <common/feat_detect.h>
14 
15 #define ISOLATE_FIELD(reg, feat, mask)						\
16 	((unsigned int)(((reg) >> (feat)) & mask))
17 
18 #define CREATE_FEATURE_SUPPORTED(name, read_func, guard)			\
19 __attribute__((always_inline))							\
20 static inline bool is_ ## name ## _supported(void)				\
21 {										\
22 	if ((guard) == FEAT_STATE_DISABLED) {					\
23 		return false;							\
24 	}									\
25 	if ((guard) == FEAT_STATE_ALWAYS) {					\
26 		return true;							\
27 	}									\
28 	return read_func();							\
29 }
30 
31 #define CREATE_FEATURE_PRESENT(name, idreg, idfield, mask, idval)		\
32 __attribute__((always_inline))							\
33 static inline bool is_ ## name ## _present(void)				\
34 {										\
35 	return (ISOLATE_FIELD(read_ ## idreg(), idfield, mask) >= idval) 	\
36 		? true : false;							\
37 }
38 
39 #define CREATE_FEATURE_FUNCS(name, idreg, idfield, mask, idval, guard)		\
40 CREATE_FEATURE_PRESENT(name, idreg, idfield, mask, idval)			\
41 CREATE_FEATURE_SUPPORTED(name, is_ ## name ## _present, guard)
42 
43 
44 /*
45  * +----------------------------+
46  * |	Features supported	|
47  * +----------------------------+
48  * |	GENTIMER		|
49  * +----------------------------+
50  * |	FEAT_TTCNP		|
51  * +----------------------------+
52  * |	FEAT_AMU		|
53  * +----------------------------+
54  * |	FEAT_AMUV1P1		|
55  * +----------------------------+
56  * |	FEAT_TRF		|
57  * +----------------------------+
58  * |	FEAT_SYS_REG_TRACE 	|
59  * +----------------------------+
60  * |	FEAT_DIT		|
61  * +----------------------------+
62  * |	FEAT_PAN		|
63  * +----------------------------+
64  * |	FEAT_SSBS		|
65  * +----------------------------+
66  * |	FEAT_PMUV3		|
67  * +----------------------------+
68  * |	FEAT_MTPMU		|
69  * +----------------------------+
70  */
71 
72 /* GENTIMER */
73 __attribute__((always_inline))
74 static inline bool is_armv7_gentimer_present(void)
75 {
76 	return ISOLATE_FIELD(read_id_pfr1(), ID_PFR1_GENTIMER_SHIFT,
77 			    ID_PFR1_GENTIMER_MASK) != 0U;
78 }
79 
80 /* FEAT_TTCNP: Translation table common not private */
81 CREATE_FEATURE_PRESENT(feat_ttcnp, id_mmfr4, ID_MMFR4_CNP_SHIFT,
82 		      ID_MMFR4_CNP_MASK, 1U)
83 
84 /* FEAT_AMU: Activity Monitors Extension */
85 CREATE_FEATURE_FUNCS(feat_amu, id_pfr0, ID_PFR0_AMU_SHIFT,
86 		    ID_PFR0_AMU_MASK, ID_PFR0_AMU_V1, ENABLE_FEAT_AMU)
87 
88 /* Auxiliary counters for FEAT_AMU */
89 CREATE_FEATURE_FUNCS(feat_amu_aux, amcfgr, AMCFGR_NCG_SHIFT,
90 		    AMCFGR_NCG_MASK, 1U, ENABLE_AMU_AUXILIARY_COUNTERS)
91 
92 /* FEAT_AMUV1P1: AMU Extension v1.1 */
93 CREATE_FEATURE_FUNCS(feat_amuv1p1, id_pfr0, ID_PFR0_AMU_SHIFT,
94 		    ID_PFR0_AMU_MASK, ID_PFR0_AMU_V1P1, ENABLE_FEAT_AMUv1p1)
95 
96 /* FEAT_TRF: Tracefilter */
97 CREATE_FEATURE_FUNCS(feat_trf, id_dfr0, ID_DFR0_TRACEFILT_SHIFT,
98 		    ID_DFR0_TRACEFILT_MASK, 1U, ENABLE_TRF_FOR_NS)
99 
100 /* FEAT_SYS_REG_TRACE */
101 CREATE_FEATURE_FUNCS(feat_sys_reg_trace, id_dfr0, ID_DFR0_COPTRC_SHIFT,
102 		    ID_DFR0_COPTRC_MASK, 1U, ENABLE_SYS_REG_TRACE_FOR_NS)
103 
104 /* FEAT_DIT: Data independent timing */
105 CREATE_FEATURE_FUNCS(feat_dit, id_pfr0, ID_PFR0_DIT_SHIFT,
106 		    ID_PFR0_DIT_MASK, 1U, ENABLE_FEAT_DIT)
107 
108 /* FEAT_PAN: Privileged access never */
109 CREATE_FEATURE_FUNCS(feat_pan, id_mmfr3, ID_MMFR3_PAN_SHIFT,
110 		    ID_MMFR3_PAN_MASK, 1U, ENABLE_FEAT_PAN)
111 
112 /* FEAT_SSBS: Speculative store bypass safe */
113 CREATE_FEATURE_PRESENT(feat_ssbs, id_pfr2, ID_PFR2_SSBS_SHIFT,
114 		      ID_PFR2_SSBS_MASK, 1U)
115 
116 /* FEAT_PMUV3 */
117 CREATE_FEATURE_PRESENT(feat_pmuv3, id_dfr0, ID_DFR0_PERFMON_SHIFT,
118 		      ID_DFR0_PERFMON_MASK, 3U)
119 
120 /* FEAT_MTPMU */
121 __attribute__((always_inline))
122 static inline bool is_feat_mtpmu_present(void)
123 {
124 	unsigned int mtpmu = ISOLATE_FIELD(read_id_dfr1(), ID_DFR1_MTPMU_SHIFT,
125 			    ID_DFR1_MTPMU_MASK);
126 	return (mtpmu != 0U) && (mtpmu != MTPMU_NOT_IMPLEMENTED);
127 }
128 CREATE_FEATURE_SUPPORTED(feat_mtpmu, is_feat_mtpmu_present, DISABLE_MTPMU)
129 
130 /*
131  * TWED, ECV, CSV2, RAS are only used by the AArch64 EL2 context switch
132  * code. In fact, EL2 context switching is only needed for AArch64 (since
133  * there is no secure AArch32 EL2), so just disable these features here.
134  */
135 __attribute__((always_inline))
136 static inline bool is_feat_twed_supported(void) { return false; }
137 __attribute__((always_inline))
138 static inline bool is_feat_ecv_supported(void) { return false; }
139 __attribute__((always_inline))
140 static inline bool is_feat_ecv_v2_supported(void) { return false; }
141 __attribute__((always_inline))
142 static inline bool is_feat_csv2_2_supported(void) { return false; }
143 __attribute__((always_inline))
144 static inline bool is_feat_csv2_3_supported(void) { return false; }
145 __attribute__((always_inline))
146 static inline bool is_feat_ras_supported(void) { return false; }
147 
148 /* The following features are supported in AArch64 only. */
149 __attribute__((always_inline))
150 static inline bool is_feat_vhe_supported(void) { return false; }
151 __attribute__((always_inline))
152 static inline bool is_feat_sel2_supported(void) { return false; }
153 __attribute__((always_inline))
154 static inline bool is_feat_fgt_supported(void) { return false; }
155 __attribute__((always_inline))
156 static inline bool is_feat_tcr2_supported(void) { return false; }
157 __attribute__((always_inline))
158 static inline bool is_feat_spe_supported(void) { return false; }
159 __attribute__((always_inline))
160 static inline bool is_feat_rng_supported(void) { return false; }
161 __attribute__((always_inline))
162 static inline bool is_feat_gcs_supported(void) { return false; }
163 __attribute__((always_inline))
164 static inline bool is_feat_mte2_supported(void) { return false; }
165 __attribute__((always_inline))
166 static inline bool is_feat_mpam_supported(void) { return false; }
167 __attribute__((always_inline))
168 static inline bool is_feat_hcx_supported(void) { return false; }
169 __attribute__((always_inline))
170 static inline bool is_feat_sve_supported(void) { return false; }
171 __attribute__((always_inline))
172 static inline bool is_feat_brbe_supported(void) { return false; }
173 __attribute__((always_inline))
174 static inline bool is_feat_trbe_supported(void) { return false; }
175 __attribute__((always_inline))
176 static inline bool is_feat_nv2_supported(void) { return false; }
177 __attribute__((always_inline))
178 static inline bool is_feat_sme_supported(void) { return false; }
179 __attribute__((always_inline))
180 static inline bool is_feat_sme2_supported(void) { return false; }
181 __attribute__((always_inline))
182 static inline bool is_feat_s2poe_supported(void) { return false; }
183 __attribute__((always_inline))
184 static inline bool is_feat_s1poe_supported(void) { return false; }
185 __attribute__((always_inline))
186 static inline bool is_feat_sxpoe_supported(void) { return false; }
187 __attribute__((always_inline))
188 static inline bool is_feat_s2pie_supported(void) { return false; }
189 __attribute__((always_inline))
190 static inline bool is_feat_s1pie_supported(void) { return false; }
191 __attribute__((always_inline))
192 static inline bool is_feat_sxpie_supported(void) { return false; }
193 __attribute__((always_inline))
194 static inline bool is_feat_uao_present(void) { return false; }
195 __attribute__((always_inline))
196 static inline bool is_feat_nmi_present(void) { return false; }
197 __attribute__((always_inline))
198 static inline bool is_feat_ebep_present(void) { return false; }
199 __attribute__((always_inline))
200 static inline bool is_feat_sebep_present(void) { return false; }
201 __attribute__((always_inline))
202 static inline bool is_feat_d128_present(void) { return false; }
203 __attribute__((always_inline))
204 static inline bool is_feat_ls64_accdata_present(void) { return false; }
205 
206 #endif /* ARCH_FEATURES_H */
207