blob: f8275229cf29d5af580735d2d2134789f6356ec6 [file] [log] [blame]
Boyan Karatotev7b7ca222024-10-25 13:33:18 +01001/*
2 * Copyright (c) 2024, Arm Limited. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7#include <tftf.h>
8
9#include <arm_arch_svc.h>
10#include <smccc.h>
11#include <test_helpers.h>
12#include <tftf_lib.h>
13
14static inline u_register_t get_feature_for_reg(u_register_t reg)
15{
16 smc_args args = {0};
17 smc_ret_values ret;
18
19 args.fid = SMCCC_ARCH_FEATURE_AVAILABILITY | (SMC_64 << FUNCID_CC_SHIFT);
20 args.arg1 = reg;
21 ret = tftf_smc(&args);
22
23 /* APi is pretty simple, support was already checked. This is simpler */
24 assert((int)ret.ret0 == SMC_ARCH_CALL_SUCCESS);
25 return ret.ret1;
26}
27
28static inline bool always_present(void)
29{
30 return true;
31}
32
33/*
34 * Checks that the bit's matches the feature's presence
35 * feat_func should be is_feat_xyz_present(), but get_feat_xyz_support() will
36 * also work.
37 */
38#define CHECK_BIT_SET(feat_func, bit) \
39 do { \
40 if (!!feat_func() != !!(reg & bit)) { \
41 tftf_testcase_printf( \
42 #feat_func " says feature is %ssupported but " \
43 #bit " was %sset!\n", feat_func() ? "" : "not ",\
44 (reg & bit) ? "" : "not "); \
45 bad = true; \
46 } \
47 reg &= ~bit; \
48 } while (0)
49
50/* when support for a new feature is added, we want this test to be
51 * updated. Fail the test so it's noticed. */
52#define CHECK_NO_BITS_SET(reg_name) \
53 do { \
54 if (reg != 0) { \
55 tftf_testcase_printf( \
56 #reg_name " still has values set: 0x%lx. " \
57 "Test needs to be updated\n", reg); \
58 bad = true; \
59 } \
60 } while (0)
61
62test_result_t test_smccc_arch_feature_availability(void)
63{
64 SKIP_TEST_IF_AARCH32();
65#ifdef __aarch64__
66
67 SKIP_TEST_IF_SMCCC_VERSION_LT(1, 1);
Arvind Ram Prakash6db21fa2025-09-19 10:17:06 -050068 SKIP_TEST_IF_SMCCC_FUNC_NOT_SUPPORTED(SMCCC_ARCH_FEATURE_AVAILABILITY |
69 (SMC_64 << FUNCID_CC_SHIFT));
Boyan Karatotev7b7ca222024-10-25 13:33:18 +010070
71 u_register_t reg;
72 bool bad = false;
73
74 reg = get_feature_for_reg(SCR_EL3_OPCODE);
75 CHECK_BIT_SET(is_armv8_9_fgt2_present, SCR_FGTEN2_BIT);
76 CHECK_BIT_SET(is_feat_fpmr_present, SCR_EnFPM_BIT);
77 CHECK_BIT_SET(is_feat_d128_supported, SCR_D128En_BIT);
78 CHECK_BIT_SET(is_feat_s1pie_present, SCR_PIEN_BIT);
79 CHECK_BIT_SET(is_feat_sctlr2_supported, SCR_SCTLR2En_BIT);
80 CHECK_BIT_SET(is_feat_tcr2_supported, SCR_TCR2EN_BIT);
81 CHECK_BIT_SET(is_feat_the_supported, SCR_RCWMASKEn_BIT);
82 CHECK_BIT_SET(is_feat_sme_supported, SCR_ENTP2_BIT);
Andre Przywara37e3f3e2025-03-07 17:25:24 +000083 CHECK_BIT_SET(is_feat_rng_present, SCR_TRNDR_BIT);
Boyan Karatotev7b7ca222024-10-25 13:33:18 +010084 CHECK_BIT_SET(is_feat_gcs_present, SCR_GCSEn_BIT);
85 CHECK_BIT_SET(get_feat_hcx_support, SCR_HXEn_BIT);
86 CHECK_BIT_SET(is_feat_ls64_accdata_present, SCR_ADEn_BIT);
87 CHECK_BIT_SET(is_feat_ls64_accdata_present, SCR_EnAS0_BIT);
88 CHECK_BIT_SET(is_feat_amuv1p1_present, SCR_AMVOFFEN_BIT);
Andre Przywara37e3f3e2025-03-07 17:25:24 +000089 CHECK_BIT_SET(is_feat_twed_present, SCR_TWEDEn_BIT);
Boyan Karatotev7b7ca222024-10-25 13:33:18 +010090 CHECK_BIT_SET(get_armv8_6_ecv_support, SCR_ECVEN_BIT);
91 CHECK_BIT_SET(is_armv8_6_fgt_present, SCR_FGTEN_BIT);
92 CHECK_BIT_SET(is_feat_mte2_present, SCR_ATA_BIT);
93 CHECK_BIT_SET(is_feat_csv2_2_present, SCR_EnSCXT_BIT);
94 CHECK_BIT_SET(is_armv8_3_pauth_present, SCR_APK_BIT);
95 CHECK_BIT_SET(is_feat_ras_present, SCR_TERR_BIT);
Andre Przywaraf0237572025-10-07 15:08:17 +010096 CHECK_BIT_SET(is_feat_aie_supported, SCR_AIEn_BIT);
97 CHECK_BIT_SET(is_feat_pfar_supported, SCR_PFAREn_BIT);
Boyan Karatotev7b7ca222024-10-25 13:33:18 +010098 CHECK_NO_BITS_SET(SCR_EL3);
99
100 reg = get_feature_for_reg(CPTR_EL3_OPCODE);
101 CHECK_BIT_SET(always_present, CPTR_EL3_TCPAC_BIT);
102 CHECK_BIT_SET(is_feat_amuv1_present, CPTR_EL3_TAM_BIT);
103 CHECK_BIT_SET(get_armv8_0_sys_reg_trace_support, CPTR_EL3_TTA_BIT);
104 CHECK_BIT_SET(is_feat_sme_supported, CPTR_EL3_ESM_BIT);
105 CHECK_BIT_SET(always_present, CPTR_EL3_TFP_BIT);
106 CHECK_BIT_SET(is_armv8_2_sve_present, CPTR_EL3_EZ_BIT);
107 CHECK_NO_BITS_SET(CPTR_EL3);
108
109 reg = get_feature_for_reg(MDCR_EL3_OPCODE);
110 CHECK_BIT_SET(get_feat_brbe_support, MDCR_SBRBE(1));
111 CHECK_BIT_SET(is_armv8_6_fgt_present, MDCR_TDCC_BIT);
112 CHECK_BIT_SET(is_feat_trbe_present, MDCR_NSTB(1));
113 CHECK_BIT_SET(get_armv8_4_trf_support, MDCR_TTRF_BIT);
114 CHECK_BIT_SET(is_feat_spe_supported, MDCR_NSPB(1));
Andre Przywara37e3f3e2025-03-07 17:25:24 +0000115 CHECK_BIT_SET(is_feat_pmuv3p9_present, MDCR_EnPM2_BIT);
Boyan Karatotev7b7ca222024-10-25 13:33:18 +0100116 CHECK_BIT_SET(is_feat_doublelock_present, MDCR_TDOSA_BIT);
117 CHECK_BIT_SET(always_present, MDCR_TDA_BIT);
118 CHECK_BIT_SET(get_feat_pmuv3_supported, MDCR_TPM_BIT);
119 CHECK_NO_BITS_SET(MDCR_EL3);
120
121 reg = get_feature_for_reg(MPAM3_EL3_OPCODE);
122 CHECK_BIT_SET(is_feat_mpam_supported, MPAM3_EL3_TRAPLOWER_BIT);
123 CHECK_NO_BITS_SET(MPAM3_EL3);
124
125 if (bad)
126 return TEST_RESULT_FAIL;
127
128 return TEST_RESULT_SUCCESS;
129#endif /* __aarch64__ */
130}