12559b2c8SAntonio Nino Diaz /* 283ec7e45SBoyan Karatotev * Copyright (c) 2019-2025, Arm Limited. All rights reserved. 32559b2c8SAntonio Nino Diaz * 42559b2c8SAntonio Nino Diaz * SPDX-License-Identifier: BSD-3-Clause 52559b2c8SAntonio Nino Diaz */ 62559b2c8SAntonio Nino Diaz 72559b2c8SAntonio Nino Diaz #ifndef ARCH_FEATURES_H 82559b2c8SAntonio Nino Diaz #define ARCH_FEATURES_H 92559b2c8SAntonio Nino Diaz 102559b2c8SAntonio Nino Diaz #include <stdbool.h> 112559b2c8SAntonio Nino Diaz 122559b2c8SAntonio Nino Diaz #include <arch_helpers.h> 13fc8d2d39SAndre Przywara #include <common/feat_detect.h> 142559b2c8SAntonio Nino Diaz 15aaaf2cc3SSona Mathew #define ISOLATE_FIELD(reg, feat, mask) \ 16aaaf2cc3SSona Mathew ((unsigned int)(((reg) >> (feat)) & mask)) 17fd1dd4cbSAndre Przywara 18aaaf2cc3SSona Mathew #define CREATE_FEATURE_SUPPORTED(name, read_func, guard) \ 190dfa07b6SOlivier Deprez __attribute__((always_inline)) \ 20aaaf2cc3SSona Mathew static inline bool is_ ## name ## _supported(void) \ 21aaaf2cc3SSona Mathew { \ 22aaaf2cc3SSona Mathew if ((guard) == FEAT_STATE_DISABLED) { \ 23aaaf2cc3SSona Mathew return false; \ 24aaaf2cc3SSona Mathew } \ 25aaaf2cc3SSona Mathew if ((guard) == FEAT_STATE_ALWAYS) { \ 26aaaf2cc3SSona Mathew return true; \ 27aaaf2cc3SSona Mathew } \ 28aaaf2cc3SSona Mathew return read_func(); \ 29aaaf2cc3SSona Mathew } 30aaaf2cc3SSona Mathew 31aaaf2cc3SSona Mathew #define CREATE_FEATURE_PRESENT(name, idreg, idfield, mask, idval) \ 320dfa07b6SOlivier Deprez __attribute__((always_inline)) \ 33aaaf2cc3SSona Mathew static inline bool is_ ## name ## _present(void) \ 34aaaf2cc3SSona Mathew { \ 35aaaf2cc3SSona Mathew return (ISOLATE_FIELD(read_ ## idreg(), idfield, mask) >= idval) \ 36aaaf2cc3SSona Mathew ? true : false; \ 37aaaf2cc3SSona Mathew } 38aaaf2cc3SSona Mathew 39aaaf2cc3SSona Mathew #define CREATE_FEATURE_FUNCS(name, idreg, idfield, mask, idval, guard) \ 40aaaf2cc3SSona Mathew CREATE_FEATURE_PRESENT(name, idreg, idfield, mask, idval) \ 41aaaf2cc3SSona Mathew CREATE_FEATURE_SUPPORTED(name, is_ ## name ## _present, guard) 42aaaf2cc3SSona Mathew 43aaaf2cc3SSona Mathew 44aaaf2cc3SSona Mathew /* 45aaaf2cc3SSona Mathew * +----------------------------+ 46aaaf2cc3SSona Mathew * | Features supported | 47aaaf2cc3SSona Mathew * +----------------------------+ 48aaaf2cc3SSona Mathew * | GENTIMER | 49aaaf2cc3SSona Mathew * +----------------------------+ 50aaaf2cc3SSona Mathew * | FEAT_TTCNP | 51aaaf2cc3SSona Mathew * +----------------------------+ 52aaaf2cc3SSona Mathew * | FEAT_AMU | 53aaaf2cc3SSona Mathew * +----------------------------+ 54aaaf2cc3SSona Mathew * | FEAT_AMUV1P1 | 55aaaf2cc3SSona Mathew * +----------------------------+ 56aaaf2cc3SSona Mathew * | FEAT_TRF | 57aaaf2cc3SSona Mathew * +----------------------------+ 58aaaf2cc3SSona Mathew * | FEAT_SYS_REG_TRACE | 59aaaf2cc3SSona Mathew * +----------------------------+ 60aaaf2cc3SSona Mathew * | FEAT_DIT | 61aaaf2cc3SSona Mathew * +----------------------------+ 62aaaf2cc3SSona Mathew * | FEAT_PAN | 63aaaf2cc3SSona Mathew * +----------------------------+ 64aaaf2cc3SSona Mathew * | FEAT_SSBS | 65aaaf2cc3SSona Mathew * +----------------------------+ 66aaaf2cc3SSona Mathew * | FEAT_PMUV3 | 67aaaf2cc3SSona Mathew * +----------------------------+ 68aaaf2cc3SSona Mathew * | FEAT_MTPMU | 69aaaf2cc3SSona Mathew * +----------------------------+ 70aaaf2cc3SSona Mathew */ 71aaaf2cc3SSona Mathew 72aaaf2cc3SSona Mathew /* GENTIMER */ 730dfa07b6SOlivier Deprez __attribute__((always_inline)) 7429a24134SAntonio Nino Diaz static inline bool is_armv7_gentimer_present(void) 7529a24134SAntonio Nino Diaz { 76aaaf2cc3SSona Mathew return ISOLATE_FIELD(read_id_pfr1(), ID_PFR1_GENTIMER_SHIFT, 77aaaf2cc3SSona Mathew ID_PFR1_GENTIMER_MASK) != 0U; 7829a24134SAntonio Nino Diaz } 7929a24134SAntonio Nino Diaz 80aaaf2cc3SSona Mathew /* FEAT_TTCNP: Translation table common not private */ 81aaaf2cc3SSona Mathew CREATE_FEATURE_PRESENT(feat_ttcnp, id_mmfr4, ID_MMFR4_CNP_SHIFT, 82aaaf2cc3SSona Mathew ID_MMFR4_CNP_MASK, 1U) 83aaaf2cc3SSona Mathew 84aaaf2cc3SSona Mathew /* FEAT_AMU: Activity Monitors Extension */ 85aaaf2cc3SSona Mathew CREATE_FEATURE_FUNCS(feat_amu, id_pfr0, ID_PFR0_AMU_SHIFT, 86aaaf2cc3SSona Mathew ID_PFR0_AMU_MASK, ID_PFR0_AMU_V1, ENABLE_FEAT_AMU) 87aaaf2cc3SSona Mathew 8883ec7e45SBoyan Karatotev /* Auxiliary counters for FEAT_AMU */ 8983ec7e45SBoyan Karatotev CREATE_FEATURE_FUNCS(feat_amu_aux, amcfgr, AMCFGR_NCG_SHIFT, 9083ec7e45SBoyan Karatotev AMCFGR_NCG_MASK, 1U, ENABLE_AMU_AUXILIARY_COUNTERS) 9183ec7e45SBoyan Karatotev 92aaaf2cc3SSona Mathew /* FEAT_AMUV1P1: AMU Extension v1.1 */ 93aaaf2cc3SSona Mathew CREATE_FEATURE_FUNCS(feat_amuv1p1, id_pfr0, ID_PFR0_AMU_SHIFT, 94aaaf2cc3SSona Mathew ID_PFR0_AMU_MASK, ID_PFR0_AMU_V1P1, ENABLE_FEAT_AMUv1p1) 95aaaf2cc3SSona Mathew 96aaaf2cc3SSona Mathew /* FEAT_TRF: Tracefilter */ 97aaaf2cc3SSona Mathew CREATE_FEATURE_FUNCS(feat_trf, id_dfr0, ID_DFR0_TRACEFILT_SHIFT, 98aaaf2cc3SSona Mathew ID_DFR0_TRACEFILT_MASK, 1U, ENABLE_TRF_FOR_NS) 99aaaf2cc3SSona Mathew 100aaaf2cc3SSona Mathew /* FEAT_SYS_REG_TRACE */ 101aaaf2cc3SSona Mathew CREATE_FEATURE_FUNCS(feat_sys_reg_trace, id_dfr0, ID_DFR0_COPTRC_SHIFT, 102aaaf2cc3SSona Mathew ID_DFR0_COPTRC_MASK, 1U, ENABLE_SYS_REG_TRACE_FOR_NS) 103aaaf2cc3SSona Mathew 104aaaf2cc3SSona Mathew /* FEAT_DIT: Data independent timing */ 105aaaf2cc3SSona Mathew CREATE_FEATURE_FUNCS(feat_dit, id_pfr0, ID_PFR0_DIT_SHIFT, 106aaaf2cc3SSona Mathew ID_PFR0_DIT_MASK, 1U, ENABLE_FEAT_DIT) 107aaaf2cc3SSona Mathew 108aaaf2cc3SSona Mathew /* FEAT_PAN: Privileged access never */ 109aaaf2cc3SSona Mathew CREATE_FEATURE_FUNCS(feat_pan, id_mmfr3, ID_MMFR3_PAN_SHIFT, 110aaaf2cc3SSona Mathew ID_MMFR3_PAN_MASK, 1U, ENABLE_FEAT_PAN) 111aaaf2cc3SSona Mathew 112aaaf2cc3SSona Mathew /* FEAT_SSBS: Speculative store bypass safe */ 113aaaf2cc3SSona Mathew CREATE_FEATURE_PRESENT(feat_ssbs, id_pfr2, ID_PFR2_SSBS_SHIFT, 114aaaf2cc3SSona Mathew ID_PFR2_SSBS_MASK, 1U) 115aaaf2cc3SSona Mathew 116aaaf2cc3SSona Mathew /* FEAT_PMUV3 */ 117aaaf2cc3SSona Mathew CREATE_FEATURE_PRESENT(feat_pmuv3, id_dfr0, ID_DFR0_PERFMON_SHIFT, 118aaaf2cc3SSona Mathew ID_DFR0_PERFMON_MASK, 3U) 119aaaf2cc3SSona Mathew 120aaaf2cc3SSona Mathew /* FEAT_MTPMU */ 1210dfa07b6SOlivier Deprez __attribute__((always_inline)) 122aaaf2cc3SSona Mathew static inline bool is_feat_mtpmu_present(void) 1232559b2c8SAntonio Nino Diaz { 124aaaf2cc3SSona Mathew unsigned int mtpmu = ISOLATE_FIELD(read_id_dfr1(), ID_DFR1_MTPMU_SHIFT, 125aaaf2cc3SSona Mathew ID_DFR1_MTPMU_MASK); 126aaaf2cc3SSona Mathew return (mtpmu != 0U) && (mtpmu != MTPMU_NOT_IMPLEMENTED); 1272559b2c8SAntonio Nino Diaz } 128aaaf2cc3SSona Mathew CREATE_FEATURE_SUPPORTED(feat_mtpmu, is_feat_mtpmu_present, DISABLE_MTPMU) 12930f05b4fSManish Pandey 130733d112fSAndre Przywara /* 131733d112fSAndre Przywara * TWED, ECV, CSV2, RAS are only used by the AArch64 EL2 context switch 132733d112fSAndre Przywara * code. In fact, EL2 context switching is only needed for AArch64 (since 133733d112fSAndre Przywara * there is no secure AArch32 EL2), so just disable these features here. 134733d112fSAndre Przywara */ 1350dfa07b6SOlivier Deprez __attribute__((always_inline)) 136733d112fSAndre Przywara static inline bool is_feat_twed_supported(void) { return false; } 1370dfa07b6SOlivier Deprez __attribute__((always_inline)) 138733d112fSAndre Przywara static inline bool is_feat_ecv_supported(void) { return false; } 1390dfa07b6SOlivier Deprez __attribute__((always_inline)) 140733d112fSAndre Przywara static inline bool is_feat_ecv_v2_supported(void) { return false; } 1410dfa07b6SOlivier Deprez __attribute__((always_inline)) 142733d112fSAndre Przywara static inline bool is_feat_csv2_2_supported(void) { return false; } 1430dfa07b6SOlivier Deprez __attribute__((always_inline)) 14430019d86SSona Mathew static inline bool is_feat_csv2_3_supported(void) { return false; } 1450dfa07b6SOlivier Deprez __attribute__((always_inline)) 146733d112fSAndre Przywara static inline bool is_feat_ras_supported(void) { return false; } 147733d112fSAndre Przywara 148733d112fSAndre Przywara /* The following features are supported in AArch64 only. */ 1490dfa07b6SOlivier Deprez __attribute__((always_inline)) 150733d112fSAndre Przywara static inline bool is_feat_vhe_supported(void) { return false; } 1510dfa07b6SOlivier Deprez __attribute__((always_inline)) 152733d112fSAndre Przywara static inline bool is_feat_sel2_supported(void) { return false; } 1530dfa07b6SOlivier Deprez __attribute__((always_inline)) 154733d112fSAndre Przywara static inline bool is_feat_fgt_supported(void) { return false; } 1550dfa07b6SOlivier Deprez __attribute__((always_inline)) 156733d112fSAndre Przywara static inline bool is_feat_tcr2_supported(void) { return false; } 1570dfa07b6SOlivier Deprez __attribute__((always_inline)) 158733d112fSAndre Przywara static inline bool is_feat_spe_supported(void) { return false; } 1590dfa07b6SOlivier Deprez __attribute__((always_inline)) 160733d112fSAndre Przywara static inline bool is_feat_rng_supported(void) { return false; } 1610dfa07b6SOlivier Deprez __attribute__((always_inline)) 162733d112fSAndre Przywara static inline bool is_feat_gcs_supported(void) { return false; } 1630dfa07b6SOlivier Deprez __attribute__((always_inline)) 1648e397889SGovindraj Raja static inline bool is_feat_mte2_supported(void) { return false; } 1650dfa07b6SOlivier Deprez __attribute__((always_inline)) 166733d112fSAndre Przywara static inline bool is_feat_mpam_supported(void) { return false; } 1670dfa07b6SOlivier Deprez __attribute__((always_inline)) 168733d112fSAndre Przywara static inline bool is_feat_hcx_supported(void) { return false; } 1690dfa07b6SOlivier Deprez __attribute__((always_inline)) 170733d112fSAndre Przywara static inline bool is_feat_sve_supported(void) { return false; } 1710dfa07b6SOlivier Deprez __attribute__((always_inline)) 172733d112fSAndre Przywara static inline bool is_feat_brbe_supported(void) { return false; } 1730dfa07b6SOlivier Deprez __attribute__((always_inline)) 174733d112fSAndre Przywara static inline bool is_feat_trbe_supported(void) { return false; } 1750dfa07b6SOlivier Deprez __attribute__((always_inline)) 176733d112fSAndre Przywara static inline bool is_feat_nv2_supported(void) { return false; } 1770dfa07b6SOlivier Deprez __attribute__((always_inline)) 178733d112fSAndre Przywara static inline bool is_feat_sme_supported(void) { return false; } 1790dfa07b6SOlivier Deprez __attribute__((always_inline)) 180733d112fSAndre Przywara static inline bool is_feat_sme2_supported(void) { return false; } 1810dfa07b6SOlivier Deprez __attribute__((always_inline)) 182733d112fSAndre Przywara static inline bool is_feat_s2poe_supported(void) { return false; } 1830dfa07b6SOlivier Deprez __attribute__((always_inline)) 184733d112fSAndre Przywara static inline bool is_feat_s1poe_supported(void) { return false; } 1850dfa07b6SOlivier Deprez __attribute__((always_inline)) 186733d112fSAndre Przywara static inline bool is_feat_sxpoe_supported(void) { return false; } 1870dfa07b6SOlivier Deprez __attribute__((always_inline)) 188733d112fSAndre Przywara static inline bool is_feat_s2pie_supported(void) { return false; } 1890dfa07b6SOlivier Deprez __attribute__((always_inline)) 190733d112fSAndre Przywara static inline bool is_feat_s1pie_supported(void) { return false; } 1910dfa07b6SOlivier Deprez __attribute__((always_inline)) 192733d112fSAndre Przywara static inline bool is_feat_sxpie_supported(void) { return false; } 1930dfa07b6SOlivier Deprez __attribute__((always_inline)) 19430f05b4fSManish Pandey static inline bool is_feat_uao_present(void) { return false; } 1950dfa07b6SOlivier Deprez __attribute__((always_inline)) 19630f05b4fSManish Pandey static inline bool is_feat_nmi_present(void) { return false; } 1970dfa07b6SOlivier Deprez __attribute__((always_inline)) 19830f05b4fSManish Pandey static inline bool is_feat_ebep_present(void) { return false; } 1990dfa07b6SOlivier Deprez __attribute__((always_inline)) 20030f05b4fSManish Pandey static inline bool is_feat_sebep_present(void) { return false; } 20130655136SGovindraj Raja __attribute__((always_inline)) 20230655136SGovindraj Raja static inline bool is_feat_d128_present(void) { return false; } 20319d52a83SAndre Przywara __attribute__((always_inline)) 20419d52a83SAndre Przywara static inline bool is_feat_ls64_accdata_present(void) { return false; } 2058656bdabSArvind Ram Prakash __attribute__((always_inline)) 2068656bdabSArvind Ram Prakash static inline bool is_feat_mops_supported(void) { return false; } 207*10ecd580SBoyan Karatotev __attribute__((always_inline)) 208*10ecd580SBoyan Karatotev static inline bool is_feat_bti_supported(void) { return false; } 209733d112fSAndre Przywara 2102559b2c8SAntonio Nino Diaz #endif /* ARCH_FEATURES_H */ 211