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