xref: /rk3399_rockchip-uboot/lib/optee_clientApi/OpteeClientRPC.c (revision d079c1a5ed50ce9f1e3b37be5ce4e13edec90bd0)
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 <stdlib.h>
9abdd2437Shisping #include <command.h>
10abdd2437Shisping #include <mmc.h>
11abdd2437Shisping #include <optee_include/OpteeClientMem.h>
12abdd2437Shisping #include <optee_include/OpteeClientRPC.h>
13abdd2437Shisping #include <optee_include/teesmc.h>
141f25ada2SHisping Lin #include <optee_include/teesmc_v2.h>
15abdd2437Shisping #include <optee_include/teesmc_optee.h>
16abdd2437Shisping #include <optee_include/tee_rpc_types.h>
17abdd2437Shisping #include <optee_include/tee_rpc.h>
183251364cSHisping Lin #ifdef CONFIG_OPTEE_V1
191f25ada2SHisping Lin #include <optee_include/OpteeClientRkFs.h>
203251364cSHisping Lin #endif
213251364cSHisping Lin #ifdef CONFIG_OPTEE_V2
223251364cSHisping Lin #include <optee_include/OpteeClientRkFs-v2.h>
233251364cSHisping Lin #endif
24abdd2437Shisping 
25abdd2437Shisping /*
26abdd2437Shisping  * Memory allocation.
27abdd2437Shisping  * Currently treated the same for both arguments & payloads.
28abdd2437Shisping  */
29abdd2437Shisping TEEC_Result OpteeRpcAlloc(uint32_t Size, uint32_t *Address)
30abdd2437Shisping {
31abdd2437Shisping 	TEEC_Result TeecResult = TEEC_SUCCESS;
321f25ada2SHisping Lin 	size_t AllocAddress;
33abdd2437Shisping 
34abdd2437Shisping 	*Address = 0;
35abdd2437Shisping 
36abdd2437Shisping 	if (Size != 0) {
371f25ada2SHisping Lin 		AllocAddress = (size_t) OpteeClientMemAlloc(Size);
38abdd2437Shisping 
39abdd2437Shisping 		if (AllocAddress == 0)
40abdd2437Shisping 			TeecResult = TEEC_ERROR_OUT_OF_MEMORY;
41abdd2437Shisping 		else
42abdd2437Shisping 			*Address = AllocAddress;
43abdd2437Shisping 	}
44abdd2437Shisping 	return TeecResult;
45abdd2437Shisping }
46abdd2437Shisping 
47abdd2437Shisping /*
48abdd2437Shisping  * Memory free.
49abdd2437Shisping  * Currently treated the same for both arguments & payloads.
50abdd2437Shisping  */
51abdd2437Shisping TEEC_Result OpteeRpcFree(uint32_t Address)
52abdd2437Shisping {
531f25ada2SHisping Lin 	OpteeClientMemFree((void *)(size_t)Address);
54abdd2437Shisping 	return TEEC_SUCCESS;
55abdd2437Shisping }
56abdd2437Shisping 
57a7df4868Stony.xu int is_uuid_equal(TEE_UUID uuid1, TEEC_UUID uuid2)
58a7df4868Stony.xu {
59a7df4868Stony.xu 	bool a, b, c;
60a7df4868Stony.xu 
61a7df4868Stony.xu 	a = (uuid1.timeLow == uuid2.timeLow);
62a7df4868Stony.xu 	b = (uuid1.timeMid == uuid2.timeMid);
63a7df4868Stony.xu 	c = (uuid1.timeHiAndVersion == uuid2.timeHiAndVersion);
64a7df4868Stony.xu 	if ((a & b & c) == 0) {
65a7df4868Stony.xu 		return 0;
66a7df4868Stony.xu 	} else {
67a7df4868Stony.xu 		if (memcmp(uuid1.clockSeqAndNode,
68a7df4868Stony.xu 			   uuid2.clockSeqAndNode, 8) == 0) {
69a7df4868Stony.xu 			return 1;
70a7df4868Stony.xu 		} else {
71a7df4868Stony.xu 			return 0;
72a7df4868Stony.xu 		}
73a7df4868Stony.xu 	}
74a7df4868Stony.xu }
75a7df4868Stony.xu 
76abdd2437Shisping /*
77abdd2437Shisping  * Load a TA from storage into memory and provide it back to OpTEE.
78abdd2437Shisping  * Param[0] = IN: struct tee_rpc_load_ta_cmd
79abdd2437Shisping  * Param[1] = IN: all-zero OUT: TA Image allocated
80abdd2437Shisping  */
81abdd2437Shisping TEEC_Result OpteeRpcCmdLoadTa(t_teesmc32_arg *TeeSmc32Arg)
82abdd2437Shisping {
83abdd2437Shisping 	TEEC_Result TeecResult = TEEC_SUCCESS;
84abdd2437Shisping 	t_teesmc32_param *TeeSmc32Param = NULL;
85abdd2437Shisping 	struct tee_rpc_load_ta_cmd *TeeLoadTaCmd = NULL;
86abdd2437Shisping 	uint32_t TeeLoadTaCmdSize = 0;
87abdd2437Shisping 
88abdd2437Shisping 	if (TeeSmc32Arg->num_params != 2) {
89abdd2437Shisping 		TeecResult = TEEC_ERROR_BAD_PARAMETERS;
90abdd2437Shisping 		goto Exit;
91abdd2437Shisping 	}
92abdd2437Shisping 
93a7df4868Stony.xu 	TEEC_UUID TA_RK_KEYMASTER_UUID = {0x258be795, 0xf9ca, 0x40e6,
94a7df4868Stony.xu 			{0xa8, 0x69, 0x9c, 0xe6, 0x88, 0x6c, 0x5d, 0x5d} };
95abdd2437Shisping 	TeeSmc32Param = TEESMC32_GET_PARAMS(TeeSmc32Arg);
96abdd2437Shisping 	TeeLoadTaCmd = (struct tee_rpc_load_ta_cmd *)
971f25ada2SHisping Lin 					(size_t)TeeSmc32Param[0].u.memref.buf_ptr;
98abdd2437Shisping 	TeeLoadTaCmdSize = TeeSmc32Param[0].u.memref.size;
99abdd2437Shisping 
100abdd2437Shisping 	if ((TeeLoadTaCmd == NULL) ||
101abdd2437Shisping 		(TeeLoadTaCmdSize != sizeof(*TeeLoadTaCmd))) {
102abdd2437Shisping 		TeecResult = TEEC_ERROR_BAD_PARAMETERS;
103abdd2437Shisping 		goto Exit;
104abdd2437Shisping 	}
105abdd2437Shisping 
106abdd2437Shisping 	TEEC_Result Status = 0;
107abdd2437Shisping 	void *ImageData = NULL;
108abdd2437Shisping 	uint32_t ImageSize = 0;
1091f25ada2SHisping Lin 	size_t AllocAddress = 0;
110abdd2437Shisping 
111a7df4868Stony.xu 	if (is_uuid_equal(TeeLoadTaCmd->uuid, TA_RK_KEYMASTER_UUID)) {
11299830019SHisping Lin 		ImageData = (void *)0;
11399830019SHisping Lin 		ImageSize = 0;
114a7df4868Stony.xu 	} else {
115d8100d74SHisping Lin 		ImageData = (void *)0;
116d8100d74SHisping Lin 		ImageSize = 0;
117a7df4868Stony.xu 	}
118abdd2437Shisping 
119abdd2437Shisping 	if (Status != 0) {
120abdd2437Shisping 		TeecResult = TEEC_ERROR_ITEM_NOT_FOUND;
121abdd2437Shisping 		goto Exit;
122abdd2437Shisping 	}
123abdd2437Shisping 
1241f25ada2SHisping Lin 	AllocAddress = (size_t) OpteeClientMemAlloc(ImageSize);
125abdd2437Shisping 
126abdd2437Shisping 	if (AllocAddress == 0) {
127abdd2437Shisping 		TeecResult = TEEC_ERROR_OUT_OF_MEMORY;
128abdd2437Shisping 		goto Exit;
129abdd2437Shisping 	}
130abdd2437Shisping 
131abdd2437Shisping 	memcpy((void *)AllocAddress, ImageData, ImageSize);
132abdd2437Shisping 
133efb93541SHisping Lin 	debug("TEEC: ...TA loaded at 0x%zu of size 0x%X bytes\n",
134abdd2437Shisping 		AllocAddress, ImageSize);
135efb93541SHisping Lin 	debug("TEEC: ...AllocAddress[0] 0x%X ; AllocAddress[1] 0x%X bytes\n",
136abdd2437Shisping 		*(char *)AllocAddress, *(char *)(AllocAddress+1));
137abdd2437Shisping 
1381f25ada2SHisping Lin 	TeeLoadTaCmd->va = AllocAddress;
139abdd2437Shisping 
140abdd2437Shisping 	TeeSmc32Param[1].u.memref.buf_ptr = AllocAddress;
141abdd2437Shisping 	TeeSmc32Param[1].u.memref.size = ImageSize;
142abdd2437Shisping 
143abdd2437Shisping Exit:
144abdd2437Shisping 	TeeSmc32Arg->ret = TeecResult;
145abdd2437Shisping 	TeeSmc32Arg->ret_origin = TEEC_ORIGIN_API;
146abdd2437Shisping 
147efb93541SHisping Lin 	debug("TEEC: OpteeRpcCmdLoadTa Exit : TeecResult=0x%X\n", TeecResult);
148abdd2437Shisping 
149abdd2437Shisping 	return TeecResult;
150abdd2437Shisping }
151abdd2437Shisping 
1521f25ada2SHisping Lin #ifdef CONFIG_OPTEE_V2
1531f25ada2SHisping Lin TEEC_Result OpteeRpcCmdLoadV2Ta(t_teesmc32_arg *TeeSmc32Arg)
1541f25ada2SHisping Lin {
1551f25ada2SHisping Lin 	TEEC_Result TeecResult = TEEC_SUCCESS;
1561f25ada2SHisping Lin 	t_teesmc32_param *TeeSmc32Param = NULL;
1571f25ada2SHisping Lin 	uint8_t uuid[16];
1581f25ada2SHisping Lin 	int i;
1591f25ada2SHisping Lin 
1601f25ada2SHisping Lin 	if (TeeSmc32Arg->num_params != 2) {
1611f25ada2SHisping Lin 		TeecResult = TEEC_ERROR_BAD_PARAMETERS;
1621f25ada2SHisping Lin 		goto Exit;
1631f25ada2SHisping Lin 	}
1641f25ada2SHisping Lin 
1651f25ada2SHisping Lin 	TeeSmc32Param = TEESMC32_GET_PARAMS(TeeSmc32Arg);
1661f25ada2SHisping Lin 
1671f25ada2SHisping Lin 	memcpy(uuid, (void *)&TeeSmc32Param[0].u.value, 16);
1681f25ada2SHisping Lin 	for (i = 0; i < 16; i++)
169efb93541SHisping Lin 		debug("TEEC: uuid 0x%x", uuid[i]);
1701f25ada2SHisping Lin 
1711f25ada2SHisping Lin 	if (TeeSmc32Param[1].u.memref.buf_ptr == 0) {
172efb93541SHisping Lin 		debug("TEEC: return size of TA, keymaster_size = 0\n");
17399830019SHisping Lin 		TeeSmc32Param[1].u.memref.size = 0;
1741f25ada2SHisping Lin 	} else {
17599830019SHisping Lin 		/*memcpy((void *)(size_t)TeeSmc32Param[1].u.memref.buf_ptr,
17699830019SHisping Lin 			(void *)keymaster_data, TeeSmc32Param[1].u.memref.size);*/
177efb93541SHisping Lin 		debug("TEEC: memref.buf_ptr = 0x%llx; memref.size = 0x%llx\n",
1781f25ada2SHisping Lin 			TeeSmc32Param[1].u.memref.buf_ptr,
1791f25ada2SHisping Lin 			TeeSmc32Param[1].u.memref.size);
1801f25ada2SHisping Lin 	}
1811f25ada2SHisping Lin 
1821f25ada2SHisping Lin Exit:
1831f25ada2SHisping Lin 	TeeSmc32Arg->ret = TeecResult;
1841f25ada2SHisping Lin 	TeeSmc32Arg->ret_origin = TEEC_ORIGIN_API;
1851f25ada2SHisping Lin 
186efb93541SHisping Lin 	debug("TEEC: OpteeRpcCmdLoadTa Exit : TeecResult=0x%X\n", TeecResult);
1871f25ada2SHisping Lin 
1881f25ada2SHisping Lin 	return TeecResult;
1891f25ada2SHisping Lin }
1901f25ada2SHisping Lin #endif
1911f25ada2SHisping Lin 
192abdd2437Shisping /*
193abdd2437Shisping  * Free a previously loaded TA and release the memory
194abdd2437Shisping  * Param[0] = IN: TA Image to free
195abdd2437Shisping  *
196abdd2437Shisping  * Um, why is OpTEE holding on to this memory? The OS code suggests that OpTEE
197abdd2437Shisping  * is using the binary in place out of shared memory but I don't understand how
198abdd2437Shisping  * runtime modifications of the binary are being prevented if that's the case?
199abdd2437Shisping  */
200abdd2437Shisping TEEC_Result OpteeRpcCmdFreeTa(t_teesmc32_arg *TeeSmc32Arg)
201abdd2437Shisping {
202abdd2437Shisping 	TEEC_Result TeecResult = TEEC_SUCCESS;
203abdd2437Shisping 	t_teesmc32_param *TeeSmc32Param = NULL;
204abdd2437Shisping 	uint32_t ImageSize = 0;
2051f25ada2SHisping Lin 	size_t AllocAddress = 0;
206abdd2437Shisping 
207abdd2437Shisping 	if (TeeSmc32Arg->num_params != 1) {
208abdd2437Shisping 		TeecResult = TEEC_ERROR_BAD_PARAMETERS;
209abdd2437Shisping 		goto Exit;
210abdd2437Shisping 	}
211abdd2437Shisping 
212abdd2437Shisping 	TeeSmc32Param = TEESMC32_GET_PARAMS(TeeSmc32Arg);
213abdd2437Shisping 
214abdd2437Shisping 	AllocAddress = TeeSmc32Param[0].u.memref.buf_ptr;
215abdd2437Shisping 	ImageSize = TeeSmc32Param[0].u.memref.size;
216abdd2437Shisping 
217efb93541SHisping Lin 	debug("TEEC: OpteeRpcCmdFreeTa Enter: AllocAddress=0x%X, ImageSize=0x%X\n",
218abdd2437Shisping 			(uint32_t) AllocAddress, (uint32_t) ImageSize);
219abdd2437Shisping 
220abdd2437Shisping 	if (AllocAddress == 0) {
221abdd2437Shisping 		TeecResult = TEEC_ERROR_BAD_PARAMETERS;
222abdd2437Shisping 		goto Exit;
223abdd2437Shisping 	}
224abdd2437Shisping 
225abdd2437Shisping 	OpteeClientMemFree((void *)AllocAddress);
226abdd2437Shisping 
227abdd2437Shisping Exit:
228abdd2437Shisping 	TeeSmc32Arg->ret = TeecResult;
229abdd2437Shisping 	TeeSmc32Arg->ret_origin = TEEC_ORIGIN_API;
230abdd2437Shisping 
231efb93541SHisping Lin 	debug("TEEC: OpteeRpcCmdFreeTa Exit : TeecResult=0x%X\n", TeecResult);
232abdd2437Shisping 
233abdd2437Shisping 	return TeecResult;
234abdd2437Shisping }
235abdd2437Shisping 
236abdd2437Shisping /*
237abdd2437Shisping  * Execute an RPMB storage operation.
238abdd2437Shisping  */
2391f25ada2SHisping Lin 
240abdd2437Shisping uint16_t global_block_count;
241abdd2437Shisping TEEC_Result OpteeRpcCmdRpmb(t_teesmc32_arg *TeeSmc32Arg)
242abdd2437Shisping {
243abdd2437Shisping 	struct tee_rpc_rpmb_dev_info *DevInfo;
244abdd2437Shisping 	TEEC_Result EfiStatus;
245abdd2437Shisping 	uint16_t RequestMsgType, i;
246abdd2437Shisping 	EFI_RK_RPMB_DATA_PACKET *RequestPackets;
247abdd2437Shisping 	EFI_RK_RPMB_DATA_PACKET *ResponsePackets;
248abdd2437Shisping 	EFI_RK_RPMB_DATA_PACKET *tempPackets;
249abdd2437Shisping 	EFI_RK_RPMB_DATA_PACKET_BACK *RequestPackets_back;
250abdd2437Shisping 	EFI_RK_RPMB_DATA_PACKET_BACK *tempPackets_back;
251abdd2437Shisping 	struct tee_rpc_rpmb_cmd *RpmbRequest;
252abdd2437Shisping 	TEEC_Result TeecResult = TEEC_SUCCESS;
253abdd2437Shisping 	t_teesmc32_param *TeeSmc32Param;
254abdd2437Shisping 	struct mmc *mmc;
255abdd2437Shisping 
256efb93541SHisping Lin 	debug("TEEC: Entered RPMB RPC\n");
257abdd2437Shisping 
258abdd2437Shisping 	if (TeeSmc32Arg->num_params != 2) {
259abdd2437Shisping 		TeecResult = TEEC_ERROR_BAD_PARAMETERS;
260abdd2437Shisping 		goto Exit;
261abdd2437Shisping 	}
262abdd2437Shisping 
263abdd2437Shisping 	TeeSmc32Param = TEESMC32_GET_PARAMS(TeeSmc32Arg);
2641f25ada2SHisping Lin 	RpmbRequest = (struct tee_rpc_rpmb_cmd *)(size_t)
265abdd2437Shisping 		TeeSmc32Param[0].u.memref.buf_ptr;
266abdd2437Shisping 	switch (RpmbRequest->cmd) {
267abdd2437Shisping 	case TEE_RPC_RPMB_CMD_DATA_REQ: {
268abdd2437Shisping 		RequestPackets = (EFI_RK_RPMB_DATA_PACKET *)(RpmbRequest + 1);
2691f25ada2SHisping Lin 		ResponsePackets = (EFI_RK_RPMB_DATA_PACKET *)(size_t)
270abdd2437Shisping 		TeeSmc32Param[1].u.memref.buf_ptr;
271abdd2437Shisping 
272abdd2437Shisping 		global_block_count =
273abdd2437Shisping 			(RpmbRequest->block_count == 0 ?
274abdd2437Shisping 			1 : RpmbRequest->block_count);
275abdd2437Shisping 		RequestPackets_back =
276abdd2437Shisping 			malloc(sizeof(EFI_RK_RPMB_DATA_PACKET_BACK)
277abdd2437Shisping 			* global_block_count);
278abdd2437Shisping 		memcpy(RequestPackets_back->stuff,
279abdd2437Shisping 			RequestPackets->stuff_bytes,
280abdd2437Shisping 			RPMB_STUFF_DATA_SIZE);
281abdd2437Shisping 		memcpy(RequestPackets_back->mac,
282abdd2437Shisping 			RequestPackets->key_mac,
283abdd2437Shisping 			RPMB_KEY_MAC_SIZE);
284abdd2437Shisping 		memcpy(RequestPackets_back->data,
285abdd2437Shisping 			RequestPackets->data,
286abdd2437Shisping 			RPMB_DATA_SIZE);
287abdd2437Shisping 		memcpy(RequestPackets_back->nonce,
288abdd2437Shisping 			RequestPackets->nonce,
289abdd2437Shisping 			RPMB_NONCE_SIZE);
290abdd2437Shisping 		RequestPackets_back->write_counter =
291abdd2437Shisping 			((RequestPackets->write_counter[3]) << 24) +
292abdd2437Shisping 			((RequestPackets->write_counter[2]) << 16) +
293abdd2437Shisping 			((RequestPackets->write_counter[1]) << 8) +
294abdd2437Shisping 			(RequestPackets->write_counter[0]);
295abdd2437Shisping 		RequestPackets_back->address =
296abdd2437Shisping 			((RequestPackets->address[1]) << 8) +
297abdd2437Shisping 			(RequestPackets->address[0]);
298abdd2437Shisping 		RequestPackets_back->block_count =
299abdd2437Shisping 			((RequestPackets->block_count[1]) << 8) +
300abdd2437Shisping 			(RequestPackets->block_count[0]);
301abdd2437Shisping 		RequestPackets_back->result =
302abdd2437Shisping 			((RequestPackets->op_result[1]) << 8) +
303abdd2437Shisping 			(RequestPackets->op_result[0]);
304abdd2437Shisping 		RequestPackets_back->request =
305abdd2437Shisping 			((RequestPackets->msg_type[1]) << 8) +
306abdd2437Shisping 			(RequestPackets->msg_type[0]);
307abdd2437Shisping 
308abdd2437Shisping 		RequestMsgType = RPMB_PACKET_DATA_TO_UINT16(
309abdd2437Shisping 				RequestPackets->msg_type);
310abdd2437Shisping 
311efb93541SHisping Lin 		debug("TEEC: RPMB Data request %d\n", RequestMsgType);
312abdd2437Shisping 
313abdd2437Shisping 		switch (RequestMsgType) {
314abdd2437Shisping 		case TEE_RPC_RPMB_MSG_TYPE_REQ_AUTH_KEY_PROGRAM: {
31568ba9373SHisping Lin 			if (init_rpmb() != 0) {
316abdd2437Shisping 				TeecResult = TEEC_ERROR_GENERIC;
317abdd2437Shisping 				break;
318abdd2437Shisping 			}
319abdd2437Shisping 
320abdd2437Shisping 			EfiStatus = do_programkey((struct s_rpmb *)
321abdd2437Shisping 				RequestPackets_back);
322abdd2437Shisping 
32368ba9373SHisping Lin 			if (finish_rpmb() != 0) {
324abdd2437Shisping 				TeecResult = TEEC_ERROR_GENERIC;
325abdd2437Shisping 				break;
326abdd2437Shisping 			}
327abdd2437Shisping 
328abdd2437Shisping 			if (EfiStatus != 0) {
329abdd2437Shisping 				TeecResult = TEEC_ERROR_GENERIC;
330abdd2437Shisping 				break;
331abdd2437Shisping 			}
332abdd2437Shisping 
333abdd2437Shisping 			break;
334abdd2437Shisping 		}
335abdd2437Shisping 
336abdd2437Shisping 		case TEE_RPC_RPMB_MSG_TYPE_REQ_WRITE_COUNTER_VAL_READ: {
33768ba9373SHisping Lin 			if (init_rpmb() != 0) {
338abdd2437Shisping 				TeecResult = TEEC_ERROR_GENERIC;
339abdd2437Shisping 				break;
340abdd2437Shisping 			}
341abdd2437Shisping 
342abdd2437Shisping 			EfiStatus = do_readcounter((struct s_rpmb *)
343abdd2437Shisping 				RequestPackets_back);
34468ba9373SHisping Lin 
34568ba9373SHisping Lin 			if (finish_rpmb() != 0) {
346abdd2437Shisping 				TeecResult = TEEC_ERROR_GENERIC;
347abdd2437Shisping 				break;
348abdd2437Shisping 			}
349abdd2437Shisping 
350abdd2437Shisping 			if (EfiStatus != 0) {
351abdd2437Shisping 				TeecResult = TEEC_ERROR_GENERIC;
352abdd2437Shisping 				break;
353abdd2437Shisping 			}
354abdd2437Shisping 
355abdd2437Shisping 			break;
356abdd2437Shisping 		}
357abdd2437Shisping 
358abdd2437Shisping 		case TEE_RPC_RPMB_MSG_TYPE_REQ_AUTH_DATA_WRITE: {
35968ba9373SHisping Lin 			if (init_rpmb() != 0) {
360abdd2437Shisping 				TeecResult = TEEC_ERROR_GENERIC;
361abdd2437Shisping 				break;
362abdd2437Shisping 			}
363abdd2437Shisping 
364abdd2437Shisping 			EfiStatus = do_authenticatedwrite((struct s_rpmb *)
365abdd2437Shisping 				RequestPackets_back);
36668ba9373SHisping Lin 
36768ba9373SHisping Lin 			if (finish_rpmb() != 0) {
368abdd2437Shisping 				TeecResult = TEEC_ERROR_GENERIC;
369abdd2437Shisping 				break;
370abdd2437Shisping 			}
371abdd2437Shisping 
372abdd2437Shisping 			if (EfiStatus != 0) {
373abdd2437Shisping 				TeecResult = TEEC_ERROR_GENERIC;
374abdd2437Shisping 				break;
375abdd2437Shisping 			}
376abdd2437Shisping 
377abdd2437Shisping 			break;
378abdd2437Shisping 		}
379abdd2437Shisping 
380abdd2437Shisping 		case TEE_RPC_RPMB_MSG_TYPE_REQ_AUTH_DATA_READ: {
38168ba9373SHisping Lin 			if (init_rpmb() != 0) {
382abdd2437Shisping 				TeecResult = TEEC_ERROR_GENERIC;
383abdd2437Shisping 				break;
384abdd2437Shisping 			}
385abdd2437Shisping 
386abdd2437Shisping 			EfiStatus = do_authenticatedread((struct s_rpmb *)
387abdd2437Shisping 				RequestPackets_back, global_block_count);
38868ba9373SHisping Lin 
38968ba9373SHisping Lin 			if (finish_rpmb() != 0) {
390abdd2437Shisping 				TeecResult = TEEC_ERROR_GENERIC;
391abdd2437Shisping 				break;
392abdd2437Shisping 			}
393abdd2437Shisping 
394abdd2437Shisping 			if (EfiStatus != 0) {
395abdd2437Shisping 				TeecResult = TEEC_ERROR_GENERIC;
396abdd2437Shisping 				break;
397abdd2437Shisping 			}
398abdd2437Shisping 
399abdd2437Shisping 			break;
400abdd2437Shisping 		}
401abdd2437Shisping 
402abdd2437Shisping 		default:
403abdd2437Shisping 			TeecResult = TEEC_ERROR_BAD_PARAMETERS;
404abdd2437Shisping 			break;
405abdd2437Shisping 		}
406efb93541SHisping Lin 		debug("TEEC: RPMB TeecResult %d\n", TeecResult);
407abdd2437Shisping 		break;
408abdd2437Shisping 	}
409abdd2437Shisping 
410abdd2437Shisping 	case TEE_RPC_RPMB_CMD_GET_DEV_INFO: {
41126690680SHisping Lin 		if (init_rpmb()) {
41226690680SHisping Lin 			TeecResult = TEEC_ERROR_GENERIC;
41326690680SHisping Lin 			goto Exit;
41426690680SHisping Lin 		}
41526690680SHisping Lin 
416abdd2437Shisping 		mmc = do_returnmmc();
41726690680SHisping Lin 		if (finish_rpmb()) {
41826690680SHisping Lin 			TeecResult = TEEC_ERROR_GENERIC;
41926690680SHisping Lin 			goto Exit;
42026690680SHisping Lin 		}
42126690680SHisping Lin 
42226690680SHisping Lin 		if (mmc == NULL) {
42326690680SHisping Lin 			TeecResult = TEEC_ERROR_GENERIC;
42426690680SHisping Lin 			goto Exit;
42526690680SHisping Lin 		}
426abdd2437Shisping 
4271f25ada2SHisping Lin 		DevInfo = (struct tee_rpc_rpmb_dev_info *)(size_t)
428abdd2437Shisping 		TeeSmc32Param[1].u.memref.buf_ptr;
429abdd2437Shisping 
430abdd2437Shisping 		DevInfo->cid[0] = (mmc->cid[0]) >> 24 & 0xff;
431abdd2437Shisping 		DevInfo->cid[1] = (mmc->cid[0]) >> 16 & 0xff;
432abdd2437Shisping 		DevInfo->cid[2] = (mmc->cid[0]) >> 8 & 0xff;
433abdd2437Shisping 		DevInfo->cid[3] = (mmc->cid[0]) & 0xff;
434abdd2437Shisping 		DevInfo->cid[4] = (mmc->cid[1]) >> 24 & 0xff;
435abdd2437Shisping 		DevInfo->cid[5] = (mmc->cid[1]) >> 16 & 0xff;
436abdd2437Shisping 		DevInfo->cid[6] = (mmc->cid[1]) >> 8 & 0xff;
437abdd2437Shisping 		DevInfo->cid[7] = (mmc->cid[1]) & 0xff;
438abdd2437Shisping 		DevInfo->cid[8] = (mmc->cid[2]) >> 24 & 0xff;
439abdd2437Shisping 		DevInfo->cid[9] = (mmc->cid[2]) >> 16 & 0xff;
440abdd2437Shisping 		DevInfo->cid[10] = (mmc->cid[2]) >> 8 & 0xff;
441abdd2437Shisping 		DevInfo->cid[11] = (mmc->cid[2]) & 0xff;
442abdd2437Shisping 		DevInfo->cid[12] = (mmc->cid[3]) >> 24 & 0xff;
443abdd2437Shisping 		DevInfo->cid[13] = (mmc->cid[3]) >> 16 & 0xff;
444abdd2437Shisping 		DevInfo->cid[14] = (mmc->cid[3]) >> 8 & 0xff;
445abdd2437Shisping 		DevInfo->cid[15] = (mmc->cid[3]) & 0xff;
446abdd2437Shisping 		DevInfo->rel_wr_sec_c = 1;
447abdd2437Shisping 		DevInfo->rpmb_size_mult =
448abdd2437Shisping 			(uint8_t)(mmc->capacity_rpmb / (128 * 1024));
449abdd2437Shisping 		DevInfo->ret_code = 0;
450abdd2437Shisping 
451abdd2437Shisping 		goto Exit;
452abdd2437Shisping 	}
453abdd2437Shisping 
454abdd2437Shisping 	default:
455abdd2437Shisping 		TeecResult = TEEC_ERROR_BAD_PARAMETERS;
456abdd2437Shisping 
457abdd2437Shisping 		goto Exit;
458abdd2437Shisping 	}
459abdd2437Shisping 
460abdd2437Shisping 	tempPackets = ResponsePackets;
461abdd2437Shisping 	tempPackets_back = RequestPackets_back;
462abdd2437Shisping 
463abdd2437Shisping 	for (i = 0; i < global_block_count; i++) {
464abdd2437Shisping 		memcpy(tempPackets->stuff_bytes,
465abdd2437Shisping 			tempPackets_back->stuff,
466abdd2437Shisping 			RPMB_STUFF_DATA_SIZE);
467abdd2437Shisping 		memcpy(tempPackets->key_mac,
468abdd2437Shisping 			tempPackets_back->mac,
469abdd2437Shisping 			RPMB_KEY_MAC_SIZE);
470abdd2437Shisping 		memcpy(tempPackets->data,
471abdd2437Shisping 			tempPackets_back->data,
472abdd2437Shisping 			RPMB_DATA_SIZE);
473abdd2437Shisping 		memcpy(tempPackets->nonce,
474abdd2437Shisping 			tempPackets_back->nonce,
475abdd2437Shisping 			RPMB_NONCE_SIZE);
476abdd2437Shisping 		tempPackets->write_counter[3] =
477abdd2437Shisping 			((tempPackets_back->write_counter) >> 24) & 0xFF;
478abdd2437Shisping 		tempPackets->write_counter[2] =
479abdd2437Shisping 			((tempPackets_back->write_counter) >> 16) & 0xFF;
480abdd2437Shisping 		tempPackets->write_counter[1] =
481abdd2437Shisping 			((tempPackets_back->write_counter) >> 8) & 0xFF;
482abdd2437Shisping 		tempPackets->write_counter[0] =
483abdd2437Shisping 			(tempPackets_back->write_counter) & 0xFF;
484abdd2437Shisping 		tempPackets->address[1] =
485abdd2437Shisping 			((tempPackets_back->address) >> 8) & 0xFF;
486abdd2437Shisping 		tempPackets->address[0] =
487abdd2437Shisping 			(tempPackets_back->address) & 0xFF;
488abdd2437Shisping 		tempPackets->block_count[1] =
489abdd2437Shisping 			((tempPackets_back->block_count) >> 8) & 0xFF;
490abdd2437Shisping 		tempPackets->block_count[0] =
491abdd2437Shisping 			(tempPackets_back->block_count) & 0xFF;
492abdd2437Shisping 		tempPackets->op_result[1] =
493abdd2437Shisping 			((tempPackets_back->result) >> 8) & 0xFF;
494abdd2437Shisping 		tempPackets->op_result[0] =
495abdd2437Shisping 			(tempPackets_back->result) & 0xFF;
496abdd2437Shisping 		tempPackets->msg_type[1] =
497abdd2437Shisping 			((tempPackets_back->request) >> 8) & 0xFF;
498abdd2437Shisping 		tempPackets->msg_type[0] =
499abdd2437Shisping 			(tempPackets_back->request) & 0xFF;
500abdd2437Shisping 		tempPackets++;
501abdd2437Shisping 		tempPackets_back++;
502abdd2437Shisping 	}
503abdd2437Shisping 
504abdd2437Shisping 	free(RequestPackets_back);
505abdd2437Shisping 
506abdd2437Shisping Exit:
507abdd2437Shisping 	TeeSmc32Arg->ret = TeecResult;
508abdd2437Shisping 	TeeSmc32Arg->ret_origin = TEEC_ORIGIN_API;
509abdd2437Shisping 
510abdd2437Shisping 	return TeecResult;
511abdd2437Shisping }
512abdd2437Shisping 
513abdd2437Shisping /*
514abdd2437Shisping  * Execute a normal world local file system operation.
515abdd2437Shisping  */
516abdd2437Shisping TEEC_Result OpteeRpcCmdFs(t_teesmc32_arg *TeeSmc32Arg)
517abdd2437Shisping {
5181f25ada2SHisping Lin 	TEEC_Result TeecResult = TEEC_SUCCESS;
5191f25ada2SHisping Lin 	t_teesmc32_param *TeeSmc32Param;
520abdd2437Shisping 
5211f25ada2SHisping Lin 	TeeSmc32Param = TEESMC32_GET_PARAMS(TeeSmc32Arg);
5223251364cSHisping Lin #ifdef CONFIG_OPTEE_V1
523*d079c1a5SHisping Lin 	TeecResult = OpteeClientRkFsProcess((void *)(size_t)TeeSmc32Param[0].u.memref.buf_ptr,
5241f25ada2SHisping Lin 							TeeSmc32Param[0].u.memref.size);
5253251364cSHisping Lin #endif
5263251364cSHisping Lin #ifdef CONFIG_OPTEE_V2
5273251364cSHisping Lin 	TeecResult = tee_supp_rk_fs_process((size_t)TeeSmc32Arg->num_params,
5283251364cSHisping Lin 							(struct tee_ioctl_param *)TeeSmc32Param);
5293251364cSHisping Lin #endif
5301f25ada2SHisping Lin 
5311f25ada2SHisping Lin 	return TeecResult;
5321f25ada2SHisping Lin }
533abdd2437Shisping 
534abdd2437Shisping /*
535abdd2437Shisping  * TBD.
536abdd2437Shisping  */
537abdd2437Shisping TEEC_Result OpteeRpcCmdGetTime(t_teesmc32_arg *TeeSmc32Arg)
538abdd2437Shisping {
539abdd2437Shisping 	return TEEC_ERROR_NOT_IMPLEMENTED;
540abdd2437Shisping }
541abdd2437Shisping 
542abdd2437Shisping /*
543abdd2437Shisping  * TBD.
544abdd2437Shisping  */
545abdd2437Shisping TEEC_Result OpteeRpcCmdWaitMutex(t_teesmc32_arg *TeeSmc32Arg)
546abdd2437Shisping {
547abdd2437Shisping 	return TEEC_ERROR_NOT_IMPLEMENTED;
548abdd2437Shisping }
549abdd2437Shisping 
550abdd2437Shisping /*
551abdd2437Shisping  * Handle the callback from secure world.
552abdd2437Shisping  */
553abdd2437Shisping TEEC_Result OpteeRpcCallback(ARM_SMC_ARGS *ArmSmcArgs)
554abdd2437Shisping {
555abdd2437Shisping 	TEEC_Result TeecResult = TEEC_SUCCESS;
556abdd2437Shisping 
5571f25ada2SHisping Lin 	//printf("OpteeRpcCallback Enter: Arg0=0x%X, Arg1=0x%X, Arg2=0x%X\n",
5581f25ada2SHisping Lin 		//ArmSmcArgs->Arg0, ArmSmcArgs->Arg1, ArmSmcArgs->Arg2);
559abdd2437Shisping 
560abdd2437Shisping 	switch (TEESMC_RETURN_GET_RPC_FUNC(ArmSmcArgs->Arg0)) {
561abdd2437Shisping 	case TEESMC_RPC_FUNC_ALLOC_ARG: {
5621f25ada2SHisping Lin #ifdef CONFIG_OPTEE_V1
563abdd2437Shisping 		TeecResult = OpteeRpcAlloc(ArmSmcArgs->Arg1, &ArmSmcArgs->Arg1);
5641f25ada2SHisping Lin #endif
5651f25ada2SHisping Lin #ifdef CONFIG_OPTEE_V2
566efb93541SHisping Lin 		debug("TEEC: ArmSmcArgs->Arg1 = 0x%x \n", ArmSmcArgs->Arg1);
5671f25ada2SHisping Lin 		TeecResult = OpteeRpcAlloc(ArmSmcArgs->Arg1, &ArmSmcArgs->Arg2);
5681f25ada2SHisping Lin 		ArmSmcArgs->Arg5 = ArmSmcArgs->Arg2;
5691f25ada2SHisping Lin 		ArmSmcArgs->Arg1 = 0;
5701f25ada2SHisping Lin 		ArmSmcArgs->Arg4 = 0;
5711f25ada2SHisping Lin #endif
572abdd2437Shisping 		break;
573abdd2437Shisping 	}
574abdd2437Shisping 
575abdd2437Shisping 	case TEESMC_RPC_FUNC_ALLOC_PAYLOAD: {
576abdd2437Shisping 		TeecResult = OpteeRpcAlloc(ArmSmcArgs->Arg1, &ArmSmcArgs->Arg1);
577abdd2437Shisping 		break;
578abdd2437Shisping 	}
579abdd2437Shisping 
580abdd2437Shisping 	case TEESMC_RPC_FUNC_FREE_ARG: {
5811f25ada2SHisping Lin #ifdef CONFIG_OPTEE_V1
582abdd2437Shisping 		TeecResult = OpteeRpcFree(ArmSmcArgs->Arg1);
5831f25ada2SHisping Lin #endif
5841f25ada2SHisping Lin #ifdef CONFIG_OPTEE_V2
5851f25ada2SHisping Lin 		TeecResult = OpteeRpcFree(ArmSmcArgs->Arg2);
5861f25ada2SHisping Lin #endif
587abdd2437Shisping 		break;
588abdd2437Shisping 	}
589abdd2437Shisping 
590abdd2437Shisping 	case TEESMC_RPC_FUNC_FREE_PAYLOAD: {
591abdd2437Shisping 		TeecResult = OpteeRpcFree(ArmSmcArgs->Arg1);
592abdd2437Shisping 		break;
593abdd2437Shisping 	}
594abdd2437Shisping 
595abdd2437Shisping 	case TEESMC_RPC_FUNC_IRQ: {
596abdd2437Shisping 		break;
597abdd2437Shisping 	}
598abdd2437Shisping 
599abdd2437Shisping 	case TEESMC_RPC_FUNC_CMD: {
6001f25ada2SHisping Lin #ifdef CONFIG_OPTEE_V1
601abdd2437Shisping 		t_teesmc32_arg *TeeSmc32Arg =
6021f25ada2SHisping Lin 			(t_teesmc32_arg *)(size_t)ArmSmcArgs->Arg1;
6031f25ada2SHisping Lin #endif
6041f25ada2SHisping Lin #ifdef CONFIG_OPTEE_V2
6051f25ada2SHisping Lin 		t_teesmc32_arg *TeeSmc32Arg =
606d156c9ffSHisping Lin 			(t_teesmc32_arg *)(size_t)((uint64_t)ArmSmcArgs->Arg1 << 32 | ArmSmcArgs->Arg2);
607efb93541SHisping Lin 		debug("TEEC: TeeSmc32Arg->cmd = 0x%x\n", TeeSmc32Arg->cmd);
6081f25ada2SHisping Lin #endif
609abdd2437Shisping 		switch (TeeSmc32Arg->cmd) {
6101f25ada2SHisping Lin #ifdef CONFIG_OPTEE_V1
611abdd2437Shisping 		case TEE_RPC_LOAD_TA: {
612abdd2437Shisping 			TeecResult = OpteeRpcCmdLoadTa(TeeSmc32Arg);
613abdd2437Shisping 			break;
614abdd2437Shisping 		}
615abdd2437Shisping 
616abdd2437Shisping 		case TEE_RPC_FREE_TA: {
617abdd2437Shisping 			TeecResult = OpteeRpcCmdFreeTa(TeeSmc32Arg);
618abdd2437Shisping 			break;
619abdd2437Shisping 		}
620abdd2437Shisping 
621abdd2437Shisping 		case TEE_RPC_RPMB_CMD: {
622abdd2437Shisping 			TeecResult = OpteeRpcCmdRpmb(TeeSmc32Arg);
623abdd2437Shisping 			break;
624abdd2437Shisping 		}
625abdd2437Shisping 
626abdd2437Shisping 		case TEE_RPC_FS: {
627abdd2437Shisping 			TeecResult = OpteeRpcCmdFs(TeeSmc32Arg);
6281f25ada2SHisping Lin 			TeeSmc32Arg->ret = TEEC_SUCCESS;
629abdd2437Shisping 			break;
630abdd2437Shisping 		}
631abdd2437Shisping 
632abdd2437Shisping 		case TEE_RPC_GET_TIME: {
633abdd2437Shisping 			TeecResult = OpteeRpcCmdGetTime(TeeSmc32Arg);
634abdd2437Shisping 			break;
635abdd2437Shisping 		}
636abdd2437Shisping 
637abdd2437Shisping 		case TEE_RPC_WAIT_MUTEX: {
638abdd2437Shisping 			TeecResult = OpteeRpcCmdWaitMutex(TeeSmc32Arg);
639abdd2437Shisping 			break;
640abdd2437Shisping 		}
6411f25ada2SHisping Lin #endif
6421f25ada2SHisping Lin #ifdef CONFIG_OPTEE_V2
6431f25ada2SHisping Lin 		case OPTEE_MSG_RPC_CMD_SHM_ALLOC_V2: {
6441f25ada2SHisping Lin 			uint32_t tempaddr;
6451f25ada2SHisping Lin 			uint32_t allocsize = TeeSmc32Arg->params[0].u.value.b;
6461f25ada2SHisping Lin 			TeecResult = OpteeRpcAlloc(allocsize, &tempaddr);
647efb93541SHisping Lin 			debug("TEEC: allocsize = 0x%x tempaddr = 0x%x\n", allocsize, tempaddr);
6481f25ada2SHisping Lin 			TeeSmc32Arg->params[0].attr = OPTEE_MSG_ATTR_TYPE_TMEM_OUTPUT_V2;
6491f25ada2SHisping Lin 			TeeSmc32Arg->params[0].u.memref.buf_ptr = tempaddr;
6501f25ada2SHisping Lin 			TeeSmc32Arg->params[0].u.memref.size = allocsize;
6511f25ada2SHisping Lin 			TeeSmc32Arg->params[0].u.memref.shm_ref = tempaddr;
6521f25ada2SHisping Lin 			TeeSmc32Arg->ret = TEE_SUCCESS;
6531f25ada2SHisping Lin 			break;
6541f25ada2SHisping Lin 		}
6551f25ada2SHisping Lin 		case OPTEE_MSG_RPC_CMD_SHM_FREE_V2: {
6561f25ada2SHisping Lin 			uint32_t tempaddr = TeeSmc32Arg->params[0].u.value.b;
6571f25ada2SHisping Lin 			TeecResult = OpteeRpcFree(tempaddr);
6581f25ada2SHisping Lin 			break;
6591f25ada2SHisping Lin 
6601f25ada2SHisping Lin 		}
6611f25ada2SHisping Lin 		case OPTEE_MSG_RPC_CMD_RPMB_V2: {
6621f25ada2SHisping Lin 			TeecResult = OpteeRpcCmdRpmb(TeeSmc32Arg);
6631f25ada2SHisping Lin 			break;
6641f25ada2SHisping Lin 		}
6653251364cSHisping Lin 		case OPTEE_MSG_RPC_CMD_FS_V2: {
6663251364cSHisping Lin 			TeecResult = OpteeRpcCmdFs(TeeSmc32Arg);
6673251364cSHisping Lin 			TeeSmc32Arg->ret = TEEC_SUCCESS;
6683251364cSHisping Lin 			break;
6693251364cSHisping Lin 		}
6701f25ada2SHisping Lin 		case OPTEE_MSG_RPC_CMD_LOAD_TA_V2: {
6711f25ada2SHisping Lin 			TeecResult = OpteeRpcCmdLoadV2Ta(TeeSmc32Arg);
6721f25ada2SHisping Lin 			break;
6731f25ada2SHisping Lin 		}
6741f25ada2SHisping Lin #endif
675abdd2437Shisping 
676abdd2437Shisping 		default: {
677efb93541SHisping Lin 			printf("TEEC: ...unsupported RPC CMD: cmd=0x%X\n",
678abdd2437Shisping 				TeeSmc32Arg->cmd);
679abdd2437Shisping 			TeecResult = TEEC_ERROR_NOT_IMPLEMENTED;
680abdd2437Shisping 			break;
681abdd2437Shisping 		}
682abdd2437Shisping 	}
683abdd2437Shisping 
684abdd2437Shisping 		break;
685abdd2437Shisping 	}
686abdd2437Shisping 
687abdd2437Shisping 	case TEESMC_OPTEE_RPC_FUNC_ALLOC_PAYLOAD: {
688abdd2437Shisping 		TeecResult = OpteeRpcAlloc(ArmSmcArgs->Arg1, &ArmSmcArgs->Arg1);
689abdd2437Shisping 		ArmSmcArgs->Arg2 = ArmSmcArgs->Arg1;
690abdd2437Shisping 		break;
691abdd2437Shisping 	}
692abdd2437Shisping 
693abdd2437Shisping 	case TEESMC_OPTEE_RPC_FUNC_FREE_PAYLOAD: {
694abdd2437Shisping 		TeecResult = OpteeRpcFree(ArmSmcArgs->Arg1);
695abdd2437Shisping 		break;
696abdd2437Shisping 	}
697abdd2437Shisping 
698abdd2437Shisping 	default: {
699efb93541SHisping Lin 		printf("TEEC: ...unsupported RPC : Arg0=0x%X\n", ArmSmcArgs->Arg0);
700abdd2437Shisping 		TeecResult = TEEC_ERROR_NOT_IMPLEMENTED;
701abdd2437Shisping 		break;
702abdd2437Shisping 	}
703abdd2437Shisping 	}
704abdd2437Shisping 
705abdd2437Shisping 	ArmSmcArgs->Arg0 = TEESMC32_CALL_RETURN_FROM_RPC;
706efb93541SHisping Lin 	debug("TEEC: OpteeRpcCallback Exit : TeecResult=0x%X\n", TeecResult);
707abdd2437Shisping 
708abdd2437Shisping 	return TeecResult;
709abdd2437Shisping }
710