pico-imx7d: Increase the CONFIG_ENV_OFFSET size
[pandora-u-boot.git] / drivers / tee / optee / supplicant.c
1 // SPDX-License-Identifier: BSD-2-Clause
2 /*
3  * Copyright (c) 2018, Linaro Limited
4  */
5
6 #include <common.h>
7 #include <log.h>
8 #include <tee.h>
9 #include <linux/types.h>
10
11 #include "optee_msg.h"
12 #include "optee_msg_supplicant.h"
13 #include "optee_private.h"
14 #include "optee_smc.h"
15
16 static void cmd_shm_alloc(struct udevice *dev, struct optee_msg_arg *arg,
17                           void **page_list)
18 {
19         int rc;
20         struct tee_shm *shm;
21         void *pl;
22         u64 ph_ptr;
23
24         arg->ret_origin = TEE_ORIGIN_COMMS;
25
26         if (arg->num_params != 1 ||
27             arg->params[0].attr != OPTEE_MSG_ATTR_TYPE_VALUE_INPUT) {
28                 arg->ret = TEE_ERROR_BAD_PARAMETERS;
29                 return;
30         }
31
32         rc = __tee_shm_add(dev, 0, NULL, arg->params[0].u.value.b,
33                            TEE_SHM_REGISTER | TEE_SHM_ALLOC, &shm);
34         if (rc) {
35                 if (rc == -ENOMEM)
36                         arg->ret = TEE_ERROR_OUT_OF_MEMORY;
37                 else
38                         arg->ret = TEE_ERROR_GENERIC;
39                 return;
40         }
41
42         pl = optee_alloc_and_init_page_list(shm->addr, shm->size, &ph_ptr);
43         if (!pl) {
44                 arg->ret = TEE_ERROR_OUT_OF_MEMORY;
45                 tee_shm_free(shm);
46                 return;
47         }
48
49         *page_list = pl;
50         arg->params[0].attr = OPTEE_MSG_ATTR_TYPE_TMEM_OUTPUT |
51                               OPTEE_MSG_ATTR_NONCONTIG;
52         arg->params[0].u.tmem.buf_ptr = ph_ptr;
53         arg->params[0].u.tmem.size = shm->size;
54         arg->params[0].u.tmem.shm_ref = (ulong)shm;
55         arg->ret = TEE_SUCCESS;
56 }
57
58 static void cmd_shm_free(struct optee_msg_arg *arg)
59 {
60         arg->ret_origin = TEE_ORIGIN_COMMS;
61
62         if (arg->num_params != 1 ||
63             arg->params[0].attr != OPTEE_MSG_ATTR_TYPE_VALUE_INPUT) {
64                 arg->ret = TEE_ERROR_BAD_PARAMETERS;
65                 return;
66         }
67
68         tee_shm_free((struct tee_shm *)(ulong)arg->params[0].u.value.b);
69         arg->ret = TEE_SUCCESS;
70 }
71
72 void optee_suppl_cmd(struct udevice *dev, struct tee_shm *shm_arg,
73                      void **page_list)
74 {
75         struct optee_msg_arg *arg = shm_arg->addr;
76
77         switch (arg->cmd) {
78         case OPTEE_MSG_RPC_CMD_SHM_ALLOC:
79                 cmd_shm_alloc(dev, arg, page_list);
80                 break;
81         case OPTEE_MSG_RPC_CMD_SHM_FREE:
82                 cmd_shm_free(arg);
83                 break;
84         case OPTEE_MSG_RPC_CMD_FS:
85                 debug("OPTEE_MSG_RPC_CMD_FS not implemented\n");
86                 arg->ret = TEE_ERROR_NOT_IMPLEMENTED;
87                 break;
88         case OPTEE_MSG_RPC_CMD_RPMB:
89                 optee_suppl_cmd_rpmb(dev, arg);
90                 break;
91         default:
92                 arg->ret = TEE_ERROR_NOT_IMPLEMENTED;
93         }
94
95         arg->ret_origin = TEE_ORIGIN_COMMS;
96 }