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