xref: /rk3399_rockchip-uboot/lib/optee_clientApi/OpteeClientRPC.c (revision 7c1937d6d1c7daf8e59b4760f8adc7ee42bd7bea)
1 /*
2  * Copyright 2017, Rockchip Electronics Co., Ltd
3  * hisping lin, <hisping.lin@rock-chips.com>
4  *
5  * SPDX-License-Identifier:	GPL-2.0+
6  */
7 #include <common.h>
8 #include <stdlib.h>
9 #include <command.h>
10 #include <mmc.h>
11 #include <optee_include/OpteeClientMem.h>
12 #include <optee_include/OpteeClientRPC.h>
13 #include <optee_include/teesmc.h>
14 #include <optee_include/teesmc_v2.h>
15 #include <optee_include/teesmc_optee.h>
16 #include <optee_include/tee_rpc_types.h>
17 #include <optee_include/tee_rpc.h>
18 #include <optee_include/258be795-f9ca-40e6-a8699ce6886c5d5d.h>
19 #include <optee_include/c11fe8ac-b997-48cf-a28de2a55e5240ef.h>
20 #ifdef CONFIG_OPTEE_V1
21 #include <optee_include/OpteeClientRkFs.h>
22 #endif
23 #ifdef CONFIG_OPTEE_V2
24 #include <optee_include/OpteeClientRkFs-v2.h>
25 #endif
26 
27 /*
28  * Memory allocation.
29  * Currently treated the same for both arguments & payloads.
30  */
31 TEEC_Result OpteeRpcAlloc(uint32_t Size, uint32_t *Address)
32 {
33 	TEEC_Result TeecResult = TEEC_SUCCESS;
34 	size_t AllocAddress;
35 
36 	*Address = 0;
37 
38 	if (Size != 0) {
39 		AllocAddress = (size_t) OpteeClientMemAlloc(Size);
40 
41 		if (AllocAddress == 0)
42 			TeecResult = TEEC_ERROR_OUT_OF_MEMORY;
43 		else
44 			*Address = AllocAddress;
45 	}
46 	return TeecResult;
47 }
48 
49 /*
50  * Memory free.
51  * Currently treated the same for both arguments & payloads.
52  */
53 TEEC_Result OpteeRpcFree(uint32_t Address)
54 {
55 	OpteeClientMemFree((void *)(size_t)Address);
56 	return TEEC_SUCCESS;
57 }
58 
59 int is_uuid_equal(TEE_UUID uuid1, TEEC_UUID uuid2)
60 {
61 	bool a, b, c;
62 
63 	a = (uuid1.timeLow == uuid2.timeLow);
64 	b = (uuid1.timeMid == uuid2.timeMid);
65 	c = (uuid1.timeHiAndVersion == uuid2.timeHiAndVersion);
66 	if ((a & b & c) == 0) {
67 		return 0;
68 	} else {
69 		if (memcmp(uuid1.clockSeqAndNode,
70 			   uuid2.clockSeqAndNode, 8) == 0) {
71 			return 1;
72 		} else {
73 			return 0;
74 		}
75 	}
76 }
77 
78 /*
79  * Load a TA from storage into memory and provide it back to OpTEE.
80  * Param[0] = IN: struct tee_rpc_load_ta_cmd
81  * Param[1] = IN: all-zero OUT: TA Image allocated
82  */
83 TEEC_Result OpteeRpcCmdLoadTa(t_teesmc32_arg *TeeSmc32Arg)
84 {
85 	TEEC_Result TeecResult = TEEC_SUCCESS;
86 	t_teesmc32_param *TeeSmc32Param = NULL;
87 	struct tee_rpc_load_ta_cmd *TeeLoadTaCmd = NULL;
88 	uint32_t TeeLoadTaCmdSize = 0;
89 
90 	if (TeeSmc32Arg->num_params != 2) {
91 		TeecResult = TEEC_ERROR_BAD_PARAMETERS;
92 		goto Exit;
93 	}
94 
95 	TEEC_UUID TA_RK_KEYMASTER_UUID = {0x258be795, 0xf9ca, 0x40e6,
96 			{0xa8, 0x69, 0x9c, 0xe6, 0x88, 0x6c, 0x5d, 0x5d} };
97 	TeeSmc32Param = TEESMC32_GET_PARAMS(TeeSmc32Arg);
98 	TeeLoadTaCmd = (struct tee_rpc_load_ta_cmd *)
99 					(size_t)TeeSmc32Param[0].u.memref.buf_ptr;
100 	TeeLoadTaCmdSize = TeeSmc32Param[0].u.memref.size;
101 
102 	if ((TeeLoadTaCmd == NULL) ||
103 		(TeeLoadTaCmdSize != sizeof(*TeeLoadTaCmd))) {
104 		TeecResult = TEEC_ERROR_BAD_PARAMETERS;
105 		goto Exit;
106 	}
107 
108 	TEEC_Result Status = 0;
109 	void *ImageData = NULL;
110 	uint32_t ImageSize = 0;
111 	size_t AllocAddress = 0;
112 
113 	if (is_uuid_equal(TeeLoadTaCmd->uuid, TA_RK_KEYMASTER_UUID)) {
114 		ImageData = (void *)keymaster_data;
115 		ImageSize = keymaster_size;
116 	} else {
117 		ImageData = (void *)widevine_keybox_data;
118 		ImageSize = widevine_keybox_size;
119 	}
120 
121 	if (Status != 0) {
122 		TeecResult = TEEC_ERROR_ITEM_NOT_FOUND;
123 		goto Exit;
124 	}
125 
126 	AllocAddress = (size_t) OpteeClientMemAlloc(ImageSize);
127 
128 	if (AllocAddress == 0) {
129 		TeecResult = TEEC_ERROR_OUT_OF_MEMORY;
130 		goto Exit;
131 	}
132 
133 	memcpy((void *)AllocAddress, ImageData, ImageSize);
134 
135 	debug("...TA loaded at 0x%zu of size 0x%X bytes\n",
136 		AllocAddress, ImageSize);
137 	debug("...AllocAddress[0] 0x%X ; AllocAddress[1] 0x%X bytes\n",
138 		*(char *)AllocAddress, *(char *)(AllocAddress+1));
139 
140 	TeeLoadTaCmd->va = AllocAddress;
141 
142 	TeeSmc32Param[1].u.memref.buf_ptr = AllocAddress;
143 	TeeSmc32Param[1].u.memref.size = ImageSize;
144 
145 Exit:
146 	TeeSmc32Arg->ret = TeecResult;
147 	TeeSmc32Arg->ret_origin = TEEC_ORIGIN_API;
148 
149 	debug("OpteeRpcCmdLoadTa Exit : TeecResult=0x%X\n", TeecResult);
150 
151 	return TeecResult;
152 }
153 
154 #ifdef CONFIG_OPTEE_V2
155 TEEC_Result OpteeRpcCmdLoadV2Ta(t_teesmc32_arg *TeeSmc32Arg)
156 {
157 	TEEC_Result TeecResult = TEEC_SUCCESS;
158 	t_teesmc32_param *TeeSmc32Param = NULL;
159 	uint8_t uuid[16];
160 	int i;
161 
162 	if (TeeSmc32Arg->num_params != 2) {
163 		TeecResult = TEEC_ERROR_BAD_PARAMETERS;
164 		goto Exit;
165 	}
166 
167 	TeeSmc32Param = TEESMC32_GET_PARAMS(TeeSmc32Arg);
168 
169 	memcpy(uuid, (void *)&TeeSmc32Param[0].u.value, 16);
170 	for (i = 0; i < 16; i++)
171 		debug("uuid 0x%x", uuid[i]);
172 
173 	if (TeeSmc32Param[1].u.memref.buf_ptr == 0) {
174 		debug("return size of TA, keymaster_size = 0x%x", keymaster_size);
175 		TeeSmc32Param[1].u.memref.size = keymaster_size;
176 	} else {
177 		memcpy((void *)(size_t)TeeSmc32Param[1].u.memref.buf_ptr,
178 			(void *)keymaster_data, TeeSmc32Param[1].u.memref.size);
179 		debug("memref.buf_ptr = 0x%llx; memref.size = 0x%llx",
180 			TeeSmc32Param[1].u.memref.buf_ptr,
181 			TeeSmc32Param[1].u.memref.size);
182 	}
183 
184 Exit:
185 	TeeSmc32Arg->ret = TeecResult;
186 	TeeSmc32Arg->ret_origin = TEEC_ORIGIN_API;
187 
188 	debug("OpteeRpcCmdLoadTa Exit : TeecResult=0x%X\n", TeecResult);
189 
190 	return TeecResult;
191 }
192 #endif
193 
194 /*
195  * Free a previously loaded TA and release the memory
196  * Param[0] = IN: TA Image to free
197  *
198  * Um, why is OpTEE holding on to this memory? The OS code suggests that OpTEE
199  * is using the binary in place out of shared memory but I don't understand how
200  * runtime modifications of the binary are being prevented if that's the case?
201  */
202 TEEC_Result OpteeRpcCmdFreeTa(t_teesmc32_arg *TeeSmc32Arg)
203 {
204 	TEEC_Result TeecResult = TEEC_SUCCESS;
205 	t_teesmc32_param *TeeSmc32Param = NULL;
206 	uint32_t ImageSize = 0;
207 	size_t AllocAddress = 0;
208 
209 	if (TeeSmc32Arg->num_params != 1) {
210 		TeecResult = TEEC_ERROR_BAD_PARAMETERS;
211 		goto Exit;
212 	}
213 
214 	TeeSmc32Param = TEESMC32_GET_PARAMS(TeeSmc32Arg);
215 
216 	AllocAddress = TeeSmc32Param[0].u.memref.buf_ptr;
217 	ImageSize = TeeSmc32Param[0].u.memref.size;
218 
219 	debug("OpteeRpcCmdFreeTa Enter: AllocAddress=0x%X, ImageSize=0x%X\n",
220 			(uint32_t) AllocAddress, (uint32_t) ImageSize);
221 
222 	if (AllocAddress == 0) {
223 		TeecResult = TEEC_ERROR_BAD_PARAMETERS;
224 		goto Exit;
225 	}
226 
227 	OpteeClientMemFree((void *)AllocAddress);
228 
229 Exit:
230 	TeeSmc32Arg->ret = TeecResult;
231 	TeeSmc32Arg->ret_origin = TEEC_ORIGIN_API;
232 
233 	debug("OpteeRpcCmdFreeTa Exit : TeecResult=0x%X\n", TeecResult);
234 
235 	return TeecResult;
236 }
237 
238 /*
239  * Execute an RPMB storage operation.
240  */
241 
242 uint16_t global_block_count;
243 TEEC_Result OpteeRpcCmdRpmb(t_teesmc32_arg *TeeSmc32Arg)
244 {
245 	struct tee_rpc_rpmb_dev_info *DevInfo;
246 	TEEC_Result EfiStatus;
247 	uint16_t RequestMsgType, i;
248 	EFI_RK_RPMB_DATA_PACKET *RequestPackets;
249 	EFI_RK_RPMB_DATA_PACKET *ResponsePackets;
250 	EFI_RK_RPMB_DATA_PACKET *tempPackets;
251 	EFI_RK_RPMB_DATA_PACKET_BACK *RequestPackets_back;
252 	EFI_RK_RPMB_DATA_PACKET_BACK *tempPackets_back;
253 	struct tee_rpc_rpmb_cmd *RpmbRequest;
254 	TEEC_Result TeecResult = TEEC_SUCCESS;
255 	t_teesmc32_param *TeeSmc32Param;
256 	struct mmc *mmc;
257 
258 	debug("Entered RPMB RPC\n");
259 
260 	if (TeeSmc32Arg->num_params != 2) {
261 		TeecResult = TEEC_ERROR_BAD_PARAMETERS;
262 		goto Exit;
263 	}
264 
265 	TeeSmc32Param = TEESMC32_GET_PARAMS(TeeSmc32Arg);
266 	RpmbRequest = (struct tee_rpc_rpmb_cmd *)(size_t)
267 		TeeSmc32Param[0].u.memref.buf_ptr;
268 	switch (RpmbRequest->cmd) {
269 	case TEE_RPC_RPMB_CMD_DATA_REQ: {
270 		RequestPackets = (EFI_RK_RPMB_DATA_PACKET *)(RpmbRequest + 1);
271 		ResponsePackets = (EFI_RK_RPMB_DATA_PACKET *)(size_t)
272 		TeeSmc32Param[1].u.memref.buf_ptr;
273 
274 		global_block_count =
275 			(RpmbRequest->block_count == 0 ?
276 			1 : RpmbRequest->block_count);
277 		RequestPackets_back =
278 			malloc(sizeof(EFI_RK_RPMB_DATA_PACKET_BACK)
279 			* global_block_count);
280 		memcpy(RequestPackets_back->stuff,
281 			RequestPackets->stuff_bytes,
282 			RPMB_STUFF_DATA_SIZE);
283 		memcpy(RequestPackets_back->mac,
284 			RequestPackets->key_mac,
285 			RPMB_KEY_MAC_SIZE);
286 		memcpy(RequestPackets_back->data,
287 			RequestPackets->data,
288 			RPMB_DATA_SIZE);
289 		memcpy(RequestPackets_back->nonce,
290 			RequestPackets->nonce,
291 			RPMB_NONCE_SIZE);
292 		RequestPackets_back->write_counter =
293 			((RequestPackets->write_counter[3]) << 24) +
294 			((RequestPackets->write_counter[2]) << 16) +
295 			((RequestPackets->write_counter[1]) << 8) +
296 			(RequestPackets->write_counter[0]);
297 		RequestPackets_back->address =
298 			((RequestPackets->address[1]) << 8) +
299 			(RequestPackets->address[0]);
300 		RequestPackets_back->block_count =
301 			((RequestPackets->block_count[1]) << 8) +
302 			(RequestPackets->block_count[0]);
303 		RequestPackets_back->result =
304 			((RequestPackets->op_result[1]) << 8) +
305 			(RequestPackets->op_result[0]);
306 		RequestPackets_back->request =
307 			((RequestPackets->msg_type[1]) << 8) +
308 			(RequestPackets->msg_type[0]);
309 
310 		RequestMsgType = RPMB_PACKET_DATA_TO_UINT16(
311 				RequestPackets->msg_type);
312 
313 		debug("RPMB Data request %d\n", RequestMsgType);
314 
315 		switch (RequestMsgType) {
316 		case TEE_RPC_RPMB_MSG_TYPE_REQ_AUTH_KEY_PROGRAM: {
317 			EfiStatus = init_rpmb();
318 			if (EfiStatus != 0) {
319 				TeecResult = TEEC_ERROR_GENERIC;
320 				break;
321 			}
322 
323 			EfiStatus = do_programkey((struct s_rpmb *)
324 				RequestPackets_back);
325 
326 			if (EfiStatus != 0) {
327 				TeecResult = TEEC_ERROR_GENERIC;
328 				break;
329 			}
330 
331 			EfiStatus = finish_rpmb();
332 			if (EfiStatus != 0) {
333 				TeecResult = TEEC_ERROR_GENERIC;
334 				break;
335 			}
336 
337 			break;
338 		}
339 
340 		case TEE_RPC_RPMB_MSG_TYPE_REQ_WRITE_COUNTER_VAL_READ: {
341 			EfiStatus = init_rpmb();
342 			if (EfiStatus != 0) {
343 				TeecResult = TEEC_ERROR_GENERIC;
344 				break;
345 			}
346 
347 			EfiStatus = do_readcounter((struct s_rpmb *)
348 				RequestPackets_back);
349 			if (EfiStatus != 0) {
350 				TeecResult = TEEC_ERROR_GENERIC;
351 				break;
352 			}
353 
354 			EfiStatus = finish_rpmb();
355 			if (EfiStatus != 0) {
356 				TeecResult = TEEC_ERROR_GENERIC;
357 				break;
358 			}
359 
360 			break;
361 		}
362 
363 		case TEE_RPC_RPMB_MSG_TYPE_REQ_AUTH_DATA_WRITE: {
364 			EfiStatus = init_rpmb();
365 			if (EfiStatus != 0) {
366 				TeecResult = TEEC_ERROR_GENERIC;
367 				break;
368 			}
369 
370 			EfiStatus = do_authenticatedwrite((struct s_rpmb *)
371 				RequestPackets_back);
372 			if (EfiStatus != 0) {
373 				TeecResult = TEEC_ERROR_GENERIC;
374 				break;
375 			}
376 
377 			EfiStatus = finish_rpmb();
378 
379 			if (EfiStatus != 0) {
380 				TeecResult = TEEC_ERROR_GENERIC;
381 				break;
382 			}
383 
384 			break;
385 		}
386 
387 		case TEE_RPC_RPMB_MSG_TYPE_REQ_AUTH_DATA_READ: {
388 			EfiStatus = init_rpmb();
389 			if (EfiStatus != 0) {
390 				TeecResult = TEEC_ERROR_GENERIC;
391 				break;
392 			}
393 
394 			EfiStatus = do_authenticatedread((struct s_rpmb *)
395 				RequestPackets_back, global_block_count);
396 			if (EfiStatus != 0) {
397 				TeecResult = TEEC_ERROR_GENERIC;
398 				break;
399 			}
400 
401 			EfiStatus = finish_rpmb();
402 
403 			if (EfiStatus != 0) {
404 				TeecResult = TEEC_ERROR_GENERIC;
405 				break;
406 			}
407 
408 			break;
409 		}
410 
411 		default:
412 			TeecResult = TEEC_ERROR_BAD_PARAMETERS;
413 			break;
414 		}
415 		debug("RPMB TeecResult %d\n", TeecResult);
416 		break;
417 	}
418 
419 	case TEE_RPC_RPMB_CMD_GET_DEV_INFO: {
420 		mmc = do_returnmmc();
421 
422 		DevInfo = (struct tee_rpc_rpmb_dev_info *)(size_t)
423 		TeeSmc32Param[1].u.memref.buf_ptr;
424 
425 		DevInfo->cid[0] = (mmc->cid[0]) >> 24 & 0xff;
426 		DevInfo->cid[1] = (mmc->cid[0]) >> 16 & 0xff;
427 		DevInfo->cid[2] = (mmc->cid[0]) >> 8 & 0xff;
428 		DevInfo->cid[3] = (mmc->cid[0]) & 0xff;
429 		DevInfo->cid[4] = (mmc->cid[1]) >> 24 & 0xff;
430 		DevInfo->cid[5] = (mmc->cid[1]) >> 16 & 0xff;
431 		DevInfo->cid[6] = (mmc->cid[1]) >> 8 & 0xff;
432 		DevInfo->cid[7] = (mmc->cid[1]) & 0xff;
433 		DevInfo->cid[8] = (mmc->cid[2]) >> 24 & 0xff;
434 		DevInfo->cid[9] = (mmc->cid[2]) >> 16 & 0xff;
435 		DevInfo->cid[10] = (mmc->cid[2]) >> 8 & 0xff;
436 		DevInfo->cid[11] = (mmc->cid[2]) & 0xff;
437 		DevInfo->cid[12] = (mmc->cid[3]) >> 24 & 0xff;
438 		DevInfo->cid[13] = (mmc->cid[3]) >> 16 & 0xff;
439 		DevInfo->cid[14] = (mmc->cid[3]) >> 8 & 0xff;
440 		DevInfo->cid[15] = (mmc->cid[3]) & 0xff;
441 		DevInfo->rel_wr_sec_c = 1;
442 		DevInfo->rpmb_size_mult =
443 			(uint8_t)(mmc->capacity_rpmb / (128 * 1024));
444 		DevInfo->ret_code = 0;
445 
446 		goto Exit;
447 	}
448 
449 	default:
450 		TeecResult = TEEC_ERROR_BAD_PARAMETERS;
451 
452 		goto Exit;
453 	}
454 
455 	tempPackets = ResponsePackets;
456 	tempPackets_back = RequestPackets_back;
457 
458 	for (i = 0; i < global_block_count; i++) {
459 		memcpy(tempPackets->stuff_bytes,
460 			tempPackets_back->stuff,
461 			RPMB_STUFF_DATA_SIZE);
462 		memcpy(tempPackets->key_mac,
463 			tempPackets_back->mac,
464 			RPMB_KEY_MAC_SIZE);
465 		memcpy(tempPackets->data,
466 			tempPackets_back->data,
467 			RPMB_DATA_SIZE);
468 		memcpy(tempPackets->nonce,
469 			tempPackets_back->nonce,
470 			RPMB_NONCE_SIZE);
471 		tempPackets->write_counter[3] =
472 			((tempPackets_back->write_counter) >> 24) & 0xFF;
473 		tempPackets->write_counter[2] =
474 			((tempPackets_back->write_counter) >> 16) & 0xFF;
475 		tempPackets->write_counter[1] =
476 			((tempPackets_back->write_counter) >> 8) & 0xFF;
477 		tempPackets->write_counter[0] =
478 			(tempPackets_back->write_counter) & 0xFF;
479 		tempPackets->address[1] =
480 			((tempPackets_back->address) >> 8) & 0xFF;
481 		tempPackets->address[0] =
482 			(tempPackets_back->address) & 0xFF;
483 		tempPackets->block_count[1] =
484 			((tempPackets_back->block_count) >> 8) & 0xFF;
485 		tempPackets->block_count[0] =
486 			(tempPackets_back->block_count) & 0xFF;
487 		tempPackets->op_result[1] =
488 			((tempPackets_back->result) >> 8) & 0xFF;
489 		tempPackets->op_result[0] =
490 			(tempPackets_back->result) & 0xFF;
491 		tempPackets->msg_type[1] =
492 			((tempPackets_back->request) >> 8) & 0xFF;
493 		tempPackets->msg_type[0] =
494 			(tempPackets_back->request) & 0xFF;
495 		tempPackets++;
496 		tempPackets_back++;
497 	}
498 
499 	free(RequestPackets_back);
500 
501 Exit:
502 	TeeSmc32Arg->ret = TeecResult;
503 	TeeSmc32Arg->ret_origin = TEEC_ORIGIN_API;
504 
505 	return TeecResult;
506 }
507 
508 /*
509  * Execute a normal world local file system operation.
510  */
511 TEEC_Result OpteeRpcCmdFs(t_teesmc32_arg *TeeSmc32Arg)
512 {
513 	TEEC_Result TeecResult = TEEC_SUCCESS;
514 	t_teesmc32_param *TeeSmc32Param;
515 
516 	TeeSmc32Param = TEESMC32_GET_PARAMS(TeeSmc32Arg);
517 #ifdef CONFIG_OPTEE_V1
518 	TeecResult = tee_supp_rk_fs_process((void *)(size_t)TeeSmc32Param[0].u.memref.buf_ptr,
519 							TeeSmc32Param[0].u.memref.size);
520 #endif
521 #ifdef CONFIG_OPTEE_V2
522 	TeecResult = tee_supp_rk_fs_process((size_t)TeeSmc32Arg->num_params,
523 							(struct tee_ioctl_param *)TeeSmc32Param);
524 #endif
525 
526 	return TeecResult;
527 }
528 
529 /*
530  * TBD.
531  */
532 TEEC_Result OpteeRpcCmdGetTime(t_teesmc32_arg *TeeSmc32Arg)
533 {
534 	return TEEC_ERROR_NOT_IMPLEMENTED;
535 }
536 
537 /*
538  * TBD.
539  */
540 TEEC_Result OpteeRpcCmdWaitMutex(t_teesmc32_arg *TeeSmc32Arg)
541 {
542 	return TEEC_ERROR_NOT_IMPLEMENTED;
543 }
544 
545 /*
546  * Handle the callback from secure world.
547  */
548 TEEC_Result OpteeRpcCallback(ARM_SMC_ARGS *ArmSmcArgs)
549 {
550 	TEEC_Result TeecResult = TEEC_SUCCESS;
551 
552 	//printf("OpteeRpcCallback Enter: Arg0=0x%X, Arg1=0x%X, Arg2=0x%X\n",
553 		//ArmSmcArgs->Arg0, ArmSmcArgs->Arg1, ArmSmcArgs->Arg2);
554 
555 	switch (TEESMC_RETURN_GET_RPC_FUNC(ArmSmcArgs->Arg0)) {
556 	case TEESMC_RPC_FUNC_ALLOC_ARG: {
557 #ifdef CONFIG_OPTEE_V1
558 		TeecResult = OpteeRpcAlloc(ArmSmcArgs->Arg1, &ArmSmcArgs->Arg1);
559 #endif
560 #ifdef CONFIG_OPTEE_V2
561 		debug("ArmSmcArgs->Arg1 = 0x%x", ArmSmcArgs->Arg1);
562 		TeecResult = OpteeRpcAlloc(ArmSmcArgs->Arg1, &ArmSmcArgs->Arg2);
563 		ArmSmcArgs->Arg5 = ArmSmcArgs->Arg2;
564 		ArmSmcArgs->Arg1 = 0;
565 		ArmSmcArgs->Arg4 = 0;
566 #endif
567 		break;
568 	}
569 
570 	case TEESMC_RPC_FUNC_ALLOC_PAYLOAD: {
571 		TeecResult = OpteeRpcAlloc(ArmSmcArgs->Arg1, &ArmSmcArgs->Arg1);
572 		break;
573 	}
574 
575 	case TEESMC_RPC_FUNC_FREE_ARG: {
576 #ifdef CONFIG_OPTEE_V1
577 		TeecResult = OpteeRpcFree(ArmSmcArgs->Arg1);
578 #endif
579 #ifdef CONFIG_OPTEE_V2
580 		TeecResult = OpteeRpcFree(ArmSmcArgs->Arg2);
581 #endif
582 		break;
583 	}
584 
585 	case TEESMC_RPC_FUNC_FREE_PAYLOAD: {
586 		TeecResult = OpteeRpcFree(ArmSmcArgs->Arg1);
587 		break;
588 	}
589 
590 	case TEESMC_RPC_FUNC_IRQ: {
591 		break;
592 	}
593 
594 	case TEESMC_RPC_FUNC_CMD: {
595 #ifdef CONFIG_OPTEE_V1
596 		t_teesmc32_arg *TeeSmc32Arg =
597 			(t_teesmc32_arg *)(size_t)ArmSmcArgs->Arg1;
598 #endif
599 #ifdef CONFIG_OPTEE_V2
600 		t_teesmc32_arg *TeeSmc32Arg =
601 			(t_teesmc32_arg *)(size_t)((uint64_t)ArmSmcArgs->Arg1 << 32 | ArmSmcArgs->Arg2);
602 		debug("TeeSmc32Arg->cmd = 0x%x", TeeSmc32Arg->cmd);
603 #endif
604 		switch (TeeSmc32Arg->cmd) {
605 #ifdef CONFIG_OPTEE_V1
606 		case TEE_RPC_LOAD_TA: {
607 			TeecResult = OpteeRpcCmdLoadTa(TeeSmc32Arg);
608 			break;
609 		}
610 
611 		case TEE_RPC_FREE_TA: {
612 			TeecResult = OpteeRpcCmdFreeTa(TeeSmc32Arg);
613 			break;
614 		}
615 
616 		case TEE_RPC_RPMB_CMD: {
617 			TeecResult = OpteeRpcCmdRpmb(TeeSmc32Arg);
618 			break;
619 		}
620 
621 		case TEE_RPC_FS: {
622 			TeecResult = OpteeRpcCmdFs(TeeSmc32Arg);
623 			TeeSmc32Arg->ret = TEEC_SUCCESS;
624 			break;
625 		}
626 
627 		case TEE_RPC_GET_TIME: {
628 			TeecResult = OpteeRpcCmdGetTime(TeeSmc32Arg);
629 			break;
630 		}
631 
632 		case TEE_RPC_WAIT_MUTEX: {
633 			TeecResult = OpteeRpcCmdWaitMutex(TeeSmc32Arg);
634 			break;
635 		}
636 #endif
637 #ifdef CONFIG_OPTEE_V2
638 		case OPTEE_MSG_RPC_CMD_SHM_ALLOC_V2: {
639 			uint32_t tempaddr;
640 			uint32_t allocsize = TeeSmc32Arg->params[0].u.value.b;
641 			TeecResult = OpteeRpcAlloc(allocsize, &tempaddr);
642 			debug("allocsize = 0x%x tempaddr = 0x%x", allocsize, tempaddr);
643 			TeeSmc32Arg->params[0].attr = OPTEE_MSG_ATTR_TYPE_TMEM_OUTPUT_V2;
644 			TeeSmc32Arg->params[0].u.memref.buf_ptr = tempaddr;
645 			TeeSmc32Arg->params[0].u.memref.size = allocsize;
646 			TeeSmc32Arg->params[0].u.memref.shm_ref = tempaddr;
647 			TeeSmc32Arg->ret = TEE_SUCCESS;
648 			break;
649 		}
650 		case OPTEE_MSG_RPC_CMD_SHM_FREE_V2: {
651 			uint32_t tempaddr = TeeSmc32Arg->params[0].u.value.b;
652 			TeecResult = OpteeRpcFree(tempaddr);
653 			break;
654 
655 		}
656 		case OPTEE_MSG_RPC_CMD_RPMB_V2: {
657 			TeecResult = OpteeRpcCmdRpmb(TeeSmc32Arg);
658 			break;
659 		}
660 		case OPTEE_MSG_RPC_CMD_FS_V2: {
661 			TeecResult = OpteeRpcCmdFs(TeeSmc32Arg);
662 			TeeSmc32Arg->ret = TEEC_SUCCESS;
663 			break;
664 		}
665 		case OPTEE_MSG_RPC_CMD_LOAD_TA_V2: {
666 			TeecResult = OpteeRpcCmdLoadV2Ta(TeeSmc32Arg);
667 			break;
668 		}
669 #endif
670 
671 		default: {
672 			printf("...unsupported RPC CMD: cmd=0x%X\n",
673 				TeeSmc32Arg->cmd);
674 			TeecResult = TEEC_ERROR_NOT_IMPLEMENTED;
675 			break;
676 		}
677 	}
678 
679 		break;
680 	}
681 
682 	case TEESMC_OPTEE_RPC_FUNC_ALLOC_PAYLOAD: {
683 		TeecResult = OpteeRpcAlloc(ArmSmcArgs->Arg1, &ArmSmcArgs->Arg1);
684 		ArmSmcArgs->Arg2 = ArmSmcArgs->Arg1;
685 		break;
686 	}
687 
688 	case TEESMC_OPTEE_RPC_FUNC_FREE_PAYLOAD: {
689 		TeecResult = OpteeRpcFree(ArmSmcArgs->Arg1);
690 		break;
691 	}
692 
693 	default: {
694 		printf("...unsupported RPC : Arg0=0x%X\n", ArmSmcArgs->Arg0);
695 		TeecResult = TEEC_ERROR_NOT_IMPLEMENTED;
696 		break;
697 	}
698 	}
699 
700 	ArmSmcArgs->Arg0 = TEESMC32_CALL_RETURN_FROM_RPC;
701 	debug("OpteeRpcCallback Exit : TeecResult=0x%X\n", TeecResult);
702 
703 	return TeecResult;
704 }
705