1 /*
2  * SPDX-License-Identifier: BSD-3-Clause
3  * SPDX-FileCopyrightText: Copyright TF-RMM Contributors.
4  */
5 
6 #include <arch_features.h>
7 #include <assert.h>
8 #include <feature.h>
9 #include <smc-handler.h>
10 #include <smc-rmi.h>
11 #include <status.h>
12 
get_feature_register_0(void)13 static unsigned long get_feature_register_0(void)
14 {
15 	/* Set S2SZ field */
16 	unsigned long s2sz = arch_feat_get_pa_width();
17 	unsigned long feat_reg0 = INPLACE(RMM_FEATURE_REGISTER_0_S2SZ, s2sz);
18 
19 	/* Set LPA2 field */
20 	if (is_feat_lpa2_4k_present()) {
21 		feat_reg0 |= INPLACE(RMM_FEATURE_REGISTER_0_LPA2, RMI_LPA2);
22 	}
23 
24 	/* Set support for SHA256 and SHA512 hash algorithms */
25 	feat_reg0 |= INPLACE(RMM_FEATURE_REGISTER_0_HASH_SHA_256, 1);
26 	feat_reg0 |= INPLACE(RMM_FEATURE_REGISTER_0_HASH_SHA_512, 1);
27 
28 	return feat_reg0;
29 }
30 
smc_read_feature_register(unsigned long index,struct smc_result * ret_struct)31 void smc_read_feature_register(unsigned long index,
32 				struct smc_result *ret_struct)
33 {
34 	switch (index) {
35 	case RMM_FEATURE_REGISTER_0_INDEX:
36 		ret_struct->x[0] = RMI_SUCCESS;
37 		ret_struct->x[1] = get_feature_register_0();
38 		break;
39 	default:
40 		ret_struct->x[0] = RMI_ERROR_INPUT;
41 	}
42 }
43 
validate_feature_register_0(unsigned long value)44 static bool validate_feature_register_0(unsigned long value)
45 {
46 	unsigned long feat_reg0 = get_feature_register_0();
47 	unsigned long s2sz = EXTRACT(RMM_FEATURE_REGISTER_0_S2SZ, value);
48 
49 	/* Validate S2SZ field */
50 	if ((s2sz < RMM_FEATURE_MIN_IPA_SIZE) ||
51 	    (s2sz > EXTRACT(RMM_FEATURE_REGISTER_0_S2SZ, feat_reg0))) {
52 		return false;
53 	}
54 
55 	/* Validate LPA2 flag */
56 	if ((EXTRACT(RMM_FEATURE_REGISTER_0_LPA2, value) == RMI_LPA2) &&
57 	    !is_feat_lpa2_4k_present()) {
58 		return false;
59 	}
60 
61 	return true;
62 }
63 
validate_feature_register(unsigned long index,unsigned long value)64 bool validate_feature_register(unsigned long index, unsigned long value)
65 {
66 	switch (index) {
67 	case RMM_FEATURE_REGISTER_0_INDEX:
68 		return validate_feature_register_0(value);
69 	default:
70 		assert(false);
71 		return false;
72 	}
73 }
74