xref: /rk3399_rockchip-uboot/lib/optee_clientApi/OpteeClientApiLib.c (revision 1d30eaa5cee0c484510623d18e5ae237a22cdfad)
1abdd2437Shisping /*
2abdd2437Shisping  * Copyright 2017, Rockchip Electronics Co., Ltd
3abdd2437Shisping  * hisping lin, <hisping.lin@rock-chips.com>
4abdd2437Shisping  *
5abdd2437Shisping  * SPDX-License-Identifier:	GPL-2.0+
6abdd2437Shisping  */
7abdd2437Shisping #include <common.h>
8abdd2437Shisping #include <optee_include/OpteeClientApiLib.h>
9abdd2437Shisping #include <optee_include/OpteeClientMem.h>
1074eb6027SHisping Lin #include <optee_include/OpteeClientRPC.h>
11abdd2437Shisping #include <optee_include/OpteeClientSMC.h>
121f25ada2SHisping Lin #include <optee_include/OpteeClientRkFs.h>
1374eb6027SHisping Lin #include <optee_include/teesmc.h>
1474eb6027SHisping Lin #include <optee_include/teesmc_optee.h>
1574eb6027SHisping Lin #include <optee_include/teesmc_v2.h>
1674eb6027SHisping Lin 
1774eb6027SHisping Lin #define OPTEE_MSG_REVISION_MAJOR        2
1874eb6027SHisping Lin #define OPTEE_MSG_REVISION_MINOR        0
1974eb6027SHisping Lin 
207a349fdcSElon Zhang static bool optee_is_init;
217a349fdcSElon Zhang 
optee_vm_create(uint32_t client_id)22*1d30eaa5SHisping Lin static bool optee_vm_create(uint32_t client_id)
23*1d30eaa5SHisping Lin {
24*1d30eaa5SHisping Lin 	ARM_SMC_ARGS ArmSmcArgs = {0};
25*1d30eaa5SHisping Lin 
26*1d30eaa5SHisping Lin 	ArmSmcArgs.Arg0 = OPTEE_SMC_VM_CREATED;
27*1d30eaa5SHisping Lin 	ArmSmcArgs.Arg1 = client_id;
28*1d30eaa5SHisping Lin 
29*1d30eaa5SHisping Lin 	tee_smc_call(&ArmSmcArgs);
30*1d30eaa5SHisping Lin 
31*1d30eaa5SHisping Lin 	if (ArmSmcArgs.Arg0 != 0)
32*1d30eaa5SHisping Lin 		return false;
33*1d30eaa5SHisping Lin 
34*1d30eaa5SHisping Lin 	return true;
35*1d30eaa5SHisping Lin }
36*1d30eaa5SHisping Lin 
optee_vm_destroyed(uint32_t client_id)37*1d30eaa5SHisping Lin static bool optee_vm_destroyed(uint32_t client_id)
38*1d30eaa5SHisping Lin {
39*1d30eaa5SHisping Lin 	ARM_SMC_ARGS ArmSmcArgs = {0};
40*1d30eaa5SHisping Lin 
41*1d30eaa5SHisping Lin 	ArmSmcArgs.Arg0 = OPTEE_SMC_VM_DESTROYED;
42*1d30eaa5SHisping Lin 	ArmSmcArgs.Arg1 = client_id;
43*1d30eaa5SHisping Lin 
44*1d30eaa5SHisping Lin 	tee_smc_call(&ArmSmcArgs);
45*1d30eaa5SHisping Lin 
46*1d30eaa5SHisping Lin 	if (ArmSmcArgs.Arg0 != 0)
47*1d30eaa5SHisping Lin 		return false;
48*1d30eaa5SHisping Lin 
49*1d30eaa5SHisping Lin 	return true;
50*1d30eaa5SHisping Lin }
51*1d30eaa5SHisping Lin 
optee_exchange_capabilities(uint32_t * sec_caps)52*1d30eaa5SHisping Lin static bool optee_exchange_capabilities(uint32_t *sec_caps)
53*1d30eaa5SHisping Lin {
54*1d30eaa5SHisping Lin 	ARM_SMC_ARGS ArmSmcArgs = {0};
55*1d30eaa5SHisping Lin 
56*1d30eaa5SHisping Lin 	ArmSmcArgs.Arg0 = OPTEE_SMC_EXCHANGE_CAPABILITIES;
57*1d30eaa5SHisping Lin 
58*1d30eaa5SHisping Lin 	tee_smc_call(&ArmSmcArgs);
59*1d30eaa5SHisping Lin 
60*1d30eaa5SHisping Lin 	if (ArmSmcArgs.Arg0 != 0)
61*1d30eaa5SHisping Lin 		return false;
62*1d30eaa5SHisping Lin 	*sec_caps = ArmSmcArgs.Arg1;
63*1d30eaa5SHisping Lin 	return true;
64*1d30eaa5SHisping Lin }
65*1d30eaa5SHisping Lin 
optee_api_revision_is_compatible(void)6674eb6027SHisping Lin static bool optee_api_revision_is_compatible(void)
6774eb6027SHisping Lin {
6874eb6027SHisping Lin 	ARM_SMC_ARGS ArmSmcArgs = {0};
6974eb6027SHisping Lin 
7074eb6027SHisping Lin 	ArmSmcArgs.Arg0 = OPTEE_SMC_CALLS_REVISION;
7174eb6027SHisping Lin 
7274eb6027SHisping Lin 	tee_smc_call(&ArmSmcArgs);
7374eb6027SHisping Lin 
7474eb6027SHisping Lin 	if (ArmSmcArgs.Arg0 == OPTEE_MSG_REVISION_MAJOR &&
7574eb6027SHisping Lin 	    ArmSmcArgs.Arg1 >= OPTEE_MSG_REVISION_MINOR) {
7674eb6027SHisping Lin 		printf("optee api revision: %d.%d\n",
7774eb6027SHisping Lin 		       ArmSmcArgs.Arg0, ArmSmcArgs.Arg1);
7874eb6027SHisping Lin 		return true;
7974eb6027SHisping Lin 	} else {
8074eb6027SHisping Lin 		printf("optee check api revision fail: %d.%d\n",
8174eb6027SHisping Lin 		       ArmSmcArgs.Arg0, ArmSmcArgs.Arg1);
8274eb6027SHisping Lin 		return false;
8374eb6027SHisping Lin 	}
8474eb6027SHisping Lin }
85abdd2437Shisping 
optee_get_shm_config(phys_addr_t * base,phys_size_t * size)86396e3049SElon Zhang void optee_get_shm_config(phys_addr_t *base, phys_size_t *size)
87396e3049SElon Zhang {
88396e3049SElon Zhang 	ARM_SMC_ARGS ArmSmcArgs = {0};
89396e3049SElon Zhang 
90396e3049SElon Zhang 	ArmSmcArgs.Arg0 = OPTEE_SMC_GET_SHM_CONFIG_V2;
91396e3049SElon Zhang 
92396e3049SElon Zhang 	tee_smc_call(&ArmSmcArgs);
93396e3049SElon Zhang 
94396e3049SElon Zhang 	*base = ArmSmcArgs.Arg1;
95396e3049SElon Zhang 	*size = ArmSmcArgs.Arg2;
96396e3049SElon Zhang }
97396e3049SElon Zhang 
98abdd2437Shisping /*
99abdd2437Shisping  * Initlialize the library
100abdd2437Shisping  */
OpteeClientApiLibInitialize(void)101abdd2437Shisping TEEC_Result OpteeClientApiLibInitialize(void)
102abdd2437Shisping {
103abdd2437Shisping 	TEEC_Result status = TEEC_SUCCESS;
104abdd2437Shisping 
1057a349fdcSElon Zhang 	if (optee_is_init)
1067a349fdcSElon Zhang 		return TEEC_SUCCESS;
1077a349fdcSElon Zhang 
10874eb6027SHisping Lin 	/* check api revision compatibility */
10974eb6027SHisping Lin 	if (!optee_api_revision_is_compatible())
11074eb6027SHisping Lin 		panic("optee api revision is too low");
11174eb6027SHisping Lin 
112f4e1db95SHisping Lin 	status = OpteeClientMemInit();
113f4e1db95SHisping Lin 	if (status != TEEC_SUCCESS) {
114efb93541SHisping Lin 		printf("TEEC: OpteeClientMemInit fail!\n");
115abdd2437Shisping 		return status;
116abdd2437Shisping 	}
117f4e1db95SHisping Lin 	status = OpteeClientRkFsInit();
118f4e1db95SHisping Lin 	if (status != TEEC_SUCCESS) {
119efb93541SHisping Lin 		printf("TEEC: OpteeClientRkFsInit fail!\n");
120f4e1db95SHisping Lin 		return status;
121f4e1db95SHisping Lin 	}
122f4e1db95SHisping Lin 
1237a349fdcSElon Zhang 	optee_is_init = true;
1247a349fdcSElon Zhang 
125f4e1db95SHisping Lin 	return TEEC_SUCCESS;
126f4e1db95SHisping Lin }
127abdd2437Shisping 
128abdd2437Shisping /*
129abdd2437Shisping  * This function initializes a new TEE Context, connecting this Client
130abdd2437Shisping  * application to the TEE indentified by the name name.
131abdd2437Shisping  *
132abdd2437Shisping  * name == NULL will give the default TEE.
133abdd2437Shisping  *
134abdd2437Shisping  * In this implementation only the default name is supported.
135abdd2437Shisping  * If name != NULL then TEEC_ERROR_ITEM_NOT_FOUND is returned.
136abdd2437Shisping  */
TEEC_InitializeContext(const char * name,TEEC_Context * context)137abdd2437Shisping TEEC_Result TEEC_InitializeContext(const char *name,
138abdd2437Shisping 				TEEC_Context *context)
139abdd2437Shisping {
140abdd2437Shisping 	TEEC_Result teecresult = TEEC_SUCCESS;
141*1d30eaa5SHisping Lin 	uint32_t sec_caps = 0;
142abdd2437Shisping 
143abdd2437Shisping 	debug("TEEC_InitializeContext Enter: name=%s  context=%s  0x%X\n",
144abdd2437Shisping 			name, context->devname, context->fd);
145abdd2437Shisping 
146*1d30eaa5SHisping Lin 
147abdd2437Shisping 	if (context == NULL) {
148abdd2437Shisping 		teecresult = TEEC_ERROR_BAD_PARAMETERS;
149abdd2437Shisping 		goto exit;
150abdd2437Shisping 	}
151abdd2437Shisping 
152abdd2437Shisping 	if (name != NULL) {
153abdd2437Shisping 		teecresult = TEEC_ERROR_ITEM_NOT_FOUND;
154abdd2437Shisping 		goto exit;
155abdd2437Shisping 	}
156abdd2437Shisping 
157abdd2437Shisping 	memset(context, 0, sizeof(*context));
158abdd2437Shisping 
159*1d30eaa5SHisping Lin 	/* get optee capabilities */
160*1d30eaa5SHisping Lin 	if (!optee_exchange_capabilities(&sec_caps))
161*1d30eaa5SHisping Lin 		panic("optee exchange capabilities fail!");
162*1d30eaa5SHisping Lin 
163*1d30eaa5SHisping Lin 	/* optee vm create */
164*1d30eaa5SHisping Lin 	if (sec_caps & OPTEE_SMC_SEC_CAP_VIRTUALIZATION) {
165*1d30eaa5SHisping Lin 		if (!optee_vm_create(0))
166*1d30eaa5SHisping Lin 			panic("optee vm create fail!");
167*1d30eaa5SHisping Lin 	}
168*1d30eaa5SHisping Lin 
169abdd2437Shisping exit:
170efb93541SHisping Lin 	debug("TEEC_InitializeContext Exit : teecresult=0x%X\n", teecresult);
171abdd2437Shisping 	return teecresult;
172abdd2437Shisping }
173abdd2437Shisping 
174abdd2437Shisping /*
175abdd2437Shisping  * This function destroys an initialized TEE Context, closing the connection
176abdd2437Shisping  * between the Client and the TEE.
177abdd2437Shisping  * The function implementation MUST do nothing if context is NULL
178abdd2437Shisping  *
179abdd2437Shisping  * There is nothing to do here since there is no context state.
180abdd2437Shisping  */
TEEC_FinalizeContext(TEEC_Context * context)181abdd2437Shisping TEEC_Result TEEC_FinalizeContext(TEEC_Context *context)
182abdd2437Shisping {
183*1d30eaa5SHisping Lin 	uint32_t sec_caps = 0;
184*1d30eaa5SHisping Lin 
185*1d30eaa5SHisping Lin 	/* get optee capabilities */
186*1d30eaa5SHisping Lin 	if (!optee_exchange_capabilities(&sec_caps))
187*1d30eaa5SHisping Lin 		panic("optee exchange capabilities fail!");
188*1d30eaa5SHisping Lin 
189*1d30eaa5SHisping Lin 	/* optee vm destroyed */
190*1d30eaa5SHisping Lin 	if (sec_caps & OPTEE_SMC_SEC_CAP_VIRTUALIZATION) {
191*1d30eaa5SHisping Lin 		if (!optee_vm_destroyed(0))
192*1d30eaa5SHisping Lin 			panic("optee vm destroyed fail!");
193*1d30eaa5SHisping Lin 	}
194*1d30eaa5SHisping Lin 
1951f25ada2SHisping Lin 	debug("TEEC_FinalizeContext Enter-Exit: context=0x%zu\n",
1961f25ada2SHisping Lin 		(size_t)context);
197abdd2437Shisping 	return TEEC_SUCCESS;
198abdd2437Shisping }
199abdd2437Shisping 
200abdd2437Shisping /*
201abdd2437Shisping  * Allocates or registers shared memory.
202abdd2437Shisping  *
203abdd2437Shisping  * Since EDK2 is configured flat with virtual memory == physical memory
204abdd2437Shisping  * then we don't need to perform any special operations to get physical
205abdd2437Shisping  * contiguous memory.
206abdd2437Shisping  */
TEEC_AllocateSharedMemory(TEEC_Context * context,TEEC_SharedMemory * shared_memory)207abdd2437Shisping TEEC_Result TEEC_AllocateSharedMemory(TEEC_Context *context,
208abdd2437Shisping 			TEEC_SharedMemory *shared_memory)
209abdd2437Shisping {
210abdd2437Shisping 	TEEC_Result TeecResult = TEEC_SUCCESS;
211abdd2437Shisping 
2121f25ada2SHisping Lin 	debug("TEEC_AllocateSharedMemory Enter: context=%s 0x%X, shared_memory=0x%zu\n",
213abdd2437Shisping 		context->devname, context->fd, shared_memory->size);
214abdd2437Shisping 
215abdd2437Shisping 	if ((context == NULL) || (shared_memory == NULL)) {
216abdd2437Shisping 		TeecResult = TEEC_ERROR_BAD_PARAMETERS;
217abdd2437Shisping 		goto Exit;
218abdd2437Shisping 	}
219abdd2437Shisping 
220abdd2437Shisping 	if (shared_memory->flags != 0) {
221abdd2437Shisping 		TeecResult = TEEC_ERROR_BAD_PARAMETERS;
222abdd2437Shisping 		goto Exit;
223abdd2437Shisping 	}
224abdd2437Shisping 
225abdd2437Shisping 	shared_memory->buffer = NULL;
226abdd2437Shisping 	shared_memory->alloc_buffer = 0;
227abdd2437Shisping 
2281f25ada2SHisping Lin 	debug("TEEC_AllocateSharedMemory: size=0x%zu, flags=0x%X\n",
229abdd2437Shisping 			shared_memory->size, shared_memory->flags);
230abdd2437Shisping 
231abdd2437Shisping 	shared_memory->buffer = OpteeClientMemAlloc(shared_memory->size);
232abdd2437Shisping 	if (shared_memory->buffer == NULL) {
233abdd2437Shisping 		TeecResult = TEEC_ERROR_OUT_OF_MEMORY;
234abdd2437Shisping 		goto Exit;
235abdd2437Shisping 	}
236abdd2437Shisping 
237abdd2437Shisping 	shared_memory->alloc_buffer = shared_memory->buffer;
238abdd2437Shisping 
239abdd2437Shisping Exit:
240abdd2437Shisping 	debug("TEEC_AllocateSharedMemory Exit : TeecResult=0x%X\n", TeecResult);
241abdd2437Shisping 	return TeecResult;
242abdd2437Shisping }
243abdd2437Shisping 
244abdd2437Shisping /*
245abdd2437Shisping  * Releases shared memory.
246abdd2437Shisping  *
247abdd2437Shisping  * The optee_client implementation allows this to be called with a null pointer
248abdd2437Shisping  * and null buffer but we'll assert this is not the case for better debugging.
249abdd2437Shisping  */
TEEC_ReleaseSharedMemory(TEEC_SharedMemory * shared_memory)250abdd2437Shisping void TEEC_ReleaseSharedMemory(TEEC_SharedMemory *shared_memory)
251abdd2437Shisping {
2521f25ada2SHisping Lin 	debug("TEEC_ReleaseSharedMemory Enter: shared_memory=0x%zu\n",
253abdd2437Shisping 				shared_memory->size);
254abdd2437Shisping 
255abdd2437Shisping 	if (shared_memory == NULL)
256abdd2437Shisping 		goto Exit;
257abdd2437Shisping 
258abdd2437Shisping 	if (shared_memory->buffer == NULL)
259abdd2437Shisping 		goto Exit;
260abdd2437Shisping 
261abdd2437Shisping 	if (shared_memory->alloc_buffer != 0) {
262abdd2437Shisping 		OpteeClientMemFree(shared_memory->alloc_buffer);
263abdd2437Shisping 		shared_memory->alloc_buffer = 0;
264abdd2437Shisping 	}
265abdd2437Shisping 
266abdd2437Shisping 	shared_memory->buffer = NULL;
267abdd2437Shisping 	shared_memory->size = 0;
268abdd2437Shisping 
269abdd2437Shisping Exit:
270abdd2437Shisping 	return;
271abdd2437Shisping }
272abdd2437Shisping 
273abdd2437Shisping /*
274abdd2437Shisping  * Register shared memory
275abdd2437Shisping  *
276abdd2437Shisping  * If the supplied buffer is compatible we can use it as supplied otherwise
277abdd2437Shisping  * we'll need to allocate a copy buffer for the transfer instead.
278abdd2437Shisping  */
TEEC_RegisterSharedMemory(TEEC_Context * context,TEEC_SharedMemory * shared_memory)279abdd2437Shisping TEEC_Result TEEC_RegisterSharedMemory(TEEC_Context *context,
280abdd2437Shisping 			TEEC_SharedMemory *shared_memory)
281abdd2437Shisping {
282abdd2437Shisping 	TEEC_Result TeecResult = TEEC_SUCCESS;
283abdd2437Shisping 
284abdd2437Shisping 	if ((context == NULL) || (shared_memory == NULL)) {
285abdd2437Shisping 		TeecResult = TEEC_ERROR_BAD_PARAMETERS;
286abdd2437Shisping 		goto Exit;
287abdd2437Shisping 	}
288abdd2437Shisping 
289abdd2437Shisping 	if (shared_memory->buffer == NULL) {
290abdd2437Shisping 		TeecResult = TEEC_ERROR_BAD_PARAMETERS;
291abdd2437Shisping 		goto Exit;
292abdd2437Shisping 	}
293abdd2437Shisping 
294abdd2437Shisping 	shared_memory->alloc_buffer = 0;
295abdd2437Shisping 
296abdd2437Shisping 	phys_addr_t start = (phys_addr_t) shared_memory->buffer;
297abdd2437Shisping 
298abdd2437Shisping 	if ((start % 4096) != 0) {
299abdd2437Shisping 		TEEC_SharedMemory TempSharedMemory;
300abdd2437Shisping 		TempSharedMemory.size  = shared_memory->size;
301abdd2437Shisping 		TempSharedMemory.flags = shared_memory->flags;
302abdd2437Shisping 
303abdd2437Shisping 		TeecResult = TEEC_AllocateSharedMemory
304abdd2437Shisping 			(context, &TempSharedMemory);
305abdd2437Shisping 
306abdd2437Shisping 		if (TeecResult != TEEC_SUCCESS)
307abdd2437Shisping 			goto Exit;
308abdd2437Shisping 
309abdd2437Shisping 		shared_memory->alloc_buffer = TempSharedMemory.alloc_buffer;
310abdd2437Shisping 	}
311abdd2437Shisping 
312abdd2437Shisping Exit:
313abdd2437Shisping 	debug("TEEC_RegisterSharedMemory Exit : TeecResult=0x%X\n", TeecResult);
314abdd2437Shisping 	return TeecResult;
315abdd2437Shisping }
316abdd2437Shisping 
317abdd2437Shisping /*
318abdd2437Shisping  * This function opens a new Session between the Client application and the
319abdd2437Shisping  * specified TEE application.
320abdd2437Shisping  *
321abdd2437Shisping  * Only connection_method == TEEC_LOGIN_PUBLIC is supported connection_data and
322abdd2437Shisping  * operation shall be set to NULL.
323abdd2437Shisping  */
TEEC_OpenSession(TEEC_Context * context,TEEC_Session * session,const TEEC_UUID * destination,uint32_t connection_method,const void * connection_data,TEEC_Operation * operation,uint32_t * error_origin)324abdd2437Shisping TEEC_Result TEEC_OpenSession(TEEC_Context *context,
325abdd2437Shisping 			TEEC_Session *session,
326abdd2437Shisping 			const TEEC_UUID *destination,
327abdd2437Shisping 			uint32_t connection_method,
328abdd2437Shisping 			const void *connection_data,
329abdd2437Shisping 			TEEC_Operation *operation,
330abdd2437Shisping 			uint32_t *error_origin)
331abdd2437Shisping {
332abdd2437Shisping 	TEEC_Result TeecResult = TEEC_SUCCESS;
333abdd2437Shisping 	uint32_t TeecErrorOrigin = TEEC_ORIGIN_API;
334abdd2437Shisping 
335abdd2437Shisping 	debug("TEEC_OpenSession: session=0x%X, ...\n", session->id);
336abdd2437Shisping 
337abdd2437Shisping 	if ((context == NULL) || (session == NULL) || (destination == NULL)) {
338abdd2437Shisping 		TeecResult = TEEC_ERROR_BAD_PARAMETERS;
339abdd2437Shisping 		goto Exit;
340abdd2437Shisping 	}
341abdd2437Shisping 
342abdd2437Shisping 	if (connection_method != TEEC_LOGIN_PUBLIC) {
343abdd2437Shisping 		TeecResult = TEEC_ERROR_NOT_SUPPORTED;
344abdd2437Shisping 		goto Exit;
345abdd2437Shisping 	}
346abdd2437Shisping 
347abdd2437Shisping 	TEEC_Operation TeecNullOperation = {0};
348abdd2437Shisping 	TEEC_Operation *TeecOperation;
349abdd2437Shisping 
350abdd2437Shisping 	if (operation == NULL) {
351abdd2437Shisping 		memset(&TeecNullOperation, 0, sizeof(TEEC_Operation));
352abdd2437Shisping 		TeecOperation = &TeecNullOperation;
353abdd2437Shisping 	} else {
354abdd2437Shisping 		TeecOperation = operation;
355abdd2437Shisping 	}
356abdd2437Shisping 
357abdd2437Shisping 	TeecResult = TEEC_SMC_OpenSession(context, session, destination,
358abdd2437Shisping 				TeecOperation, &TeecErrorOrigin);
359abdd2437Shisping 
360abdd2437Shisping Exit:
361abdd2437Shisping 	if (error_origin != NULL)
362abdd2437Shisping 		*error_origin = TeecErrorOrigin;
363abdd2437Shisping 
364efb93541SHisping Lin 	debug("TEEC_OpenSession Exit : TeecResult=0x%X, TeecErrorOrigin=0x%X\n",
365abdd2437Shisping 				TeecResult, TeecErrorOrigin);
366abdd2437Shisping 	return TeecResult;
367abdd2437Shisping }
368abdd2437Shisping 
369abdd2437Shisping /*
370abdd2437Shisping  * This function closes a session which has been opened with a TEE
371abdd2437Shisping  * application.
372abdd2437Shisping  */
TEEC_CloseSession(TEEC_Session * session)373abdd2437Shisping void TEEC_CloseSession(TEEC_Session *session)
374abdd2437Shisping {
375abdd2437Shisping 	TEEC_Result TeecResult = TEEC_SUCCESS;
376abdd2437Shisping 	uint32_t TeecErrorOrigin = TEEC_ORIGIN_API;
377abdd2437Shisping 
378abdd2437Shisping 	debug("TEEC_CloseSession Enter: session=0x%X\n", session->id);
379abdd2437Shisping 
380abdd2437Shisping 	if (session == NULL)
381abdd2437Shisping 		goto Exit;
382abdd2437Shisping 
383abdd2437Shisping 	TeecResult = TEEC_SMC_CloseSession(session, &TeecErrorOrigin);
384abdd2437Shisping 
385abdd2437Shisping Exit:
386efb93541SHisping Lin 	debug("TEEC_CloseSession Exit : TeecResult=0x%X, TeecErrorOrigin=0x%X\n",
387abdd2437Shisping 			TeecResult, TeecErrorOrigin);
388abdd2437Shisping 	return;
389abdd2437Shisping }
390abdd2437Shisping 
391abdd2437Shisping /*
392abdd2437Shisping  * Invokes a TEE command (secure service, sub-PA or whatever).
393abdd2437Shisping  */
TEEC_InvokeCommand(TEEC_Session * session,uint32_t cmd_id,TEEC_Operation * operation,uint32_t * error_origin)394abdd2437Shisping TEEC_Result TEEC_InvokeCommand(TEEC_Session *session,
395abdd2437Shisping 				uint32_t cmd_id,
396abdd2437Shisping 				TEEC_Operation *operation,
397abdd2437Shisping 				uint32_t *error_origin)
398abdd2437Shisping {
399abdd2437Shisping 	TEEC_Result TeecResult = TEEC_SUCCESS;
400abdd2437Shisping 	uint32_t TeecErrorOrigin = TEEC_ORIGIN_API;
401abdd2437Shisping 
402abdd2437Shisping 	debug("TEEC_InvokeCommand Enter: session=0x%X, cmd_id=0x%X\n",
403abdd2437Shisping 			session->id, cmd_id);
404abdd2437Shisping 
405abdd2437Shisping 	if (session == NULL) {
406abdd2437Shisping 		TeecResult = TEEC_ERROR_BAD_PARAMETERS;
407abdd2437Shisping 		goto Exit;
408abdd2437Shisping 	}
409abdd2437Shisping 
410abdd2437Shisping 	TEEC_Operation TeecNullOperation = {0};
411abdd2437Shisping 	TEEC_Operation *TeecOperation;
412abdd2437Shisping 
413abdd2437Shisping 	if (operation == NULL)
414abdd2437Shisping 		TeecOperation = &TeecNullOperation;
415abdd2437Shisping 	else
416abdd2437Shisping 		TeecOperation = operation;
417abdd2437Shisping 
418abdd2437Shisping 	TeecResult = TEEC_SMC_InvokeCommand(session, cmd_id,
419abdd2437Shisping 			TeecOperation, &TeecErrorOrigin);
420abdd2437Shisping 
421abdd2437Shisping Exit:
422abdd2437Shisping 	if (error_origin != NULL)
423abdd2437Shisping 		*error_origin = TeecErrorOrigin;
424abdd2437Shisping 
425efb93541SHisping Lin 	debug("TEEC_InvokeCommand Exit : TeecResult=0x%X, TeecErrorOrigin=0x%X\n",
426abdd2437Shisping 				TeecResult, TeecErrorOrigin);
427abdd2437Shisping 
428abdd2437Shisping 	return TeecResult;
429abdd2437Shisping }
430abdd2437Shisping 
431abdd2437Shisping /*
432abdd2437Shisping  * Request a cancellation of a in-progress operation (best effort)
433abdd2437Shisping  */
TEEC_RequestCancellation(TEEC_Operation * operation)434abdd2437Shisping void TEEC_RequestCancellation(TEEC_Operation *operation)
435abdd2437Shisping {
436abdd2437Shisping 	TEEC_Result TeecResult = TEEC_SUCCESS;
437abdd2437Shisping 	uint32_t TeecErrorOrigin = TEEC_ORIGIN_API;
438abdd2437Shisping 
439abdd2437Shisping 	if (operation == NULL)
440abdd2437Shisping 		goto Exit;
441abdd2437Shisping 
442abdd2437Shisping 	TeecResult = TEEC_SMC_RequestCancellation(operation, &TeecErrorOrigin);
443abdd2437Shisping 
444abdd2437Shisping Exit:
445abdd2437Shisping 	debug("TEEC_RequestCancellation Exit : TeecResult=0x%X, TeecErrorOrigin=0x%X\n",
446abdd2437Shisping 			TeecResult, TeecErrorOrigin);
447abdd2437Shisping 
448abdd2437Shisping 	return;
449abdd2437Shisping }
450