// SPDX-License-Identifier: BSD-2-Clause /* * Copyright (C) 2019, Linaro Limited */ /* * This pseudo TA is used by normal world OS TEE driver to fetch pseudo TA's * UUIDs which can act as TEE bus devices. */ #include #include #include #include #include #include #define PTA_NAME "device.pta" static TEE_Result get_devices(uint32_t types, TEE_Param params[TEE_NUM_PARAMS]) { const struct pseudo_ta_head *ta; TEE_UUID *device_uuid = NULL; uint8_t uuid_octet[sizeof(TEE_UUID)]; size_t ip_size, op_size = 0; TEE_Result res = TEE_SUCCESS; if (types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_OUTPUT, TEE_PARAM_TYPE_NONE, TEE_PARAM_TYPE_NONE, TEE_PARAM_TYPE_NONE)) return TEE_ERROR_BAD_PARAMETERS; if (!params[0].memref.buffer && (params[0].memref.size > 0)) return TEE_ERROR_BAD_PARAMETERS; device_uuid = (TEE_UUID *)params[0].memref.buffer; ip_size = params[0].memref.size; SCATTERED_ARRAY_FOREACH(ta, pseudo_tas, struct pseudo_ta_head) { if (ta->flags & TA_FLAG_DEVICE_ENUM) { if (ip_size < sizeof(TEE_UUID)) { res = TEE_ERROR_SHORT_BUFFER; } else { tee_uuid_to_octets(uuid_octet, &ta->uuid); memcpy(device_uuid, uuid_octet, sizeof(TEE_UUID)); device_uuid++; ip_size -= sizeof(TEE_UUID); } op_size += sizeof(TEE_UUID); } } params[0].memref.size = op_size; return res; } static TEE_Result invoke_command(void *pSessionContext __unused, uint32_t nCommandID, uint32_t nParamTypes, TEE_Param pParams[TEE_NUM_PARAMS]) { switch (nCommandID) { case PTA_CMD_GET_DEVICES: return get_devices(nParamTypes, pParams); default: break; } return TEE_ERROR_NOT_IMPLEMENTED; } pseudo_ta_register(.uuid = PTA_DEVICE_UUID, .name = PTA_NAME, .flags = PTA_DEFAULT_FLAGS, .invoke_command_entry_point = invoke_command);