static TEE_Result gprof_send_rpc(TEE_UUID *uuid, void *buf, size_t len, uint32_t *id) { struct mobj *mobj; TEE_Result res = TEE_ERROR_GENERIC; char *va; mobj = thread_rpc_alloc_payload(sizeof(*uuid) + len); if (!mobj) return TEE_ERROR_OUT_OF_MEMORY; va = mobj_get_va(mobj, 0); if (!va) goto exit; memcpy(va, uuid, sizeof(*uuid)); memcpy(va + sizeof(*uuid), buf, len); struct thread_param params[3] = { [0] = THREAD_PARAM_VALUE(INOUT, *id, 0, 0), [1] = THREAD_PARAM_MEMREF(IN, mobj, 0, sizeof(*uuid)), [2] = THREAD_PARAM_MEMREF(IN, mobj, sizeof(*uuid), len), }; res = thread_rpc_cmd(OPTEE_RPC_CMD_GPROF, 3, params); if (res != TEE_SUCCESS) goto exit; *id = (uint32_t)params[0].u.value.a; exit: thread_rpc_free_payload(mobj); return res; }
/* * Load a TA via RPC with UUID defined by input param @uuid. The virtual * address of the raw TA binary is received in out parameter @ta. */ static TEE_Result rpc_load(const TEE_UUID *uuid, struct shdr **ta, size_t *ta_size, struct mobj **mobj) { TEE_Result res; struct thread_param params[2]; if (!uuid || !ta || !mobj || !ta_size) return TEE_ERROR_BAD_PARAMETERS; memset(params, 0, sizeof(params)); params[0].attr = THREAD_PARAM_ATTR_VALUE_IN; tee_uuid_to_octets((void *)¶ms[0].u.value, uuid); params[1].attr = THREAD_PARAM_ATTR_MEMREF_OUT; res = thread_rpc_cmd(OPTEE_RPC_CMD_LOAD_TA, 2, params); if (res != TEE_SUCCESS) return res; *mobj = thread_rpc_alloc_payload(params[1].u.memref.size); if (!*mobj) return TEE_ERROR_OUT_OF_MEMORY; if ((*mobj)->size < params[1].u.memref.size) { res = TEE_ERROR_SHORT_BUFFER; goto exit; } *ta = mobj_get_va(*mobj, 0); /* We don't expect NULL as thread_rpc_alloc_payload() was successful */ assert(*ta); *ta_size = params[1].u.memref.size; params[0].attr = THREAD_PARAM_ATTR_VALUE_IN; tee_uuid_to_octets((void *)¶ms[0].u.value, uuid); params[1].attr = THREAD_PARAM_ATTR_MEMREF_OUT; params[1].u.memref.offs = 0; params[1].u.memref.mobj = *mobj; res = thread_rpc_cmd(OPTEE_RPC_CMD_LOAD_TA, 2, params); exit: if (res != TEE_SUCCESS) thread_rpc_free_payload(*mobj); return res; }
static TEE_Result socket_open(uint32_t instance_id, uint32_t param_types, TEE_Param params[TEE_NUM_PARAMS]) { struct mobj *mobj; TEE_Result res; uint64_t cookie; void *va; struct optee_msg_param msg_params[4]; uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT, TEE_PARAM_TYPE_MEMREF_INPUT, TEE_PARAM_TYPE_VALUE_INPUT, TEE_PARAM_TYPE_VALUE_OUTPUT); if (exp_pt != param_types) { DMSG("got param_types 0x%x, expected 0x%x", param_types, exp_pt); return TEE_ERROR_BAD_PARAMETERS; } memset(msg_params, 0, sizeof(msg_params)); va = tee_fs_rpc_cache_alloc(params[1].memref.size, &mobj, &cookie); if (!va) return TEE_ERROR_OUT_OF_MEMORY; msg_params[0].attr = OPTEE_MSG_ATTR_TYPE_VALUE_INPUT; msg_params[0].u.value.a = OPTEE_MRC_SOCKET_OPEN; msg_params[0].u.value.b = instance_id; msg_params[1].attr = OPTEE_MSG_ATTR_TYPE_VALUE_INPUT; msg_params[1].u.value.a = params[0].value.b; /* server port number */ msg_params[1].u.value.b = params[2].value.a; /* protocol */ msg_params[1].u.value.c = params[0].value.a; /* ip version */ /* server address */ if (!msg_param_init_memparam(msg_params + 2, mobj, 0, params[1].memref.size, cookie, MSG_PARAM_MEM_DIR_IN)) return TEE_ERROR_BAD_STATE; memcpy(va, params[1].memref.buffer, params[1].memref.size); /* socket handle */ msg_params[3].attr = OPTEE_MSG_ATTR_TYPE_VALUE_OUTPUT; res = thread_rpc_cmd(OPTEE_MSG_RPC_CMD_SOCKET, 4, msg_params); if (res == TEE_SUCCESS) params[3].value.a = msg_params[3].u.value.a; return res; }
static TEE_Result socket_ioctl(uint32_t instance_id, uint32_t param_types, TEE_Param params[TEE_NUM_PARAMS]) { struct mobj *mobj; TEE_Result res; uint64_t cookie; void *va; struct optee_msg_param msg_params[3]; uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT, TEE_PARAM_TYPE_MEMREF_INOUT, TEE_PARAM_TYPE_NONE, TEE_PARAM_TYPE_NONE); if (exp_pt != param_types) { DMSG("got param_types 0x%x, expected 0x%x", param_types, exp_pt); return TEE_ERROR_BAD_PARAMETERS; } memset(msg_params, 0, sizeof(msg_params)); va = tee_fs_rpc_cache_alloc(params[1].memref.size, &mobj, &cookie); if (!va) return TEE_ERROR_OUT_OF_MEMORY; msg_params[0].attr = OPTEE_MSG_ATTR_TYPE_VALUE_INPUT; msg_params[0].u.value.a = OPTEE_MRC_SOCKET_IOCTL; msg_params[0].u.value.b = instance_id; msg_params[0].u.value.c = params[0].value.a; /* handle */ /* buffer */ if (!msg_param_init_memparam(msg_params + 1, mobj, 0, params[1].memref.size, cookie, MSG_PARAM_MEM_DIR_INOUT)) return TEE_ERROR_BAD_STATE; memcpy(va, params[1].memref.buffer, params[1].memref.size); msg_params[2].attr = OPTEE_MSG_ATTR_TYPE_VALUE_INPUT; msg_params[2].u.value.a = params[0].value.b; /* ioctl command */ res = thread_rpc_cmd(OPTEE_MSG_RPC_CMD_SOCKET, 3, msg_params); if (msg_param_get_buf_size(msg_params + 1) <= params[1].memref.size) memcpy(params[1].memref.buffer, va, msg_param_get_buf_size(msg_params + 1)); params[1].memref.size = msg_param_get_buf_size(msg_params + 1); return res; }
void tee_time_wait(uint32_t milliseconds_delay) { struct tee_ta_session *sess = NULL; struct teesmc32_param params; tee_ta_get_current_session(&sess); if (sess) tee_ta_set_current_session(NULL); memset(¶ms, 0, sizeof(params)); params.attr = TEESMC_ATTR_TYPE_VALUE_INPUT; params.u.value.a = milliseconds_delay; thread_rpc_cmd(TEE_RPC_WAIT, 1, ¶ms); if (sess) tee_ta_set_current_session(sess); }
/* * tee_time_get_ree_time(): this function implements the GP Internal API * function TEE_GetREETime() * Goal is to get the time of the Rich Execution Environment * This is why this time is provided through the supplicant */ TEE_Result tee_time_get_ree_time(TEE_Time *time) { struct tee_ta_session *sess = NULL; TEE_Result res = TEE_ERROR_BAD_PARAMETERS; struct teesmc32_param params; paddr_t phpayload = 0; paddr_t cookie = 0; TEE_Time *payload; tee_ta_get_current_session(&sess); tee_ta_set_current_session(NULL); if (!time) goto exit; thread_optee_rpc_alloc_payload(sizeof(TEE_Time), &phpayload, &cookie); if (!phpayload) goto exit; if (!TEE_ALIGNMENT_IS_OK(phpayload, TEE_Time)) goto exit; if (core_pa2va(phpayload, &payload)) goto exit; memset(¶ms, 0, sizeof(params)); params.attr = TEESMC_ATTR_TYPE_MEMREF_OUTPUT | (TEESMC_ATTR_CACHE_I_WRITE_THR | TEESMC_ATTR_CACHE_O_WRITE_THR) << TEESMC_ATTR_CACHE_SHIFT; params.u.memref.buf_ptr = phpayload; params.u.memref.size = sizeof(TEE_Time); res = thread_rpc_cmd(TEE_RPC_GET_TIME, 1, ¶ms); if (res != TEE_SUCCESS) goto exit; *time = *payload; exit: thread_optee_rpc_free_payload(cookie); tee_ta_set_current_session(sess); return res; }
static TEE_Result gprof_send_rpc(TEE_UUID *uuid, void *buf, size_t len, uint32_t *id) { struct optee_msg_param params[3]; TEE_Result res = TEE_ERROR_GENERIC; uint64_t c = 0; paddr_t pa; char *va; thread_rpc_alloc_payload(sizeof(*uuid) + len, &pa, &c); if (!pa) return TEE_ERROR_OUT_OF_MEMORY; va = phys_to_virt(pa, MEM_AREA_NSEC_SHM); if (!va) goto exit; memcpy(va, uuid, sizeof(*uuid)); memcpy(va + sizeof(*uuid), buf, len); memset(params, 0, sizeof(params)); params[0].attr = OPTEE_MSG_ATTR_TYPE_VALUE_INOUT; params[0].u.value.a = *id; params[1].attr = OPTEE_MSG_ATTR_TYPE_TMEM_INPUT; params[1].u.tmem.buf_ptr = pa; params[1].u.tmem.size = sizeof(*uuid); params[1].u.tmem.shm_ref = c; params[2].attr = OPTEE_MSG_ATTR_TYPE_TMEM_INPUT; params[2].u.tmem.buf_ptr = pa + sizeof(*uuid); params[2].u.tmem.size = len; params[2].u.tmem.shm_ref = c; res = thread_rpc_cmd(OPTEE_MSG_RPC_CMD_GPROF, 3, params); if (res != TEE_SUCCESS) goto exit; *id = (uint32_t)params[0].u.value.a; exit: thread_rpc_free_payload(c); return res; }
static TEE_Result socket_close(uint32_t instance_id, uint32_t param_types, TEE_Param params[TEE_NUM_PARAMS]) { struct optee_msg_param msg_params[1]; uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT, TEE_PARAM_TYPE_NONE, TEE_PARAM_TYPE_NONE, TEE_PARAM_TYPE_NONE); if (exp_pt != param_types) { DMSG("got param_types 0x%x, expected 0x%x", param_types, exp_pt); return TEE_ERROR_BAD_PARAMETERS; } memset(msg_params, 0, sizeof(msg_params)); msg_params[0].attr = OPTEE_MSG_ATTR_TYPE_VALUE_INPUT; msg_params[0].u.value.a = OPTEE_MRC_SOCKET_CLOSE; msg_params[0].u.value.b = instance_id; msg_params[0].u.value.c = params[0].value.a; return thread_rpc_cmd(OPTEE_MSG_RPC_CMD_SOCKET, 1, msg_params); }
static TEE_Result rpc_reg_global_buf(uint64_t type, paddr_t phta, size_t size) { struct thread_param tpm = THREAD_PARAM_VALUE(IN, type, phta, size); return thread_rpc_cmd(OPTEE_RPC_CMD_BENCH_REG, 1, &tpm); }