1 /*
2  * Copyright (c) 2023 EPAM Systems
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 /**
8  * @addtogroup t_optee_driver
9  * @{
10  * @defgroup t_optee_driver test_optee_driver
11  * @}
12  */
13 
14 #include <zephyr/arch/arm64/arm-smccc.h>
15 #include <zephyr/kernel.h>
16 #include <zephyr/ztest.h>
17 #include <zephyr/device.h>
18 
19 #include <zephyr/drivers/tee.h>
20 #include <optee_msg.h>
21 #include <optee_smc.h>
22 #include <optee_rpc_cmd.h>
23 
24 /*
25  * TODO: Test shm_register/shm_register API to work with huge
26  * buffers (more than 512K) to ensure that optee_construct_page_list
27  * builds correct page list.
28  */
29 
30 #define TEE_OPTEE_CAP_TZ BIT(0)
31 
32 typedef void (*smc_cb_t)(unsigned long a0, unsigned long a1, unsigned long a2, unsigned long a3,
33 			 unsigned long a4, unsigned long a5, unsigned long a6, unsigned long a7,
34 			 struct arm_smccc_res *res);
35 
36 static struct test_call {
37 	int num;
38 	int pending;
39 	smc_cb_t smc_cb;
40 	uint32_t a0;
41 	uint32_t a1;
42 	uint32_t a2;
43 	uint32_t a3;
44 	uint32_t a4;
45 	uint32_t a5;
46 	uint32_t a6;
47 	uint32_t a7;
48 	k_tid_t th_id;
49 } t_call;
50 
51 static struct test_call wait_call;
52 static struct test_call send_call;
53 
arm_smccc_smc(unsigned long a0,unsigned long a1,unsigned long a2,unsigned long a3,unsigned long a4,unsigned long a5,unsigned long a6,unsigned long a7,struct arm_smccc_res * res)54 void arm_smccc_smc(unsigned long a0, unsigned long a1, unsigned long a2, unsigned long a3,
55 		   unsigned long a4, unsigned long a5, unsigned long a6, unsigned long a7,
56 		   struct arm_smccc_res *res)
57 {
58 	if (a0 == OPTEE_SMC_CALLS_UID) {
59 		res->a0 = OPTEE_MSG_UID_0;
60 		res->a1 = OPTEE_MSG_UID_1;
61 		res->a2 = OPTEE_MSG_UID_2;
62 		res->a3 = OPTEE_MSG_UID_3;
63 		return;
64 	}
65 
66 	if (a0 == OPTEE_SMC_EXCHANGE_CAPABILITIES) {
67 		res->a1 = OPTEE_SMC_SEC_CAP_DYNAMIC_SHM;
68 		return;
69 	}
70 	if (a0 == OPTEE_SMC_GET_THREAD_COUNT) {
71 		res->a1 = 5;
72 		return;
73 	}
74 	if (t_call.pending && t_call.smc_cb) {
75 		t_call.smc_cb(a0, a1, a2, a3, a4, a5, a6, a7, res);
76 	}
77 	if (wait_call.pending && wait_call.smc_cb && (k_current_get() == wait_call.th_id)) {
78 		wait_call.smc_cb(a0, a1, a2, a3, a4, a5, a6, a7, res);
79 	}
80 	if (send_call.pending && send_call.smc_cb) {
81 		send_call.smc_cb(a0, a1, a2, a3, a4, a5, a6, a7, res);
82 	}
83 }
84 
85 /* Allocate dummy arm_smccc_hvc function for the tests */
arm_smccc_hvc(unsigned long a0,unsigned long a1,unsigned long a2,unsigned long a3,unsigned long a4,unsigned long a5,unsigned long a6,unsigned long a7,struct arm_smccc_res * res)86 void arm_smccc_hvc(unsigned long a0, unsigned long a1, unsigned long a2, unsigned long a3,
87 		   unsigned long a4, unsigned long a5, unsigned long a6, unsigned long a7,
88 		   struct arm_smccc_res *res)
89 {
90 }
91 
ZTEST(optee_test_suite,test_get_version)92 ZTEST(optee_test_suite, test_get_version)
93 {
94 	int ret;
95 	struct tee_version_info info;
96 	const struct device *const dev = DEVICE_DT_GET_ONE(linaro_optee_tz);
97 
98 	zassert_not_null(dev, "Unable to get dev");
99 
100 	ret = tee_get_version(dev, NULL);
101 	zassert_equal(ret, -EINVAL, "tee_get_version failed with code %d", ret);
102 
103 	ret = tee_get_version(dev, &info);
104 	zassert_ok(ret, "tee_get_version failed with code %d", ret);
105 	zassert_equal(info.impl_id, 1, "Wrong impl_id");
106 	zassert_equal(info.impl_caps, TEE_OPTEE_CAP_TZ, "Wrong impl_caps");
107 	zassert_equal(info.gen_caps, TEE_GEN_CAP_GP | TEE_GEN_CAP_REG_MEM,
108 		      "Wrong gen_caps");
109 
110 	ret = tee_get_version(dev, NULL);
111 	zassert_equal(ret, -EINVAL, "tee_get_version failed with code %d", ret);
112 }
113 
fast_call(unsigned long a0,unsigned long a1,unsigned long a2,unsigned long a3,unsigned long a4,unsigned long a5,unsigned long a6,unsigned long a7,struct arm_smccc_res * res)114 void fast_call(unsigned long a0, unsigned long a1, unsigned long a2, unsigned long a3,
115 	       unsigned long a4, unsigned long a5, unsigned long a6, unsigned long a7,
116 	       struct arm_smccc_res *res)
117 {
118 	t_call.a0 = a0;
119 	t_call.a1 = a1;
120 	t_call.a2 = a2;
121 	t_call.a3 = a3;
122 	t_call.a4 = a4;
123 	t_call.a5 = a5;
124 	t_call.a6 = a6;
125 	t_call.a7 = a7;
126 
127 	res->a0 = OPTEE_SMC_RETURN_OK;
128 }
129 
fail_call(unsigned long a0,unsigned long a1,unsigned long a2,unsigned long a3,unsigned long a4,unsigned long a5,unsigned long a6,unsigned long a7,struct arm_smccc_res * res)130 void fail_call(unsigned long a0, unsigned long a1, unsigned long a2, unsigned long a3,
131 	       unsigned long a4, unsigned long a5, unsigned long a6, unsigned long a7,
132 	       struct arm_smccc_res *res)
133 {
134 	res->a0 = OPTEE_SMC_RETURN_EBUSY;
135 }
136 
ZTEST(optee_test_suite,test_fast_calls)137 ZTEST(optee_test_suite, test_fast_calls)
138 {
139 	int ret;
140 	uint32_t session_id;
141 	struct tee_open_session_arg arg = {};
142 	struct tee_param param = {};
143 	const struct device *const dev = DEVICE_DT_GET_ONE(linaro_optee_tz);
144 
145 	zassert_not_null(dev, "Unable to get dev");
146 
147 	t_call.pending = 1;
148 	t_call.num = 0;
149 	t_call.smc_cb = fast_call;
150 
151 	/* Fail pass */
152 	ret = tee_open_session(dev, NULL, 0, NULL, &session_id);
153 	zassert_equal(ret, -EINVAL, "tee_open_session failed with code %d", ret);
154 
155 	ret = tee_open_session(dev, NULL, 0, NULL, NULL);
156 	zassert_equal(ret, -EINVAL, "tee_open_session failed with code %d", ret);
157 
158 	/* Happy pass */
159 	arg.uuid[0] = 111;
160 	arg.clnt_uuid[0] = 222;
161 	arg.clnt_login = TEEC_LOGIN_PUBLIC;
162 	param.attr = TEE_PARAM_ATTR_TYPE_NONE;
163 	param.a = 3333;
164 	ret = tee_open_session(dev, &arg, 1, &param, &session_id);
165 	zassert_ok(ret, "tee_open_session failed with code %d", ret);
166 
167 	ret = tee_close_session(dev, session_id);
168 	zassert_ok(ret, "close_session failed with code %d", ret);
169 	t_call.pending = 0;
170 }
171 
ZTEST(optee_test_suite,test_invoke_fn)172 ZTEST(optee_test_suite, test_invoke_fn)
173 {
174 	int ret;
175 	uint32_t session_id;
176 	struct tee_open_session_arg arg = {};
177 	struct tee_invoke_func_arg invoke_arg = {};
178 	struct tee_param param = {};
179 	const struct device *const dev = DEVICE_DT_GET_ONE(linaro_optee_tz);
180 
181 	zassert_not_null(dev, "Unable to get dev");
182 
183 	t_call.pending = 1;
184 	t_call.num = 0;
185 	t_call.smc_cb = fast_call;
186 
187 	/* Fail pass */
188 	ret = tee_invoke_func(dev, NULL, 0, NULL);
189 	zassert_equal(ret, -EINVAL, "tee_invoke_fn failed with code %d", ret);
190 
191 	t_call.smc_cb = fail_call;
192 
193 	invoke_arg.func = 12;
194 	invoke_arg.session = 1;
195 	ret = tee_invoke_func(dev, &invoke_arg, 0, NULL);
196 	zassert_equal(ret, -EINVAL, "tee_invoke_fn failed with code %d", ret);
197 
198 	t_call.smc_cb = fast_call;
199 
200 	/* Happy pass */
201 	arg.uuid[0] = 111;
202 	arg.clnt_uuid[0] = 222;
203 	arg.clnt_login = TEEC_LOGIN_PUBLIC;
204 	param.attr = TEE_PARAM_ATTR_TYPE_NONE;
205 	param.a = 3333;
206 	ret = tee_open_session(dev, &arg, 1, &param, &session_id);
207 	zassert_ok(ret, "tee_open_session failed with code %d", ret);
208 
209 	invoke_arg.func = 12;
210 	invoke_arg.session = 1;
211 	ret = tee_invoke_func(dev, &invoke_arg, 1, &param);
212 	zassert_ok(ret, "tee_invoke_fn failed with code %d", ret);
213 
214 	ret = tee_close_session(dev, session_id);
215 	zassert_ok(ret, "close_session failed with code %d", ret);
216 	t_call.pending = 0;
217 }
218 
ZTEST(optee_test_suite,test_cancel)219 ZTEST(optee_test_suite, test_cancel)
220 {
221 	int ret;
222 	uint32_t session_id;
223 	struct tee_open_session_arg arg = {};
224 	struct tee_param param = {};
225 	const struct device *const dev = DEVICE_DT_GET_ONE(linaro_optee_tz);
226 
227 	zassert_not_null(dev, "Unable to get dev");
228 
229 	t_call.pending = 1;
230 	t_call.num = 0;
231 	t_call.smc_cb = fast_call;
232 
233 	arg.uuid[0] = 111;
234 	arg.clnt_uuid[0] = 222;
235 	arg.clnt_login = TEEC_LOGIN_PUBLIC;
236 	param.attr = TEE_PARAM_ATTR_TYPE_NONE;
237 	param.a = 3333;
238 	ret = tee_open_session(dev, &arg, 1, &param, &session_id);
239 	zassert_ok(ret, "tee_open_session failed with code %d", ret);
240 
241 	ret = tee_cancel(dev, 1, 25);
242 	zassert_ok(ret, "tee_cancel failed with code %d", ret);
243 
244 	ret = tee_close_session(dev, session_id);
245 	zassert_ok(ret, "close_session failed with code %d", ret);
246 	t_call.pending = 0;
247 }
248 
normal_call(unsigned long a0,unsigned long a1,unsigned long a2,unsigned long a3,unsigned long a4,unsigned long a5,unsigned long a6,unsigned long a7,struct arm_smccc_res * res)249 void normal_call(unsigned long a0, unsigned long a1, unsigned long a2, unsigned long a3,
250 		 unsigned long a4, unsigned long a5, unsigned long a6, unsigned long a7,
251 		 struct arm_smccc_res *res)
252 {
253 	t_call.a0 = a0;
254 	t_call.a1 = a1;
255 	t_call.a2 = a2;
256 	t_call.a3 = a3;
257 	t_call.a4 = a4;
258 	t_call.a5 = a5;
259 	t_call.a6 = a6;
260 	t_call.a7 = a7;
261 
262 	switch (t_call.num) {
263 	case 0:
264 		res->a0 = OPTEE_SMC_RETURN_RPC_PREFIX | OPTEE_SMC_RPC_FUNC_ALLOC;
265 		res->a1 = a4;
266 		res->a2 = a5;
267 		res->a3 = a3;
268 		res->a4 = 0;
269 		res->a5 = 0;
270 		break;
271 	case 1:
272 		zassert_equal(a0, 0x32000003, "%s failed with ret %lx", __func__, a0);
273 		res->a0 = OPTEE_SMC_RETURN_RPC_PREFIX | OPTEE_SMC_RPC_FUNC_FREE;
274 		res->a1 = a1;
275 		res->a2 = a2;
276 		res->a3 = a3;
277 		res->a4 = a4;
278 		res->a5 = a5;
279 		break;
280 	case 2:
281 		zassert_equal(a0, 0x32000003, "%s failed with ret %lx", __func__, a0);
282 		res->a0 = OPTEE_SMC_RETURN_RPC_PREFIX | OPTEE_SMC_RPC_FUNC_FOREIGN_INTR;
283 		break;
284 	default:
285 		zassert_equal(a0, 0x32000003, "%s failed with ret %lx", __func__, a0);
286 		res->a0 = OPTEE_SMC_RETURN_OK;
287 	}
288 
289 	t_call.num++;
290 }
291 
ZTEST(optee_test_suite,test_normal_calls)292 ZTEST(optee_test_suite, test_normal_calls)
293 {
294 	int ret;
295 	uint32_t session_id;
296 	struct tee_open_session_arg arg = {};
297 	struct tee_param param = {};
298 	const struct device *const dev = DEVICE_DT_GET_ONE(linaro_optee_tz);
299 
300 	zassert_not_null(dev, "Unable to get dev");
301 
302 	t_call.pending = 1;
303 	t_call.num = 0;
304 	t_call.smc_cb = normal_call;
305 
306 	arg.uuid[0] = 111;
307 	arg.clnt_uuid[0] = 222;
308 	arg.clnt_login = TEEC_LOGIN_PUBLIC;
309 	param.attr = TEE_PARAM_ATTR_TYPE_NONE;
310 	param.a = 3333;
311 	ret = tee_open_session(dev, &arg, 1, &param, &session_id);
312 	zassert_ok(ret, "tee_open_session failed with code %d", ret);
313 
314 	t_call.num = 0;
315 
316 	ret = tee_close_session(dev, session_id);
317 	zassert_ok(ret, "close_session failed with code %d", ret);
318 	t_call.pending = 0;
319 }
320 
ZTEST(optee_test_suite,test_reg_unreg)321 ZTEST(optee_test_suite, test_reg_unreg)
322 {
323 	int ret;
324 	int addr;
325 	struct tee_shm *shm = NULL;
326 	const struct device *const dev = DEVICE_DT_GET_ONE(linaro_optee_tz);
327 
328 	t_call.pending = 1;
329 	t_call.num = 0;
330 	t_call.smc_cb = normal_call;
331 	zassert_not_null(dev, "Unable to get dev");
332 
333 	/* Fail pass */
334 	ret = tee_shm_register(dev, &addr, 1, 0, NULL);
335 	zassert_equal(ret, -EINVAL, "tee_shm_register failed with code %d", ret);
336 	t_call.num = 0;
337 
338 	ret = tee_shm_register(dev, NULL, 1, 0, &shm);
339 	zassert_equal(ret, -ENOMEM, "tee_shm_register failed with code %d", ret);
340 
341 	t_call.num = 0;
342 	ret = tee_shm_register(dev, &addr, 1, 0, NULL);
343 	zassert_equal(ret, -EINVAL, "tee_shm_register failed with code %d", ret);
344 
345 	t_call.num = 0;
346 	ret = tee_shm_register(dev, &addr, 0, 0, &shm);
347 	zassert_equal(ret, 0, "tee_shm_register failed with code %d", ret);
348 
349 	t_call.num = 0;
350 	ret = tee_shm_unregister(dev, NULL);
351 	zassert_equal(ret, -EINVAL, "tee_shm_unregister failed with code %d", ret);
352 
353 	/* Happy pass */
354 	t_call.num = 0;
355 	ret = tee_shm_register(dev, &addr, 1, 0, &shm);
356 	zassert_ok(ret, "tee_shm_register failed with code %d", ret);
357 
358 	t_call.num = 0;
359 	ret = tee_shm_unregister(dev, shm);
360 	zassert_ok(ret, "tee_shm_unregister failed with code %d", ret);
361 
362 	t_call.num = 0;
363 	ret = tee_shm_alloc(dev, 1, 0, &shm);
364 	zassert_ok(ret, "tee_shm_alloc failed with code %d", ret);
365 
366 	t_call.num = 0;
367 	ret = tee_shm_free(dev, shm);
368 	zassert_ok(ret, "tee_shm_free failed with code %d", ret);
369 	t_call.pending = 0;
370 }
371 
regs_to_u64(uint32_t reg0,uint32_t reg1)372 static uint64_t regs_to_u64(uint32_t reg0, uint32_t reg1)
373 {
374 	return (uint64_t)(((uint64_t)reg0 << 32) | reg1);
375 }
376 
u64_to_regs(uint64_t val,unsigned long * reg0,unsigned long * reg1)377 static void u64_to_regs(uint64_t val, unsigned long *reg0, unsigned long *reg1)
378 {
379 	*reg0 = val >> 32;
380 	*reg1 = val;
381 }
382 
383 uint64_t g_shm_ref;
384 uint64_t g_func_shm_ref;
385 
cmd_alloc_free_call(unsigned long a0,unsigned long a1,unsigned long a2,unsigned long a3,unsigned long a4,unsigned long a5,unsigned long a6,unsigned long a7,struct arm_smccc_res * res)386 void cmd_alloc_free_call(unsigned long a0, unsigned long a1, unsigned long a2, unsigned long a3,
387 			 unsigned long a4, unsigned long a5, unsigned long a6, unsigned long a7,
388 			 struct arm_smccc_res *res)
389 {
390 	struct optee_msg_arg *arg;
391 	struct tee_shm *shm;
392 
393 	t_call.a0 = a0;
394 	t_call.a1 = a1;
395 	t_call.a2 = a2;
396 	t_call.a3 = a3;
397 	t_call.a4 = a4;
398 	t_call.a5 = a5;
399 	t_call.a6 = a6;
400 	t_call.a7 = a7;
401 
402 	res->a1 = a1;
403 	res->a2 = a2;
404 	res->a3 = a3;
405 	res->a4 = a4;
406 	res->a5 = a5;
407 
408 	switch (t_call.num) {
409 	case 0:
410 		res->a0 = OPTEE_SMC_RETURN_RPC_PREFIX | OPTEE_SMC_RPC_FUNC_ALLOC;
411 		res->a1 = 1;
412 		break;
413 	case 1:
414 		zassert_equal(a0, 0x32000003, "%s failed with ret %lx", __func__, a0);
415 		res->a0 = OPTEE_SMC_RETURN_RPC_PREFIX | OPTEE_SMC_RPC_FUNC_CMD;
416 		arg = (struct optee_msg_arg *)regs_to_u64(a1, a2);
417 		arg->cmd = OPTEE_RPC_CMD_SHM_ALLOC;
418 		arg->num_params = 1;
419 		arg->params[0].attr = OPTEE_MSG_ATTR_TYPE_VALUE_INPUT;
420 		arg->params[0].u.value.b = 4096;
421 		arg->params[0].u.value.a = OPTEE_RPC_SHM_TYPE_KERNEL;
422 		res->a1 = a4;
423 		res->a2 = a5;
424 		g_shm_ref = regs_to_u64(a4, a5);
425 		break;
426 	case 2:
427 		zassert_equal(a0, 0x32000003, "%s failed with ret %lx", __func__, a0);
428 		res->a0 = OPTEE_SMC_RETURN_RPC_PREFIX | OPTEE_SMC_RPC_FUNC_CMD;
429 		printk("a1 %lx, a2 %lx a4 %lx a5 %lx\n", a1, a2);
430 		shm = (struct tee_shm *)regs_to_u64(a1, a2);
431 		arg = (struct optee_msg_arg *)shm->addr;
432 		arg->cmd = OPTEE_RPC_CMD_SHM_FREE;
433 		arg->num_params = 1;
434 		arg->params[0].attr = OPTEE_MSG_ATTR_TYPE_VALUE_INPUT;
435 		arg->params[0].u.value.a = OPTEE_RPC_SHM_TYPE_KERNEL;
436 		arg->params[0].u.value.b = g_func_shm_ref;
437 		u64_to_regs(g_shm_ref, &res->a1, &res->a2);
438 		break;
439 	case 3:
440 		zassert_equal(a0, 0x32000003, "%s failed with ret %lx", __func__, a0);
441 		u64_to_regs(g_shm_ref, &res->a1, &res->a2);
442 		res->a0 = OPTEE_SMC_RETURN_RPC_PREFIX | OPTEE_SMC_RPC_FUNC_FREE;
443 		break;
444 	case 4:
445 		zassert_equal(a0, 0x32000003, "%s failed with ret %lx", __func__, a0);
446 		res->a0 = OPTEE_SMC_RETURN_OK;
447 		break;
448 	default:
449 		zassert_equal(a0, 0x32000003, "%s failed with ret %lx", __func__, a0);
450 		res->a0 = OPTEE_SMC_RETURN_OK;
451 	}
452 
453 	t_call.num++;
454 }
455 
ZTEST(optee_test_suite,test_func_shm_alloc)456 ZTEST(optee_test_suite, test_func_shm_alloc)
457 {
458 	int ret;
459 	uint32_t session_id;
460 	struct tee_open_session_arg arg = {};
461 	struct tee_invoke_func_arg invoke_arg = {};
462 	struct tee_param param = {};
463 	const struct device *const dev = DEVICE_DT_GET_ONE(linaro_optee_tz);
464 
465 	zassert_not_null(dev, "Unable to get dev");
466 
467 	t_call.pending = 1;
468 	t_call.num = 0;
469 	t_call.smc_cb = fast_call;
470 
471 	arg.uuid[0] = 111;
472 	arg.clnt_uuid[0] = 222;
473 	arg.clnt_login = TEEC_LOGIN_PUBLIC;
474 	param.attr = TEE_PARAM_ATTR_TYPE_NONE;
475 	param.a = 3333;
476 	ret = tee_open_session(dev, &arg, 1, &param, &session_id);
477 	zassert_ok(ret, "tee_open_session failed with code %d", ret);
478 
479 	t_call.num = 0;
480 	t_call.smc_cb = cmd_alloc_free_call;
481 
482 	invoke_arg.func = 12;
483 	invoke_arg.session = 1;
484 	ret = tee_invoke_func(dev, &invoke_arg, 1, &param);
485 	zassert_ok(ret, "tee_invoke_fn failed with code %d", ret);
486 
487 	t_call.num = 0;
488 	t_call.smc_cb = fast_call;
489 
490 	ret = tee_close_session(dev, session_id);
491 	zassert_ok(ret, "close_session failed with code %d", ret);
492 
493 	t_call.pending = 0;
494 }
495 
496 K_KERNEL_STACK_DEFINE(supp_stack, 8192);
497 #define TEE_NUM_PARAMS 5
498 static struct k_thread supp_thread_data;
499 volatile int supp_thread_ok;
500 
cmd_rpc_call(unsigned long a0,unsigned long a1,unsigned long a2,unsigned long a3,unsigned long a4,unsigned long a5,unsigned long a6,unsigned long a7,struct arm_smccc_res * res)501 void cmd_rpc_call(unsigned long a0, unsigned long a1, unsigned long a2, unsigned long a3,
502 		  unsigned long a4, unsigned long a5, unsigned long a6, unsigned long a7,
503 		  struct arm_smccc_res *res)
504 {
505 	struct optee_msg_arg *arg;
506 	struct tee_shm *shm;
507 
508 	t_call.a0 = a0;
509 	t_call.a1 = a1;
510 	t_call.a2 = a2;
511 	t_call.a3 = a3;
512 	t_call.a4 = a4;
513 	t_call.a5 = a5;
514 	t_call.a6 = a6;
515 	t_call.a7 = a7;
516 
517 	res->a1 = a1;
518 	res->a2 = a2;
519 	res->a3 = a3;
520 	res->a4 = a4;
521 	res->a5 = a5;
522 
523 	switch (t_call.num) {
524 	case 0:
525 		res->a0 = OPTEE_SMC_RETURN_RPC_PREFIX | OPTEE_SMC_RPC_FUNC_ALLOC;
526 		res->a1 = 1;
527 		break;
528 	case 1:
529 		zassert_equal(a0, 0x32000003, "%s failed with ret %lx", __func__, a0);
530 		res->a0 = OPTEE_SMC_RETURN_RPC_PREFIX | OPTEE_SMC_RPC_FUNC_CMD;
531 		arg = (struct optee_msg_arg *)regs_to_u64(a1, a2);
532 		/* Fall back to supplicant branch */
533 		arg->cmd = 555;
534 		arg->num_params = 2;
535 		arg->params[0].attr = OPTEE_MSG_ATTR_TYPE_VALUE_INPUT;
536 		arg->params[0].u.value.a = 1111;
537 		arg->params[0].u.value.b = 3;
538 		arg->params[1].attr = OPTEE_MSG_ATTR_TYPE_VALUE_OUTPUT;
539 		res->a1 = a4;
540 		res->a2 = a5;
541 		break;
542 	case 2:
543 		zassert_equal(a0, 0x32000003, "%s failed with ret %lx", __func__, a0);
544 		shm = (struct tee_shm *)regs_to_u64(a1, a2);
545 		arg = (struct optee_msg_arg *)shm->addr;
546 		zassert_equal(arg->params[1].attr, OPTEE_MSG_ATTR_TYPE_VALUE_OUTPUT,
547 			      "%s failed wrong attr %lx", __func__, arg->params[0].attr);
548 		zassert_equal(arg->params[1].u.value.a, 0x1234, "%s failed wrong a %lx",
549 			      __func__, arg->params[0].u.value.a);
550 		zassert_equal(arg->params[1].u.value.b, 0x5678, "%s failed wrong b %lx",
551 			      __func__, arg->params[0].u.value.b);
552 		res->a0 = OPTEE_SMC_RETURN_OK;
553 		break;
554 	default:
555 		zassert_equal(a0, 0x32000003, "%s failed with ret %lx", __func__, a0);
556 		res->a0 = OPTEE_SMC_RETURN_OK;
557 	}
558 
559 	t_call.num++;
560 }
561 
supp_thread_comm(void)562 static void supp_thread_comm(void)
563 {
564 	const struct device *const dev = DEVICE_DT_GET_ONE(linaro_optee_tz);
565 	struct tee_param params[TEE_NUM_PARAMS];
566 	unsigned int num_params = TEE_NUM_PARAMS;
567 	uint32_t func;
568 	int ret;
569 
570 	supp_thread_ok = true;
571 
572 	ret = tee_suppl_recv(dev, &func, &num_params, params);
573 
574 	if (ret != 0) {
575 		printk("tee_suppl_recv failed with %d\n", ret);
576 		supp_thread_ok = false;
577 	}
578 
579 	if (func != 555 || num_params != 2) {
580 		printk("Unexpected func & num_params %d %d\n", func, num_params);
581 		supp_thread_ok = false;
582 	}
583 
584 	if (params[0].attr != OPTEE_MSG_ATTR_TYPE_VALUE_INPUT ||
585 	    params[1].attr != OPTEE_MSG_ATTR_TYPE_VALUE_OUTPUT ||
586 	    params[0].a != 1111 ||
587 	    params[0].b != 3) {
588 		printk("Unexpected params %d %d %d\n", params[0].attr,
589 		       params[0].a, params[0].b);
590 		supp_thread_ok = false;
591 	}
592 
593 	params[1].a = 0x1234;
594 	params[1].b = 0x5678;
595 	tee_suppl_send(dev, 0, 2, params);
596 }
597 
ZTEST(optee_test_suite,test_func_rpc_supp_cmd)598 ZTEST(optee_test_suite, test_func_rpc_supp_cmd)
599 {
600 	int ret;
601 	uint32_t session_id;
602 	struct tee_open_session_arg arg = {};
603 	struct tee_invoke_func_arg invoke_arg = {};
604 	struct tee_param param = {};
605 	const struct device *const dev = DEVICE_DT_GET_ONE(linaro_optee_tz);
606 	k_tid_t tid;
607 
608 	tid = k_thread_create(&supp_thread_data, supp_stack,
609 			      K_KERNEL_STACK_SIZEOF(supp_stack),
610 			      (k_thread_entry_t)supp_thread_comm, NULL, NULL, NULL,
611 			      K_PRIO_PREEMPT(CONFIG_NUM_PREEMPT_PRIORITIES - 1), 0, K_NO_WAIT);
612 	zassert_not_null(dev, "Unable to get dev");
613 
614 	t_call.pending = 1;
615 	t_call.num = 0;
616 	t_call.smc_cb = fast_call;
617 
618 	arg.uuid[0] = 111;
619 	arg.clnt_uuid[0] = 222;
620 	arg.clnt_login = TEEC_LOGIN_PUBLIC;
621 	param.attr = TEE_PARAM_ATTR_TYPE_NONE;
622 	param.a = 3333;
623 	ret = tee_open_session(dev, &arg, 1, &param, &session_id);
624 	zassert_ok(ret, "tee_open_session failed with code %d", ret);
625 
626 	t_call.num = 0;
627 	t_call.smc_cb = cmd_rpc_call;
628 
629 	invoke_arg.func = 12;
630 	invoke_arg.session = 1;
631 	ret = tee_invoke_func(dev, &invoke_arg, 1, &param);
632 	zassert_ok(ret, "tee_invoke_fn failed with code %d", ret);
633 
634 	t_call.num = 0;
635 	t_call.smc_cb = fast_call;
636 
637 	ret = tee_close_session(dev, session_id);
638 	zassert_ok(ret, "close_session failed with code %d", ret);
639 	zassert_true(supp_thread_ok, "supp_thread_comm failed");
640 	t_call.pending = 0;
641 	k_thread_abort(tid);
642 }
643 
cmd_shm_alloc_appl(unsigned long a0,unsigned long a1,unsigned long a2,unsigned long a3,unsigned long a4,unsigned long a5,unsigned long a6,unsigned long a7,struct arm_smccc_res * res)644 void cmd_shm_alloc_appl(unsigned long a0, unsigned long a1, unsigned long a2, unsigned long a3,
645 			unsigned long a4, unsigned long a5, unsigned long a6, unsigned long a7,
646 			struct arm_smccc_res *res)
647 {
648 	struct optee_msg_arg *arg;
649 	struct tee_shm *shm;
650 
651 	t_call.a0 = a0;
652 	t_call.a1 = a1;
653 	t_call.a2 = a2;
654 	t_call.a3 = a3;
655 	t_call.a4 = a4;
656 	t_call.a5 = a5;
657 	t_call.a6 = a6;
658 	t_call.a7 = a7;
659 
660 	res->a1 = a1;
661 	res->a2 = a2;
662 	res->a3 = a3;
663 	res->a4 = a4;
664 	res->a5 = a5;
665 
666 	switch (t_call.num) {
667 	case 0:
668 		res->a0 = OPTEE_SMC_RETURN_RPC_PREFIX | OPTEE_SMC_RPC_FUNC_ALLOC;
669 		res->a1 = 1;
670 		break;
671 	case 1:
672 		zassert_equal(a0, 0x32000003, "%s failed with ret %lx", __func__, a0);
673 		res->a0 = OPTEE_SMC_RETURN_RPC_PREFIX | OPTEE_SMC_RPC_FUNC_CMD;
674 		arg = (struct optee_msg_arg *)regs_to_u64(a1, a2);
675 		arg->cmd = OPTEE_RPC_CMD_SHM_ALLOC;
676 		arg->num_params = 1;
677 		arg->params[0].attr = OPTEE_MSG_ATTR_TYPE_VALUE_INPUT;
678 		arg->params[0].u.value.b = 4096;
679 		arg->params[0].u.value.a = OPTEE_RPC_SHM_TYPE_APPL;
680 		res->a1 = a4;
681 		res->a2 = a5;
682 		g_shm_ref = regs_to_u64(a4, a5);
683 		break;
684 	case 2:
685 		res->a0 = OPTEE_SMC_RETURN_OK;
686 		break;
687 	case 3:
688 		zassert_equal(a0, 0x32000003, "%s failed with ret %lx", __func__, a0);
689 		res->a0 = OPTEE_SMC_RETURN_RPC_PREFIX | OPTEE_SMC_RPC_FUNC_CMD;
690 		shm = (struct tee_shm *)regs_to_u64(a1, a2);
691 		arg = (struct optee_msg_arg *)shm->addr;
692 		arg->cmd = OPTEE_RPC_CMD_SHM_FREE;
693 		arg->num_params = 1;
694 		arg->params[0].attr = OPTEE_MSG_ATTR_TYPE_VALUE_INPUT;
695 		arg->params[0].u.value.a = OPTEE_RPC_SHM_TYPE_APPL;
696 		arg->params[0].u.value.b = g_shm_ref;
697 		u64_to_regs(g_shm_ref, &res->a1, &res->a2);
698 		break;
699 	case 4:
700 		u64_to_regs(g_shm_ref, &res->a1, &res->a2);
701 		res->a0 = OPTEE_SMC_RETURN_OK;
702 		break;
703 	case 5:
704 		zassert_equal(a0, 0x32000003, "%s failed with ret %lx", __func__, a0);
705 		res->a0 = OPTEE_SMC_RETURN_OK;
706 		break;
707 	default:
708 		zassert_equal(a0, 0x32000003, "%s failed with ret %lx", __func__, a0);
709 		res->a0 = OPTEE_SMC_RETURN_OK;
710 	}
711 
712 	t_call.num++;
713 }
714 
supp_thread_alloc(void)715 static void supp_thread_alloc(void)
716 {
717 	const struct device *const dev = DEVICE_DT_GET_ONE(linaro_optee_tz);
718 	struct tee_param params[TEE_NUM_PARAMS];
719 	void *mem;
720 	unsigned int num_params = TEE_NUM_PARAMS;
721 	uint32_t func;
722 	int ret;
723 
724 	supp_thread_ok = true;
725 
726 	ret = tee_suppl_recv(dev, &func, &num_params, params);
727 
728 	if (ret != 0) {
729 		printk("tee_suppl_recv failed with %d\n", ret);
730 		supp_thread_ok = false;
731 		goto fail1;
732 	}
733 
734 	if (func != OPTEE_RPC_CMD_SHM_ALLOC || num_params != 1) {
735 		printk("Unexpected func & num_params %d %d\n", func, num_params);
736 		supp_thread_ok = false;
737 		goto fail1;
738 	}
739 
740 	if (params[0].attr != OPTEE_MSG_ATTR_TYPE_VALUE_INOUT ||
741 	    params[0].a != OPTEE_RPC_SHM_TYPE_APPL) {
742 		printk("Unexpected params %d %d\n", params[0].attr,
743 		       params[0].a);
744 		supp_thread_ok = false;
745 		goto fail1;
746 	}
747 
748 	mem = k_malloc(params[0].b);
749 
750 	if (!mem) {
751 		printk("k_malloc failed\n");
752 		supp_thread_ok = false;
753 		goto fail1;
754 	}
755 
756 	params[0].c = (uint64_t)mem;
757 	tee_suppl_send(dev, 0, 1, params);
758 
759 	ret = tee_suppl_recv(dev, &func, &num_params, params);
760 	if (func != OPTEE_RPC_CMD_SHM_FREE || num_params != 1) {
761 		printk("Unexpected func & num_params %d %d\n", func, num_params);
762 		supp_thread_ok = false;
763 		goto fail2;
764 	}
765 
766 	tee_suppl_send(dev, 0, 1, params);
767 	k_free(mem);
768 
769 	return;
770 fail1:
771 	tee_suppl_send(dev, -1, 1, params);
772 fail2:
773 	tee_suppl_send(dev, -1, 1, params);
774 }
775 
ZTEST(optee_test_suite,test_func_rpc_shm_alloc_appl)776 ZTEST(optee_test_suite, test_func_rpc_shm_alloc_appl)
777 {
778 	int ret;
779 	uint32_t session_id;
780 	struct tee_open_session_arg arg = {};
781 	struct tee_invoke_func_arg invoke_arg = {};
782 	struct tee_param param = {};
783 	const struct device *const dev = DEVICE_DT_GET_ONE(linaro_optee_tz);
784 	k_tid_t tid;
785 
786 	tid = k_thread_create(&supp_thread_data, supp_stack,
787 			      K_KERNEL_STACK_SIZEOF(supp_stack),
788 			      (k_thread_entry_t)supp_thread_alloc, NULL, NULL, NULL,
789 			      K_PRIO_PREEMPT(CONFIG_NUM_PREEMPT_PRIORITIES - 1), 0, K_NO_WAIT);
790 	zassert_not_null(dev, "Unable to get dev");
791 
792 	t_call.pending = 1;
793 	t_call.num = 0;
794 	t_call.smc_cb = fast_call;
795 
796 	arg.uuid[0] = 111;
797 	arg.clnt_uuid[0] = 222;
798 	arg.clnt_login = TEEC_LOGIN_PUBLIC;
799 	param.attr = TEE_PARAM_ATTR_TYPE_NONE;
800 	param.a = 3333;
801 	ret = tee_open_session(dev, &arg, 1, &param, &session_id);
802 	zassert_ok(ret, "tee_open_session failed with code %d", ret);
803 
804 	t_call.num = 0;
805 	t_call.smc_cb = cmd_shm_alloc_appl;
806 
807 	invoke_arg.func = 12;
808 	invoke_arg.session = 1;
809 	ret = tee_invoke_func(dev, &invoke_arg, 1, &param);
810 	zassert_ok(ret, "tee_invoke_fn failed with code %d", ret);
811 	zassert_true(supp_thread_ok, "supp_thread failed");
812 
813 	t_call.num = 0;
814 	t_call.smc_cb = fast_call;
815 
816 	ret = tee_close_session(dev, session_id);
817 	zassert_ok(ret, "close_session failed with code %d", ret);
818 	t_call.pending = 0;
819 	k_thread_abort(tid);
820 }
821 
cmd_gettime_call(unsigned long a0,unsigned long a1,unsigned long a2,unsigned long a3,unsigned long a4,unsigned long a5,unsigned long a6,unsigned long a7,struct arm_smccc_res * res)822 void cmd_gettime_call(unsigned long a0, unsigned long a1, unsigned long a2, unsigned long a3,
823 		      unsigned long a4, unsigned long a5, unsigned long a6, unsigned long a7,
824 		      struct arm_smccc_res *res)
825 {
826 	struct optee_msg_arg *arg;
827 	struct tee_shm *shm;
828 
829 	res->a1 = a1;
830 	res->a2 = a2;
831 	res->a3 = a3;
832 	res->a4 = a4;
833 	res->a5 = a5;
834 
835 	switch (t_call.num) {
836 	case 0:
837 		res->a0 = OPTEE_SMC_RETURN_RPC_PREFIX | OPTEE_SMC_RPC_FUNC_ALLOC;
838 		res->a1 = 1;
839 		break;
840 	case 1:
841 		zassert_equal(a0, 0x32000003, "%s failed with ret %lx", __func__, a0);
842 		res->a0 = OPTEE_SMC_RETURN_RPC_PREFIX | OPTEE_SMC_RPC_FUNC_CMD;
843 		arg = (struct optee_msg_arg *)regs_to_u64(a1, a2);
844 		arg->cmd = OPTEE_RPC_CMD_GET_TIME;
845 		arg->num_params = 1;
846 		arg->params[0].attr = OPTEE_MSG_ATTR_TYPE_VALUE_OUTPUT;
847 		res->a1 = a4;
848 		res->a2 = a5;
849 		g_shm_ref = regs_to_u64(a4, a5);
850 		break;
851 	case 2:
852 		zassert_equal(a0, 0x32000003, "%s failed with ret %lx", __func__, a0);
853 		res->a0 = OPTEE_SMC_RETURN_RPC_PREFIX | OPTEE_SMC_RPC_FUNC_FREE;
854 		shm = (struct tee_shm *)regs_to_u64(a1, a2);
855 		arg = (struct optee_msg_arg *)shm->addr;
856 
857 		t_call.a6 = arg->params[0].u.value.a;
858 		t_call.a7 = arg->params[0].u.value.b;
859 		u64_to_regs(g_shm_ref, &res->a1, &res->a2);
860 		break;
861 	case 3:
862 		zassert_equal(a0, 0x32000003, "%s failed with ret %lx", __func__, a0);
863 		res->a0 = OPTEE_SMC_RETURN_OK;
864 		break;
865 	default:
866 		zassert_equal(a0, 0x32000003, "%s failed with ret %lx", __func__, a0);
867 		res->a0 = OPTEE_SMC_RETURN_OK;
868 	}
869 
870 	t_call.num++;
871 }
872 
873 #define TICKS 0xDEADBEEF
874 #define TEST_SEC 37359285
875 #define TEST_NSEC 590000000
876 extern void z_vrfy_sys_clock_tick_set(uint64_t tick);
877 
ZTEST(optee_test_suite,test_gettime)878 ZTEST(optee_test_suite, test_gettime)
879 {
880 	int ret;
881 	uint32_t session_id;
882 	struct tee_open_session_arg arg = {};
883 	struct tee_invoke_func_arg invoke_arg = {};
884 	struct tee_param param = {};
885 	const struct device *const dev = DEVICE_DT_GET_ONE(linaro_optee_tz);
886 
887 	zassert_not_null(dev, "Unable to get dev");
888 
889 	t_call.pending = 1;
890 	t_call.num = 0;
891 	t_call.smc_cb = fast_call;
892 
893 	arg.uuid[0] = 111;
894 	arg.clnt_uuid[0] = 222;
895 	arg.clnt_login = TEEC_LOGIN_PUBLIC;
896 	param.attr = TEE_PARAM_ATTR_TYPE_NONE;
897 	param.a = 3333;
898 	ret = tee_open_session(dev, &arg, 1, &param, &session_id);
899 	zassert_ok(ret, "tee_open_session failed with code %d", ret);
900 
901 	t_call.num = 0;
902 	t_call.smc_cb = cmd_gettime_call;
903 
904 	z_vrfy_sys_clock_tick_set(TICKS);
905 
906 	invoke_arg.func = 12;
907 	invoke_arg.session = 1;
908 	ret = tee_invoke_func(dev, &invoke_arg, 1, &param);
909 	zassert_ok(ret, "tee_invoke_fn failed with code %d", ret);
910 
911 	zassert_equal(t_call.a6, TEST_SEC, "Unexpected secs");
912 	zassert_equal(t_call.a7, TEST_NSEC, "Unexpected nsecs");
913 
914 	t_call.num = 0;
915 	t_call.smc_cb = fast_call;
916 
917 	ret = tee_close_session(dev, session_id);
918 	zassert_ok(ret, "close_session failed with code %d", ret);
919 	t_call.pending = 0;
920 }
921 
cmd_suspend_call(unsigned long a0,unsigned long a1,unsigned long a2,unsigned long a3,unsigned long a4,unsigned long a5,unsigned long a6,unsigned long a7,struct arm_smccc_res * res)922 void cmd_suspend_call(unsigned long a0, unsigned long a1, unsigned long a2, unsigned long a3,
923 		      unsigned long a4, unsigned long a5, unsigned long a6, unsigned long a7,
924 		      struct arm_smccc_res *res)
925 {
926 	struct optee_msg_arg *arg;
927 	struct tee_shm *shm;
928 
929 	res->a1 = a1;
930 	res->a2 = a2;
931 	res->a3 = a3;
932 	res->a4 = a4;
933 	res->a5 = a5;
934 
935 	switch (t_call.num) {
936 	case 0:
937 		res->a0 = OPTEE_SMC_RETURN_RPC_PREFIX | OPTEE_SMC_RPC_FUNC_ALLOC;
938 		res->a1 = 1;
939 		break;
940 	case 1:
941 		zassert_equal(a0, 0x32000003, "%s failed with ret %lx", __func__, a0);
942 		res->a0 = OPTEE_SMC_RETURN_RPC_PREFIX | OPTEE_SMC_RPC_FUNC_CMD;
943 		arg = (struct optee_msg_arg *)regs_to_u64(a1, a2);
944 		arg->cmd = OPTEE_RPC_CMD_SUSPEND;
945 		arg->num_params = 1;
946 		arg->params[0].attr = OPTEE_MSG_ATTR_TYPE_VALUE_INPUT;
947 		arg->params[0].u.value.a = t_call.a0;
948 		res->a1 = a4;
949 		res->a2 = a5;
950 		g_shm_ref = regs_to_u64(a4, a5);
951 		break;
952 	case 2:
953 		zassert_equal(a0, 0x32000003, "%s failed with ret %lx", __func__, a0);
954 		res->a0 = OPTEE_SMC_RETURN_RPC_PREFIX | OPTEE_SMC_RPC_FUNC_FREE;
955 		shm = (struct tee_shm *)regs_to_u64(a1, a2);
956 		arg = (struct optee_msg_arg *)shm->addr;
957 
958 		t_call.a6 = arg->params[0].u.value.a;
959 		t_call.a7 = arg->params[0].u.value.b;
960 		u64_to_regs(g_shm_ref, &res->a1, &res->a2);
961 		break;
962 	case 3:
963 		zassert_equal(a0, 0x32000003, "%s failed with ret %lx", __func__, a0);
964 		res->a0 = OPTEE_SMC_RETURN_OK;
965 		break;
966 	default:
967 		zassert_equal(a0, 0x32000003, "%s failed with ret %lx", __func__, a0);
968 		res->a0 = OPTEE_SMC_RETURN_OK;
969 	}
970 
971 	t_call.num++;
972 }
973 
ZTEST(optee_test_suite,test_suspend)974 ZTEST(optee_test_suite, test_suspend)
975 {
976 	int ret;
977 	uint32_t session_id;
978 	struct tee_open_session_arg arg = {};
979 	struct tee_invoke_func_arg invoke_arg = {};
980 	struct tee_param param = {};
981 	const struct device *const dev = DEVICE_DT_GET_ONE(linaro_optee_tz);
982 
983 	zassert_not_null(dev, "Unable to get dev");
984 
985 	t_call.pending = 1;
986 	t_call.num = 0;
987 	t_call.smc_cb = fast_call;
988 
989 	arg.uuid[0] = 111;
990 	arg.clnt_uuid[0] = 222;
991 	arg.clnt_login = TEEC_LOGIN_PUBLIC;
992 	param.attr = TEE_PARAM_ATTR_TYPE_NONE;
993 	param.a = 3333;
994 	ret = tee_open_session(dev, &arg, 1, &param, &session_id);
995 	zassert_ok(ret, "tee_open_session failed with code %d", ret);
996 
997 	t_call.num = 0;
998 	t_call.a0 = 4000; /* Set timeout 4000 ms */
999 	t_call.smc_cb = cmd_suspend_call;
1000 
1001 	invoke_arg.func = 12;
1002 	invoke_arg.session = 1;
1003 	ret = tee_invoke_func(dev, &invoke_arg, 1, &param);
1004 	zassert_ok(ret, "tee_invoke_fn failed with code %d", ret);
1005 
1006 	t_call.num = 0;
1007 	t_call.smc_cb = fast_call;
1008 
1009 	ret = tee_close_session(dev, session_id);
1010 	zassert_ok(ret, "close_session failed with code %d", ret);
1011 	t_call.pending = 0;
1012 }
1013 
cmd_notify_alloc_call(unsigned long a0,unsigned long a1,unsigned long a2,unsigned long a3,unsigned long a4,unsigned long a5,unsigned long a6,unsigned long a7,struct arm_smccc_res * res)1014 void cmd_notify_alloc_call(unsigned long a0, unsigned long a1, unsigned long a2, unsigned long a3,
1015 			   unsigned long a4, unsigned long a5, unsigned long a6, unsigned long a7,
1016 			   struct arm_smccc_res *res)
1017 {
1018 	res->a1 = a1;
1019 	res->a2 = a2;
1020 	res->a3 = a3;
1021 	res->a4 = a4;
1022 	res->a5 = a5;
1023 
1024 	switch (t_call.num) {
1025 	case 0:
1026 		res->a0 = OPTEE_SMC_RETURN_RPC_PREFIX | OPTEE_SMC_RPC_FUNC_ALLOC;
1027 		res->a1 = 1;
1028 		break;
1029 	case 1:
1030 		zassert_equal(a0, 0x32000003, "%s failed with ret %lx", __func__, a0);
1031 		res->a0 = OPTEE_SMC_RETURN_OK;
1032 		/* res->a1 = a4; */
1033 		/* res->a2 = a5; */
1034 		g_shm_ref = regs_to_u64(a4, a5);
1035 		break;
1036 	default:
1037 		zassert_equal(a0, 0x32000004, "%s failed with ret %lx", __func__, a0);
1038 		res->a0 = OPTEE_SMC_RETURN_OK;
1039 	}
1040 
1041 	t_call.num++;
1042 }
1043 
cmd_notify_free_call(unsigned long a0,unsigned long a1,unsigned long a2,unsigned long a3,unsigned long a4,unsigned long a5,unsigned long a6,unsigned long a7,struct arm_smccc_res * res)1044 void cmd_notify_free_call(unsigned long a0, unsigned long a1, unsigned long a2, unsigned long a3,
1045 			  unsigned long a4, unsigned long a5, unsigned long a6, unsigned long a7,
1046 			  struct arm_smccc_res *res)
1047 {
1048 	res->a1 = a1;
1049 	res->a2 = a2;
1050 	res->a3 = a3;
1051 	res->a4 = a4;
1052 	res->a5 = a5;
1053 
1054 	switch (t_call.num) {
1055 	case 0:
1056 		zassert_equal(a0, 0x32000004, "%s failed with ret %lx", __func__, a0);
1057 		u64_to_regs(g_shm_ref, &res->a1, &res->a2);
1058 		res->a0 = OPTEE_SMC_RETURN_RPC_PREFIX | OPTEE_SMC_RPC_FUNC_FREE;
1059 		break;
1060 	case 1:
1061 		zassert_equal(a0, 0x32000003, "%s failed with ret %lx", __func__, a0);
1062 		res->a0 = OPTEE_SMC_RETURN_OK;
1063 		res->a1 = a4;
1064 		res->a2 = a5;
1065 		break;
1066 	default:
1067 		zassert_equal(a0, 0x32000003, "%s failed with ret %lx", __func__, a0);
1068 		res->a0 = OPTEE_SMC_RETURN_OK;
1069 	}
1070 
1071 	t_call.num++;
1072 }
1073 
1074 static struct test_call wait_call;
1075 static struct test_call send_call;
1076 
cmd_notify_wait_call(unsigned long a0,unsigned long a1,unsigned long a2,unsigned long a3,unsigned long a4,unsigned long a5,unsigned long a6,unsigned long a7,struct arm_smccc_res * res)1077 void cmd_notify_wait_call(unsigned long a0, unsigned long a1, unsigned long a2, unsigned long a3,
1078 			  unsigned long a4, unsigned long a5, unsigned long a6, unsigned long a7,
1079 			  struct arm_smccc_res *res)
1080 {
1081 	struct optee_msg_arg *arg;
1082 	struct tee_shm *shm;
1083 
1084 	res->a1 = a1;
1085 	res->a2 = a2;
1086 	res->a3 = a3;
1087 	res->a4 = a4;
1088 	res->a5 = a5;
1089 
1090 	switch (wait_call.num) {
1091 	case 0:
1092 		zassert_equal(a0, 0x32000004, "%s failed with ret %lx", __func__, a0);
1093 		res->a0 = OPTEE_SMC_RETURN_RPC_PREFIX | OPTEE_SMC_RPC_FUNC_CMD;
1094 		shm = (struct tee_shm *)g_shm_ref;
1095 		arg = (struct optee_msg_arg *)shm->addr;
1096 		arg->cmd = OPTEE_RPC_CMD_NOTIFICATION;
1097 		arg->num_params = 1;
1098 		arg->params[0].attr = OPTEE_MSG_ATTR_TYPE_VALUE_INPUT;
1099 		arg->params[0].u.value.a = OPTEE_RPC_NOTIFICATION_WAIT;
1100 		arg->params[0].u.value.b = wait_call.a0; /* Set notification key */
1101 		u64_to_regs(g_shm_ref, &res->a1, &res->a2);
1102 		break;
1103 	default:
1104 		zassert_equal(a0, 0x32000003, "%s failed with ret %lx", __func__, a0);
1105 		res->a0 = OPTEE_SMC_RETURN_OK;
1106 		wait_call.a6 = 1;
1107 	}
1108 
1109 	wait_call.num++;
1110 }
1111 
cmd_notify_send_call(unsigned long a0,unsigned long a1,unsigned long a2,unsigned long a3,unsigned long a4,unsigned long a5,unsigned long a6,unsigned long a7,struct arm_smccc_res * res)1112 void cmd_notify_send_call(unsigned long a0, unsigned long a1, unsigned long a2, unsigned long a3,
1113 			  unsigned long a4, unsigned long a5, unsigned long a6, unsigned long a7,
1114 			  struct arm_smccc_res *res)
1115 {
1116 	struct optee_msg_arg *arg;
1117 	struct tee_shm *shm;
1118 
1119 	res->a1 = a1;
1120 	res->a2 = a2;
1121 	res->a3 = a3;
1122 	res->a4 = a4;
1123 	res->a5 = a5;
1124 
1125 	switch (send_call.num) {
1126 	case 0:
1127 		zassert_equal(a0, 0x32000004, "%s failed with ret %lx", __func__, a0);
1128 		res->a0 = OPTEE_SMC_RETURN_RPC_PREFIX | OPTEE_SMC_RPC_FUNC_CMD;
1129 		shm = (struct tee_shm *)g_shm_ref;
1130 		arg = (struct optee_msg_arg *)shm->addr;
1131 		arg->cmd = OPTEE_RPC_CMD_NOTIFICATION;
1132 		arg->num_params = 1;
1133 		arg->params[0].attr = OPTEE_MSG_ATTR_TYPE_VALUE_INPUT;
1134 		arg->params[0].u.value.a = OPTEE_RPC_NOTIFICATION_SEND;
1135 		arg->params[0].u.value.b = send_call.a0; /* Set notification key */
1136 		u64_to_regs(g_shm_ref, &res->a1, &res->a2);
1137 		break;
1138 	default:
1139 		zassert_equal(a0, 0x32000003, "%s failed with ret %lx", __func__, a0);
1140 		res->a0 = OPTEE_SMC_RETURN_OK;
1141 		send_call.a6 = 1;
1142 	}
1143 
1144 	send_call.num++;
1145 }
1146 
test_invoke_fn(const struct device * const dev,uint32_t session_id)1147 static int test_invoke_fn(const struct device *const dev, uint32_t session_id)
1148 {
1149 	struct tee_invoke_func_arg invoke_arg = {};
1150 	struct tee_param param = {};
1151 
1152 	invoke_arg.func = 12;
1153 	invoke_arg.session = session_id;
1154 
1155 	return tee_invoke_func(dev, &invoke_arg, 1, &param);
1156 }
1157 
wait_handler(void * arg0,void * arg1,void * arg2)1158 static void wait_handler(void *arg0, void *arg1, void *arg2)
1159 {
1160 	int ret;
1161 	const struct device *const dev = DEVICE_DT_GET_ONE(linaro_optee_tz);
1162 
1163 	ARG_UNUSED(arg0);
1164 	ARG_UNUSED(arg1);
1165 	ARG_UNUSED(arg2);
1166 
1167 	/* This expects wait_call.a0 to be set as key and wait_call.a4 as session_id */
1168 	wait_call.pending = 1;
1169 	wait_call.th_id = k_current_get();
1170 	wait_call.num = 0;
1171 	wait_call.a6 = 0; /* result */
1172 
1173 	wait_call.smc_cb = cmd_notify_wait_call;
1174 
1175 	ret = test_invoke_fn(dev, t_call.a4);
1176 	zassert_ok(ret, "tee_invoke_fn failed with code %d", ret);
1177 	wait_call.a6 = 1;
1178 	wait_call.pending = 0;
1179 }
1180 
1181 #define WAIT_STACKSIZE 512
1182 #define WAIT_PRIORITY  4
1183 
1184 static K_THREAD_STACK_DEFINE(wait_stack, WAIT_STACKSIZE);
1185 static struct k_thread wait_thread;
1186 
do_wait(int key,uint32_t session_id)1187 static void do_wait(int key, uint32_t session_id)
1188 {
1189 	wait_call.a0 = key;
1190 	wait_call.a4 = session_id;
1191 	k_thread_create(&wait_thread, wait_stack, WAIT_STACKSIZE, wait_handler,
1192 			INT_TO_POINTER(1) /* key */,
1193 			NULL, NULL, K_PRIO_COOP(WAIT_PRIORITY), 0, K_NO_WAIT);
1194 }
1195 
ZTEST(optee_test_suite,test_notify)1196 ZTEST(optee_test_suite, test_notify)
1197 {
1198 	int ret;
1199 	uint32_t session_id;
1200 	struct tee_open_session_arg arg = {};
1201 	struct tee_param param = {};
1202 	const struct device *const dev = DEVICE_DT_GET_ONE(linaro_optee_tz);
1203 
1204 	zassert_not_null(dev, "Unable to get dev");
1205 
1206 	t_call.pending = 1;
1207 	t_call.num = 0;
1208 	t_call.smc_cb = fast_call;
1209 
1210 	arg.uuid[0] = 111;
1211 	arg.clnt_uuid[0] = 222;
1212 	arg.clnt_login = TEEC_LOGIN_PUBLIC;
1213 	param.attr = TEE_PARAM_ATTR_TYPE_NONE;
1214 	param.a = 3333;
1215 	ret = tee_open_session(dev, &arg, 1, &param, &session_id);
1216 	zassert_ok(ret, "tee_open_session failed with code %d", ret);
1217 
1218 	t_call.num = 0;
1219 	t_call.smc_cb = cmd_notify_alloc_call;
1220 
1221 	ret = test_invoke_fn(dev, session_id);
1222 	zassert_ok(ret, "tee_invoke_fn failed with code %d", ret);
1223 	t_call.pending = 0;
1224 
1225 	/* Wait then send */
1226 	do_wait(1, session_id);
1227 	k_sleep(K_MSEC(100));
1228 
1229 	send_call.pending = 1;
1230 	send_call.num = 0;
1231 	send_call.a0 = 1; /* key */
1232 	send_call.smc_cb = cmd_notify_send_call;
1233 
1234 	ret = test_invoke_fn(dev, session_id);
1235 	zassert_ok(ret, "tee_invoke_fn failed with code %d", ret);
1236 	send_call.pending = 0;
1237 
1238 	k_sleep(K_MSEC(100));
1239 	zassert_equal(wait_call.a6, 1, "Notify wait is still in progress");
1240 
1241 	/* Test send then wait */
1242 	send_call.pending = 1;
1243 	send_call.num = 0;
1244 	send_call.a0 = 2; /* key */
1245 	send_call.smc_cb = cmd_notify_send_call;
1246 
1247 	ret = test_invoke_fn(dev, session_id);
1248 	zassert_ok(ret, "tee_invoke_fn failed with code %d", ret);
1249 	send_call.pending = 0;
1250 
1251 	wait_call.pending = 1;
1252 	wait_call.th_id = k_current_get();
1253 	wait_call.num = 0;
1254 	wait_call.a0 = 2; /* key */
1255 
1256 	wait_call.smc_cb = cmd_notify_wait_call;
1257 
1258 	ret = test_invoke_fn(dev, session_id);
1259 	zassert_ok(ret, "tee_invoke_fn failed with code %d", ret);
1260 
1261 	wait_call.pending = 0;
1262 	/* End of test section */
1263 
1264 	t_call.pending = 1;
1265 	t_call.num = 0;
1266 	t_call.smc_cb = cmd_notify_free_call;
1267 
1268 	ret = test_invoke_fn(dev, session_id);
1269 	zassert_ok(ret, "tee_invoke_fn failed with code %d", ret);
1270 
1271 	t_call.num = 0;
1272 	t_call.smc_cb = fast_call;
1273 
1274 	ret = tee_close_session(dev, session_id);
1275 	zassert_ok(ret, "close_session failed with code %d", ret);
1276 	t_call.pending = 0;
1277 }
1278 
1279 ZTEST_SUITE(optee_test_suite, NULL, NULL, NULL, NULL, NULL);
1280