1 /* 2 * Copyright (c) 2019-2024, 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 18 static inline bool is_armv7_gentimer_present(void) 19 { 20 return ISOLATE_FIELD(read_id_pfr1(), ID_PFR1_GENTIMER) != 0U; 21 } 22 23 static inline bool is_armv8_2_ttcnp_present(void) 24 { 25 return ISOLATE_FIELD(read_id_mmfr4(), ID_MMFR4_CNP) != 0U; 26 } 27 28 static unsigned int read_feat_amu_id_field(void) 29 { 30 return ISOLATE_FIELD(read_id_pfr0(), ID_PFR0_AMU); 31 } 32 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 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 59 static inline unsigned int read_feat_trf_id_field(void) 60 { 61 return ISOLATE_FIELD(read_id_dfr0(), ID_DFR0_TRACEFILT); 62 } 63 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 77 static inline unsigned int read_feat_coptrc_id_field(void) 78 { 79 return ISOLATE_FIELD(read_id_dfr0(), ID_DFR0_COPTRC); 80 } 81 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 95 static inline unsigned int read_feat_dit_id_field(void) 96 { 97 return ISOLATE_FIELD(read_id_pfr0(), ID_PFR0_DIT); 98 } 99 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 113 static inline unsigned int read_feat_pan_id_field(void) 114 { 115 return ISOLATE_FIELD(read_id_mmfr3(), ID_MMFR3_PAN); 116 } 117 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 static inline bool is_feat_pan_present(void) 132 { 133 return read_feat_pan_id_field() != 0U; 134 } 135 136 static inline unsigned int is_feat_ssbs_present(void) 137 { 138 return ((read_id_pfr2() >> ID_PFR2_SSBS_SHIFT) & 139 ID_PFR2_SSBS_MASK) != SSBS_UNAVAILABLE; 140 } 141 142 /* 143 * TWED, ECV, CSV2, RAS are only used by the AArch64 EL2 context switch 144 * code. In fact, EL2 context switching is only needed for AArch64 (since 145 * there is no secure AArch32 EL2), so just disable these features here. 146 */ 147 static inline bool is_feat_twed_supported(void) { return false; } 148 static inline bool is_feat_ecv_supported(void) { return false; } 149 static inline bool is_feat_ecv_v2_supported(void) { return false; } 150 static inline bool is_feat_csv2_2_supported(void) { return false; } 151 static inline bool is_feat_csv2_3_supported(void) { return false; } 152 static inline bool is_feat_ras_supported(void) { return false; } 153 154 /* The following features are supported in AArch64 only. */ 155 static inline bool is_feat_vhe_supported(void) { return false; } 156 static inline bool is_feat_sel2_supported(void) { return false; } 157 static inline bool is_feat_fgt_supported(void) { return false; } 158 static inline bool is_feat_tcr2_supported(void) { return false; } 159 static inline bool is_feat_spe_supported(void) { return false; } 160 static inline bool is_feat_rng_supported(void) { return false; } 161 static inline bool is_feat_gcs_supported(void) { return false; } 162 static inline bool is_feat_mte2_supported(void) { return false; } 163 static inline bool is_feat_mpam_supported(void) { return false; } 164 static inline bool is_feat_hcx_supported(void) { return false; } 165 static inline bool is_feat_sve_supported(void) { return false; } 166 static inline bool is_feat_brbe_supported(void) { return false; } 167 static inline bool is_feat_trbe_supported(void) { return false; } 168 static inline bool is_feat_nv2_supported(void) { return false; } 169 static inline bool is_feat_sme_supported(void) { return false; } 170 static inline bool is_feat_sme2_supported(void) { return false; } 171 static inline bool is_feat_s2poe_supported(void) { return false; } 172 static inline bool is_feat_s1poe_supported(void) { return false; } 173 static inline bool is_feat_sxpoe_supported(void) { return false; } 174 static inline bool is_feat_s2pie_supported(void) { return false; } 175 static inline bool is_feat_s1pie_supported(void) { return false; } 176 static inline bool is_feat_sxpie_supported(void) { return false; } 177 static inline bool is_feat_uao_present(void) { return false; } 178 static inline bool is_feat_nmi_present(void) { return false; } 179 static inline bool is_feat_ebep_present(void) { return false; } 180 static inline bool is_feat_sebep_present(void) { return false; } 181 182 static inline unsigned int read_feat_pmuv3_id_field(void) 183 { 184 return ISOLATE_FIELD(read_id_dfr0(), ID_DFR0_PERFMON); 185 } 186 187 static inline unsigned int read_feat_mtpmu_id_field(void) 188 { 189 return ISOLATE_FIELD(read_id_dfr1(), ID_DFR1_MTPMU); 190 } 191 192 static inline bool is_feat_mtpmu_supported(void) 193 { 194 if (DISABLE_MTPMU == FEAT_STATE_DISABLED) { 195 return false; 196 } 197 198 if (DISABLE_MTPMU == FEAT_STATE_ALWAYS) { 199 return true; 200 } 201 202 unsigned int mtpmu = read_feat_mtpmu_id_field(); 203 204 return mtpmu != 0U && mtpmu != ID_DFR1_MTPMU_DISABLED; 205 } 206 207 #endif /* ARCH_FEATURES_H */ 208