1 /*
2 * Copyright 2023 EPAM Systems
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <zephyr/arch/arm64/arm-smccc.h>
8 #include <zephyr/drivers/tee.h>
9 #include <zephyr/logging/log.h>
10 #include <zephyr/sys/bitarray.h>
11 #include <zephyr/sys/dlist.h>
12
13 #include "optee_msg.h"
14 #include "optee_rpc_cmd.h"
15 #include "optee_smc.h"
16 LOG_MODULE_REGISTER(optee);
17
18 #define DT_DRV_COMPAT linaro_optee_tz
19
20 /* amount of physical addresses that can be stored in one page */
21 #define OPTEE_NUMBER_OF_ADDR_PER_PAGE (OPTEE_MSG_NONCONTIG_PAGE_SIZE / sizeof(uint64_t))
22
23 /*
24 * TEE Implementation ID
25 */
26 #define TEE_IMPL_ID_OPTEE 1
27
28 /*
29 * OP-TEE specific capabilities
30 */
31 #define TEE_OPTEE_CAP_TZ BIT(0)
32
33 struct optee_rpc_param {
34 uint32_t a0;
35 uint32_t a1;
36 uint32_t a2;
37 uint32_t a3;
38 uint32_t a4;
39 uint32_t a5;
40 uint32_t a6;
41 uint32_t a7;
42 };
43
44 typedef void (*smc_call_t)(unsigned long a0, unsigned long a1, unsigned long a2, unsigned long a3,
45 unsigned long a4, unsigned long a5, unsigned long a6, unsigned long a7,
46 struct arm_smccc_res *res);
47
48 struct optee_driver_config {
49 const char *method;
50 };
51
52 struct optee_notify {
53 sys_dnode_t node;
54 uint32_t key;
55 struct k_sem wait;
56 };
57
58 struct optee_supp_req {
59 sys_dnode_t link;
60
61 bool in_queue;
62 uint32_t func;
63 uint32_t ret;
64 size_t num_params;
65 struct tee_param *param;
66
67 struct k_sem complete;
68 };
69
70 struct optee_supp {
71 /* Serializes access to this struct */
72 struct k_mutex mutex;
73
74 int req_id;
75 sys_dlist_t reqs;
76 struct optee_supp_req *current;
77 struct k_sem reqs_c;
78 };
79
80 struct optee_driver_data {
81 smc_call_t smc_call;
82
83 sys_bitarray_t *notif_bitmap;
84
85 sys_dlist_t notif;
86 struct k_spinlock notif_lock;
87 struct optee_supp supp;
88 unsigned long sec_caps;
89 struct k_sem call_sem;
90 };
91
92 /* Wrapping functions so function pointer can be used */
optee_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)93 static void optee_smccc_smc(unsigned long a0, unsigned long a1, unsigned long a2, unsigned long a3,
94 unsigned long a4, unsigned long a5, unsigned long a6, unsigned long a7,
95 struct arm_smccc_res *res)
96 {
97 arm_smccc_smc(a0, a1, a2, a3, a4, a5, a6, a7, res);
98 }
99
optee_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)100 static void optee_smccc_hvc(unsigned long a0, unsigned long a1, unsigned long a2, unsigned long a3,
101 unsigned long a4, unsigned long a5, unsigned long a6, unsigned long a7,
102 struct arm_smccc_res *res)
103 {
104 arm_smccc_hvc(a0, a1, a2, a3, a4, a5, a6, a7, res);
105 }
106
param_to_msg_param(const struct tee_param * param,unsigned int num_param,struct optee_msg_param * msg_param)107 static int param_to_msg_param(const struct tee_param *param, unsigned int num_param,
108 struct optee_msg_param *msg_param)
109 {
110 int i;
111 const struct tee_param *tp = param;
112 struct optee_msg_param *mtp = msg_param;
113
114 if (!param || !msg_param) {
115 return -EINVAL;
116 }
117
118 for (i = 0; i < num_param; i++, tp++, mtp++) {
119 if (!tp || !mtp) {
120 LOG_ERR("Wrong param on %d iteration", i);
121 return -EINVAL;
122 }
123
124 switch (tp->attr) {
125 case TEE_PARAM_ATTR_TYPE_NONE:
126 mtp->attr = OPTEE_MSG_ATTR_TYPE_NONE;
127 memset(&mtp->u, 0, sizeof(mtp->u));
128 break;
129 case TEE_PARAM_ATTR_TYPE_VALUE_INPUT:
130 case TEE_PARAM_ATTR_TYPE_VALUE_OUTPUT:
131 case TEE_PARAM_ATTR_TYPE_VALUE_INOUT:
132 mtp->attr = OPTEE_MSG_ATTR_TYPE_VALUE_INPUT + tp->attr -
133 TEE_PARAM_ATTR_TYPE_VALUE_INPUT;
134 mtp->u.value.a = tp->a;
135 mtp->u.value.b = tp->b;
136 mtp->u.value.c = tp->c;
137 break;
138 case TEE_PARAM_ATTR_TYPE_MEMREF_INPUT:
139 case TEE_PARAM_ATTR_TYPE_MEMREF_OUTPUT:
140 case TEE_PARAM_ATTR_TYPE_MEMREF_INOUT:
141 mtp->attr = OPTEE_MSG_ATTR_TYPE_RMEM_INPUT + tp->attr -
142 TEE_PARAM_ATTR_TYPE_MEMREF_INPUT;
143 mtp->u.rmem.shm_ref = tp->c;
144 mtp->u.rmem.size = tp->b;
145 mtp->u.rmem.offs = tp->a;
146 break;
147 default:
148 return -EINVAL;
149 }
150 }
151
152 return 0;
153 }
154
msg_param_to_tmp_mem(struct tee_param * p,uint32_t attr,const struct optee_msg_param * mp)155 static void msg_param_to_tmp_mem(struct tee_param *p, uint32_t attr,
156 const struct optee_msg_param *mp)
157 {
158 struct tee_shm *shm = (struct tee_shm *)mp->u.tmem.shm_ref;
159
160 p->attr = TEE_PARAM_ATTR_TYPE_MEMREF_INPUT + attr - OPTEE_MSG_ATTR_TYPE_TMEM_INPUT;
161 p->b = mp->u.tmem.size;
162
163 if (!shm) {
164 p->a = 0;
165 p->c = 0;
166 return;
167 }
168
169 p->a = mp->u.tmem.buf_ptr - k_mem_phys_addr(shm->addr);
170 p->c = mp->u.tmem.shm_ref;
171 }
172
msg_param_to_param(struct tee_param * param,unsigned int num_param,const struct optee_msg_param * msg_param)173 static int msg_param_to_param(struct tee_param *param, unsigned int num_param,
174 const struct optee_msg_param *msg_param)
175 {
176 int i;
177 struct tee_param *tp = param;
178 const struct optee_msg_param *mtp = msg_param;
179
180 if (!param || !msg_param) {
181 return -EINVAL;
182 }
183
184 for (i = 0; i < num_param; i++, tp++, mtp++) {
185 uint32_t attr = mtp->attr & OPTEE_MSG_ATTR_TYPE_MASK;
186
187 if (!tp || !mtp) {
188 LOG_ERR("Wrong param on %d iteration", i);
189 return -EINVAL;
190 }
191
192 switch (attr) {
193 case OPTEE_MSG_ATTR_TYPE_NONE:
194 memset(tp, 0, sizeof(*tp));
195 tp->attr = TEE_PARAM_ATTR_TYPE_NONE;
196 break;
197 case OPTEE_MSG_ATTR_TYPE_VALUE_INPUT:
198 case OPTEE_MSG_ATTR_TYPE_VALUE_OUTPUT:
199 case OPTEE_MSG_ATTR_TYPE_VALUE_INOUT:
200 tp->attr = TEE_PARAM_ATTR_TYPE_VALUE_INPUT + attr -
201 OPTEE_MSG_ATTR_TYPE_VALUE_INPUT;
202 tp->a = mtp->u.value.a;
203 tp->b = mtp->u.value.b;
204 tp->c = mtp->u.value.c;
205 break;
206 case OPTEE_MSG_ATTR_TYPE_RMEM_INPUT:
207 case OPTEE_MSG_ATTR_TYPE_RMEM_OUTPUT:
208 case OPTEE_MSG_ATTR_TYPE_RMEM_INOUT:
209 tp->attr = TEE_PARAM_ATTR_TYPE_MEMREF_INPUT + attr -
210 OPTEE_MSG_ATTR_TYPE_RMEM_INPUT;
211 tp->b = mtp->u.rmem.size;
212
213 if (!mtp->u.rmem.shm_ref) {
214 tp->a = 0;
215 tp->c = 0;
216 } else {
217 tp->a = mtp->u.rmem.offs;
218 tp->c = mtp->u.rmem.shm_ref;
219 }
220
221 break;
222 case OPTEE_MSG_ATTR_TYPE_TMEM_INPUT:
223 case OPTEE_MSG_ATTR_TYPE_TMEM_OUTPUT:
224 case OPTEE_MSG_ATTR_TYPE_TMEM_INOUT:
225 msg_param_to_tmp_mem(tp, attr, mtp);
226 break;
227 default:
228 return -EINVAL;
229 }
230 }
231
232 return 0;
233 }
234
regs_to_u64(uint32_t reg0,uint32_t reg1)235 static uint64_t regs_to_u64(uint32_t reg0, uint32_t reg1)
236 {
237 return (uint64_t)(((uint64_t)reg0 << 32) | reg1);
238 }
239
u64_to_regs(uint64_t val,uint32_t * reg0,uint32_t * reg1)240 static void u64_to_regs(uint64_t val, uint32_t *reg0, uint32_t *reg1)
241 {
242 *reg0 = val >> 32;
243 *reg1 = val;
244 }
245
check_param_input(struct optee_msg_arg * arg)246 static inline bool check_param_input(struct optee_msg_arg *arg)
247 {
248 return arg->num_params == 1 &&
249 arg->params[0].attr == OPTEE_MSG_ATTR_TYPE_VALUE_INPUT;
250 }
251
252 static void *optee_construct_page_list(void *buf, uint32_t len, uint64_t *phys_buf);
253
optee_call_supp(const struct device * dev,uint32_t func,size_t num_params,struct tee_param * param)254 static uint32_t optee_call_supp(const struct device *dev, uint32_t func, size_t num_params,
255 struct tee_param *param)
256 {
257 struct optee_driver_data *data = (struct optee_driver_data *)dev->data;
258 struct optee_supp *supp = &data->supp;
259 struct optee_supp_req *req;
260 uint32_t ret;
261
262 req = k_malloc(sizeof(*req));
263 if (!req) {
264 return TEEC_ERROR_OUT_OF_MEMORY;
265 }
266
267 k_sem_init(&req->complete, 0, 1);
268 req->func = func;
269 req->num_params = num_params;
270 req->param = param;
271
272 /* Insert the request in the request list */
273 k_mutex_lock(&supp->mutex, K_FOREVER);
274 sys_dlist_append(&supp->reqs, &req->link);
275 k_mutex_unlock(&supp->mutex);
276
277 /* Tell an event listener there's a new request */
278 k_sem_give(&supp->reqs_c);
279
280 /*
281 * Wait for supplicant to process and return result, once we've
282 * returned from k_sem_take(&req->c) successfully we have
283 * exclusive access again.
284 */
285
286 k_sem_take(&req->complete, K_FOREVER);
287
288 ret = req->ret;
289 k_free(req);
290
291 return ret;
292 }
293
cmd_alloc_suppl(const struct device * dev,size_t sz,struct tee_shm ** shm)294 static int cmd_alloc_suppl(const struct device *dev, size_t sz, struct tee_shm **shm)
295 {
296 uint32_t ret;
297 struct tee_param param;
298
299 param.attr = TEE_PARAM_ATTR_TYPE_VALUE_INOUT;
300 param.a = OPTEE_RPC_SHM_TYPE_APPL;
301 param.b = sz;
302 param.c = 0;
303
304 ret = optee_call_supp(dev, OPTEE_RPC_CMD_SHM_ALLOC, 1, ¶m);
305
306 if (ret) {
307 return ret;
308 }
309
310 ret = tee_add_shm(dev, (void *)param.c, 0, param.b, 0, shm);
311
312 return ret;
313 }
314
cmd_free_suppl(const struct device * dev,struct tee_shm * shm)315 static void cmd_free_suppl(const struct device *dev, struct tee_shm *shm)
316 {
317 struct tee_param param;
318
319 param.attr = TEE_PARAM_ATTR_TYPE_VALUE_INOUT;
320 param.a = OPTEE_RPC_SHM_TYPE_APPL;
321 param.b = (uint64_t)shm;
322 param.c = 0;
323
324 optee_call_supp(dev, OPTEE_RPC_CMD_SHM_FREE, 1, ¶m);
325 tee_rm_shm(dev, shm);
326 }
327
handle_cmd_alloc(const struct device * dev,struct optee_msg_arg * arg,void ** pages)328 static void handle_cmd_alloc(const struct device *dev, struct optee_msg_arg *arg,
329 void **pages)
330 {
331 int rc;
332 struct tee_shm *shm = NULL;
333 void *pl;
334 uint64_t pl_phys_and_offset;
335
336 arg->ret_origin = TEEC_ORIGIN_COMMS;
337
338 if (!check_param_input(arg)) {
339 arg->ret = TEEC_ERROR_BAD_PARAMETERS;
340 return;
341 }
342
343 switch (arg->params[0].u.value.a) {
344 case OPTEE_RPC_SHM_TYPE_KERNEL:
345 /* TODO handle situation when shm was allocated statically so buffer can be reused*/
346 rc = tee_add_shm(dev, NULL, 0, arg->params[0].u.value.b, TEE_SHM_ALLOC, &shm);
347 break;
348 case OPTEE_RPC_SHM_TYPE_APPL:
349 rc = cmd_alloc_suppl(dev, arg->params[0].u.value.b, &shm);
350 break;
351 default:
352 arg->ret = TEEC_ERROR_BAD_PARAMETERS;
353 return;
354 }
355
356 if (rc) {
357 if (rc == -ENOMEM) {
358 arg->ret = TEEC_ERROR_OUT_OF_MEMORY;
359 } else {
360 arg->ret = TEEC_ERROR_GENERIC;
361 }
362 return;
363 }
364
365 pl = optee_construct_page_list(shm->addr, shm->size, &pl_phys_and_offset);
366 if (!pl) {
367 arg->ret = TEEC_ERROR_OUT_OF_MEMORY;
368 goto out;
369 }
370
371 *pages = pl;
372 arg->params[0].attr = OPTEE_MSG_ATTR_TYPE_TMEM_OUTPUT | OPTEE_MSG_ATTR_NONCONTIG;
373 arg->params[0].u.tmem.buf_ptr = pl_phys_and_offset;
374 arg->params[0].u.tmem.size = shm->size;
375 arg->params[0].u.tmem.shm_ref = (uint64_t)shm;
376 arg->ret = TEEC_SUCCESS;
377 return;
378 out:
379 tee_shm_free(dev, shm);
380 }
381
handle_cmd_free(const struct device * dev,struct optee_msg_arg * arg)382 static void handle_cmd_free(const struct device *dev, struct optee_msg_arg *arg)
383 {
384 int rc = 0;
385
386 if (!check_param_input(arg)) {
387 arg->ret = TEEC_ERROR_BAD_PARAMETERS;
388 return;
389 }
390
391 switch (arg->params[0].u.value.a) {
392 case OPTEE_RPC_SHM_TYPE_KERNEL:
393 rc = tee_rm_shm(dev, (struct tee_shm *)arg->params[0].u.value.b);
394 break;
395 case OPTEE_RPC_SHM_TYPE_APPL:
396 cmd_free_suppl(dev, (struct tee_shm *)arg->params[0].u.value.b);
397 break;
398 default:
399 arg->ret = TEEC_ERROR_BAD_PARAMETERS;
400 return;
401 }
402
403 if (rc) {
404 arg->ret = TEEC_ERROR_OUT_OF_MEMORY;
405 return;
406 }
407
408 arg->ret = TEEC_SUCCESS;
409 }
410
handle_cmd_get_time(const struct device * dev,struct optee_msg_arg * arg)411 static void handle_cmd_get_time(const struct device *dev, struct optee_msg_arg *arg)
412 {
413 int64_t ticks;
414 int64_t up_secs;
415 int64_t up_nsecs;
416
417 if (arg->num_params != 1 ||
418 (arg->params[0].attr & OPTEE_MSG_ATTR_TYPE_MASK)
419 != OPTEE_MSG_ATTR_TYPE_VALUE_OUTPUT) {
420 arg->ret = TEEC_ERROR_BAD_PARAMETERS;
421 return;
422 }
423
424 ticks = k_uptime_ticks();
425
426 up_secs = ticks / CONFIG_SYS_CLOCK_TICKS_PER_SEC;
427 up_nsecs = k_ticks_to_ns_floor64(ticks - up_secs * CONFIG_SYS_CLOCK_TICKS_PER_SEC);
428 arg->params[0].u.value.a = up_secs;
429 arg->params[0].u.value.b = up_nsecs;
430
431 arg->ret = TEEC_SUCCESS;
432 }
433
434 /* This should be called under notif_lock */
key_is_pending(struct optee_driver_data * data,uint32_t key)435 static inline bool key_is_pending(struct optee_driver_data *data, uint32_t key)
436 {
437 struct optee_notify *iter;
438
439 SYS_DLIST_FOR_EACH_CONTAINER(&data->notif, iter, node) {
440 if (iter->key == key) {
441 k_sem_give(&iter->wait);
442 return true;
443 }
444 }
445
446 return false;
447 }
448
optee_notif_send(const struct device * dev,uint32_t key)449 static int optee_notif_send(const struct device *dev, uint32_t key)
450 {
451 struct optee_driver_data *data = dev->data;
452 k_spinlock_key_t sp_key;
453
454 if (key > CONFIG_OPTEE_MAX_NOTIF) {
455 return -EINVAL;
456 }
457
458 sp_key = k_spin_lock(&data->notif_lock);
459 if (!key_is_pending(data, key)) {
460 /* If nobody is waiting for key - set bit in the bitmap */
461 sys_bitarray_set_bit(data->notif_bitmap, key);
462 }
463 k_spin_unlock(&data->notif_lock, sp_key);
464
465 return 0;
466 }
467
optee_notif_wait(const struct device * dev,uint32_t key)468 static int optee_notif_wait(const struct device *dev, uint32_t key)
469 {
470 int rc = 0;
471 struct optee_driver_data *data = dev->data;
472 struct optee_notify *entry;
473 k_spinlock_key_t sp_key;
474 int prev_val;
475
476 if (key > CONFIG_OPTEE_MAX_NOTIF) {
477 return -EINVAL;
478 }
479
480 entry = k_malloc(sizeof(*entry));
481 if (!entry) {
482 return -ENOMEM;
483 }
484
485 k_sem_init(&entry->wait, 0, 1);
486 entry->key = key;
487
488 sp_key = k_spin_lock(&data->notif_lock);
489
490 /*
491 * If notif bit was set then SEND command was already received.
492 * Skipping wait.
493 */
494 rc = sys_bitarray_test_and_clear_bit(data->notif_bitmap, key, &prev_val);
495 if (rc || prev_val) {
496 goto out;
497 }
498
499 /*
500 * If key is already registred, then skip.
501 */
502 if (key_is_pending(data, key)) {
503 rc = -EBUSY;
504 goto out;
505 }
506
507 sys_dlist_append(&data->notif, &entry->node);
508
509 k_spin_unlock(&data->notif_lock, sp_key);
510 k_sem_take(&entry->wait, K_FOREVER);
511 sp_key = k_spin_lock(&data->notif_lock);
512
513 sys_dlist_remove(&entry->node);
514 out:
515 k_spin_unlock(&data->notif_lock, sp_key);
516
517 k_free(entry);
518
519 return rc;
520 }
521
handle_cmd_notify(const struct device * dev,struct optee_msg_arg * arg)522 static void handle_cmd_notify(const struct device *dev, struct optee_msg_arg *arg)
523 {
524 if (!check_param_input(arg)) {
525 arg->ret = TEEC_ERROR_BAD_PARAMETERS;
526 return;
527 }
528
529 switch (arg->params[0].u.value.a) {
530 case OPTEE_RPC_NOTIFICATION_SEND:
531 if (optee_notif_send(dev, arg->params[0].u.value.b)) {
532 goto err;
533 }
534 break;
535 case OPTEE_RPC_NOTIFICATION_WAIT:
536 if (optee_notif_wait(dev, arg->params[0].u.value.b)) {
537 goto err;
538 }
539 break;
540 default:
541 goto err;
542 }
543
544 arg->ret = TEEC_SUCCESS;
545 return;
546
547 err:
548 arg->ret = TEEC_ERROR_BAD_PARAMETERS;
549 }
550
handle_cmd_wait(const struct device * dev,struct optee_msg_arg * arg)551 static void handle_cmd_wait(const struct device *dev, struct optee_msg_arg *arg)
552 {
553 if (!check_param_input(arg)) {
554 arg->ret = TEEC_ERROR_BAD_PARAMETERS;
555 return;
556 }
557
558 k_sleep(K_MSEC(arg->params[0].u.value.a));
559
560 arg->ret = TEEC_SUCCESS;
561 }
562
free_shm_pages(void ** pages)563 static void free_shm_pages(void **pages)
564 {
565 /*
566 * Clean allocated pages if needed. Some function calls requires pages
567 * allocation which should be freed after processing new request.
568 * It is safe to free this list when another SHM op (e,g. another alloc
569 * or free) was received.
570 */
571 if (*pages) {
572 k_free(*pages);
573 *pages = NULL;
574 }
575 }
576
handle_rpc_supp_cmd(const struct device * dev,struct optee_msg_arg * arg)577 static void handle_rpc_supp_cmd(const struct device *dev, struct optee_msg_arg *arg)
578 {
579 struct tee_param *params;
580 int ret;
581
582 arg->ret_origin = TEEC_ORIGIN_COMMS;
583
584 params = k_malloc(sizeof(*params) * arg->num_params);
585 if (!params) {
586 arg->ret = TEEC_ERROR_OUT_OF_MEMORY;
587 return;
588 }
589
590 ret = msg_param_to_param(params, arg->num_params, arg->params);
591 if (ret) {
592 arg->ret = TEEC_ERROR_BAD_PARAMETERS;
593 arg->ret_origin = TEEC_ORIGIN_COMMS;
594 goto out;
595 }
596
597 arg->ret = optee_call_supp(dev, arg->cmd, arg->num_params, params);
598
599 ret = param_to_msg_param(params, arg->num_params, arg->params);
600 if (ret) {
601 arg->ret = TEEC_ERROR_GENERIC;
602 arg->ret_origin = TEEC_ORIGIN_COMMS;
603 }
604 out:
605 k_free(params);
606 }
607
handle_func_rpc_call(const struct device * dev,struct tee_shm * shm,void ** pages)608 static uint32_t handle_func_rpc_call(const struct device *dev, struct tee_shm *shm,
609 void **pages)
610 {
611 struct optee_msg_arg *arg = shm->addr;
612
613 switch (arg->cmd) {
614 case OPTEE_RPC_CMD_SHM_ALLOC:
615 free_shm_pages(pages);
616 handle_cmd_alloc(dev, arg, pages);
617 break;
618 case OPTEE_RPC_CMD_SHM_FREE:
619 handle_cmd_free(dev, arg);
620 break;
621 case OPTEE_RPC_CMD_GET_TIME:
622 handle_cmd_get_time(dev, arg);
623 break;
624 case OPTEE_RPC_CMD_NOTIFICATION:
625 handle_cmd_notify(dev, arg);
626 break;
627 case OPTEE_RPC_CMD_SUSPEND:
628 handle_cmd_wait(dev, arg);
629 break;
630 case OPTEE_RPC_CMD_I2C_TRANSFER:
631 /* TODO: i2c transfer case is not implemented right now */
632 return TEEC_ERROR_NOT_IMPLEMENTED;
633 default:
634 handle_rpc_supp_cmd(dev, arg);
635 break;
636 }
637
638 return OPTEE_SMC_CALL_RETURN_FROM_RPC;
639 }
640
handle_rpc_call(const struct device * dev,struct optee_rpc_param * param,void ** pages)641 static void handle_rpc_call(const struct device *dev, struct optee_rpc_param *param,
642 void **pages)
643 {
644 struct tee_shm *shm = NULL;
645 uint32_t res = OPTEE_SMC_CALL_RETURN_FROM_RPC;
646
647 switch (OPTEE_SMC_RETURN_GET_RPC_FUNC(param->a0)) {
648 case OPTEE_SMC_RPC_FUNC_ALLOC:
649 if (!tee_add_shm(dev, NULL, OPTEE_MSG_NONCONTIG_PAGE_SIZE,
650 param->a1,
651 TEE_SHM_ALLOC, &shm)) {
652 u64_to_regs((uint64_t)k_mem_phys_addr(shm->addr), ¶m->a1, ¶m->a2);
653 u64_to_regs((uint64_t)shm, ¶m->a4, ¶m->a5);
654 } else {
655 param->a1 = 0;
656 param->a2 = 0;
657 param->a4 = 0;
658 param->a5 = 0;
659 }
660 break;
661 case OPTEE_SMC_RPC_FUNC_FREE:
662 shm = (struct tee_shm *)regs_to_u64(param->a1, param->a2);
663 tee_rm_shm(dev, shm);
664 break;
665 case OPTEE_SMC_RPC_FUNC_FOREIGN_INTR:
666 /* Foreign interrupt was raised */
667 break;
668 case OPTEE_SMC_RPC_FUNC_CMD:
669 shm = (struct tee_shm *)regs_to_u64(param->a1, param->a2);
670 res = handle_func_rpc_call(dev, shm, pages);
671 break;
672 default:
673 break;
674 }
675
676 param->a0 = res;
677 }
678
optee_call(const struct device * dev,struct optee_msg_arg * arg)679 static int optee_call(const struct device *dev, struct optee_msg_arg *arg)
680 {
681 struct optee_driver_data *data = (struct optee_driver_data *)dev->data;
682 struct optee_rpc_param param = {
683 .a0 = OPTEE_SMC_CALL_WITH_ARG
684 };
685 void *pages = NULL;
686
687 u64_to_regs((uint64_t)k_mem_phys_addr(arg), ¶m.a1, ¶m.a2);
688
689 k_sem_take(&data->call_sem, K_FOREVER);
690 while (true) {
691 struct arm_smccc_res res;
692
693 data->smc_call(param.a0, param.a1, param.a2, param.a3,
694 param.a4, param.a5, param.a6, param.a7, &res);
695
696 if (OPTEE_SMC_RETURN_IS_RPC(res.a0)) {
697 param.a0 = res.a0;
698 param.a1 = res.a1;
699 param.a2 = res.a2;
700 param.a3 = res.a3;
701 handle_rpc_call(dev, ¶m, &pages);
702 } else {
703 free_shm_pages(&pages);
704 k_sem_give(&data->call_sem);
705 return res.a0 == OPTEE_SMC_RETURN_OK ? TEEC_SUCCESS :
706 TEEC_ERROR_BAD_PARAMETERS;
707 }
708 }
709 }
710
optee_get_version(const struct device * dev,struct tee_version_info * info)711 static int optee_get_version(const struct device *dev, struct tee_version_info *info)
712 {
713 if (!info) {
714 return -EINVAL;
715 }
716
717 /*
718 * TODO Version and capabilities should be requested from
719 * OP-TEE OS.
720 */
721
722 info->impl_id = TEE_IMPL_ID_OPTEE;
723 info->impl_caps = TEE_OPTEE_CAP_TZ;
724 info->gen_caps = TEE_GEN_CAP_GP | TEE_GEN_CAP_REG_MEM;
725
726 return 0;
727 }
728
optee_close_session(const struct device * dev,uint32_t session_id)729 static int optee_close_session(const struct device *dev, uint32_t session_id)
730 {
731 int rc;
732 struct tee_shm *shm;
733 struct optee_msg_arg *marg;
734
735 rc = tee_add_shm(dev, NULL, OPTEE_MSG_NONCONTIG_PAGE_SIZE,
736 OPTEE_MSG_GET_ARG_SIZE(0),
737 TEE_SHM_ALLOC, &shm);
738 if (rc) {
739 LOG_ERR("Unable to get shared memory, rc = %d", rc);
740 return rc;
741 }
742
743 marg = shm->addr;
744 marg->num_params = 0;
745 marg->cmd = OPTEE_MSG_CMD_CLOSE_SESSION;
746 marg->session = session_id;
747
748 rc = optee_call(dev, marg);
749
750 if (tee_rm_shm(dev, shm)) {
751 LOG_ERR("Unable to free shared memory");
752 }
753
754 return rc;
755 }
756
optee_open_session(const struct device * dev,struct tee_open_session_arg * arg,unsigned int num_param,struct tee_param * param,uint32_t * session_id)757 static int optee_open_session(const struct device *dev, struct tee_open_session_arg *arg,
758 unsigned int num_param, struct tee_param *param,
759 uint32_t *session_id)
760 {
761 int rc, ret;
762 struct tee_shm *shm;
763 struct optee_msg_arg *marg;
764
765 if (!arg || !session_id) {
766 return -EINVAL;
767 }
768
769 rc = tee_add_shm(dev, NULL, OPTEE_MSG_NONCONTIG_PAGE_SIZE,
770 OPTEE_MSG_GET_ARG_SIZE(num_param + 2),
771 TEE_SHM_ALLOC, &shm);
772 if (rc) {
773 LOG_ERR("Unable to get shared memory, rc = %d", rc);
774 return rc;
775 }
776
777 marg = shm->addr;
778 memset(marg, 0, OPTEE_MSG_GET_ARG_SIZE(num_param + 2));
779
780 marg->num_params = num_param + 2;
781 marg->cmd = OPTEE_MSG_CMD_OPEN_SESSION;
782 marg->params[0].attr = OPTEE_MSG_ATTR_TYPE_VALUE_INPUT | OPTEE_MSG_ATTR_META;
783 marg->params[1].attr = OPTEE_MSG_ATTR_TYPE_VALUE_INPUT | OPTEE_MSG_ATTR_META;
784
785 memcpy(&marg->params[0].u.value, arg->uuid, sizeof(arg->uuid));
786 memcpy(&marg->params[1].u.value, arg->uuid, sizeof(arg->clnt_uuid));
787
788 marg->params[1].u.value.c = arg->clnt_login;
789
790 rc = param_to_msg_param(param, num_param, marg->params + 2);
791 if (rc) {
792 goto out;
793 }
794
795 arg->ret = optee_call(dev, marg);
796 if (arg->ret) {
797 arg->ret_origin = TEEC_ORIGIN_COMMS;
798 goto out;
799 }
800
801 rc = msg_param_to_param(param, num_param, marg->params);
802 if (rc) {
803 arg->ret = TEEC_ERROR_COMMUNICATION;
804 arg->ret_origin = TEEC_ORIGIN_COMMS;
805 /*
806 * Ret is needed here only to print an error. Param conversion error
807 * should be returned from the function.
808 */
809 ret = optee_close_session(dev, marg->session);
810 if (ret) {
811 LOG_ERR("Unable to close session: %d", ret);
812 }
813 goto out;
814 }
815
816 *session_id = marg->session;
817
818 arg->ret = marg->ret;
819 arg->ret_origin = marg->ret_origin;
820 out:
821 ret = tee_rm_shm(dev, shm);
822 if (ret) {
823 LOG_ERR("Unable to free shared memory");
824 }
825
826 return (rc) ? rc : ret;
827 }
828
optee_cancel(const struct device * dev,uint32_t session_id,uint32_t cancel_id)829 static int optee_cancel(const struct device *dev, uint32_t session_id, uint32_t cancel_id)
830 {
831 int rc;
832 struct tee_shm *shm;
833 struct optee_msg_arg *marg;
834
835 rc = tee_add_shm(dev, NULL, OPTEE_MSG_NONCONTIG_PAGE_SIZE,
836 OPTEE_MSG_GET_ARG_SIZE(0),
837 TEE_SHM_ALLOC, &shm);
838 if (rc) {
839 LOG_ERR("Unable to get shared memory, rc = %d", rc);
840 return rc;
841 }
842
843 marg = shm->addr;
844 marg->num_params = 0;
845 marg->cmd = OPTEE_MSG_CMD_CANCEL;
846 marg->cancel_id = cancel_id;
847 marg->session = session_id;
848
849 rc = optee_call(dev, marg);
850
851 if (tee_rm_shm(dev, shm)) {
852 LOG_ERR("Unable to free shared memory");
853 }
854
855 return rc;
856 }
857
optee_invoke_func(const struct device * dev,struct tee_invoke_func_arg * arg,unsigned int num_param,struct tee_param * param)858 static int optee_invoke_func(const struct device *dev, struct tee_invoke_func_arg *arg,
859 unsigned int num_param, struct tee_param *param)
860 {
861 int rc, ret;
862 struct tee_shm *shm;
863 struct optee_msg_arg *marg;
864
865 if (!arg) {
866 return -EINVAL;
867 }
868
869 rc = tee_add_shm(dev, NULL, OPTEE_MSG_NONCONTIG_PAGE_SIZE,
870 OPTEE_MSG_GET_ARG_SIZE(num_param),
871 TEE_SHM_ALLOC, &shm);
872 if (rc) {
873 LOG_ERR("Unable to get shared memory, rc = %d", rc);
874 return rc;
875 }
876
877 marg = shm->addr;
878 memset(marg, 0, OPTEE_MSG_GET_ARG_SIZE(num_param));
879
880 marg->num_params = num_param;
881 marg->cmd = OPTEE_MSG_CMD_INVOKE_COMMAND;
882 marg->func = arg->func;
883 marg->session = arg->session;
884
885 rc = param_to_msg_param(param, num_param, marg->params);
886 if (rc) {
887 goto out;
888 }
889
890 arg->ret = optee_call(dev, marg);
891 if (arg->ret) {
892 arg->ret_origin = TEEC_ORIGIN_COMMS;
893 goto out;
894 }
895
896 rc = msg_param_to_param(param, num_param, marg->params);
897 if (rc) {
898 arg->ret = TEEC_ERROR_COMMUNICATION;
899 arg->ret_origin = TEEC_ORIGIN_COMMS;
900 goto out;
901 }
902
903 arg->ret = marg->ret;
904 arg->ret_origin = marg->ret_origin;
905 out:
906 ret = tee_rm_shm(dev, shm);
907 if (ret) {
908 LOG_ERR("Unable to free shared memory");
909 }
910
911 return (rc) ? rc : ret;
912 }
913
optee_construct_page_list(void * buf,uint32_t len,uint64_t * phys_buf)914 static void *optee_construct_page_list(void *buf, uint32_t len, uint64_t *phys_buf)
915 {
916 const size_t page_size = OPTEE_MSG_NONCONTIG_PAGE_SIZE;
917 const size_t num_pages_in_pl = OPTEE_NUMBER_OF_ADDR_PER_PAGE - 1;
918 uint32_t page_offset = (uintptr_t)buf & (page_size - 1);
919
920 uint8_t *buf_page;
921 uint32_t num_pages;
922 uint32_t list_size;
923
924 /* see description of OPTEE_MSG_ATTR_NONCONTIG */
925 struct {
926 uint64_t pages[OPTEE_NUMBER_OF_ADDR_PER_PAGE - 1];
927 uint64_t next_page;
928 } *pl;
929
930 BUILD_ASSERT(sizeof(*pl) == OPTEE_MSG_NONCONTIG_PAGE_SIZE);
931
932 num_pages = ROUND_UP(page_offset + len, page_size) / page_size;
933 list_size = DIV_ROUND_UP(num_pages, num_pages_in_pl) * page_size;
934
935 pl = k_aligned_alloc(page_size, list_size);
936 if (!pl) {
937 return NULL;
938 }
939
940 memset(pl, 0, list_size);
941
942 buf_page = (uint8_t *)ROUND_DOWN((uintptr_t)buf, page_size);
943
944 for (uint32_t pl_idx = 0; pl_idx < list_size / page_size; pl_idx++) {
945 for (uint32_t page_idx = 0; num_pages && page_idx < num_pages_in_pl; page_idx++) {
946 pl[pl_idx].pages[page_idx] = k_mem_phys_addr(buf_page);
947 buf_page += page_size;
948 num_pages--;
949 }
950
951 if (!num_pages) {
952 break;
953 }
954
955 pl[pl_idx].next_page = k_mem_phys_addr(pl + 1);
956 }
957
958 /* 12 least significant bits of optee_msg_param.u.tmem.buf_ptr should hold page offset
959 * of user buffer
960 */
961 *phys_buf = k_mem_phys_addr(pl) | page_offset;
962
963 return pl;
964 }
965
optee_shm_register(const struct device * dev,struct tee_shm * shm)966 static int optee_shm_register(const struct device *dev, struct tee_shm *shm)
967 {
968 struct tee_shm *shm_arg;
969 struct optee_msg_arg *msg_arg;
970 void *pl;
971 uint64_t pl_phys_and_offset;
972 int rc;
973
974 rc = tee_add_shm(dev, NULL, OPTEE_MSG_NONCONTIG_PAGE_SIZE, OPTEE_MSG_GET_ARG_SIZE(1),
975 TEE_SHM_ALLOC, &shm_arg);
976 if (rc) {
977 return rc;
978 }
979
980 msg_arg = shm_arg->addr;
981
982 memset(msg_arg, 0, OPTEE_MSG_GET_ARG_SIZE(1));
983
984 pl = optee_construct_page_list(shm->addr, shm->size, &pl_phys_and_offset);
985 if (!pl) {
986 rc = -ENOMEM;
987 goto out;
988 }
989
990 /* for this command op-tee os should support CFG_CORE_DYN_SHM */
991 msg_arg->cmd = OPTEE_MSG_CMD_REGISTER_SHM;
992 /* op-tee OS ingnore this cmd in case when TYPE_TMEM_OUTPUT and NONCONTIG aren't set */
993 msg_arg->params->attr = OPTEE_MSG_ATTR_TYPE_TMEM_OUTPUT | OPTEE_MSG_ATTR_NONCONTIG;
994 msg_arg->num_params = 1;
995 msg_arg->params->u.tmem.buf_ptr = pl_phys_and_offset;
996 msg_arg->params->u.tmem.shm_ref = (uint64_t)shm;
997 msg_arg->params->u.tmem.size = shm->size;
998
999 if (optee_call(dev, msg_arg)) {
1000 rc = -EINVAL;
1001 }
1002
1003 k_free(pl);
1004 out:
1005 tee_rm_shm(dev, shm_arg);
1006
1007 return rc;
1008 }
1009
optee_shm_unregister(const struct device * dev,struct tee_shm * shm)1010 static int optee_shm_unregister(const struct device *dev, struct tee_shm *shm)
1011 {
1012 struct tee_shm *shm_arg;
1013 struct optee_msg_arg *msg_arg;
1014 int rc;
1015
1016 rc = tee_add_shm(dev, NULL, OPTEE_MSG_NONCONTIG_PAGE_SIZE, OPTEE_MSG_GET_ARG_SIZE(1),
1017 TEE_SHM_ALLOC, &shm_arg);
1018 if (rc) {
1019 return rc;
1020 }
1021
1022 msg_arg = shm_arg->addr;
1023
1024 memset(msg_arg, 0, OPTEE_MSG_GET_ARG_SIZE(1));
1025
1026 msg_arg->cmd = OPTEE_MSG_CMD_UNREGISTER_SHM;
1027 msg_arg->num_params = 1;
1028 msg_arg->params[0].attr = OPTEE_MSG_ATTR_TYPE_RMEM_INPUT;
1029 msg_arg->params[0].u.rmem.shm_ref = (uint64_t)shm;
1030
1031 if (optee_call(dev, msg_arg)) {
1032 rc = -EINVAL;
1033 }
1034
1035 tee_rm_shm(dev, shm_arg);
1036 return rc;
1037 }
1038
optee_suppl_recv(const struct device * dev,uint32_t * func,unsigned int * num_params,struct tee_param * param)1039 static int optee_suppl_recv(const struct device *dev, uint32_t *func, unsigned int *num_params,
1040 struct tee_param *param)
1041 {
1042 struct optee_driver_data *data = (struct optee_driver_data *)dev->data;
1043 struct optee_supp *supp = &data->supp;
1044 struct optee_supp_req *req = NULL;
1045
1046 while (true) {
1047 k_mutex_lock(&supp->mutex, K_FOREVER);
1048 req = (struct optee_supp_req *)sys_dlist_peek_head(&supp->reqs);
1049
1050 if (req) {
1051 if (supp->current) {
1052 LOG_ERR("Concurrent supp_recv calls are not supported");
1053 k_mutex_unlock(&supp->mutex);
1054 return -EBUSY;
1055 }
1056
1057 if (*num_params < req->num_params) {
1058 LOG_ERR("Not enough space for params, need at least %lu",
1059 req->num_params);
1060 k_mutex_unlock(&supp->mutex);
1061 return -EINVAL;
1062 }
1063
1064 supp->current = req;
1065 sys_dlist_remove(&req->link);
1066 }
1067 k_mutex_unlock(&supp->mutex);
1068
1069 if (req) {
1070 break;
1071 }
1072
1073 k_sem_take(&supp->reqs_c, K_FOREVER);
1074 }
1075
1076 *func = req->func;
1077 *num_params = req->num_params;
1078 memcpy(param, req->param, sizeof(struct tee_param) * req->num_params);
1079
1080 return 0;
1081 }
1082
optee_suppl_send(const struct device * dev,unsigned int ret,unsigned int num_params,struct tee_param * param)1083 static int optee_suppl_send(const struct device *dev, unsigned int ret, unsigned int num_params,
1084 struct tee_param *param)
1085 {
1086 struct optee_driver_data *data = (struct optee_driver_data *)dev->data;
1087 struct optee_supp *supp = &data->supp;
1088 struct optee_supp_req *req = NULL;
1089 size_t n;
1090
1091 k_mutex_lock(&supp->mutex, K_FOREVER);
1092 if (supp->current && num_params >= supp->current->num_params) {
1093 req = supp->current;
1094 supp->current = NULL;
1095 } else {
1096 LOG_ERR("Invalid number of parameters, expected %lu got %u", req->num_params,
1097 num_params);
1098 }
1099 k_mutex_unlock(&supp->mutex);
1100
1101 if (!req) {
1102 return -EINVAL;
1103 }
1104
1105 /* Update out and in/out parameters */
1106 for (n = 0; n < req->num_params; n++) {
1107 struct tee_param *p = req->param + n;
1108
1109 switch (p->attr & TEE_PARAM_ATTR_TYPE_MASK) {
1110 case TEE_PARAM_ATTR_TYPE_VALUE_OUTPUT:
1111 case TEE_PARAM_ATTR_TYPE_VALUE_INOUT:
1112 p->a = param[n].a;
1113 p->b = param[n].b;
1114 p->c = param[n].c;
1115 break;
1116 case TEE_PARAM_ATTR_TYPE_MEMREF_OUTPUT:
1117 case TEE_PARAM_ATTR_TYPE_MEMREF_INOUT:
1118 LOG_WRN("Memref params are not fully tested");
1119 p->a = param[n].a;
1120 p->b = param[n].b;
1121 p->c = param[n].c;
1122 break;
1123 default:
1124 break;
1125 }
1126 }
1127 req->ret = ret;
1128
1129 /* Let the requesting thread continue */
1130 k_mutex_lock(&supp->mutex, K_FOREVER);
1131 supp->current = NULL;
1132 k_mutex_unlock(&supp->mutex);
1133 k_sem_give(&req->complete);
1134
1135 return 0;
1136 }
1137
set_optee_method(const struct device * dev)1138 static int set_optee_method(const struct device *dev)
1139 {
1140 const struct optee_driver_config *conf = dev->config;
1141 struct optee_driver_data *data = dev->data;
1142
1143 if (!strcmp("hvc", conf->method)) {
1144 data->smc_call = optee_smccc_hvc;
1145 } else if (!strcmp("smc", conf->method)) {
1146 data->smc_call = optee_smccc_smc;
1147 } else {
1148 LOG_ERR("Invalid smc_call method");
1149 return -EINVAL;
1150 }
1151
1152 return 0;
1153 }
1154
optee_check_uid(const struct device * dev)1155 static bool optee_check_uid(const struct device *dev)
1156 {
1157 struct arm_smccc_res res;
1158 struct optee_driver_data *data = (struct optee_driver_data *)dev->data;
1159
1160 data->smc_call(OPTEE_SMC_CALLS_UID, 0, 0, 0, 0, 0, 0, 0, &res);
1161
1162 if (res.a0 == OPTEE_MSG_UID_0 && res.a1 == OPTEE_MSG_UID_1 &&
1163 res.a2 == OPTEE_MSG_UID_2 && res.a3 == OPTEE_MSG_UID_3) {
1164 return true;
1165 }
1166
1167 return false;
1168 }
1169
optee_get_revision(const struct device * dev)1170 static void optee_get_revision(const struct device *dev)
1171 {
1172 struct optee_driver_data *data = (struct optee_driver_data *)dev->data;
1173 struct arm_smccc_res res = { 0 };
1174
1175 data->smc_call(OPTEE_SMC_CALL_GET_OS_REVISION, 0, 0, 0, 0, 0, 0, 0, &res);
1176
1177 if (res.a2) {
1178 LOG_INF("OPTEE revision %lu.%lu (%08lx)", res.a0,
1179 res.a1, res.a2);
1180 } else {
1181 LOG_INF("OPTEE revision %lu.%lu", res.a0, res.a1);
1182 }
1183 }
1184
optee_exchange_caps(const struct device * dev,unsigned long * sec_caps)1185 static bool optee_exchange_caps(const struct device *dev, unsigned long *sec_caps)
1186 {
1187 struct optee_driver_data *data = (struct optee_driver_data *)dev->data;
1188 struct arm_smccc_res res = { 0 };
1189 unsigned long a1 = 0;
1190
1191 if (!IS_ENABLED(CONFIG_SMP) || arch_num_cpus() == 1) {
1192 a1 |= OPTEE_SMC_NSEC_CAP_UNIPROCESSOR;
1193 }
1194
1195 data->smc_call(OPTEE_SMC_EXCHANGE_CAPABILITIES, a1, 0, 0, 0, 0, 0, 0, &res);
1196
1197 if (res.a0 != OPTEE_SMC_RETURN_OK) {
1198 return false;
1199 }
1200
1201 *sec_caps = res.a1;
1202 return true;
1203 }
1204
optee_get_thread_count(const struct device * dev,unsigned long * thread_count)1205 static unsigned long optee_get_thread_count(const struct device *dev, unsigned long *thread_count)
1206 {
1207 struct optee_driver_data *data = (struct optee_driver_data *)dev->data;
1208 struct arm_smccc_res res = { 0 };
1209 unsigned long a1 = 0;
1210
1211 data->smc_call(OPTEE_SMC_GET_THREAD_COUNT, a1, 0, 0, 0, 0, 0, 0, &res);
1212
1213 if (res.a0 != OPTEE_SMC_RETURN_OK) {
1214 return false;
1215 }
1216
1217 *thread_count = res.a1;
1218 return true;
1219 }
1220
optee_init(const struct device * dev)1221 static int optee_init(const struct device *dev)
1222 {
1223 struct optee_driver_data *data = dev->data;
1224 unsigned long thread_count;
1225
1226 if (set_optee_method(dev)) {
1227 return -ENOTSUP;
1228 }
1229
1230 sys_dlist_init(&data->notif);
1231 k_mutex_init(&data->supp.mutex);
1232 k_sem_init(&data->supp.reqs_c, 0, 1);
1233 sys_dlist_init(&data->supp.reqs);
1234
1235 if (!optee_check_uid(dev)) {
1236 LOG_ERR("OPTEE API UID mismatch");
1237 return -EINVAL;
1238 }
1239
1240 optee_get_revision(dev);
1241
1242 if (!optee_exchange_caps(dev, &data->sec_caps)) {
1243 LOG_ERR("OPTEE capabilities exchange failed\n");
1244 return -EINVAL;
1245 }
1246
1247 if (!(data->sec_caps & OPTEE_SMC_SEC_CAP_DYNAMIC_SHM)) {
1248 LOG_ERR("OPTEE does not support dynamic shared memory");
1249 return -ENOTSUP;
1250 }
1251
1252 if (!optee_get_thread_count(dev, &thread_count)) {
1253 LOG_ERR("OPTEE unable to get maximum thread count");
1254 return -ENOTSUP;
1255 }
1256
1257 k_sem_init(&data->call_sem, thread_count, thread_count);
1258
1259 return 0;
1260 }
1261
1262 static DEVICE_API(tee, optee_driver_api) = {
1263 .get_version = optee_get_version,
1264 .open_session = optee_open_session,
1265 .close_session = optee_close_session,
1266 .cancel = optee_cancel,
1267 .invoke_func = optee_invoke_func,
1268 .shm_register = optee_shm_register,
1269 .shm_unregister = optee_shm_unregister,
1270 .suppl_recv = optee_suppl_recv,
1271 .suppl_send = optee_suppl_send,
1272 };
1273
1274 /*
1275 * Bitmap of the ongoing notificatons, received from OP-TEE. Maximum number is
1276 * CONFIG_OPTEE_MAX_NOTIF. This bitmap is needed to handle case when SEND command
1277 * was received before WAIT command from OP-TEE. In this case WAIT will not create
1278 * locks.
1279 */
1280 #define OPTEE_DT_DEVICE_INIT(inst) \
1281 SYS_BITARRAY_DEFINE_STATIC(notif_bitmap_##inst, CONFIG_OPTEE_MAX_NOTIF); \
1282 \
1283 static struct optee_driver_config optee_config_##inst = { \
1284 .method = DT_INST_PROP(inst, method) \
1285 }; \
1286 \
1287 static struct optee_driver_data optee_data_##inst = { \
1288 .notif_bitmap = ¬if_bitmap_##inst \
1289 }; \
1290 \
1291 DEVICE_DT_INST_DEFINE(inst, optee_init, NULL, &optee_data_##inst, \
1292 &optee_config_##inst, POST_KERNEL, \
1293 CONFIG_KERNEL_INIT_PRIORITY_DEVICE, \
1294 &optee_driver_api); \
1295
1296 DT_INST_FOREACH_STATUS_OKAY(OPTEE_DT_DEVICE_INIT)
1297