2 * Copyright (c) 2014, STMicroelectronics International N.V.
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License Version 2 as
6 * published by the Free Software Foundation.
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
13 #include <linux/module.h>
14 #include <linux/device.h>
15 #include <linux/miscdevice.h>
17 #include <linux/vmalloc.h>
19 #include "linux/tee_kernel_api.h"
20 #include "linux/tee_core.h"
21 #include "linux/tee_ioc.h"
23 #include "tee_core_priv.h"
25 #include "tee_supp_com.h"
27 #define TEE_TZ_DEVICE_NAME "opteearmtz00"
29 static void reset_tee_cmd(struct tee_cmd_io *cmd)
31 memset(cmd, 0, sizeof(struct tee_cmd_io));
35 cmd->origin = TEEC_ORIGIN_API;
36 cmd->err = TEEC_SUCCESS;
42 TEEC_Result TEEC_InitializeContext(const char *name, TEEC_Context *context)
45 struct tee_context *ctx;
46 pr_cont("%s: > name=\"%s\"\n", __func__, name);
49 return TEEC_ERROR_BAD_PARAMETERS;
54 strncpy(context->devname, TEE_TZ_DEVICE_NAME,
55 sizeof(context->devname));
57 strncpy(context->devname, name, sizeof(context->devname));
59 tee = tee_get_tee(context->devname);
61 pr_err("%s - can't get device [%s]\n", __func__, name);
62 return TEEC_ERROR_BAD_PARAMETERS;
65 ctx = tee_context_create(tee);
66 if (IS_ERR_OR_NULL(ctx))
67 return TEEC_ERROR_BAD_PARAMETERS;
71 /* TODO fixme will not work on 64-bit platform */
72 context->fd = (int)(uintptr_t)ctx;
73 BUG_ON(ctx != (struct tee_context *)(uintptr_t)context->fd);
75 pr_cont("%s: < ctx=%p is created\n", __func__, (void *)ctx);
78 EXPORT_SYMBOL(TEEC_InitializeContext);
80 void TEEC_FinalizeContext(TEEC_Context *context)
82 if (!context || !context->fd) {
83 pr_err("%s - can't release context %p:[%s]\n", __func__,
85 && context->devname) ? context->devname : "");
88 /* TODO fixme will not work on 64-bit platform */
89 tee_context_destroy((struct tee_context *)(uintptr_t)context->fd);
92 EXPORT_SYMBOL(TEEC_FinalizeContext);
94 TEEC_Result TEEC_OpenSession(TEEC_Context *context,
95 TEEC_Session *session,
96 const TEEC_UUID *destination,
97 uint32_t connectionMethod,
98 const void *connectionData,
99 TEEC_Operation *operation,
100 uint32_t *return_origin)
102 TEEC_Operation dummy_op;
103 struct tee_cmd_io cmd;
104 struct tee_session *sess;
105 struct tee_context *ctx;
109 * The code here exist because Global Platform API states that
110 * it is allowed to give operation as a NULL pointer.
111 * In kernel and secure world we in most cases don't want
112 * this to be NULL, hence we use this dummy operation when
113 * a client doesn't provide any operation.
115 memset(&dummy_op, 0, sizeof(TEEC_Operation));
116 operation = &dummy_op;
119 if (!context || !session || !destination || !operation
121 return TEEC_ERROR_BAD_PARAMETERS;
125 /* TODO fixme will not work on 64-bit platform */
126 ctx = (struct tee_context *)(uintptr_t)context->fd;
129 cmd.uuid = (TEEC_UUID *) destination;
131 sess = tee_session_create_and_open(ctx, &cmd);
132 if (IS_ERR_OR_NULL(sess)) {
134 *return_origin = cmd.origin;
136 *return_origin = TEEC_ORIGIN_COMMS;
140 return TEEC_ERROR_COMMUNICATION;
142 *return_origin = cmd.origin;
143 /* TODO fixme will not work on 64-bit platform */
144 session->fd = (int)(uintptr_t)sess;
145 BUG_ON(sess != (struct tee_session *)(uintptr_t)session->fd);
149 EXPORT_SYMBOL(TEEC_OpenSession);
151 void TEEC_CloseSession(TEEC_Session *session)
153 if (session && session->fd) {
154 /* TODO fixme will not work on 64-bit platform */
155 struct tee_session *sess =
156 (struct tee_session *)(uintptr_t)session->fd;
157 tee_session_close_and_destroy(sess);
160 EXPORT_SYMBOL(TEEC_CloseSession);
162 TEEC_Result TEEC_InvokeCommand(TEEC_Session *session,
164 TEEC_Operation *operation,
165 uint32_t *return_origin)
168 struct tee_cmd_io cmd;
169 struct tee_session *sess;
171 if (!session || !operation || !return_origin || !session->fd)
172 return TEEC_ERROR_BAD_PARAMETERS;
174 /* TODO fixme will not work on 64-bit platform */
175 sess = (struct tee_session *)(uintptr_t)session->fd;
180 ret = tee_session_invoke_be(sess, &cmd);
183 *return_origin = cmd.origin;
185 *return_origin = TEEC_ORIGIN_COMMS;
189 return TEEC_ERROR_COMMUNICATION;
191 *return_origin = cmd.origin;
195 EXPORT_SYMBOL(TEEC_InvokeCommand);
197 TEEC_Result TEEC_RegisterSharedMemory(TEEC_Context *context,
198 TEEC_SharedMemory *sharedMem)
201 return TEEC_ERROR_BAD_PARAMETERS;
203 sharedMem->registered = 1;
206 EXPORT_SYMBOL(TEEC_RegisterSharedMemory);
208 TEEC_Result TEEC_AllocateSharedMemory(TEEC_Context *context,
209 TEEC_SharedMemory *shared_memory)
211 struct tee_shm_io shm_io;
215 if (!context || !context->ctx || !shared_memory)
216 return TEEC_ERROR_BAD_PARAMETERS;
218 shm_io.size = shared_memory->size;
219 shm_io.flags = shared_memory->flags | TEEC_MEM_KAPI;
220 ret = tee_shm_alloc_io(context->ctx, &shm_io);
222 pr_err("%s: tee_shm_alloc_io(%zd) failed\n", __func__,
223 shared_memory->size);
224 return TEEC_ERROR_OUT_OF_MEMORY;
227 shared_memory->registered = 0;
228 shared_memory->flags = shm_io.flags;
229 shared_memory->d.fd = shm_io.fd_shm;
231 shm = (struct tee_shm *)(long)shm_io.fd_shm;
232 shared_memory->buffer = shm->kaddr;
234 pr_debug("%s(%d) => fd=%d, kaddr=%p\n", __func__,
235 shm_io.size, shm_io.fd_shm, (void *)shared_memory->buffer);
239 EXPORT_SYMBOL(TEEC_AllocateSharedMemory);
241 void TEEC_ReleaseSharedMemory(TEEC_SharedMemory *shared_memory)
245 if (!shared_memory || shared_memory->registered)
248 pr_debug("%s (vaddr = %p)\n", __func__, shared_memory->buffer);
250 shm = (struct tee_shm *)(long)shared_memory->d.fd;
251 tee_shm_free_io(shm);
253 shared_memory->buffer = NULL;
254 shared_memory->d.fd = 0;
256 EXPORT_SYMBOL(TEEC_ReleaseSharedMemory);