blob: 5ec2ac44b0f1f52e19d2dcfe5a7c92b69f564452 [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
33/* FID: Function number */
34#define SMC_FNUM_SHIFT U(0)
35#define SMC_FNUM_MASK U(0xFFFF)
36
37#define SMC_FIELD_VAL(_field, _val) \
38 (((_val) & SMC_##_field##_MASK) << SMC_##_field##_SHIFT)
39
40#define SMC_SET_FIELD(_init_val, _field, _val) \
41 (((_init_val) & ~SMC_FIELD_VAL(_field, SMC_##_field##_MASK)) | \
42 SMC_FIELD_VAL(_field, _val))
43
44#define SMC_GET_FIELD(_fid, _field) \
45 (((_fid) >> SMC_##_field##_SHIFT) & SMC_##_field##_MASK)
46
47/* Arm Architecture Call range function IDs */
48 /* 0x80000000 */
49#define SMC_ARCH_CALL_BASE (SMC_SET_FIELD(U(0), TYPE, SMC_TYPE_FAST) | \
50 SMC_SET_FIELD(U(0), OEN, SMC_OEN_ARCH))
51
52 /* 0x8000FFFF */
53#define SMC_ARCH_CALL_LIMIT (SMC_SET_FIELD(SMC_ARCH_CALL_BASE, FNUM, \
54 U(0xFFFF)))
55
56/*
57 * We allocate all RMM calls as function IDs within the Standard Secure
58 * Service Call range category defined in the SMCCC.
59 */
60 /* 0x84000000 */
61#define SMC_STD_CALL_BASE (SMC_SET_FIELD(U(0), TYPE, SMC_TYPE_FAST) | \
62 SMC_SET_FIELD(U(0), OEN, SMC_OEN_STD))
63
64 /* 0x840001CF */
65#define SMC_STD_CALL_LIMIT (SMC_SET_FIELD(SMC_STD_CALL_BASE, FNUM, \
66 U(0x1CF)))
67
68/* STD calls FNUM Min/Max ranges */
69#define SMC32_PSCI_FNUM_MIN (U(0x0))
70#define SMC32_PSCI_FNUM_MAX (U(0x14))
71
72#define SMC64_PSCI_FNUM_MIN (U(0x0))
73#define SMC64_PSCI_FNUM_MAX (U(0x14))
74
75#define SMC64_RMI_FNUM_MIN (U(0x150))
76#define SMC64_RMI_FNUM_MAX (U(0x169))
77
78#define SMC64_RSI_FNUM_MIN (U(0x190))
79#define SMC64_RSI_FNUM_MAX (U(0x1AF))
80
81#define SMC64_RMM_EL3_FNUM_MIN (U(0x1B0))
82#define SMC64_RMM_EL3_FNUM_MAX (U(0x1CF))
83
84/* Utility macros for FID range values */
85#define SMC32_ARCH_FID(_offset) \
86 (SMC_SET_FIELD(SMC_ARCH_CALL_BASE, CC, SMC_CC_SMC32) | \
87 SMC_SET_FIELD(SMC_ARCH_CALL_BASE, FNUM, (_offset)))
88
89#define SMC32_STD_FID(_range, _offset) \
90 (SMC_SET_FIELD(SMC_STD_CALL_BASE, CC, SMC_CC_SMC32) | \
91 SMC_SET_FIELD(SMC_STD_CALL_BASE, FNUM, \
92 (SMC32_##_range##_FNUM_MIN + (_offset))))
93
94#define SMC64_STD_FID(_range, _offset) \
95 (SMC_SET_FIELD(SMC_STD_CALL_BASE, CC, SMC_CC_SMC64) | \
96 SMC_SET_FIELD(SMC_STD_CALL_BASE, FNUM, \
97 (SMC64_##_range##_FNUM_MIN + (_offset))))
98
99#define IS_SMC64_FID_IN_RANGE(_range, _fid) \
100 ((SMC_GET_FIELD(_fid, FNUM) >= SMC64_##_range##_FNUM_MIN) && \
101 (SMC_GET_FIELD(_fid, FNUM) <= SMC64_##_range##_FNUM_MAX))
102
103#define IS_SMC32_FID_IN_RANGE(_range, _fid) \
104 ((SMC_GET_FIELD(_fid, FNUM) >= SMC32_##_range##_FNUM_MIN) && \
105 (SMC_GET_FIELD(_fid, FNUM) <= SMC32_##_range##_FNUM_MAX))
106
107#define IS_SMC64_FID_STD_FAST(_fid) \
108 (((_fid) & ~SMC_FIELD_VAL(FNUM, SMC_FNUM_MASK)) == \
109 ((SMC_FIELD_VAL(CC, SMC_CC_SMC64) | \
110 SMC_FIELD_VAL(TYPE, SMC_TYPE_FAST) | \
111 SMC_FIELD_VAL(OEN, SMC_OEN_STD))))
112
113#define IS_SMC32_FID_STD_FAST(_fid) \
114 (((_fid) & ~SMC_FIELD_VAL(FNUM, SMC_FNUM_MASK)) == \
115 ((SMC_FIELD_VAL(CC, SMC_CC_SMC32) | \
116 SMC_FIELD_VAL(TYPE, SMC_TYPE_FAST) | \
117 SMC_FIELD_VAL(OEN, SMC_OEN_STD))))
118
119#define IS_SMC64_STD_FAST_IN_RANGE(_range, _fid) \
120 (IS_SMC64_FID_STD_FAST(_fid) && IS_SMC64_FID_IN_RANGE(_range, _fid))
121
122#define IS_SMC32_STD_FAST_IN_RANGE(_range, _fid) \
123 (IS_SMC32_FID_STD_FAST(_fid) && IS_SMC32_FID_IN_RANGE(_range, _fid))
124
125#define SMC64_NUM_FIDS_IN_RANGE(_range) \
126 (SMC64_##_range##_FNUM_MAX - SMC64_##_range##_FNUM_MIN + 1)
127
128/* Gets the offset in a range. Inputs must be pre-verified */
129#define SMC64_FID_OFFSET_FROM_RANGE_MIN(_range, _fid) \
130 (SMC_GET_FIELD(_fid, FNUM) - SMC64_##_range##_FNUM_MIN)
131
132/* Implementation defined FID values */
133 /* 0x18F */
134#define SMC_RMM_REQ_COMPLETE SMC64_STD_FID(RMI, U(0x3F))
135
136 /* 0x1B0 - 0x1B3 */
137#define SMC_ASC_MARK_SECURE SMC64_STD_FID(RMM_EL3, U(0))
138#define SMC_ASC_MARK_NONSECURE SMC64_STD_FID(RMM_EL3, U(1))
139
140/* 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 */
161#define SMC_SUCCESS 0
162#define SMC_NOT_SUPPORTED (-1)
163#define SMC_NOT_REQUIRED (-2)
164#define SMC_INVALID_PARAMETER (-3)
165
166#define SMC_UNKNOWN (-1)
167
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 */