1 // SPDX-License-Identifier: BSD-2-Clause 2 /* 3 * Copyright (c) 2020, Open Mobile Platform LLC 4 */ 5 6 #include <assert.h> 7 #include <kernel/thread.h> 8 #include <mm/mobj.h> 9 #include <optee_rpc_cmd.h> 10 #include <stddef.h> 11 #include <stdint.h> 12 #include <stdlib.h> 13 #include <string.h> 14 #include <tee/tee_supp_plugin_rpc.h> 15 #include <tee/uuid.h> 16 #include <trace.h> 17 18 TEE_Result tee_invoke_supp_plugin_rpc(const TEE_UUID *uuid, uint32_t cmd, 19 uint32_t sub_cmd, void *buf, size_t len, 20 size_t *outlen) 21 { 22 TEE_Result res = TEE_ERROR_GENERIC; 23 struct thread_param params[THREAD_RPC_MAX_NUM_PARAMS]; 24 uint32_t uuid_words[4] = { }; 25 void *va = NULL; 26 struct mobj *mobj = NULL; 27 28 /* 29 * sizeof 'TEE_UUID' and array 'uuid_words' must be same size, 30 * because 'tee_uuid_to_octets()' is used to copy variable 31 * with one type to another. 32 * 33 * Array 'uuid_words' is used just for convenient work with 34 * 'TEE_UUID' as with uint32_t values. 35 */ 36 COMPILE_TIME_ASSERT(sizeof(TEE_UUID) == sizeof(uuid_words)); 37 38 if (!uuid || (len && !buf) || (!len && buf)) 39 return TEE_ERROR_BAD_PARAMETERS; 40 41 if (len) { 42 mobj = thread_rpc_alloc_payload(len); 43 if (!mobj) { 44 EMSG("can't create mobj for plugin data"); 45 return TEE_ERROR_OUT_OF_MEMORY; 46 } 47 48 va = mobj_get_va(mobj, 0, len); 49 if (!va) { 50 EMSG("can't get va from mobj"); 51 goto out; 52 } 53 54 memcpy(va, buf, len); 55 } 56 57 tee_uuid_to_octets((uint8_t *)uuid_words, uuid); 58 59 params[0] = THREAD_PARAM_VALUE(IN, OPTEE_RPC_SUPP_PLUGIN_INVOKE, 60 uuid_words[0], uuid_words[1]); 61 params[1] = THREAD_PARAM_VALUE(IN, uuid_words[2], uuid_words[3], cmd); 62 params[2] = THREAD_PARAM_VALUE(INOUT, sub_cmd, 0, 0); 63 params[3] = THREAD_PARAM_MEMREF(INOUT, mobj, 0, len); 64 65 res = thread_rpc_cmd(OPTEE_RPC_CMD_SUPP_PLUGIN, 4, params); 66 67 if (outlen) 68 *outlen = params[2].u.value.b; 69 70 if (len && outlen && *outlen) 71 memcpy(buf, va, *outlen <= len ? *outlen : len); 72 73 out: 74 if (len) 75 thread_rpc_free_payload(mobj); 76 77 return res; 78 } 79