blob: a5da41319815dbbd353833f1c12dbc9e2cf62d6f [file] [log] [blame]
Soby Mathewb4c6df42022-11-09 11:13:29 +00001/*
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
Yousuf Aa297b9b2022-10-13 13:54:21 +010013#define RMM_FEATURE_MIN_IPA_SIZE PARANGE_0000_WIDTH
14
Soby Mathewb4c6df42022-11-09 11:13:29 +000015static unsigned long get_feature_register_0(void)
16{
17 /* Set S2SZ field */
18 unsigned long s2sz = arch_feat_get_pa_width();
19 unsigned long feat_reg0 = INPLACE(RMM_FEATURE_REGISTER_0_S2SZ, s2sz);
20
21 /* Set LPA2 field */
22 if (is_feat_lpa2_4k_present()) {
23 feat_reg0 |= INPLACE(RMM_FEATURE_REGISTER_0_LPA2, RMI_LPA2);
24 }
25
26 /* Set support for SHA256 and SHA512 hash algorithms */
AlexeiFedorov7bb7a702023-01-17 17:04:14 +000027 feat_reg0 |= INPLACE(RMM_FEATURE_REGISTER_0_HASH_SHA_256,
28 RMI_SUPPORTED);
29 feat_reg0 |= INPLACE(RMM_FEATURE_REGISTER_0_HASH_SHA_512,
30 RMI_SUPPORTED);
31
32 /* PMU is not supported */
33 feat_reg0 |= INPLACE(RMM_FEATURE_REGISTER_0_PMU_EN,
34 RMI_NOT_SUPPORTED);
35 feat_reg0 |= INPLACE(RMM_FEATURE_REGISTER_0_PMU_NUM_CTRS, 0U);
Soby Mathewb4c6df42022-11-09 11:13:29 +000036
37 return feat_reg0;
38}
39
40void smc_read_feature_register(unsigned long index,
41 struct smc_result *ret_struct)
42{
43 switch (index) {
44 case RMM_FEATURE_REGISTER_0_INDEX:
45 ret_struct->x[0] = RMI_SUCCESS;
46 ret_struct->x[1] = get_feature_register_0();
47 break;
48 default:
49 ret_struct->x[0] = RMI_ERROR_INPUT;
50 }
51}
52
53static bool validate_feature_register_0(unsigned long value)
54{
55 unsigned long feat_reg0 = get_feature_register_0();
56 unsigned long s2sz = EXTRACT(RMM_FEATURE_REGISTER_0_S2SZ, value);
57
58 /* Validate S2SZ field */
59 if ((s2sz < RMM_FEATURE_MIN_IPA_SIZE) ||
60 (s2sz > EXTRACT(RMM_FEATURE_REGISTER_0_S2SZ, feat_reg0))) {
61 return false;
62 }
63
64 /* Validate LPA2 flag */
65 if ((EXTRACT(RMM_FEATURE_REGISTER_0_LPA2, value) == RMI_LPA2) &&
66 !is_feat_lpa2_4k_present()) {
67 return false;
68 }
69
AlexeiFedorov7bb7a702023-01-17 17:04:14 +000070 /* Validate PMU_EN flag */
71 if ((EXTRACT(RMM_FEATURE_REGISTER_0_PMU_EN, value) == RMI_SUPPORTED) ||
72 (EXTRACT(RMM_FEATURE_REGISTER_0_PMU_NUM_CTRS, value) != 0U)) {
73 return false;
74 }
75
Soby Mathewb4c6df42022-11-09 11:13:29 +000076 return true;
77}
78
79bool validate_feature_register(unsigned long index, unsigned long value)
80{
81 switch (index) {
82 case RMM_FEATURE_REGISTER_0_INDEX:
83 return validate_feature_register_0(value);
84 default:
85 assert(false);
86 return false;
87 }
88}