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)
34 cmd->origin = TEEC_ORIGIN_API;
35 cmd->err = TEEC_SUCCESS;
41 TEEC_Result TEEC_InitializeContext(const char *name, TEEC_Context *context)
44 struct tee_context *ctx;
45 pr_cont("%s: > name=\"%s\"\n", __func__, name);
48 return TEEC_ERROR_BAD_PARAMETERS;
53 strncpy(context->devname, TEE_TZ_DEVICE_NAME,
54 sizeof(context->devname));
56 strncpy(context->devname, name, sizeof(context->devname));
58 tee = tee_get_tee(context->devname);
60 pr_err("%s - can't get device [%s]\n", __func__, name);
61 return TEEC_ERROR_BAD_PARAMETERS;
64 ctx = tee_context_create(tee);
65 if (IS_ERR_OR_NULL(ctx))
66 return TEEC_ERROR_BAD_PARAMETERS;
70 /* TODO fixme will not work on 64-bit platform */
71 context->fd = (int)(uintptr_t)ctx;
72 BUG_ON(ctx != (struct tee_context *)(uintptr_t)context->fd);
74 pr_cont("%s: < ctx=%p is created\n", __func__, (void *)ctx);
77 EXPORT_SYMBOL(TEEC_InitializeContext);
79 void TEEC_FinalizeContext(TEEC_Context *context)
81 if (!context || !context->fd) {
82 pr_err("%s - can't release context %p:[%s]\n", __func__,
84 && context->devname) ? context->devname : "");
87 /* TODO fixme will not work on 64-bit platform */
88 tee_context_destroy((struct tee_context *)(uintptr_t)context->fd);
91 EXPORT_SYMBOL(TEEC_FinalizeContext);
93 TEEC_Result TEEC_OpenSession(TEEC_Context *context,
94 TEEC_Session *session,
95 const TEEC_UUID *destination,
96 uint32_t connectionMethod,
97 const void *connectionData,
98 TEEC_Operation *operation,
99 uint32_t *return_origin)
101 TEEC_Operation dummy_op;
102 struct tee_cmd_io cmd;
103 struct tee_session *sess;
104 struct tee_context *ctx;
108 * The code here exist because Global Platform API states that
109 * it is allowed to give operation as a NULL pointer.
110 * In kernel and secure world we in most cases don't want
111 * this to be NULL, hence we use this dummy operation when
112 * a client doesn't provide any operation.
114 memset(&dummy_op, 0, sizeof(TEEC_Operation));
115 operation = &dummy_op;
118 if (!context || !session || !destination || !operation
120 return TEEC_ERROR_BAD_PARAMETERS;
124 /* TODO fixme will not work on 64-bit platform */
125 ctx = (struct tee_context *)(uintptr_t)context->fd;
128 cmd.uuid = (TEEC_UUID *) destination;
130 sess = tee_session_create_and_open(ctx, &cmd);
131 if (IS_ERR_OR_NULL(sess)) {
133 *return_origin = cmd.origin;
135 *return_origin = TEEC_ORIGIN_COMMS;
139 return TEEC_ERROR_COMMUNICATION;
141 *return_origin = cmd.origin;
142 /* TODO fixme will not work on 64-bit platform */
143 session->fd = (int)(uintptr_t)sess;
144 BUG_ON(sess != (struct tee_session *)(uintptr_t)session->fd);
148 EXPORT_SYMBOL(TEEC_OpenSession);
150 void TEEC_CloseSession(TEEC_Session *session)
152 if (session && session->fd) {
153 /* TODO fixme will not work on 64-bit platform */
154 struct tee_session *sess =
155 (struct tee_session *)(uintptr_t)session->fd;
156 tee_session_close_and_destroy(sess);
159 EXPORT_SYMBOL(TEEC_CloseSession);
161 TEEC_Result TEEC_InvokeCommand(TEEC_Session *session,
163 TEEC_Operation *operation,
164 uint32_t *return_origin)
167 struct tee_cmd_io cmd;
168 struct tee_session *sess;
170 if (!session || !operation || !return_origin || !session->fd)
171 return TEEC_ERROR_BAD_PARAMETERS;
173 /* TODO fixme will not work on 64-bit platform */
174 sess = (struct tee_session *)(uintptr_t)session->fd;
179 ret = tee_session_invoke_be(sess, &cmd);
182 *return_origin = cmd.origin;
184 *return_origin = TEEC_ORIGIN_COMMS;
188 return TEEC_ERROR_COMMUNICATION;
190 *return_origin = cmd.origin;
194 EXPORT_SYMBOL(TEEC_InvokeCommand);
196 TEEC_Result TEEC_RegisterSharedMemory(TEEC_Context *context,
197 TEEC_SharedMemory *sharedMem)
200 return TEEC_ERROR_BAD_PARAMETERS;
202 sharedMem->registered = 1;
205 EXPORT_SYMBOL(TEEC_RegisterSharedMemory);
207 TEEC_Result TEEC_AllocateSharedMemory(TEEC_Context *context,
208 TEEC_SharedMemory *shared_memory)
210 struct tee_shm_io shm_io;
214 if (!context || !context->ctx || !shared_memory)
215 return TEEC_ERROR_BAD_PARAMETERS;
217 shm_io.size = shared_memory->size;
218 shm_io.flags = shared_memory->flags | TEEC_MEM_KAPI;
219 ret = tee_shm_alloc_io(context->ctx, &shm_io);
221 pr_err("%s: tee_shm_alloc_io(%zd) failed\n", __func__,
222 shared_memory->size);
223 return TEEC_ERROR_OUT_OF_MEMORY;
226 shared_memory->registered = 0;
227 shared_memory->flags = shm_io.flags;
228 shared_memory->d.fd = shm_io.fd_shm;
230 shm = (struct tee_shm *)(long)shm_io.fd_shm;
231 shared_memory->buffer = shm->kaddr;
233 pr_debug("%s(%zd) => fd=%d, kaddr=%p\n", __func__,
234 shm_io.size, shm_io.fd_shm, (void *)shared_memory->buffer);
238 EXPORT_SYMBOL(TEEC_AllocateSharedMemory);
240 void TEEC_ReleaseSharedMemory(TEEC_SharedMemory *shared_memory)
244 if (!shared_memory || shared_memory->registered)
247 pr_debug("%s (vaddr = %p)\n", __func__, shared_memory->buffer);
249 shm = (struct tee_shm *)(long)shared_memory->d.fd;
250 tee_shm_free_io(shm);
252 shared_memory->buffer = NULL;
253 shared_memory->d.fd = 0;
255 EXPORT_SYMBOL(TEEC_ReleaseSharedMemory);