1 /*
2 * Copyright (c) 2019-2023, 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) \
16 ((unsigned int)(((reg) >> (feat ## _SHIFT)) & (feat ## _MASK)))
17
is_armv7_gentimer_present(void)18 static inline bool is_armv7_gentimer_present(void)
19 {
20 return ISOLATE_FIELD(read_id_pfr1(), ID_PFR1_GENTIMER) != 0U;
21 }
22
is_armv8_2_ttcnp_present(void)23 static inline bool is_armv8_2_ttcnp_present(void)
24 {
25 return ISOLATE_FIELD(read_id_mmfr4(), ID_MMFR4_CNP) != 0U;
26 }
27
read_feat_amu_id_field(void)28 static unsigned int read_feat_amu_id_field(void)
29 {
30 return ISOLATE_FIELD(read_id_pfr0(), ID_PFR0_AMU);
31 }
32
is_feat_amu_supported(void)33 static inline bool is_feat_amu_supported(void)
34 {
35 if (ENABLE_FEAT_AMU == FEAT_STATE_DISABLED) {
36 return false;
37 }
38
39 if (ENABLE_FEAT_AMU == FEAT_STATE_ALWAYS) {
40 return true;
41 }
42
43 return read_feat_amu_id_field() >= ID_PFR0_AMU_V1;
44 }
45
is_feat_amuv1p1_supported(void)46 static inline bool is_feat_amuv1p1_supported(void)
47 {
48 if (ENABLE_FEAT_AMUv1p1 == FEAT_STATE_DISABLED) {
49 return false;
50 }
51
52 if (ENABLE_FEAT_AMUv1p1 == FEAT_STATE_ALWAYS) {
53 return true;
54 }
55
56 return read_feat_amu_id_field() >= ID_PFR0_AMU_V1P1;
57 }
58
read_feat_trf_id_field(void)59 static inline unsigned int read_feat_trf_id_field(void)
60 {
61 return ISOLATE_FIELD(read_id_dfr0(), ID_DFR0_TRACEFILT);
62 }
63
is_feat_trf_supported(void)64 static inline bool is_feat_trf_supported(void)
65 {
66 if (ENABLE_TRF_FOR_NS == FEAT_STATE_DISABLED) {
67 return false;
68 }
69
70 if (ENABLE_TRF_FOR_NS == FEAT_STATE_ALWAYS) {
71 return true;
72 }
73
74 return read_feat_trf_id_field() != 0U;
75 }
76
read_feat_coptrc_id_field(void)77 static inline unsigned int read_feat_coptrc_id_field(void)
78 {
79 return ISOLATE_FIELD(read_id_dfr0(), ID_DFR0_COPTRC);
80 }
81
is_feat_sys_reg_trace_supported(void)82 static inline bool is_feat_sys_reg_trace_supported(void)
83 {
84 if (ENABLE_SYS_REG_TRACE_FOR_NS == FEAT_STATE_DISABLED) {
85 return false;
86 }
87
88 if (ENABLE_SYS_REG_TRACE_FOR_NS == FEAT_STATE_ALWAYS) {
89 return true;
90 }
91
92 return read_feat_coptrc_id_field() != 0U;
93 }
94
read_feat_dit_id_field(void)95 static inline unsigned int read_feat_dit_id_field(void)
96 {
97 return ISOLATE_FIELD(read_id_pfr0(), ID_PFR0_DIT);
98 }
99
is_feat_dit_supported(void)100 static inline bool is_feat_dit_supported(void)
101 {
102 if (ENABLE_FEAT_DIT == FEAT_STATE_DISABLED) {
103 return false;
104 }
105
106 if (ENABLE_FEAT_DIT == FEAT_STATE_ALWAYS) {
107 return true;
108 }
109
110 return read_feat_dit_id_field() != 0U;
111 }
112
read_feat_pan_id_field(void)113 static inline unsigned int read_feat_pan_id_field(void)
114 {
115 return ISOLATE_FIELD(read_id_mmfr3(), ID_MMFR3_PAN);
116 }
117
is_feat_pan_supported(void)118 static inline bool is_feat_pan_supported(void)
119 {
120 if (ENABLE_FEAT_PAN == FEAT_STATE_DISABLED) {
121 return false;
122 }
123
124 if (ENABLE_FEAT_PAN == FEAT_STATE_ALWAYS) {
125 return true;
126 }
127
128 return read_feat_pan_id_field() != 0U;
129 }
130
131 /*
132 * TWED, ECV, CSV2, RAS are only used by the AArch64 EL2 context switch
133 * code. In fact, EL2 context switching is only needed for AArch64 (since
134 * there is no secure AArch32 EL2), so just disable these features here.
135 */
is_feat_twed_supported(void)136 static inline bool is_feat_twed_supported(void) { return false; }
is_feat_ecv_supported(void)137 static inline bool is_feat_ecv_supported(void) { return false; }
is_feat_ecv_v2_supported(void)138 static inline bool is_feat_ecv_v2_supported(void) { return false; }
is_feat_csv2_2_supported(void)139 static inline bool is_feat_csv2_2_supported(void) { return false; }
is_feat_ras_supported(void)140 static inline bool is_feat_ras_supported(void) { return false; }
141
142 /* The following features are supported in AArch64 only. */
is_feat_vhe_supported(void)143 static inline bool is_feat_vhe_supported(void) { return false; }
is_feat_sel2_supported(void)144 static inline bool is_feat_sel2_supported(void) { return false; }
is_feat_fgt_supported(void)145 static inline bool is_feat_fgt_supported(void) { return false; }
is_feat_tcr2_supported(void)146 static inline bool is_feat_tcr2_supported(void) { return false; }
is_feat_spe_supported(void)147 static inline bool is_feat_spe_supported(void) { return false; }
is_feat_rng_supported(void)148 static inline bool is_feat_rng_supported(void) { return false; }
is_feat_gcs_supported(void)149 static inline bool is_feat_gcs_supported(void) { return false; }
is_feat_mpam_supported(void)150 static inline bool is_feat_mpam_supported(void) { return false; }
is_feat_hcx_supported(void)151 static inline bool is_feat_hcx_supported(void) { return false; }
is_feat_sve_supported(void)152 static inline bool is_feat_sve_supported(void) { return false; }
is_feat_brbe_supported(void)153 static inline bool is_feat_brbe_supported(void) { return false; }
is_feat_trbe_supported(void)154 static inline bool is_feat_trbe_supported(void) { return false; }
is_feat_nv2_supported(void)155 static inline bool is_feat_nv2_supported(void) { return false; }
is_feat_sme_supported(void)156 static inline bool is_feat_sme_supported(void) { return false; }
is_feat_sme2_supported(void)157 static inline bool is_feat_sme2_supported(void) { return false; }
is_feat_s2poe_supported(void)158 static inline bool is_feat_s2poe_supported(void) { return false; }
is_feat_s1poe_supported(void)159 static inline bool is_feat_s1poe_supported(void) { return false; }
is_feat_sxpoe_supported(void)160 static inline bool is_feat_sxpoe_supported(void) { return false; }
is_feat_s2pie_supported(void)161 static inline bool is_feat_s2pie_supported(void) { return false; }
is_feat_s1pie_supported(void)162 static inline bool is_feat_s1pie_supported(void) { return false; }
is_feat_sxpie_supported(void)163 static inline bool is_feat_sxpie_supported(void) { return false; }
164
read_feat_pmuv3_id_field(void)165 static inline unsigned int read_feat_pmuv3_id_field(void)
166 {
167 return ISOLATE_FIELD(read_id_dfr0(), ID_DFR0_PERFMON);
168 }
169
read_feat_mtpmu_id_field(void)170 static inline unsigned int read_feat_mtpmu_id_field(void)
171 {
172 return ISOLATE_FIELD(read_id_dfr1(), ID_DFR1_MTPMU);
173 }
174
is_feat_mtpmu_supported(void)175 static inline bool is_feat_mtpmu_supported(void)
176 {
177 if (DISABLE_MTPMU == FEAT_STATE_DISABLED) {
178 return false;
179 }
180
181 if (DISABLE_MTPMU == FEAT_STATE_ALWAYS) {
182 return true;
183 }
184
185 unsigned int mtpmu = read_feat_mtpmu_id_field();
186
187 return mtpmu != 0U && mtpmu != ID_DFR1_MTPMU_DISABLED;
188 }
189
190 #endif /* ARCH_FEATURES_H */
191