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 <optee_include/OpteeClientMem.h> 9abdd2437Shisping #include <optee_include/OpteeClientSMC.h> 10abdd2437Shisping #include <optee_include/OpteeClientRPC.h> 11abdd2437Shisping #include <optee_include/teesmc.h> 121f25ada2SHisping Lin #include <optee_include/teesmc_v2.h> 131f25ada2SHisping Lin 14abdd2437Shisping 15abdd2437Shisping #define TEEC_SMC_DEFAULT_CACHE_ATTRIBUTES \ 16abdd2437Shisping (TEESMC_ATTR_CACHE_DEFAULT << TEESMC_ATTR_CACHE_SHIFT); 17abdd2437Shisping 18abdd2437Shisping static void SetTeeSmc32Params(TEEC_Operation *operation, 19abdd2437Shisping t_teesmc32_param *TeeSmc32Param); 20abdd2437Shisping static void GetTeeSmc32Params(t_teesmc32_param *TeeSmc32Param, 21abdd2437Shisping TEEC_Operation *operation); 22abdd2437Shisping static TEEC_Result OpteeSmcCall(t_teesmc32_arg *TeeSmc32Arg); 23abdd2437Shisping 241f25ada2SHisping Lin void tee_uuid_to_octets(uint8_t *d, const TEEC_UUID *s) 251f25ada2SHisping Lin { 261f25ada2SHisping Lin d[0] = s->timeLow >> 24; 271f25ada2SHisping Lin d[1] = s->timeLow >> 16; 281f25ada2SHisping Lin d[2] = s->timeLow >> 8; 291f25ada2SHisping Lin d[3] = s->timeLow; 301f25ada2SHisping Lin d[4] = s->timeMid >> 8; 311f25ada2SHisping Lin d[5] = s->timeMid; 321f25ada2SHisping Lin d[6] = s->timeHiAndVersion >> 8; 331f25ada2SHisping Lin d[7] = s->timeHiAndVersion; 341f25ada2SHisping Lin memcpy(d + 8, s->clockSeqAndNode, sizeof(s->clockSeqAndNode)); 351f25ada2SHisping Lin } 361f25ada2SHisping Lin 37abdd2437Shisping /* 38abdd2437Shisping * This function opens a new Session between the Client application and the 39abdd2437Shisping * specified TEE application. 40abdd2437Shisping * 41abdd2437Shisping * Only connection_method == TEEC_LOGIN_PUBLIC is supported connection_data and 42abdd2437Shisping * operation shall be set to NULL. 43abdd2437Shisping */ 44abdd2437Shisping TEEC_Result TEEC_SMC_OpenSession(TEEC_Context *context, 45abdd2437Shisping TEEC_Session *session, 46abdd2437Shisping const TEEC_UUID *destination, 47abdd2437Shisping TEEC_Operation *operation, 48abdd2437Shisping uint32_t *error_origin) 49abdd2437Shisping { 50abdd2437Shisping TEEC_Result TeecResult = TEEC_SUCCESS; 51abdd2437Shisping uint32_t TeeSmc32ArgLength; 52abdd2437Shisping uint32_t TeeSmcMetaSessionLength; 53abdd2437Shisping 54abdd2437Shisping t_teesmc32_arg *TeeSmc32Arg = NULL; 55abdd2437Shisping t_teesmc32_param *TeeSmc32Param = NULL; 561f25ada2SHisping Lin 57abdd2437Shisping t_teesmc_meta_open_session *TeeSmcMetaSession = NULL; 581f25ada2SHisping Lin 591f25ada2SHisping Lin #ifdef CONFIG_OPTEE_V1 601f25ada2SHisping Lin uint32_t MetaNum = 1; 611f25ada2SHisping Lin #endif 621f25ada2SHisping Lin 631f25ada2SHisping Lin #ifdef CONFIG_OPTEE_V2 641f25ada2SHisping Lin uint32_t MetaNum = 2; 651f25ada2SHisping Lin #endif 66abdd2437Shisping 67abdd2437Shisping *error_origin = TEEC_ORIGIN_API; 68abdd2437Shisping 69abdd2437Shisping TeeSmc32ArgLength = 70abdd2437Shisping TEESMC32_GET_ARG_SIZE(TEEC_CONFIG_PAYLOAD_REF_COUNT + MetaNum); 71abdd2437Shisping 72abdd2437Shisping TeeSmc32Arg = (t_teesmc32_arg *)OpteeClientMemAlloc(TeeSmc32ArgLength); 73abdd2437Shisping 74abdd2437Shisping if (TeeSmc32Arg == NULL) { 75abdd2437Shisping TeecResult = TEEC_ERROR_OUT_OF_MEMORY; 76abdd2437Shisping goto Exit; 77abdd2437Shisping } 78abdd2437Shisping 79abdd2437Shisping memset(TeeSmc32Arg, 0, TeeSmc32ArgLength); 80abdd2437Shisping 81abdd2437Shisping TeeSmcMetaSessionLength = sizeof(*TeeSmcMetaSession); 82abdd2437Shisping 83abdd2437Shisping TeeSmcMetaSession = (t_teesmc_meta_open_session *) 84abdd2437Shisping OpteeClientMemAlloc(TeeSmcMetaSessionLength); 85abdd2437Shisping 86abdd2437Shisping if (TeeSmcMetaSession == NULL) { 87abdd2437Shisping TeecResult = TEEC_ERROR_OUT_OF_MEMORY; 88abdd2437Shisping goto Exit; 89abdd2437Shisping } 90abdd2437Shisping 91abdd2437Shisping memset(TeeSmcMetaSession, 0, TeeSmcMetaSessionLength); 92abdd2437Shisping 93abdd2437Shisping TeeSmc32Arg->cmd = TEESMC_CMD_OPEN_SESSION; 94abdd2437Shisping TeeSmc32Arg->num_params = TEEC_CONFIG_PAYLOAD_REF_COUNT + MetaNum; 95abdd2437Shisping 96abdd2437Shisping TeeSmc32Param = TEESMC32_GET_PARAMS(TeeSmc32Arg); 97abdd2437Shisping 98abdd2437Shisping memcpy(&TeeSmcMetaSession->uuid, 99abdd2437Shisping destination, 100abdd2437Shisping sizeof(TeeSmcMetaSession->uuid)); 101abdd2437Shisping TeeSmcMetaSession->clnt_login = TEEC_LOGIN_PUBLIC; 102abdd2437Shisping 1031f25ada2SHisping Lin TeeSmc32Param[0].u.memref.buf_ptr = (uint32_t) (size_t)TeeSmcMetaSession; 104abdd2437Shisping TeeSmc32Param[0].u.memref.size = sizeof(*TeeSmcMetaSession); 105abdd2437Shisping 1061f25ada2SHisping Lin #ifdef CONFIG_OPTEE_V1 1071f25ada2SHisping Lin #ifdef CONFIG_ARM64 108abdd2437Shisping TeeSmc32Param[0].attr = TEESMC_ATTR_TYPE_MEMREF_INPUT | 109abdd2437Shisping TEESMC_ATTR_META | 110abdd2437Shisping TEEC_SMC_DEFAULT_CACHE_ATTRIBUTES; 1111f25ada2SHisping Lin #else 112abdd2437Shisping TeeSmc32Param[0].attr = TEESMC_ATTR_TYPE_MEMREF_INPUT | 113abdd2437Shisping TEESMC_ATTR_META; 114abdd2437Shisping #endif 1151f25ada2SHisping Lin #endif 1161f25ada2SHisping Lin 1171f25ada2SHisping Lin #ifdef CONFIG_OPTEE_V2 118*d156c9ffSHisping Lin #if defined CONFIG_ARM64 || defined CONFIG_ARM64_BOOT_AARCH32 1191f25ada2SHisping Lin uint8_t * session_uuid = (uint8_t *)&TeeSmcMetaSession->uuid; 1201f25ada2SHisping Lin tee_uuid_to_octets(session_uuid, destination); 1211f25ada2SHisping Lin memcpy((void *)&TeeSmc32Param[0].u.value, &TeeSmcMetaSession->uuid, sizeof(TeeSmcMetaSession->uuid)); 1221f25ada2SHisping Lin TeeSmc32Param[1].u.value.c = TeeSmcMetaSession->clnt_login; 1231f25ada2SHisping Lin 1241f25ada2SHisping Lin TeeSmc32Param[0].attr = OPTEE_MSG_ATTR_TYPE_VALUE_INPUT_V2 | 1251f25ada2SHisping Lin OPTEE_MSG_ATTR_META_V2; 1261f25ada2SHisping Lin TeeSmc32Param[1].attr = OPTEE_MSG_ATTR_TYPE_VALUE_INPUT_V2 | 1271f25ada2SHisping Lin OPTEE_MSG_ATTR_META_V2; 1281f25ada2SHisping Lin #else 1291f25ada2SHisping Lin printf("Not support! All rockchips use optee v2.5 are 64 bits! \n"); 1301f25ada2SHisping Lin #endif 1311f25ada2SHisping Lin #endif 132abdd2437Shisping 133abdd2437Shisping SetTeeSmc32Params(operation, TeeSmc32Param + MetaNum); 134abdd2437Shisping 135abdd2437Shisping *error_origin = TEEC_ORIGIN_COMMS; 136abdd2437Shisping 137abdd2437Shisping TeecResult = OpteeSmcCall(TeeSmc32Arg); 138abdd2437Shisping if (TeecResult != TEEC_SUCCESS) 139abdd2437Shisping goto Exit; 140abdd2437Shisping 141abdd2437Shisping session->id = TeeSmc32Arg->session; 142abdd2437Shisping TeecResult = TeeSmc32Arg->ret; 143abdd2437Shisping *error_origin = TeeSmc32Arg->ret_origin; 144abdd2437Shisping 145abdd2437Shisping GetTeeSmc32Params(TeeSmc32Param + MetaNum, operation); 146abdd2437Shisping 147abdd2437Shisping Exit: 148abdd2437Shisping if (TeeSmc32Arg != NULL) 149abdd2437Shisping OpteeClientMemFree(TeeSmc32Arg); 150abdd2437Shisping 151abdd2437Shisping if (TeeSmcMetaSession != NULL) 152abdd2437Shisping OpteeClientMemFree(TeeSmcMetaSession); 153abdd2437Shisping 154abdd2437Shisping return TeecResult; 155abdd2437Shisping } 156abdd2437Shisping 157abdd2437Shisping /* 158abdd2437Shisping * This function closes a session which has been opened with a TEE 159abdd2437Shisping * application. 160abdd2437Shisping * 161abdd2437Shisping * Note that the GP specification does not allow for this API to fail and return 162abdd2437Shisping * a failure code however we'll support this at the SMC level so we can get 163abdd2437Shisping * see debug information about such failures. 164abdd2437Shisping */ 165abdd2437Shisping TEEC_Result TEEC_SMC_CloseSession(TEEC_Session *session, 166abdd2437Shisping uint32_t *error_origin) 167abdd2437Shisping { 168abdd2437Shisping TEEC_Result TeecResult = TEEC_SUCCESS; 169abdd2437Shisping uint32_t TeeSmc32ArgLength; 1701f25ada2SHisping Lin 171abdd2437Shisping t_teesmc32_arg *TeeSmc32Arg = NULL; 172abdd2437Shisping 173abdd2437Shisping *error_origin = TEEC_ORIGIN_API; 174abdd2437Shisping 175abdd2437Shisping TeeSmc32ArgLength = 176abdd2437Shisping TEESMC32_GET_ARG_SIZE(TEEC_CONFIG_PAYLOAD_REF_COUNT); 177abdd2437Shisping 178abdd2437Shisping TeeSmc32Arg = (t_teesmc32_arg *)OpteeClientMemAlloc(TeeSmc32ArgLength); 179abdd2437Shisping 180abdd2437Shisping if (TeeSmc32Arg == NULL) { 181abdd2437Shisping TeecResult = TEEC_ERROR_OUT_OF_MEMORY; 182abdd2437Shisping goto Exit; 183abdd2437Shisping } 184abdd2437Shisping 185abdd2437Shisping memset(TeeSmc32Arg, 0, TeeSmc32ArgLength); 186abdd2437Shisping 187abdd2437Shisping TeeSmc32Arg->cmd = TEESMC_CMD_CLOSE_SESSION; 188abdd2437Shisping TeeSmc32Arg->session = session->id; 189abdd2437Shisping 190abdd2437Shisping *error_origin = TEEC_ORIGIN_COMMS; 191abdd2437Shisping 192abdd2437Shisping TeecResult = OpteeSmcCall(TeeSmc32Arg); 193abdd2437Shisping 194abdd2437Shisping if (TeecResult != TEEC_SUCCESS) 195abdd2437Shisping goto Exit; 196abdd2437Shisping 197abdd2437Shisping TeecResult = TeeSmc32Arg->ret; 198abdd2437Shisping *error_origin = TeeSmc32Arg->ret_origin; 199abdd2437Shisping 200abdd2437Shisping Exit: 201abdd2437Shisping if (TeeSmc32Arg != NULL) 202abdd2437Shisping OpteeClientMemFree(TeeSmc32Arg); 203abdd2437Shisping 204abdd2437Shisping return TeecResult; 205abdd2437Shisping } 206abdd2437Shisping 207abdd2437Shisping /* 208abdd2437Shisping * Invokes a TEE command (secure service, sub-PA or whatever). 209abdd2437Shisping */ 210abdd2437Shisping TEEC_Result TEEC_SMC_InvokeCommand(TEEC_Session *session, 211abdd2437Shisping uint32_t cmd_id, 212abdd2437Shisping TEEC_Operation *operation, 213abdd2437Shisping uint32_t *error_origin) 214abdd2437Shisping { 215abdd2437Shisping TEEC_Result TeecResult = TEEC_SUCCESS; 216abdd2437Shisping uint32_t TeeSmc32ArgLength; 2171f25ada2SHisping Lin 218abdd2437Shisping t_teesmc32_arg *TeeSmc32Arg = NULL; 219abdd2437Shisping t_teesmc32_param *TeeSmc32Param = NULL; 220abdd2437Shisping 221abdd2437Shisping *error_origin = TEEC_ORIGIN_API; 222abdd2437Shisping 223abdd2437Shisping TeeSmc32ArgLength = 224abdd2437Shisping TEESMC32_GET_ARG_SIZE(TEEC_CONFIG_PAYLOAD_REF_COUNT); 225abdd2437Shisping 226abdd2437Shisping TeeSmc32Arg = (t_teesmc32_arg *)OpteeClientMemAlloc(TeeSmc32ArgLength); 227abdd2437Shisping 228abdd2437Shisping if (TeeSmc32Arg == NULL) { 229abdd2437Shisping TeecResult = TEEC_ERROR_OUT_OF_MEMORY; 230abdd2437Shisping goto Exit; 231abdd2437Shisping } 232abdd2437Shisping 233abdd2437Shisping memset(TeeSmc32Arg, 0, TeeSmc32ArgLength); 234abdd2437Shisping 235abdd2437Shisping TeeSmc32Arg->cmd = TEESMC_CMD_INVOKE_COMMAND; 236abdd2437Shisping TeeSmc32Arg->ta_func = cmd_id; 237abdd2437Shisping TeeSmc32Arg->session = session->id; 238abdd2437Shisping TeeSmc32Arg->num_params = TEEC_CONFIG_PAYLOAD_REF_COUNT; 239abdd2437Shisping 240abdd2437Shisping TeeSmc32Param = TEESMC32_GET_PARAMS(TeeSmc32Arg); 241abdd2437Shisping 242abdd2437Shisping SetTeeSmc32Params(operation, TeeSmc32Param); 243abdd2437Shisping 244abdd2437Shisping *error_origin = TEEC_ORIGIN_COMMS; 245abdd2437Shisping 246abdd2437Shisping TeecResult = OpteeSmcCall(TeeSmc32Arg); 247abdd2437Shisping if (TeecResult != TEEC_SUCCESS) 248abdd2437Shisping goto Exit; 249abdd2437Shisping 250abdd2437Shisping TeecResult = TeeSmc32Arg->ret; 251abdd2437Shisping *error_origin = TeeSmc32Arg->ret_origin; 252abdd2437Shisping 253abdd2437Shisping GetTeeSmc32Params(TeeSmc32Param, operation); 254abdd2437Shisping 255abdd2437Shisping Exit: 256abdd2437Shisping if (TeeSmc32Arg != NULL) 257abdd2437Shisping OpteeClientMemFree(TeeSmc32Arg); 258abdd2437Shisping 259abdd2437Shisping 260abdd2437Shisping return TeecResult; 261abdd2437Shisping } 262abdd2437Shisping 263abdd2437Shisping /* 264abdd2437Shisping * Request a cancellation of a in-progress operation (best effort) 265abdd2437Shisping * 266abdd2437Shisping * Note that the GP specification does not allow for this API to fail and return 267abdd2437Shisping * a failure code however we'll support this at the SMC level so we can get 268abdd2437Shisping * see debug information about such failures. 269abdd2437Shisping */ 270abdd2437Shisping TEEC_Result TEEC_SMC_RequestCancellation(TEEC_Operation *operation, 271abdd2437Shisping uint32_t *error_origin) 272abdd2437Shisping { 273abdd2437Shisping return TEEC_ERROR_NOT_IMPLEMENTED; 274abdd2437Shisping } 275abdd2437Shisping 276abdd2437Shisping /* 277abdd2437Shisping * Set the call parameter blocks in the 278abdd2437Shisping * SMC call based on the TEEC parameter supplied. 279abdd2437Shisping * This only handles the parameters supplied in 280abdd2437Shisping * the originating call and not those 281abdd2437Shisping * considered internal meta parameters and is 282abdd2437Shisping * thus constrained by the build 283abdd2437Shisping * constants exposed to callers. 284abdd2437Shisping */ 285abdd2437Shisping void SetTeeSmc32Params(TEEC_Operation *operation, 286abdd2437Shisping t_teesmc32_param *TeeSmc32Param) 287abdd2437Shisping { 288abdd2437Shisping uint32_t ParamCount; 289abdd2437Shisping 290abdd2437Shisping for (ParamCount = 0; 291abdd2437Shisping ParamCount < TEEC_CONFIG_PAYLOAD_REF_COUNT; 292abdd2437Shisping ParamCount++) { 293abdd2437Shisping uint32_t attr = 294abdd2437Shisping TEEC_PARAM_TYPE_GET(operation->paramTypes, ParamCount); 295abdd2437Shisping 296abdd2437Shisping if (attr == TEEC_MEMREF_TEMP_INPUT || 297abdd2437Shisping attr == TEEC_MEMREF_TEMP_OUTPUT || 298abdd2437Shisping attr == TEEC_MEMREF_TEMP_INOUT) { 2991f25ada2SHisping Lin 3001f25ada2SHisping Lin #ifdef CONFIG_OPTEE_V1 3011f25ada2SHisping Lin #ifdef CONFIG_ARM64 302abdd2437Shisping attr |= TEEC_SMC_DEFAULT_CACHE_ATTRIBUTES; 3031f25ada2SHisping Lin debug(" OPTEE_OS_V1 ARCH64 attr %x\n", attr); 3041f25ada2SHisping Lin #else 3051f25ada2SHisping Lin debug(" OPTEE_OS_V1 ARCH32 attr %x\n", attr); 306abdd2437Shisping #endif 307abdd2437Shisping #endif 3081f25ada2SHisping Lin 3091f25ada2SHisping Lin #ifdef CONFIG_OPTEE_V2 310*d156c9ffSHisping Lin #if defined CONFIG_ARM64 || defined CONFIG_ARM64_BOOT_AARCH32 3111f25ada2SHisping Lin attr += (OPTEE_MSG_ATTR_TYPE_TMEM_INPUT_V2 - TEEC_MEMREF_TEMP_INPUT); 3121f25ada2SHisping Lin debug(" OPTEE_OS_V2 ARCH64 attr %x\n", attr); 3131f25ada2SHisping Lin #else 3141f25ada2SHisping Lin printf("Not support! All rockchips use optee v2 are 64 bits! \n"); 3151f25ada2SHisping Lin #endif 3161f25ada2SHisping Lin #endif 3171f25ada2SHisping Lin 318abdd2437Shisping TeeSmc32Param[ParamCount].attr = attr; 319abdd2437Shisping TeeSmc32Param[ParamCount].u.memref.buf_ptr = 3201f25ada2SHisping Lin (uint32_t)(size_t)operation->params[ParamCount].tmpref.buffer; 321abdd2437Shisping TeeSmc32Param[ParamCount].u.memref.size = 322abdd2437Shisping operation->params[ParamCount].tmpref.size; 323abdd2437Shisping } else { 324abdd2437Shisping TeeSmc32Param[ParamCount].attr = attr; 325abdd2437Shisping TeeSmc32Param[ParamCount].u.value.a = 326abdd2437Shisping operation->params[ParamCount].value.a; 327abdd2437Shisping TeeSmc32Param[ParamCount].u.value.b = 328abdd2437Shisping operation->params[ParamCount].value.b; 329abdd2437Shisping } 330abdd2437Shisping } 331abdd2437Shisping } 332abdd2437Shisping 333abdd2437Shisping /* 334abdd2437Shisping * Get the return parameter blocks from 335abdd2437Shisping * the SMC call into the TEEC parameter supplied. 336abdd2437Shisping * This only handles the parameters supplied 337abdd2437Shisping * in the originating call and not those 338abdd2437Shisping * considered internal meta parameters and 339abdd2437Shisping * is thus constrained by the build 340abdd2437Shisping * constants exposed to callers. 341abdd2437Shisping */ 342abdd2437Shisping void GetTeeSmc32Params(t_teesmc32_param *TeeSmc32Param, 343abdd2437Shisping TEEC_Operation *operation) 344abdd2437Shisping { 345abdd2437Shisping uint32_t ParamCount; 346abdd2437Shisping 347abdd2437Shisping for (ParamCount = 0; 348abdd2437Shisping ParamCount < TEEC_CONFIG_PAYLOAD_REF_COUNT; 349abdd2437Shisping ParamCount++) { 350abdd2437Shisping operation->params[ParamCount].value.a = 351abdd2437Shisping TeeSmc32Param[ParamCount].u.value.a; 352abdd2437Shisping operation->params[ParamCount].value.b = 353abdd2437Shisping TeeSmc32Param[ParamCount].u.value.b; 354abdd2437Shisping } 355abdd2437Shisping } 356abdd2437Shisping 357abdd2437Shisping /* 358abdd2437Shisping * Populate the SMC registers and make 359abdd2437Shisping * the call with OpTEE specific handling. 360abdd2437Shisping */ 361abdd2437Shisping TEEC_Result OpteeSmcCall(t_teesmc32_arg *TeeSmc32Arg) 362abdd2437Shisping { 363abdd2437Shisping TEEC_Result TeecResult = TEEC_SUCCESS; 364abdd2437Shisping ARM_SMC_ARGS ArmSmcArgs = {0}; 365abdd2437Shisping 3661f25ada2SHisping Lin #ifdef CONFIG_OPTEE_V1 367abdd2437Shisping ArmSmcArgs.Arg0 = TEESMC32_CALL_WITH_ARG; 3681f25ada2SHisping Lin ArmSmcArgs.Arg1 = (uint32_t) (size_t)TeeSmc32Arg; 3691f25ada2SHisping Lin #endif 3701f25ada2SHisping Lin 3711f25ada2SHisping Lin #ifdef CONFIG_OPTEE_V2 3721f25ada2SHisping Lin ArmSmcArgs.Arg0 = OPTEE_SMC_CALL_WITH_ARG_V2; 3731f25ada2SHisping Lin ArmSmcArgs.Arg1 = 0; 3741f25ada2SHisping Lin ArmSmcArgs.Arg2 = (uint32_t) (size_t)TeeSmc32Arg; 3751f25ada2SHisping Lin #endif 376abdd2437Shisping 377abdd2437Shisping while (1) { 378abdd2437Shisping tee_smc_call(&ArmSmcArgs); 379*d156c9ffSHisping Lin debug("arg0=0x%x arg1=0x%x arg2=0x%x arg3=0x%x \n", 3801f25ada2SHisping Lin ArmSmcArgs.Arg0, ArmSmcArgs.Arg1, ArmSmcArgs.Arg2, ArmSmcArgs.Arg3); 381abdd2437Shisping if (TEESMC_RETURN_IS_RPC(ArmSmcArgs.Arg0)) { 382abdd2437Shisping (void) OpteeRpcCallback(&ArmSmcArgs); 383abdd2437Shisping } else if (ArmSmcArgs.Arg0 == TEESMC_RETURN_UNKNOWN_FUNCTION) { 384abdd2437Shisping TeecResult = TEEC_ERROR_NOT_IMPLEMENTED; 385abdd2437Shisping break; 386abdd2437Shisping } else if (ArmSmcArgs.Arg0 != TEESMC_RETURN_OK) { 387abdd2437Shisping TeecResult = TEEC_ERROR_COMMUNICATION; 388abdd2437Shisping break; 389abdd2437Shisping } else { 390abdd2437Shisping TeecResult = TEEC_SUCCESS; 391abdd2437Shisping break; 392abdd2437Shisping } 393abdd2437Shisping } 394abdd2437Shisping 395abdd2437Shisping return TeecResult; 396abdd2437Shisping } 397abdd2437Shisping 398