1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun * Copyright 2017, Rockchip Electronics Co., Ltd
3*4882a593Smuzhiyun * hisping lin, <hisping.lin@rock-chips.com>
4*4882a593Smuzhiyun *
5*4882a593Smuzhiyun * SPDX-License-Identifier: GPL-2.0+
6*4882a593Smuzhiyun */
7*4882a593Smuzhiyun #include <common.h>
8*4882a593Smuzhiyun #include <optee_include/OpteeClientMem.h>
9*4882a593Smuzhiyun #include <optee_include/OpteeClientSMC.h>
10*4882a593Smuzhiyun #include <optee_include/OpteeClientRPC.h>
11*4882a593Smuzhiyun #include <optee_include/teesmc.h>
12*4882a593Smuzhiyun #include <optee_include/teesmc_v2.h>
13*4882a593Smuzhiyun
14*4882a593Smuzhiyun
15*4882a593Smuzhiyun #define TEEC_SMC_DEFAULT_CACHE_ATTRIBUTES \
16*4882a593Smuzhiyun (TEESMC_ATTR_CACHE_DEFAULT << TEESMC_ATTR_CACHE_SHIFT);
17*4882a593Smuzhiyun
18*4882a593Smuzhiyun static void SetTeeSmc32Params(TEEC_Operation *operation,
19*4882a593Smuzhiyun t_teesmc32_param *TeeSmc32Param);
20*4882a593Smuzhiyun static void GetTeeSmc32Params(t_teesmc32_param *TeeSmc32Param,
21*4882a593Smuzhiyun TEEC_Operation *operation);
22*4882a593Smuzhiyun static TEEC_Result OpteeSmcCall(t_teesmc32_arg *TeeSmc32Arg);
23*4882a593Smuzhiyun
tee_uuid_to_octets(uint8_t * d,const TEEC_UUID * s)24*4882a593Smuzhiyun void tee_uuid_to_octets(uint8_t *d, const TEEC_UUID *s)
25*4882a593Smuzhiyun {
26*4882a593Smuzhiyun d[0] = s->timeLow >> 24;
27*4882a593Smuzhiyun d[1] = s->timeLow >> 16;
28*4882a593Smuzhiyun d[2] = s->timeLow >> 8;
29*4882a593Smuzhiyun d[3] = s->timeLow;
30*4882a593Smuzhiyun d[4] = s->timeMid >> 8;
31*4882a593Smuzhiyun d[5] = s->timeMid;
32*4882a593Smuzhiyun d[6] = s->timeHiAndVersion >> 8;
33*4882a593Smuzhiyun d[7] = s->timeHiAndVersion;
34*4882a593Smuzhiyun memcpy(d + 8, s->clockSeqAndNode, sizeof(s->clockSeqAndNode));
35*4882a593Smuzhiyun }
36*4882a593Smuzhiyun
37*4882a593Smuzhiyun /*
38*4882a593Smuzhiyun * This function opens a new Session between the Client application and the
39*4882a593Smuzhiyun * specified TEE application.
40*4882a593Smuzhiyun *
41*4882a593Smuzhiyun * Only connection_method == TEEC_LOGIN_PUBLIC is supported connection_data and
42*4882a593Smuzhiyun * operation shall be set to NULL.
43*4882a593Smuzhiyun */
TEEC_SMC_OpenSession(TEEC_Context * context,TEEC_Session * session,const TEEC_UUID * destination,TEEC_Operation * operation,uint32_t * error_origin)44*4882a593Smuzhiyun TEEC_Result TEEC_SMC_OpenSession(TEEC_Context *context,
45*4882a593Smuzhiyun TEEC_Session *session,
46*4882a593Smuzhiyun const TEEC_UUID *destination,
47*4882a593Smuzhiyun TEEC_Operation *operation,
48*4882a593Smuzhiyun uint32_t *error_origin)
49*4882a593Smuzhiyun {
50*4882a593Smuzhiyun TEEC_Result TeecResult = TEEC_SUCCESS;
51*4882a593Smuzhiyun uint32_t TeeSmc32ArgLength;
52*4882a593Smuzhiyun uint32_t TeeSmcMetaSessionLength;
53*4882a593Smuzhiyun
54*4882a593Smuzhiyun t_teesmc32_arg *TeeSmc32Arg = NULL;
55*4882a593Smuzhiyun t_teesmc32_param *TeeSmc32Param = NULL;
56*4882a593Smuzhiyun
57*4882a593Smuzhiyun t_teesmc_meta_open_session *TeeSmcMetaSession = NULL;
58*4882a593Smuzhiyun
59*4882a593Smuzhiyun uint32_t MetaNum = 2;
60*4882a593Smuzhiyun
61*4882a593Smuzhiyun *error_origin = TEEC_ORIGIN_API;
62*4882a593Smuzhiyun
63*4882a593Smuzhiyun TeeSmc32ArgLength =
64*4882a593Smuzhiyun TEESMC32_GET_ARG_SIZE(TEEC_CONFIG_PAYLOAD_REF_COUNT + MetaNum);
65*4882a593Smuzhiyun
66*4882a593Smuzhiyun TeeSmc32Arg = (t_teesmc32_arg *)OpteeClientMemAlloc(TeeSmc32ArgLength);
67*4882a593Smuzhiyun
68*4882a593Smuzhiyun if (TeeSmc32Arg == NULL) {
69*4882a593Smuzhiyun TeecResult = TEEC_ERROR_OUT_OF_MEMORY;
70*4882a593Smuzhiyun goto Exit;
71*4882a593Smuzhiyun }
72*4882a593Smuzhiyun
73*4882a593Smuzhiyun memset(TeeSmc32Arg, 0, TeeSmc32ArgLength);
74*4882a593Smuzhiyun
75*4882a593Smuzhiyun TeeSmcMetaSessionLength = sizeof(*TeeSmcMetaSession);
76*4882a593Smuzhiyun
77*4882a593Smuzhiyun TeeSmcMetaSession = (t_teesmc_meta_open_session *)
78*4882a593Smuzhiyun OpteeClientMemAlloc(TeeSmcMetaSessionLength);
79*4882a593Smuzhiyun
80*4882a593Smuzhiyun if (TeeSmcMetaSession == NULL) {
81*4882a593Smuzhiyun TeecResult = TEEC_ERROR_OUT_OF_MEMORY;
82*4882a593Smuzhiyun goto Exit;
83*4882a593Smuzhiyun }
84*4882a593Smuzhiyun
85*4882a593Smuzhiyun memset(TeeSmcMetaSession, 0, TeeSmcMetaSessionLength);
86*4882a593Smuzhiyun
87*4882a593Smuzhiyun TeeSmc32Arg->cmd = TEESMC_CMD_OPEN_SESSION;
88*4882a593Smuzhiyun TeeSmc32Arg->num_params = TEEC_CONFIG_PAYLOAD_REF_COUNT + MetaNum;
89*4882a593Smuzhiyun
90*4882a593Smuzhiyun TeeSmc32Param = TEESMC32_GET_PARAMS(TeeSmc32Arg);
91*4882a593Smuzhiyun
92*4882a593Smuzhiyun memcpy(&TeeSmcMetaSession->uuid,
93*4882a593Smuzhiyun destination,
94*4882a593Smuzhiyun sizeof(TeeSmcMetaSession->uuid));
95*4882a593Smuzhiyun TeeSmcMetaSession->clnt_login = TEEC_LOGIN_PUBLIC;
96*4882a593Smuzhiyun
97*4882a593Smuzhiyun TeeSmc32Param[0].u.memref.buf_ptr = (uint32_t) (size_t)TeeSmcMetaSession;
98*4882a593Smuzhiyun TeeSmc32Param[0].u.memref.size = sizeof(*TeeSmcMetaSession);
99*4882a593Smuzhiyun
100*4882a593Smuzhiyun #ifdef CONFIG_OPTEE_V1
101*4882a593Smuzhiyun memcpy((void *)&TeeSmc32Param[0].u.value, &TeeSmcMetaSession->uuid, sizeof(TeeSmcMetaSession->uuid));
102*4882a593Smuzhiyun #endif
103*4882a593Smuzhiyun
104*4882a593Smuzhiyun #ifdef CONFIG_OPTEE_V2
105*4882a593Smuzhiyun uint8_t * session_uuid = (uint8_t *)&TeeSmcMetaSession->uuid;
106*4882a593Smuzhiyun tee_uuid_to_octets(session_uuid, destination);
107*4882a593Smuzhiyun memcpy((void *)&TeeSmc32Param[0].u.value, &TeeSmcMetaSession->uuid, sizeof(TeeSmcMetaSession->uuid));
108*4882a593Smuzhiyun #endif
109*4882a593Smuzhiyun TeeSmc32Param[1].u.value.c = TeeSmcMetaSession->clnt_login;
110*4882a593Smuzhiyun
111*4882a593Smuzhiyun TeeSmc32Param[0].attr = OPTEE_MSG_ATTR_TYPE_VALUE_INPUT_V2 |
112*4882a593Smuzhiyun OPTEE_MSG_ATTR_META_V2;
113*4882a593Smuzhiyun TeeSmc32Param[1].attr = OPTEE_MSG_ATTR_TYPE_VALUE_INPUT_V2 |
114*4882a593Smuzhiyun OPTEE_MSG_ATTR_META_V2;
115*4882a593Smuzhiyun
116*4882a593Smuzhiyun SetTeeSmc32Params(operation, TeeSmc32Param + MetaNum);
117*4882a593Smuzhiyun
118*4882a593Smuzhiyun *error_origin = TEEC_ORIGIN_COMMS;
119*4882a593Smuzhiyun
120*4882a593Smuzhiyun TeecResult = OpteeSmcCall(TeeSmc32Arg);
121*4882a593Smuzhiyun if (TeecResult != TEEC_SUCCESS)
122*4882a593Smuzhiyun goto Exit;
123*4882a593Smuzhiyun
124*4882a593Smuzhiyun session->id = TeeSmc32Arg->session;
125*4882a593Smuzhiyun TeecResult = TeeSmc32Arg->ret;
126*4882a593Smuzhiyun *error_origin = TeeSmc32Arg->ret_origin;
127*4882a593Smuzhiyun
128*4882a593Smuzhiyun GetTeeSmc32Params(TeeSmc32Param + MetaNum, operation);
129*4882a593Smuzhiyun
130*4882a593Smuzhiyun Exit:
131*4882a593Smuzhiyun if (TeeSmc32Arg != NULL)
132*4882a593Smuzhiyun OpteeClientMemFree(TeeSmc32Arg);
133*4882a593Smuzhiyun
134*4882a593Smuzhiyun if (TeeSmcMetaSession != NULL)
135*4882a593Smuzhiyun OpteeClientMemFree(TeeSmcMetaSession);
136*4882a593Smuzhiyun
137*4882a593Smuzhiyun return TeecResult;
138*4882a593Smuzhiyun }
139*4882a593Smuzhiyun
140*4882a593Smuzhiyun /*
141*4882a593Smuzhiyun * This function closes a session which has been opened with a TEE
142*4882a593Smuzhiyun * application.
143*4882a593Smuzhiyun *
144*4882a593Smuzhiyun * Note that the GP specification does not allow for this API to fail and return
145*4882a593Smuzhiyun * a failure code however we'll support this at the SMC level so we can get
146*4882a593Smuzhiyun * see debug information about such failures.
147*4882a593Smuzhiyun */
TEEC_SMC_CloseSession(TEEC_Session * session,uint32_t * error_origin)148*4882a593Smuzhiyun TEEC_Result TEEC_SMC_CloseSession(TEEC_Session *session,
149*4882a593Smuzhiyun uint32_t *error_origin)
150*4882a593Smuzhiyun {
151*4882a593Smuzhiyun TEEC_Result TeecResult = TEEC_SUCCESS;
152*4882a593Smuzhiyun uint32_t TeeSmc32ArgLength;
153*4882a593Smuzhiyun
154*4882a593Smuzhiyun t_teesmc32_arg *TeeSmc32Arg = NULL;
155*4882a593Smuzhiyun
156*4882a593Smuzhiyun *error_origin = TEEC_ORIGIN_API;
157*4882a593Smuzhiyun
158*4882a593Smuzhiyun TeeSmc32ArgLength =
159*4882a593Smuzhiyun TEESMC32_GET_ARG_SIZE(TEEC_CONFIG_PAYLOAD_REF_COUNT);
160*4882a593Smuzhiyun
161*4882a593Smuzhiyun TeeSmc32Arg = (t_teesmc32_arg *)OpteeClientMemAlloc(TeeSmc32ArgLength);
162*4882a593Smuzhiyun
163*4882a593Smuzhiyun if (TeeSmc32Arg == NULL) {
164*4882a593Smuzhiyun TeecResult = TEEC_ERROR_OUT_OF_MEMORY;
165*4882a593Smuzhiyun goto Exit;
166*4882a593Smuzhiyun }
167*4882a593Smuzhiyun
168*4882a593Smuzhiyun memset(TeeSmc32Arg, 0, TeeSmc32ArgLength);
169*4882a593Smuzhiyun
170*4882a593Smuzhiyun TeeSmc32Arg->cmd = TEESMC_CMD_CLOSE_SESSION;
171*4882a593Smuzhiyun TeeSmc32Arg->session = session->id;
172*4882a593Smuzhiyun
173*4882a593Smuzhiyun *error_origin = TEEC_ORIGIN_COMMS;
174*4882a593Smuzhiyun
175*4882a593Smuzhiyun TeecResult = OpteeSmcCall(TeeSmc32Arg);
176*4882a593Smuzhiyun
177*4882a593Smuzhiyun if (TeecResult != TEEC_SUCCESS)
178*4882a593Smuzhiyun goto Exit;
179*4882a593Smuzhiyun
180*4882a593Smuzhiyun TeecResult = TeeSmc32Arg->ret;
181*4882a593Smuzhiyun *error_origin = TeeSmc32Arg->ret_origin;
182*4882a593Smuzhiyun
183*4882a593Smuzhiyun Exit:
184*4882a593Smuzhiyun if (TeeSmc32Arg != NULL)
185*4882a593Smuzhiyun OpteeClientMemFree(TeeSmc32Arg);
186*4882a593Smuzhiyun
187*4882a593Smuzhiyun return TeecResult;
188*4882a593Smuzhiyun }
189*4882a593Smuzhiyun
190*4882a593Smuzhiyun /*
191*4882a593Smuzhiyun * Invokes a TEE command (secure service, sub-PA or whatever).
192*4882a593Smuzhiyun */
TEEC_SMC_InvokeCommand(TEEC_Session * session,uint32_t cmd_id,TEEC_Operation * operation,uint32_t * error_origin)193*4882a593Smuzhiyun TEEC_Result TEEC_SMC_InvokeCommand(TEEC_Session *session,
194*4882a593Smuzhiyun uint32_t cmd_id,
195*4882a593Smuzhiyun TEEC_Operation *operation,
196*4882a593Smuzhiyun uint32_t *error_origin)
197*4882a593Smuzhiyun {
198*4882a593Smuzhiyun TEEC_Result TeecResult = TEEC_SUCCESS;
199*4882a593Smuzhiyun uint32_t TeeSmc32ArgLength;
200*4882a593Smuzhiyun
201*4882a593Smuzhiyun t_teesmc32_arg *TeeSmc32Arg = NULL;
202*4882a593Smuzhiyun t_teesmc32_param *TeeSmc32Param = NULL;
203*4882a593Smuzhiyun
204*4882a593Smuzhiyun *error_origin = TEEC_ORIGIN_API;
205*4882a593Smuzhiyun
206*4882a593Smuzhiyun TeeSmc32ArgLength =
207*4882a593Smuzhiyun TEESMC32_GET_ARG_SIZE(TEEC_CONFIG_PAYLOAD_REF_COUNT);
208*4882a593Smuzhiyun
209*4882a593Smuzhiyun TeeSmc32Arg = (t_teesmc32_arg *)OpteeClientMemAlloc(TeeSmc32ArgLength);
210*4882a593Smuzhiyun
211*4882a593Smuzhiyun if (TeeSmc32Arg == NULL) {
212*4882a593Smuzhiyun TeecResult = TEEC_ERROR_OUT_OF_MEMORY;
213*4882a593Smuzhiyun goto Exit;
214*4882a593Smuzhiyun }
215*4882a593Smuzhiyun
216*4882a593Smuzhiyun memset(TeeSmc32Arg, 0, TeeSmc32ArgLength);
217*4882a593Smuzhiyun
218*4882a593Smuzhiyun TeeSmc32Arg->cmd = TEESMC_CMD_INVOKE_COMMAND;
219*4882a593Smuzhiyun TeeSmc32Arg->ta_func = cmd_id;
220*4882a593Smuzhiyun TeeSmc32Arg->session = session->id;
221*4882a593Smuzhiyun TeeSmc32Arg->num_params = TEEC_CONFIG_PAYLOAD_REF_COUNT;
222*4882a593Smuzhiyun
223*4882a593Smuzhiyun TeeSmc32Param = TEESMC32_GET_PARAMS(TeeSmc32Arg);
224*4882a593Smuzhiyun
225*4882a593Smuzhiyun SetTeeSmc32Params(operation, TeeSmc32Param);
226*4882a593Smuzhiyun
227*4882a593Smuzhiyun *error_origin = TEEC_ORIGIN_COMMS;
228*4882a593Smuzhiyun
229*4882a593Smuzhiyun TeecResult = OpteeSmcCall(TeeSmc32Arg);
230*4882a593Smuzhiyun if (TeecResult != TEEC_SUCCESS)
231*4882a593Smuzhiyun goto Exit;
232*4882a593Smuzhiyun
233*4882a593Smuzhiyun TeecResult = TeeSmc32Arg->ret;
234*4882a593Smuzhiyun *error_origin = TeeSmc32Arg->ret_origin;
235*4882a593Smuzhiyun
236*4882a593Smuzhiyun GetTeeSmc32Params(TeeSmc32Param, operation);
237*4882a593Smuzhiyun
238*4882a593Smuzhiyun Exit:
239*4882a593Smuzhiyun if (TeeSmc32Arg != NULL)
240*4882a593Smuzhiyun OpteeClientMemFree(TeeSmc32Arg);
241*4882a593Smuzhiyun
242*4882a593Smuzhiyun
243*4882a593Smuzhiyun return TeecResult;
244*4882a593Smuzhiyun }
245*4882a593Smuzhiyun
246*4882a593Smuzhiyun /*
247*4882a593Smuzhiyun * Request a cancellation of a in-progress operation (best effort)
248*4882a593Smuzhiyun *
249*4882a593Smuzhiyun * Note that the GP specification does not allow for this API to fail and return
250*4882a593Smuzhiyun * a failure code however we'll support this at the SMC level so we can get
251*4882a593Smuzhiyun * see debug information about such failures.
252*4882a593Smuzhiyun */
TEEC_SMC_RequestCancellation(TEEC_Operation * operation,uint32_t * error_origin)253*4882a593Smuzhiyun TEEC_Result TEEC_SMC_RequestCancellation(TEEC_Operation *operation,
254*4882a593Smuzhiyun uint32_t *error_origin)
255*4882a593Smuzhiyun {
256*4882a593Smuzhiyun return TEEC_ERROR_NOT_IMPLEMENTED;
257*4882a593Smuzhiyun }
258*4882a593Smuzhiyun
259*4882a593Smuzhiyun /*
260*4882a593Smuzhiyun * Set the call parameter blocks in the
261*4882a593Smuzhiyun * SMC call based on the TEEC parameter supplied.
262*4882a593Smuzhiyun * This only handles the parameters supplied in
263*4882a593Smuzhiyun * the originating call and not those
264*4882a593Smuzhiyun * considered internal meta parameters and is
265*4882a593Smuzhiyun * thus constrained by the build
266*4882a593Smuzhiyun * constants exposed to callers.
267*4882a593Smuzhiyun */
SetTeeSmc32Params(TEEC_Operation * operation,t_teesmc32_param * TeeSmc32Param)268*4882a593Smuzhiyun void SetTeeSmc32Params(TEEC_Operation *operation,
269*4882a593Smuzhiyun t_teesmc32_param *TeeSmc32Param)
270*4882a593Smuzhiyun {
271*4882a593Smuzhiyun uint32_t ParamCount;
272*4882a593Smuzhiyun
273*4882a593Smuzhiyun for (ParamCount = 0;
274*4882a593Smuzhiyun ParamCount < TEEC_CONFIG_PAYLOAD_REF_COUNT;
275*4882a593Smuzhiyun ParamCount++) {
276*4882a593Smuzhiyun uint32_t attr =
277*4882a593Smuzhiyun TEEC_PARAM_TYPE_GET(operation->paramTypes, ParamCount);
278*4882a593Smuzhiyun
279*4882a593Smuzhiyun if (attr == TEEC_MEMREF_TEMP_INPUT ||
280*4882a593Smuzhiyun attr == TEEC_MEMREF_TEMP_OUTPUT ||
281*4882a593Smuzhiyun attr == TEEC_MEMREF_TEMP_INOUT) {
282*4882a593Smuzhiyun
283*4882a593Smuzhiyun attr += (OPTEE_MSG_ATTR_TYPE_TMEM_INPUT_V2 - TEEC_MEMREF_TEMP_INPUT);
284*4882a593Smuzhiyun debug("TEEC: OPTEE_OS_V2 ARCH64 attr %x\n", attr);
285*4882a593Smuzhiyun
286*4882a593Smuzhiyun TeeSmc32Param[ParamCount].attr = attr;
287*4882a593Smuzhiyun TeeSmc32Param[ParamCount].u.memref.buf_ptr =
288*4882a593Smuzhiyun (uint32_t)(size_t)operation->params[ParamCount].tmpref.buffer;
289*4882a593Smuzhiyun TeeSmc32Param[ParamCount].u.memref.size =
290*4882a593Smuzhiyun operation->params[ParamCount].tmpref.size;
291*4882a593Smuzhiyun } else {
292*4882a593Smuzhiyun TeeSmc32Param[ParamCount].attr = attr;
293*4882a593Smuzhiyun TeeSmc32Param[ParamCount].u.value.a =
294*4882a593Smuzhiyun operation->params[ParamCount].value.a;
295*4882a593Smuzhiyun TeeSmc32Param[ParamCount].u.value.b =
296*4882a593Smuzhiyun operation->params[ParamCount].value.b;
297*4882a593Smuzhiyun }
298*4882a593Smuzhiyun }
299*4882a593Smuzhiyun }
300*4882a593Smuzhiyun
301*4882a593Smuzhiyun /*
302*4882a593Smuzhiyun * Get the return parameter blocks from
303*4882a593Smuzhiyun * the SMC call into the TEEC parameter supplied.
304*4882a593Smuzhiyun * This only handles the parameters supplied
305*4882a593Smuzhiyun * in the originating call and not those
306*4882a593Smuzhiyun * considered internal meta parameters and
307*4882a593Smuzhiyun * is thus constrained by the build
308*4882a593Smuzhiyun * constants exposed to callers.
309*4882a593Smuzhiyun */
GetTeeSmc32Params(t_teesmc32_param * TeeSmc32Param,TEEC_Operation * operation)310*4882a593Smuzhiyun void GetTeeSmc32Params(t_teesmc32_param *TeeSmc32Param,
311*4882a593Smuzhiyun TEEC_Operation *operation)
312*4882a593Smuzhiyun {
313*4882a593Smuzhiyun uint32_t ParamCount;
314*4882a593Smuzhiyun
315*4882a593Smuzhiyun for (ParamCount = 0;
316*4882a593Smuzhiyun ParamCount < TEEC_CONFIG_PAYLOAD_REF_COUNT;
317*4882a593Smuzhiyun ParamCount++) {
318*4882a593Smuzhiyun operation->params[ParamCount].value.a =
319*4882a593Smuzhiyun TeeSmc32Param[ParamCount].u.value.a;
320*4882a593Smuzhiyun operation->params[ParamCount].value.b =
321*4882a593Smuzhiyun TeeSmc32Param[ParamCount].u.value.b;
322*4882a593Smuzhiyun }
323*4882a593Smuzhiyun }
324*4882a593Smuzhiyun
325*4882a593Smuzhiyun /*
326*4882a593Smuzhiyun * Populate the SMC registers and make
327*4882a593Smuzhiyun * the call with OpTEE specific handling.
328*4882a593Smuzhiyun */
OpteeSmcCall(t_teesmc32_arg * TeeSmc32Arg)329*4882a593Smuzhiyun TEEC_Result OpteeSmcCall(t_teesmc32_arg *TeeSmc32Arg)
330*4882a593Smuzhiyun {
331*4882a593Smuzhiyun TEEC_Result TeecResult = TEEC_SUCCESS;
332*4882a593Smuzhiyun ARM_SMC_ARGS ArmSmcArgs = {0};
333*4882a593Smuzhiyun
334*4882a593Smuzhiyun ArmSmcArgs.Arg0 = OPTEE_SMC_CALL_WITH_ARG_V2;
335*4882a593Smuzhiyun ArmSmcArgs.Arg1 = 0;
336*4882a593Smuzhiyun ArmSmcArgs.Arg2 = (uint32_t) (size_t)TeeSmc32Arg;
337*4882a593Smuzhiyun
338*4882a593Smuzhiyun while (1) {
339*4882a593Smuzhiyun tee_smc_call(&ArmSmcArgs);
340*4882a593Smuzhiyun debug("TEEC: arg0=0x%x arg1=0x%x arg2=0x%x arg3=0x%x \n",
341*4882a593Smuzhiyun ArmSmcArgs.Arg0, ArmSmcArgs.Arg1, ArmSmcArgs.Arg2, ArmSmcArgs.Arg3);
342*4882a593Smuzhiyun if (TEESMC_RETURN_IS_RPC(ArmSmcArgs.Arg0)) {
343*4882a593Smuzhiyun (void) OpteeRpcCallback(&ArmSmcArgs);
344*4882a593Smuzhiyun } else if (ArmSmcArgs.Arg0 == TEESMC_RETURN_UNKNOWN_FUNCTION) {
345*4882a593Smuzhiyun TeecResult = TEEC_ERROR_NOT_IMPLEMENTED;
346*4882a593Smuzhiyun break;
347*4882a593Smuzhiyun } else if (ArmSmcArgs.Arg0 != TEESMC_RETURN_OK) {
348*4882a593Smuzhiyun TeecResult = TEEC_ERROR_COMMUNICATION;
349*4882a593Smuzhiyun break;
350*4882a593Smuzhiyun } else {
351*4882a593Smuzhiyun TeecResult = TEEC_SUCCESS;
352*4882a593Smuzhiyun break;
353*4882a593Smuzhiyun }
354*4882a593Smuzhiyun }
355*4882a593Smuzhiyun
356*4882a593Smuzhiyun return TeecResult;
357*4882a593Smuzhiyun }
358*4882a593Smuzhiyun
359