arch_features.h 7.2 KB

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