xref: /rk3399_rockchip-uboot/lib/optee_clientApi/OpteeClientRPC.c (revision 10adce6ab7d0e77e93532d48d086965391446d25)
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/OpteeClientLoadTa.h>
12 #include <optee_include/OpteeClientMem.h>
13 #include <optee_include/OpteeClientRPC.h>
14 #include <optee_include/teesmc.h>
15 #include <optee_include/teesmc_v2.h>
16 #include <optee_include/teesmc_optee.h>
17 #include <optee_include/tee_mmc_rpmb.h>
18 #include <optee_include/tee_rpc_types.h>
19 #include <optee_include/tee_rpc.h>
20 #ifdef CONFIG_OPTEE_V1
21 #include <optee_include/OpteeClientRkFs.h>
22 #endif
23 #ifdef CONFIG_OPTEE_V2
24 #include <optee_include/OpteeClientRkNewFs.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 TEEC_Result OpteeRpcCmdLoadV2Ta(t_teesmc32_arg *TeeSmc32Arg)
60 {
61 	TEEC_Result TeecResult = TEEC_SUCCESS;
62 	t_teesmc32_param *TeeSmc32Param = NULL;
63 	int ta_found = 0;
64 	size_t size = 0;
65 
66 	if (TeeSmc32Arg->num_params != 2) {
67 		TeecResult = TEEC_ERROR_BAD_PARAMETERS;
68 		goto Exit;
69 	}
70 
71 	TeeSmc32Param = TEESMC32_GET_PARAMS(TeeSmc32Arg);
72 
73 	size = TeeSmc32Param[1].u.memref.size;
74 	ta_found = search_ta((void *)(size_t)&TeeSmc32Param[0].u.value,
75 				(void *)(size_t)TeeSmc32Param[1].u.memref.buf_ptr, &size);
76 	if (ta_found == TA_BINARY_FOUND) {
77 		TeeSmc32Param[1].u.memref.size = size;
78 		TeecResult = TEEC_SUCCESS;
79 	} else {
80 		printf("  TA not found \n");
81 		TeecResult = TEEC_ERROR_ITEM_NOT_FOUND;
82 	}
83 
84 Exit:
85 	TeeSmc32Arg->ret = TeecResult;
86 	TeeSmc32Arg->ret_origin = TEEC_ORIGIN_API;
87 
88 	debug("TEEC: OpteeRpcCmdLoadV2Ta Exit : TeecResult=0x%X\n", TeecResult);
89 
90 	return TeecResult;
91 }
92 
93 /*
94  * Execute an RPMB storage operation.
95  */
96 TEEC_Result OpteeRpcCmdRpmb(t_teesmc32_arg *TeeSmc32Arg)
97 {
98 	return emmc_rpmb_process(TeeSmc32Arg);
99 }
100 
101 /*
102  * Execute a normal world local file system operation.
103  */
104 TEEC_Result OpteeRpcCmdFs(t_teesmc32_arg *TeeSmc32Arg)
105 {
106 	TEEC_Result TeecResult = TEEC_SUCCESS;
107 	t_teesmc32_param *TeeSmc32Param;
108 
109 	TeeSmc32Param = TEESMC32_GET_PARAMS(TeeSmc32Arg);
110 #ifdef CONFIG_OPTEE_V1
111 	TeecResult = OpteeClientRkFsProcess((void *)(size_t)TeeSmc32Param[0].u.memref.buf_ptr,
112 							TeeSmc32Param[0].u.memref.size);
113 	TeeSmc32Arg->ret = TEEC_SUCCESS;
114 #endif
115 #ifdef CONFIG_OPTEE_V2
116 	TeecResult = OpteeClientRkFsProcess((size_t)TeeSmc32Arg->num_params,
117 							(struct tee_ioctl_param *)TeeSmc32Param);
118 	TeeSmc32Arg->ret = TeecResult;
119 #endif
120 	return TeecResult;
121 }
122 
123 /*
124  * TBD.
125  */
126 TEEC_Result OpteeRpcCmdGetTime(t_teesmc32_arg *TeeSmc32Arg)
127 {
128 	return TEEC_ERROR_NOT_IMPLEMENTED;
129 }
130 
131 /*
132  * TBD.
133  */
134 TEEC_Result OpteeRpcCmdWaitMutex(t_teesmc32_arg *TeeSmc32Arg)
135 {
136 	return TEEC_ERROR_NOT_IMPLEMENTED;
137 }
138 
139 /*
140  * Handle the callback from secure world.
141  */
142 TEEC_Result OpteeRpcCallback(ARM_SMC_ARGS *ArmSmcArgs)
143 {
144 	TEEC_Result TeecResult = TEEC_SUCCESS;
145 
146 	//printf("OpteeRpcCallback Enter: Arg0=0x%X, Arg1=0x%X, Arg2=0x%X\n",
147 		//ArmSmcArgs->Arg0, ArmSmcArgs->Arg1, ArmSmcArgs->Arg2);
148 
149 	switch (TEESMC_RETURN_GET_RPC_FUNC(ArmSmcArgs->Arg0)) {
150 	case TEESMC_RPC_FUNC_ALLOC_ARG: {
151 		debug("TEEC: ArmSmcArgs->Arg1 = 0x%x \n", ArmSmcArgs->Arg1);
152 		TeecResult = OpteeRpcAlloc(ArmSmcArgs->Arg1, &ArmSmcArgs->Arg2);
153 		ArmSmcArgs->Arg5 = ArmSmcArgs->Arg2;
154 		ArmSmcArgs->Arg1 = 0;
155 		ArmSmcArgs->Arg4 = 0;
156 		break;
157 	}
158 
159 	case TEESMC_RPC_FUNC_ALLOC_PAYLOAD: {
160 		TeecResult = OpteeRpcAlloc(ArmSmcArgs->Arg1, &ArmSmcArgs->Arg1);
161 		break;
162 	}
163 
164 	case TEESMC_RPC_FUNC_FREE_ARG: {
165 		TeecResult = OpteeRpcFree(ArmSmcArgs->Arg2);
166 		break;
167 	}
168 
169 	case TEESMC_RPC_FUNC_FREE_PAYLOAD: {
170 		TeecResult = OpteeRpcFree(ArmSmcArgs->Arg1);
171 		break;
172 	}
173 
174 	case TEESMC_RPC_FUNC_IRQ: {
175 		break;
176 	}
177 
178 	case TEESMC_RPC_FUNC_CMD: {
179 		t_teesmc32_arg *TeeSmc32Arg =
180 			(t_teesmc32_arg *)(size_t)((uint64_t)ArmSmcArgs->Arg1 << 32 | ArmSmcArgs->Arg2);
181 		debug("TEEC: TeeSmc32Arg->cmd = 0x%x\n", TeeSmc32Arg->cmd);
182 		switch (TeeSmc32Arg->cmd) {
183 		case OPTEE_MSG_RPC_CMD_SHM_ALLOC_V2: {
184 			uint32_t tempaddr;
185 			uint32_t allocsize = TeeSmc32Arg->params[0].u.value.b;
186 			TeecResult = OpteeRpcAlloc(allocsize, &tempaddr);
187 			debug("TEEC: allocsize = 0x%x tempaddr = 0x%x\n", allocsize, tempaddr);
188 			TeeSmc32Arg->params[0].attr = OPTEE_MSG_ATTR_TYPE_TMEM_OUTPUT_V2;
189 			TeeSmc32Arg->params[0].u.memref.buf_ptr = tempaddr;
190 			TeeSmc32Arg->params[0].u.memref.size = allocsize;
191 			TeeSmc32Arg->params[0].u.memref.shm_ref = tempaddr;
192 			TeeSmc32Arg->ret = TEE_SUCCESS;
193 			break;
194 		}
195 		case OPTEE_MSG_RPC_CMD_SHM_FREE_V2: {
196 			uint32_t tempaddr = TeeSmc32Arg->params[0].u.value.b;
197 			TeecResult = OpteeRpcFree(tempaddr);
198 			break;
199 
200 		}
201 		case OPTEE_MSG_RPC_CMD_RPMB_V2: {
202 			TeecResult = OpteeRpcCmdRpmb(TeeSmc32Arg);
203 			break;
204 		}
205 		case OPTEE_MSG_RPC_CMD_FS_V2: {
206 			TeecResult = OpteeRpcCmdFs(TeeSmc32Arg);
207 			break;
208 		}
209 		case OPTEE_MSG_RPC_CMD_LOAD_TA_V2: {
210 			TeecResult = OpteeRpcCmdLoadV2Ta(TeeSmc32Arg);
211 			break;
212 		}
213 
214 		default: {
215 			printf("TEEC: ...unsupported RPC CMD: cmd=0x%X\n",
216 				TeeSmc32Arg->cmd);
217 			TeecResult = TEEC_ERROR_NOT_IMPLEMENTED;
218 			break;
219 		}
220 	}
221 
222 		break;
223 	}
224 
225 	case TEESMC_OPTEE_RPC_FUNC_ALLOC_PAYLOAD: {
226 		TeecResult = OpteeRpcAlloc(ArmSmcArgs->Arg1, &ArmSmcArgs->Arg1);
227 		ArmSmcArgs->Arg2 = ArmSmcArgs->Arg1;
228 		break;
229 	}
230 
231 	case TEESMC_OPTEE_RPC_FUNC_FREE_PAYLOAD: {
232 		TeecResult = OpteeRpcFree(ArmSmcArgs->Arg1);
233 		break;
234 	}
235 
236 	default: {
237 		printf("TEEC: ...unsupported RPC : Arg0=0x%X\n", ArmSmcArgs->Arg0);
238 		TeecResult = TEEC_ERROR_NOT_IMPLEMENTED;
239 		break;
240 	}
241 	}
242 
243 	ArmSmcArgs->Arg0 = TEESMC32_CALL_RETURN_FROM_RPC;
244 	debug("TEEC: OpteeRpcCallback Exit : TeecResult=0x%X\n", TeecResult);
245 
246 	return TeecResult;
247 }
248