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, mask) \ 16 ((unsigned int)(((reg) >> (feat)) & mask)) 17 18 #define CREATE_FEATURE_SUPPORTED(name, read_func, guard) \ 19 static inline bool is_ ## name ## _supported(void) \ 20 { \ 21 if ((guard) == FEAT_STATE_DISABLED) { \ 22 return false; \ 23 } \ 24 if ((guard) == FEAT_STATE_ALWAYS) { \ 25 return true; \ 26 } \ 27 return read_func(); \ 28 } 29 30 #define CREATE_FEATURE_PRESENT(name, idreg, idfield, mask, idval) \ 31 static inline bool is_ ## name ## _present(void) \ 32 { \ 33 return (ISOLATE_FIELD(read_ ## idreg(), idfield, mask) >= idval) \ 34 ? true : false; \ 35 } 36 37 #define CREATE_FEATURE_FUNCS(name, idreg, idfield, mask, idval, guard) \ 38 CREATE_FEATURE_PRESENT(name, idreg, idfield, mask, idval) \ 39 CREATE_FEATURE_SUPPORTED(name, is_ ## name ## _present, guard) 40 41 42 /* 43 * +----------------------------+ 44 * | Features supported | 45 * +----------------------------+ 46 * | GENTIMER | 47 * +----------------------------+ 48 * | FEAT_TTCNP | 49 * +----------------------------+ 50 * | FEAT_AMU | 51 * +----------------------------+ 52 * | FEAT_AMUV1P1 | 53 * +----------------------------+ 54 * | FEAT_TRF | 55 * +----------------------------+ 56 * | FEAT_SYS_REG_TRACE | 57 * +----------------------------+ 58 * | FEAT_DIT | 59 * +----------------------------+ 60 * | FEAT_PAN | 61 * +----------------------------+ 62 * | FEAT_SSBS | 63 * +----------------------------+ 64 * | FEAT_PMUV3 | 65 * +----------------------------+ 66 * | FEAT_MTPMU | 67 * +----------------------------+ 68 */ 69 70 /* GENTIMER */ 71 static inline bool is_armv7_gentimer_present(void) 72 { 73 return ISOLATE_FIELD(read_id_pfr1(), ID_PFR1_GENTIMER_SHIFT, 74 ID_PFR1_GENTIMER_MASK) != 0U; 75 } 76 77 /* FEAT_TTCNP: Translation table common not private */ 78 CREATE_FEATURE_PRESENT(feat_ttcnp, id_mmfr4, ID_MMFR4_CNP_SHIFT, 79 ID_MMFR4_CNP_MASK, 1U) 80 81 /* FEAT_AMU: Activity Monitors Extension */ 82 CREATE_FEATURE_FUNCS(feat_amu, id_pfr0, ID_PFR0_AMU_SHIFT, 83 ID_PFR0_AMU_MASK, ID_PFR0_AMU_V1, ENABLE_FEAT_AMU) 84 85 /* FEAT_AMUV1P1: AMU Extension v1.1 */ 86 CREATE_FEATURE_FUNCS(feat_amuv1p1, id_pfr0, ID_PFR0_AMU_SHIFT, 87 ID_PFR0_AMU_MASK, ID_PFR0_AMU_V1P1, ENABLE_FEAT_AMUv1p1) 88 89 /* FEAT_TRF: Tracefilter */ 90 CREATE_FEATURE_FUNCS(feat_trf, id_dfr0, ID_DFR0_TRACEFILT_SHIFT, 91 ID_DFR0_TRACEFILT_MASK, 1U, ENABLE_TRF_FOR_NS) 92 93 /* FEAT_SYS_REG_TRACE */ 94 CREATE_FEATURE_FUNCS(feat_sys_reg_trace, id_dfr0, ID_DFR0_COPTRC_SHIFT, 95 ID_DFR0_COPTRC_MASK, 1U, ENABLE_SYS_REG_TRACE_FOR_NS) 96 97 /* FEAT_DIT: Data independent timing */ 98 CREATE_FEATURE_FUNCS(feat_dit, id_pfr0, ID_PFR0_DIT_SHIFT, 99 ID_PFR0_DIT_MASK, 1U, ENABLE_FEAT_DIT) 100 101 /* FEAT_PAN: Privileged access never */ 102 CREATE_FEATURE_FUNCS(feat_pan, id_mmfr3, ID_MMFR3_PAN_SHIFT, 103 ID_MMFR3_PAN_MASK, 1U, ENABLE_FEAT_PAN) 104 105 /* FEAT_SSBS: Speculative store bypass safe */ 106 CREATE_FEATURE_PRESENT(feat_ssbs, id_pfr2, ID_PFR2_SSBS_SHIFT, 107 ID_PFR2_SSBS_MASK, 1U) 108 109 /* FEAT_PMUV3 */ 110 CREATE_FEATURE_PRESENT(feat_pmuv3, id_dfr0, ID_DFR0_PERFMON_SHIFT, 111 ID_DFR0_PERFMON_MASK, 3U) 112 113 /* FEAT_MTPMU */ 114 static inline bool is_feat_mtpmu_present(void) 115 { 116 unsigned int mtpmu = ISOLATE_FIELD(read_id_dfr1(), ID_DFR1_MTPMU_SHIFT, 117 ID_DFR1_MTPMU_MASK); 118 return (mtpmu != 0U) && (mtpmu != MTPMU_NOT_IMPLEMENTED); 119 } 120 CREATE_FEATURE_SUPPORTED(feat_mtpmu, is_feat_mtpmu_present, DISABLE_MTPMU) 121 122 /* 123 * TWED, ECV, CSV2, RAS are only used by the AArch64 EL2 context switch 124 * code. In fact, EL2 context switching is only needed for AArch64 (since 125 * there is no secure AArch32 EL2), so just disable these features here. 126 */ 127 static inline bool is_feat_twed_supported(void) { return false; } 128 static inline bool is_feat_ecv_supported(void) { return false; } 129 static inline bool is_feat_ecv_v2_supported(void) { return false; } 130 static inline bool is_feat_csv2_2_supported(void) { return false; } 131 static inline bool is_feat_csv2_3_supported(void) { return false; } 132 static inline bool is_feat_ras_supported(void) { return false; } 133 134 /* The following features are supported in AArch64 only. */ 135 static inline bool is_feat_vhe_supported(void) { return false; } 136 static inline bool is_feat_sel2_supported(void) { return false; } 137 static inline bool is_feat_fgt_supported(void) { return false; } 138 static inline bool is_feat_tcr2_supported(void) { return false; } 139 static inline bool is_feat_spe_supported(void) { return false; } 140 static inline bool is_feat_rng_supported(void) { return false; } 141 static inline bool is_feat_gcs_supported(void) { return false; } 142 static inline bool is_feat_mte2_supported(void) { return false; } 143 static inline bool is_feat_mpam_supported(void) { return false; } 144 static inline bool is_feat_hcx_supported(void) { return false; } 145 static inline bool is_feat_sve_supported(void) { return false; } 146 static inline bool is_feat_brbe_supported(void) { return false; } 147 static inline bool is_feat_trbe_supported(void) { return false; } 148 static inline bool is_feat_nv2_supported(void) { return false; } 149 static inline bool is_feat_sme_supported(void) { return false; } 150 static inline bool is_feat_sme2_supported(void) { return false; } 151 static inline bool is_feat_s2poe_supported(void) { return false; } 152 static inline bool is_feat_s1poe_supported(void) { return false; } 153 static inline bool is_feat_sxpoe_supported(void) { return false; } 154 static inline bool is_feat_s2pie_supported(void) { return false; } 155 static inline bool is_feat_s1pie_supported(void) { return false; } 156 static inline bool is_feat_sxpie_supported(void) { return false; } 157 static inline bool is_feat_uao_present(void) { return false; } 158 static inline bool is_feat_nmi_present(void) { return false; } 159 static inline bool is_feat_ebep_present(void) { return false; } 160 static inline bool is_feat_sebep_present(void) { return false; } 161 162 #endif /* ARCH_FEATURES_H */ 163