xref: /rk3399_rockchip-uboot/lib/optee_clientApi/OpteeClientRPC.c (revision 395c77b5f9b45eba4468a378527c654ac1160fc0)
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 <boot_rkimg.h>
9 #include <stdlib.h>
10 #include <command.h>
11 #include <mmc.h>
12 #include <optee_include/OpteeClientLoadTa.h>
13 #include <optee_include/OpteeClientMem.h>
14 #include <optee_include/OpteeClientRPC.h>
15 #include <optee_include/teesmc.h>
16 #include <optee_include/teesmc_v2.h>
17 #include <optee_include/teesmc_optee.h>
18 #include <optee_include/tee_mmc_rpmb.h>
19 #include <optee_include/tee_ufs_rpmb.h>
20 #include <optee_include/tee_rpc_types.h>
21 #include <optee_include/tee_rpc.h>
22 #ifdef CONFIG_OPTEE_V1
23 #include <optee_include/OpteeClientRkFs.h>
24 #endif
25 #ifdef CONFIG_OPTEE_V2
26 #include <optee_include/OpteeClientRkNewFs.h>
27 #endif
28 
29 /*
30  * Memory allocation.
31  * Currently treated the same for both arguments & payloads.
32  */
OpteeRpcAlloc(uint32_t Size,uint32_t * Address)33 TEEC_Result OpteeRpcAlloc(uint32_t Size, uint32_t *Address)
34 {
35 	TEEC_Result TeecResult = TEEC_SUCCESS;
36 	size_t AllocAddress;
37 
38 	*Address = 0;
39 
40 	if (Size != 0) {
41 		AllocAddress = (size_t) OpteeClientMemAlloc(Size);
42 
43 		if (AllocAddress == 0)
44 			TeecResult = TEEC_ERROR_OUT_OF_MEMORY;
45 		else
46 			*Address = AllocAddress;
47 	}
48 	return TeecResult;
49 }
50 
51 /*
52  * Memory free.
53  * Currently treated the same for both arguments & payloads.
54  */
OpteeRpcFree(uint32_t Address)55 TEEC_Result OpteeRpcFree(uint32_t Address)
56 {
57 	OpteeClientMemFree((void *)(size_t)Address);
58 	return TEEC_SUCCESS;
59 }
60 
OpteeRpcCmdLoadV2Ta(t_teesmc32_arg * TeeSmc32Arg)61 TEEC_Result OpteeRpcCmdLoadV2Ta(t_teesmc32_arg *TeeSmc32Arg)
62 {
63 	TEEC_Result TeecResult = TEEC_SUCCESS;
64 	t_teesmc32_param *TeeSmc32Param = NULL;
65 	int ta_found = 0;
66 	size_t size = 0;
67 
68 	if (TeeSmc32Arg->num_params != 2) {
69 		TeecResult = TEEC_ERROR_BAD_PARAMETERS;
70 		goto Exit;
71 	}
72 
73 	TeeSmc32Param = TEESMC32_GET_PARAMS(TeeSmc32Arg);
74 
75 	size = TeeSmc32Param[1].u.memref.size;
76 	ta_found = search_ta((void *)(size_t)&TeeSmc32Param[0].u.value,
77 				(void *)(size_t)TeeSmc32Param[1].u.memref.buf_ptr, &size);
78 	if (ta_found == TA_BINARY_FOUND) {
79 		TeeSmc32Param[1].u.memref.size = size;
80 		TeecResult = TEEC_SUCCESS;
81 	} else {
82 		printf("  TA not found \n");
83 		TeecResult = TEEC_ERROR_ITEM_NOT_FOUND;
84 	}
85 
86 Exit:
87 	TeeSmc32Arg->ret = TeecResult;
88 	TeeSmc32Arg->ret_origin = TEEC_ORIGIN_API;
89 
90 	debug("TEEC: OpteeRpcCmdLoadV2Ta Exit : TeecResult=0x%X\n", TeecResult);
91 
92 	return TeecResult;
93 }
94 
95 /*
96  * Execute an RPMB storage operation.
97  */
OpteeRpcCmdRpmb(t_teesmc32_arg * TeeSmc32Arg)98 TEEC_Result OpteeRpcCmdRpmb(t_teesmc32_arg *TeeSmc32Arg)
99 {
100 	struct blk_desc *dev_desc;
101 
102 	dev_desc = rockchip_get_bootdev();
103 	if (!dev_desc) {
104 		printf("%s: dev_desc is NULL!\n", __func__);
105 		return TEEC_ERROR_GENERIC;
106 	}
107 
108 	if (dev_desc->if_type == IF_TYPE_MMC && dev_desc->devnum == 0)//emmc
109 		return emmc_rpmb_process(TeeSmc32Arg);
110 	else if (dev_desc->if_type == IF_TYPE_SCSI)//ufs
111 		return ufs_rpmb_process(TeeSmc32Arg);
112 
113 	printf("Device not support rpmb!\n");
114 	return TEEC_ERROR_NOT_IMPLEMENTED;
115 }
116 
117 /*
118  * Execute a normal world local file system operation.
119  */
OpteeRpcCmdFs(t_teesmc32_arg * TeeSmc32Arg)120 TEEC_Result OpteeRpcCmdFs(t_teesmc32_arg *TeeSmc32Arg)
121 {
122 	TEEC_Result TeecResult = TEEC_SUCCESS;
123 	t_teesmc32_param *TeeSmc32Param;
124 
125 	TeeSmc32Param = TEESMC32_GET_PARAMS(TeeSmc32Arg);
126 #ifdef CONFIG_OPTEE_V1
127 	TeecResult = OpteeClientRkFsProcess((void *)(size_t)TeeSmc32Param[0].u.memref.buf_ptr,
128 							TeeSmc32Param[0].u.memref.size);
129 	TeeSmc32Arg->ret = TEEC_SUCCESS;
130 #endif
131 #ifdef CONFIG_OPTEE_V2
132 	TeecResult = OpteeClientRkFsProcess((size_t)TeeSmc32Arg->num_params,
133 							(struct tee_ioctl_param *)TeeSmc32Param);
134 	TeeSmc32Arg->ret = TeecResult;
135 #endif
136 	return TeecResult;
137 }
138 
139 /*
140  * TBD.
141  */
OpteeRpcCmdGetTime(t_teesmc32_arg * TeeSmc32Arg)142 TEEC_Result OpteeRpcCmdGetTime(t_teesmc32_arg *TeeSmc32Arg)
143 {
144 	return TEEC_ERROR_NOT_IMPLEMENTED;
145 }
146 
147 /*
148  * TBD.
149  */
OpteeRpcCmdWaitMutex(t_teesmc32_arg * TeeSmc32Arg)150 TEEC_Result OpteeRpcCmdWaitMutex(t_teesmc32_arg *TeeSmc32Arg)
151 {
152 	return TEEC_ERROR_NOT_IMPLEMENTED;
153 }
154 
155 /*
156  * Handle the callback from secure world.
157  */
OpteeRpcCallback(ARM_SMC_ARGS * ArmSmcArgs)158 TEEC_Result OpteeRpcCallback(ARM_SMC_ARGS *ArmSmcArgs)
159 {
160 	TEEC_Result TeecResult = TEEC_SUCCESS;
161 
162 	//printf("OpteeRpcCallback Enter: Arg0=0x%X, Arg1=0x%X, Arg2=0x%X\n",
163 		//ArmSmcArgs->Arg0, ArmSmcArgs->Arg1, ArmSmcArgs->Arg2);
164 
165 	switch (TEESMC_RETURN_GET_RPC_FUNC(ArmSmcArgs->Arg0)) {
166 	case TEESMC_RPC_FUNC_ALLOC_ARG: {
167 		debug("TEEC: ArmSmcArgs->Arg1 = 0x%x \n", ArmSmcArgs->Arg1);
168 		TeecResult = OpteeRpcAlloc(ArmSmcArgs->Arg1, &ArmSmcArgs->Arg2);
169 		ArmSmcArgs->Arg5 = ArmSmcArgs->Arg2;
170 		ArmSmcArgs->Arg1 = 0;
171 		ArmSmcArgs->Arg4 = 0;
172 		break;
173 	}
174 
175 	case TEESMC_RPC_FUNC_ALLOC_PAYLOAD: {
176 		TeecResult = OpteeRpcAlloc(ArmSmcArgs->Arg1, &ArmSmcArgs->Arg1);
177 		break;
178 	}
179 
180 	case TEESMC_RPC_FUNC_FREE_ARG: {
181 		TeecResult = OpteeRpcFree(ArmSmcArgs->Arg2);
182 		break;
183 	}
184 
185 	case TEESMC_RPC_FUNC_FREE_PAYLOAD: {
186 		TeecResult = OpteeRpcFree(ArmSmcArgs->Arg1);
187 		break;
188 	}
189 
190 	case TEESMC_RPC_FUNC_IRQ: {
191 		break;
192 	}
193 
194 	case TEESMC_RPC_FUNC_CMD: {
195 		t_teesmc32_arg *TeeSmc32Arg =
196 			(t_teesmc32_arg *)(size_t)((uint64_t)ArmSmcArgs->Arg1 << 32 | ArmSmcArgs->Arg2);
197 		debug("TEEC: TeeSmc32Arg->cmd = 0x%x\n", TeeSmc32Arg->cmd);
198 		switch (TeeSmc32Arg->cmd) {
199 		case OPTEE_MSG_RPC_CMD_SHM_ALLOC_V2: {
200 			uint32_t tempaddr;
201 			uint32_t allocsize = TeeSmc32Arg->params[0].u.value.b;
202 			TeecResult = OpteeRpcAlloc(allocsize, &tempaddr);
203 			debug("TEEC: allocsize = 0x%x tempaddr = 0x%x\n", allocsize, tempaddr);
204 			TeeSmc32Arg->params[0].attr = OPTEE_MSG_ATTR_TYPE_TMEM_OUTPUT_V2;
205 			TeeSmc32Arg->params[0].u.memref.buf_ptr = tempaddr;
206 			TeeSmc32Arg->params[0].u.memref.size = allocsize;
207 			TeeSmc32Arg->params[0].u.memref.shm_ref = tempaddr;
208 			TeeSmc32Arg->ret = TEE_SUCCESS;
209 			break;
210 		}
211 		case OPTEE_MSG_RPC_CMD_SHM_FREE_V2: {
212 			uint32_t tempaddr = TeeSmc32Arg->params[0].u.value.b;
213 			TeecResult = OpteeRpcFree(tempaddr);
214 			break;
215 
216 		}
217 		case OPTEE_MSG_RPC_CMD_RPMB_V2: {
218 			TeecResult = OpteeRpcCmdRpmb(TeeSmc32Arg);
219 			break;
220 		}
221 		case OPTEE_MSG_RPC_CMD_FS_V2: {
222 			TeecResult = OpteeRpcCmdFs(TeeSmc32Arg);
223 			break;
224 		}
225 		case OPTEE_MSG_RPC_CMD_LOAD_TA_V2: {
226 			TeecResult = OpteeRpcCmdLoadV2Ta(TeeSmc32Arg);
227 			break;
228 		}
229 
230 		default: {
231 			printf("TEEC: ...unsupported RPC CMD: cmd=0x%X\n",
232 				TeeSmc32Arg->cmd);
233 			TeecResult = TEEC_ERROR_NOT_IMPLEMENTED;
234 			break;
235 		}
236 	}
237 
238 		break;
239 	}
240 
241 	case TEESMC_OPTEE_RPC_FUNC_ALLOC_PAYLOAD: {
242 		TeecResult = OpteeRpcAlloc(ArmSmcArgs->Arg1, &ArmSmcArgs->Arg1);
243 		ArmSmcArgs->Arg2 = ArmSmcArgs->Arg1;
244 		break;
245 	}
246 
247 	case TEESMC_OPTEE_RPC_FUNC_FREE_PAYLOAD: {
248 		TeecResult = OpteeRpcFree(ArmSmcArgs->Arg1);
249 		break;
250 	}
251 
252 	default: {
253 		printf("TEEC: ...unsupported RPC : Arg0=0x%X\n", ArmSmcArgs->Arg0);
254 		TeecResult = TEEC_ERROR_NOT_IMPLEMENTED;
255 		break;
256 	}
257 	}
258 
259 	ArmSmcArgs->Arg0 = TEESMC32_CALL_RETURN_FROM_RPC;
260 	debug("TEEC: OpteeRpcCallback Exit : TeecResult=0x%X\n", TeecResult);
261 
262 	return TeecResult;
263 }
264