blob: 279d249e14517d71ab7ea3ecd95a471d7fb3ad28 [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#ifndef SMC_H
7#define SMC_H
8
9#include <utils_def.h>
10
11/* FID: Type - Fast Call */
12#define SMC_TYPE_SHIFT U(31)
13#define SMC_TYPE_MASK U(1)
14#define SMC_TYPE_FAST U(1)
15
16/* FID: Calling convention - SMC32/SMC64 */
17#define SMC_CC_SHIFT U(30)
18#define SMC_CC_MASK U(1)
19#define SMC_CC_SMC32 U(0)
20#define SMC_CC_SMC64 U(1)
21
22/* FID: Owning entity number - Standard Secure Service Calls */
23#define SMC_OEN_SHIFT U(24)
24#define SMC_OEN_MASK U(0x3F)
25#define SMC_OEN_STD U(0x4)
26#define SMC_OEN_ARCH U(0x0)
27
28/* FID: Must be zero (MBZ) */
29#define SMC_MBZ_SHIFT U(16)
30#define SMC_MBZ_MASK U(0xFF)
31#define SMC_MBZ_ZERO U(0x0)
32
Arunachalam Ganapathy937b5492023-02-28 11:17:52 +000033/* SVE Hint bit (SMCCCv1.3), denoting the absence of SVE specific live state */
AlexeiFedorov4faab852023-08-30 15:06:49 +010034#define SMC_SVE_HINT (U(1) << 16)
Arunachalam Ganapathy937b5492023-02-28 11:17:52 +000035
Soby Mathewb4c6df42022-11-09 11:13:29 +000036/* FID: Function number */
37#define SMC_FNUM_SHIFT U(0)
38#define SMC_FNUM_MASK U(0xFFFF)
39
40#define SMC_FIELD_VAL(_field, _val) \
41 (((_val) & SMC_##_field##_MASK) << SMC_##_field##_SHIFT)
42
43#define SMC_SET_FIELD(_init_val, _field, _val) \
44 (((_init_val) & ~SMC_FIELD_VAL(_field, SMC_##_field##_MASK)) | \
45 SMC_FIELD_VAL(_field, _val))
46
47#define SMC_GET_FIELD(_fid, _field) \
48 (((_fid) >> SMC_##_field##_SHIFT) & SMC_##_field##_MASK)
49
50/* Arm Architecture Call range function IDs */
51 /* 0x80000000 */
52#define SMC_ARCH_CALL_BASE (SMC_SET_FIELD(U(0), TYPE, SMC_TYPE_FAST) | \
53 SMC_SET_FIELD(U(0), OEN, SMC_OEN_ARCH))
54
55 /* 0x8000FFFF */
56#define SMC_ARCH_CALL_LIMIT (SMC_SET_FIELD(SMC_ARCH_CALL_BASE, FNUM, \
57 U(0xFFFF)))
58
59/*
60 * We allocate all RMM calls as function IDs within the Standard Secure
61 * Service Call range category defined in the SMCCC.
62 */
63 /* 0x84000000 */
64#define SMC_STD_CALL_BASE (SMC_SET_FIELD(U(0), TYPE, SMC_TYPE_FAST) | \
65 SMC_SET_FIELD(U(0), OEN, SMC_OEN_STD))
66
67 /* 0x840001CF */
68#define SMC_STD_CALL_LIMIT (SMC_SET_FIELD(SMC_STD_CALL_BASE, FNUM, \
69 U(0x1CF)))
70
71/* STD calls FNUM Min/Max ranges */
72#define SMC32_PSCI_FNUM_MIN (U(0x0))
73#define SMC32_PSCI_FNUM_MAX (U(0x14))
74
75#define SMC64_PSCI_FNUM_MIN (U(0x0))
76#define SMC64_PSCI_FNUM_MAX (U(0x14))
77
78#define SMC64_RMI_FNUM_MIN (U(0x150))
79#define SMC64_RMI_FNUM_MAX (U(0x169))
80
81#define SMC64_RSI_FNUM_MIN (U(0x190))
82#define SMC64_RSI_FNUM_MAX (U(0x1AF))
83
84#define SMC64_RMM_EL3_FNUM_MIN (U(0x1B0))
85#define SMC64_RMM_EL3_FNUM_MAX (U(0x1CF))
86
87/* Utility macros for FID range values */
88#define SMC32_ARCH_FID(_offset) \
89 (SMC_SET_FIELD(SMC_ARCH_CALL_BASE, CC, SMC_CC_SMC32) | \
90 SMC_SET_FIELD(SMC_ARCH_CALL_BASE, FNUM, (_offset)))
91
92#define SMC32_STD_FID(_range, _offset) \
93 (SMC_SET_FIELD(SMC_STD_CALL_BASE, CC, SMC_CC_SMC32) | \
94 SMC_SET_FIELD(SMC_STD_CALL_BASE, FNUM, \
95 (SMC32_##_range##_FNUM_MIN + (_offset))))
96
97#define SMC64_STD_FID(_range, _offset) \
98 (SMC_SET_FIELD(SMC_STD_CALL_BASE, CC, SMC_CC_SMC64) | \
99 SMC_SET_FIELD(SMC_STD_CALL_BASE, FNUM, \
100 (SMC64_##_range##_FNUM_MIN + (_offset))))
101
102#define IS_SMC64_FID_IN_RANGE(_range, _fid) \
103 ((SMC_GET_FIELD(_fid, FNUM) >= SMC64_##_range##_FNUM_MIN) && \
104 (SMC_GET_FIELD(_fid, FNUM) <= SMC64_##_range##_FNUM_MAX))
105
106#define IS_SMC32_FID_IN_RANGE(_range, _fid) \
107 ((SMC_GET_FIELD(_fid, FNUM) >= SMC32_##_range##_FNUM_MIN) && \
108 (SMC_GET_FIELD(_fid, FNUM) <= SMC32_##_range##_FNUM_MAX))
109
110#define IS_SMC64_FID_STD_FAST(_fid) \
111 (((_fid) & ~SMC_FIELD_VAL(FNUM, SMC_FNUM_MASK)) == \
112 ((SMC_FIELD_VAL(CC, SMC_CC_SMC64) | \
113 SMC_FIELD_VAL(TYPE, SMC_TYPE_FAST) | \
114 SMC_FIELD_VAL(OEN, SMC_OEN_STD))))
115
116#define IS_SMC32_FID_STD_FAST(_fid) \
117 (((_fid) & ~SMC_FIELD_VAL(FNUM, SMC_FNUM_MASK)) == \
118 ((SMC_FIELD_VAL(CC, SMC_CC_SMC32) | \
119 SMC_FIELD_VAL(TYPE, SMC_TYPE_FAST) | \
120 SMC_FIELD_VAL(OEN, SMC_OEN_STD))))
121
122#define IS_SMC64_STD_FAST_IN_RANGE(_range, _fid) \
123 (IS_SMC64_FID_STD_FAST(_fid) && IS_SMC64_FID_IN_RANGE(_range, _fid))
124
125#define IS_SMC32_STD_FAST_IN_RANGE(_range, _fid) \
126 (IS_SMC32_FID_STD_FAST(_fid) && IS_SMC32_FID_IN_RANGE(_range, _fid))
127
128#define SMC64_NUM_FIDS_IN_RANGE(_range) \
129 (SMC64_##_range##_FNUM_MAX - SMC64_##_range##_FNUM_MIN + 1)
130
131/* Gets the offset in a range. Inputs must be pre-verified */
132#define SMC64_FID_OFFSET_FROM_RANGE_MIN(_range, _fid) \
133 (SMC_GET_FIELD(_fid, FNUM) - SMC64_##_range##_FNUM_MIN)
134
135/* Implementation defined FID values */
136 /* 0x18F */
137#define SMC_RMM_REQ_COMPLETE SMC64_STD_FID(RMI, U(0x3F))
138
Soby Mathewb4c6df42022-11-09 11:13:29 +0000139/* ARM ARCH call FIDs */
140#define SMCCC_VERSION SMC32_ARCH_FID(U(0))
141#define SMCCC_ARCH_FEATURES SMC32_ARCH_FID(U(1))
142#define SMCCC_ARCH_SOC_ID SMC32_ARCH_FID(U(2))
143#define SMCCC_ARCH_WORKAROUND_2 SMC32_ARCH_FID(U(0x7FFF))
144#define SMCCC_ARCH_WORKAROUND_1 SMC32_ARCH_FID(U(0x8000))
145
146/* Implemented version of the SMC Calling Convention */
147#define SMCCC_VERSION_MAJOR U(1)
148#define SMCCC_VERSION_MINOR U(2)
149
150/*
151 * SMCCC version encoding:
152 * Bit[31] must be zero
153 * Bits [30:16] Major version
154 * Bits [15:0] Minor version
155 */
156#define SMCCC_VERSION_NUMBER \
157 ((SMCCC_VERSION_MAJOR << U(16)) | SMCCC_VERSION_MINOR)
158
159/* SMCCC return codes */
AlexeiFedorove4ade462023-01-06 12:15:38 +0000160#define SMC_SUCCESS UL(0)
161#define SMC_NOT_SUPPORTED UL(-1)
162#define SMC_NOT_REQUIRED UL(-2)
163#define SMC_INVALID_PARAMETER UL(-3)
Soby Mathewb4c6df42022-11-09 11:13:29 +0000164
AlexeiFedorove4ade462023-01-06 12:15:38 +0000165#define SMC_UNKNOWN UL(-1)
Soby Mathewb4c6df42022-11-09 11:13:29 +0000166
167#ifndef __ASSEMBLER__
168unsigned long monitor_call(unsigned long id,
169 unsigned long arg0,
170 unsigned long arg1,
171 unsigned long arg2,
172 unsigned long arg3,
173 unsigned long arg4,
174 unsigned long arg5);
175
176/* Result registers X0-X4 */
177#define SMC_RESULT_REGS 5U
178
179struct smc_result {
180 unsigned long x[SMC_RESULT_REGS];
181};
182
183void monitor_call_with_res(unsigned long id,
184 unsigned long arg0,
185 unsigned long arg1,
186 unsigned long arg2,
187 unsigned long arg3,
188 unsigned long arg4,
189 unsigned long arg5,
190 struct smc_result *res);
191
192#endif /* __ASSEMBLER__ */
193
194#endif /* SMC_H */