1 /* SPDX-License-Identifier: GPL-2.0-only */
2 /*
3 * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
4 */
5
6 #ifndef QCOMTEE_MSG_H
7 #define QCOMTEE_MSG_H
8
9 #include <linux/bitfield.h>
10
11 /**
12 * DOC: ''Qualcomm TEE'' (QTEE) Transport Message
13 *
14 * There are two buffers shared with QTEE: inbound and outbound buffers.
15 * The inbound buffer is used for direct object invocation, and the outbound
16 * buffer is used to make a request from QTEE to the kernel; i.e., a callback
17 * request.
18 *
19 * The unused tail of the outbound buffer is also used for sending and
20 * receiving asynchronous messages. An asynchronous message is independent of
21 * the current object invocation (i.e., contents of the inbound buffer) or
22 * callback request (i.e., the head of the outbound buffer); see
23 * qcomtee_get_async_buffer(). It is used by endpoints (QTEE or kernel) as an
24 * optimization to reduce the number of context switches between the secure and
25 * non-secure worlds.
26 *
27 * For instance, QTEE never sends an explicit callback request to release an
28 * object in the kernel. Instead, it sends asynchronous release messages in the
29 * outbound buffer when QTEE returns from the previous direct object invocation,
30 * or appends asynchronous release messages after the current callback request.
31 *
32 * QTEE supports two types of arguments in a message: buffer and object
33 * arguments. Depending on the direction of data flow, they could be input
34 * buffer (IO) to QTEE, output buffer (OB) from QTEE, input object (IO) to QTEE,
35 * or output object (OO) from QTEE. Object arguments hold object IDs. Buffer
36 * arguments hold (offset, size) pairs into the inbound or outbound buffers.
37 *
38 * QTEE holds an object table for objects it hosts and exposes to the kernel.
39 * An object ID is an index to the object table in QTEE.
40 *
41 * For the direct object invocation message format in the inbound buffer, see
42 * &struct qcomtee_msg_object_invoke. For the callback request message format
43 * in the outbound buffer, see &struct qcomtee_msg_callback. For the message
44 * format for asynchronous messages in the outbound buffer, see
45 * &struct qcomtee_async_msg_hdr.
46 */
47
48 /**
49 * define QCOMTEE_MSG_OBJECT_NS_BIT - Non-secure bit
50 *
51 * Object ID is a globally unique 32-bit number. IDs referencing objects
52 * in the kernel should have %QCOMTEE_MSG_OBJECT_NS_BIT set.
53 */
54 #define QCOMTEE_MSG_OBJECT_NS_BIT BIT(31)
55
56 /* Static object IDs recognized by QTEE. */
57 #define QCOMTEE_MSG_OBJECT_NULL (0U)
58 #define QCOMTEE_MSG_OBJECT_ROOT (1U)
59
60 /* Definitions from QTEE as part of the transport protocol. */
61
62 /* qcomtee_msg_arg is an argument as recognized by QTEE. */
63 union qcomtee_msg_arg {
64 struct {
65 u32 offset;
66 u32 size;
67 } b;
68 u32 o;
69 };
70
71 /* BI and BO payloads in QTEE messages should be at 64-bit boundaries. */
72 #define qcomtee_msg_offset_align(o) ALIGN((o), sizeof(u64))
73
74 /* Operations for objects are 32-bit. Transport uses the upper 16 bits. */
75 #define QCOMTEE_MSG_OBJECT_OP_MASK GENMASK(15, 0)
76
77 /* Reserved Operation IDs sent to QTEE: */
78 /* QCOMTEE_MSG_OBJECT_OP_RELEASE - Reduces the refcount and releases the object.
79 * QCOMTEE_MSG_OBJECT_OP_RETAIN - Increases the refcount.
80 *
81 * These operation IDs are valid for all objects.
82 */
83
84 #define QCOMTEE_MSG_OBJECT_OP_RELEASE (QCOMTEE_MSG_OBJECT_OP_MASK - 0)
85 #define QCOMTEE_MSG_OBJECT_OP_RETAIN (QCOMTEE_MSG_OBJECT_OP_MASK - 1)
86
87 /* Subset of operations supported by QTEE root object. */
88
89 #define QCOMTEE_ROOT_OP_REG_WITH_CREDENTIALS 5
90 #define QCOMTEE_ROOT_OP_NOTIFY_DOMAIN_CHANGE 4
91 #define QCOMTEE_ROOT_OP_ADCI_ACCEPT 8
92 #define QCOMTEE_ROOT_OP_ADCI_SHUTDOWN 9
93
94 /* Subset of operations supported by client_env object. */
95
96 #define QCOMTEE_CLIENT_ENV_OPEN 0
97
98 /* List of available QTEE service UIDs and subset of operations. */
99
100 #define QCOMTEE_FEATURE_VER_UID 2033
101 #define QCOMTEE_FEATURE_VER_OP_GET 0
102 /* Get QTEE version number. */
103 #define QCOMTEE_FEATURE_VER_OP_GET_QTEE_ID 10
104 #define QTEE_VERSION_GET_MAJOR(x) (((x) >> 22) & 0xffU)
105 #define QTEE_VERSION_GET_MINOR(x) (((x) >> 12) & 0xffU)
106 #define QTEE_VERSION_GET_PATCH(x) ((x) >> 0 & 0xfffU)
107
108 /* Response types as returned from qcomtee_object_invoke_ctx_invoke(). */
109
110 /* The message contains a callback request. */
111 #define QCOMTEE_RESULT_INBOUND_REQ_NEEDED 3
112
113 /**
114 * struct qcomtee_msg_object_invoke - Direct object invocation message.
115 * @ctx: object ID hosted in QTEE.
116 * @op: operation for the object.
117 * @counts: number of different types of arguments in @args.
118 * @args: array of arguments.
119 *
120 * @counts consists of 4 * 4-bit fields. Bits 0 - 3 represent the number of
121 * input buffers, bits 4 - 7 represent the number of output buffers,
122 * bits 8 - 11 represent the number of input objects, and bits 12 - 15
123 * represent the number of output objects. The remaining bits should be zero.
124 *
125 * 15 12 11 8 7 4 3 0
126 * +----------------+----------------+----------------+----------------+
127 * | #OO objects | #IO objects | #OB buffers | #IB buffers |
128 * +----------------+----------------+----------------+----------------+
129 *
130 * The maximum number of arguments of each type is defined by
131 * %QCOMTEE_ARGS_PER_TYPE.
132 */
133 struct qcomtee_msg_object_invoke {
134 u32 cxt;
135 u32 op;
136 u32 counts;
137 union qcomtee_msg_arg args[];
138 };
139
140 /* Bit masks for the four 4-bit nibbles holding the counts. */
141 #define QCOMTEE_MASK_IB GENMASK(3, 0)
142 #define QCOMTEE_MASK_OB GENMASK(7, 4)
143 #define QCOMTEE_MASK_IO GENMASK(11, 8)
144 #define QCOMTEE_MASK_OO GENMASK(15, 12)
145
146 /**
147 * struct qcomtee_msg_callback - Callback request message.
148 * @result: result of operation @op on the object referenced by @cxt.
149 * @cxt: object ID hosted in the kernel.
150 * @op: operation for the object.
151 * @counts: number of different types of arguments in @args.
152 * @args: array of arguments.
153 *
154 * For details of @counts, see &qcomtee_msg_object_invoke.counts.
155 */
156 struct qcomtee_msg_callback {
157 u32 result;
158 u32 cxt;
159 u32 op;
160 u32 counts;
161 union qcomtee_msg_arg args[];
162 };
163
164 /* Offset in the message for the beginning of the buffer argument's contents. */
165 #define qcomtee_msg_buffer_args(t, n) \
166 qcomtee_msg_offset_align(struct_size_t(t, args, n))
167 /* Pointer to the beginning of a buffer argument's content at an offset. */
168 #define qcomtee_msg_offset_to_ptr(m, off) ((void *)&((char *)(m))[(off)])
169
170 /* Some helpers to manage msg.counts. */
171
qcomtee_msg_num_ib(u32 counts)172 static inline unsigned int qcomtee_msg_num_ib(u32 counts)
173 {
174 return FIELD_GET(QCOMTEE_MASK_IB, counts);
175 }
176
qcomtee_msg_num_ob(u32 counts)177 static inline unsigned int qcomtee_msg_num_ob(u32 counts)
178 {
179 return FIELD_GET(QCOMTEE_MASK_OB, counts);
180 }
181
qcomtee_msg_num_io(u32 counts)182 static inline unsigned int qcomtee_msg_num_io(u32 counts)
183 {
184 return FIELD_GET(QCOMTEE_MASK_IO, counts);
185 }
186
qcomtee_msg_num_oo(u32 counts)187 static inline unsigned int qcomtee_msg_num_oo(u32 counts)
188 {
189 return FIELD_GET(QCOMTEE_MASK_OO, counts);
190 }
191
qcomtee_msg_idx_ib(u32 counts)192 static inline unsigned int qcomtee_msg_idx_ib(u32 counts)
193 {
194 return 0;
195 }
196
qcomtee_msg_idx_ob(u32 counts)197 static inline unsigned int qcomtee_msg_idx_ob(u32 counts)
198 {
199 return qcomtee_msg_num_ib(counts);
200 }
201
qcomtee_msg_idx_io(u32 counts)202 static inline unsigned int qcomtee_msg_idx_io(u32 counts)
203 {
204 return qcomtee_msg_idx_ob(counts) + qcomtee_msg_num_ob(counts);
205 }
206
qcomtee_msg_idx_oo(u32 counts)207 static inline unsigned int qcomtee_msg_idx_oo(u32 counts)
208 {
209 return qcomtee_msg_idx_io(counts) + qcomtee_msg_num_io(counts);
210 }
211
212 #define qcomtee_msg_for_each(i, first, num) \
213 for ((i) = (first); (i) < (first) + (num); (i)++)
214
215 #define qcomtee_msg_for_each_input_buffer(i, m) \
216 qcomtee_msg_for_each(i, qcomtee_msg_idx_ib((m)->counts), \
217 qcomtee_msg_num_ib((m)->counts))
218
219 #define qcomtee_msg_for_each_output_buffer(i, m) \
220 qcomtee_msg_for_each(i, qcomtee_msg_idx_ob((m)->counts), \
221 qcomtee_msg_num_ob((m)->counts))
222
223 #define qcomtee_msg_for_each_input_object(i, m) \
224 qcomtee_msg_for_each(i, qcomtee_msg_idx_io((m)->counts), \
225 qcomtee_msg_num_io((m)->counts))
226
227 #define qcomtee_msg_for_each_output_object(i, m) \
228 qcomtee_msg_for_each(i, qcomtee_msg_idx_oo((m)->counts), \
229 qcomtee_msg_num_oo((m)->counts))
230
231 /* Sum of arguments in a message. */
232 #define qcomtee_msg_args(m) \
233 (qcomtee_msg_idx_oo((m)->counts) + qcomtee_msg_num_oo((m)->counts))
234
qcomtee_msg_init(struct qcomtee_msg_object_invoke * msg,u32 cxt,u32 op,int in_buffer,int out_buffer,int in_object,int out_object)235 static inline void qcomtee_msg_init(struct qcomtee_msg_object_invoke *msg,
236 u32 cxt, u32 op, int in_buffer,
237 int out_buffer, int in_object,
238 int out_object)
239 {
240 u32 counts = 0;
241
242 counts |= (in_buffer & 0xfU);
243 counts |= ((out_buffer - in_buffer) & 0xfU) << 4;
244 counts |= ((in_object - out_buffer) & 0xfU) << 8;
245 counts |= ((out_object - in_object) & 0xfU) << 12;
246
247 msg->cxt = cxt;
248 msg->op = op;
249 msg->counts = counts;
250 }
251
252 /* Generic error codes. */
253 #define QCOMTEE_MSG_OK 0 /* non-specific success code. */
254 #define QCOMTEE_MSG_ERROR 1 /* non-specific error. */
255 #define QCOMTEE_MSG_ERROR_INVALID 2 /* unsupported/unrecognized request. */
256 #define QCOMTEE_MSG_ERROR_SIZE_IN 3 /* supplied buffer/string too large. */
257 #define QCOMTEE_MSG_ERROR_SIZE_OUT 4 /* supplied output buffer too small. */
258 #define QCOMTEE_MSG_ERROR_USERBASE 10 /* start of user-defined error range. */
259
260 /* Transport layer error codes. */
261 #define QCOMTEE_MSG_ERROR_DEFUNCT -90 /* object no longer exists. */
262 #define QCOMTEE_MSG_ERROR_ABORT -91 /* calling thread must exit. */
263 #define QCOMTEE_MSG_ERROR_BADOBJ -92 /* invalid object context. */
264 #define QCOMTEE_MSG_ERROR_NOSLOTS -93 /* caller's object table full. */
265 #define QCOMTEE_MSG_ERROR_MAXARGS -94 /* too many args. */
266 #define QCOMTEE_MSG_ERROR_MAXDATA -95 /* buffers too large. */
267 #define QCOMTEE_MSG_ERROR_UNAVAIL -96 /* the request could not be processed. */
268 #define QCOMTEE_MSG_ERROR_KMEM -97 /* kernel out of memory. */
269 #define QCOMTEE_MSG_ERROR_REMOTE -98 /* local method sent to remote object. */
270 #define QCOMTEE_MSG_ERROR_BUSY -99 /* Object is busy. */
271 #define QCOMTEE_MSG_ERROR_TIMEOUT -103 /* Call Back Object invocation timed out. */
272
qcomtee_msg_set_result(struct qcomtee_msg_callback * cb_msg,int err)273 static inline void qcomtee_msg_set_result(struct qcomtee_msg_callback *cb_msg,
274 int err)
275 {
276 if (!err) {
277 cb_msg->result = QCOMTEE_MSG_OK;
278 } else if (err < 0) {
279 /* If err < 0, then it is a transport error. */
280 switch (err) {
281 case -ENOMEM:
282 cb_msg->result = QCOMTEE_MSG_ERROR_KMEM;
283 break;
284 case -ENODEV:
285 cb_msg->result = QCOMTEE_MSG_ERROR_DEFUNCT;
286 break;
287 case -ENOSPC:
288 case -EBUSY:
289 cb_msg->result = QCOMTEE_MSG_ERROR_BUSY;
290 break;
291 case -EBADF:
292 case -EINVAL:
293 cb_msg->result = QCOMTEE_MSG_ERROR_UNAVAIL;
294 break;
295 default:
296 cb_msg->result = QCOMTEE_MSG_ERROR;
297 }
298 } else {
299 /* If err > 0, then it is user defined error, pass it as is. */
300 cb_msg->result = err;
301 }
302 }
303
304 #endif /* QCOMTEE_MSG_H */
305