static void call_tee(uintptr_t parg32, struct teesmc32_arg *arg32) { u32 ret; u32 funcid; struct smc_param param = { 0 }; if (irqs_disabled()) funcid = TEESMC32_FASTCALL_WITH_ARG; else funcid = TEESMC32_CALL_WITH_ARG; param.a1 = parg32; while (true) { param.a0 = funcid; tee_smc_call(¶m); ret = param.a0; if (ret == TEESMC_RETURN_EBUSY) { /* "Can't happen" */ BUG_ON(1); } else if (TEESMC_RETURN_IS_RPC(ret)) { /* Process the RPC. */ funcid = handle_rpc(¶m); } else { break; } } switch (ret) { case TEESMC_RETURN_UNKNOWN_FUNCTION: arg32->ret = TEEC_ERROR_NOT_IMPLEMENTED; arg32->ret_origin = TEEC_ORIGIN_COMMS; break; case TEESMC_RETURN_OK: /* arg32->ret set by secure world */ break; default: /* Should not happen */ arg32->ret = TEEC_ERROR_COMMUNICATION; arg32->ret_origin = TEEC_ORIGIN_COMMS; break; } }
static void call_tee(struct tee_tz *ptee, uintptr_t parg32, struct teesmc32_arg *arg32) { u32 ret; u32 funcid; struct smc_param param = { 0 }; if (irqs_disabled()) funcid = TEESMC32_FASTCALL_WITH_ARG; else funcid = TEESMC32_CALL_WITH_ARG; /* * Commented out elements used to visualize the layout dynamic part * of the struct. Note that these fields are not available at all * if num_params == 0. * * params is accessed through the macro TEESMC32_GET_PARAMS */ /* struct teesmc32_param params[num_params]; */ param.a1 = parg32; e_lock_teez(ptee); while (true) { param.a0 = funcid; tee_smc_call(¶m); ret = param.a0; if (ret == TEESMC_RETURN_EBUSY) { /* * Since secure world returned busy, release the * lock we had when entering this function and wait * for "something to happen" (something else to * exit from secure world and needed resources may * have become available). */ e_lock_wait_completion_teez(ptee); } else if (TEESMC_RETURN_IS_RPC(ret)) { /* Process the RPC. */ e_unlock_teez(ptee); funcid = handle_rpc(ptee, ¶m); e_lock_teez(ptee); } else { break; } } e_unlock_teez(ptee); switch (ret) { case TEESMC_RETURN_UNKNOWN_FUNCTION: break; case TEESMC_RETURN_OK: /* arg32->ret set by secure world */ break; default: /* Should not happen */ arg32->ret = TEEC_ERROR_COMMUNICATION; arg32->ret_origin = TEEC_ORIGIN_COMMS; break; } }