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