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