1*5843bb75SJerome Forissier // SPDX-License-Identifier: BSD-2-Clause 2*5843bb75SJerome Forissier /* 3*5843bb75SJerome Forissier * Copyright (C) 2019, Linaro Limited 4*5843bb75SJerome Forissier */ 5*5843bb75SJerome Forissier 6*5843bb75SJerome Forissier /* 7*5843bb75SJerome Forissier * This pseudo TA is used by normal world OS TEE driver to fetch pseudo TA's 8*5843bb75SJerome Forissier * UUIDs which can act as TEE bus devices. 9*5843bb75SJerome Forissier */ 10*5843bb75SJerome Forissier 11*5843bb75SJerome Forissier #include <kernel/pseudo_ta.h> 12*5843bb75SJerome Forissier #include <kernel/tee_ta_manager.h> 13*5843bb75SJerome Forissier #include <pta_device.h> 14*5843bb75SJerome Forissier #include <string.h> 15*5843bb75SJerome Forissier #include <tee/uuid.h> 16*5843bb75SJerome Forissier #include <user_ta_header.h> 17*5843bb75SJerome Forissier 18*5843bb75SJerome Forissier #define PTA_NAME "device.pta" 19*5843bb75SJerome Forissier 20*5843bb75SJerome Forissier static TEE_Result get_devices(uint32_t types, 21*5843bb75SJerome Forissier TEE_Param params[TEE_NUM_PARAMS]) 22*5843bb75SJerome Forissier { 23*5843bb75SJerome Forissier const struct pseudo_ta_head *ta; 24*5843bb75SJerome Forissier TEE_UUID *device_uuid = NULL; 25*5843bb75SJerome Forissier uint8_t uuid_octet[sizeof(TEE_UUID)]; 26*5843bb75SJerome Forissier size_t ip_size, op_size = 0; 27*5843bb75SJerome Forissier TEE_Result res = TEE_SUCCESS; 28*5843bb75SJerome Forissier 29*5843bb75SJerome Forissier if (types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_OUTPUT, 30*5843bb75SJerome Forissier TEE_PARAM_TYPE_NONE, 31*5843bb75SJerome Forissier TEE_PARAM_TYPE_NONE, 32*5843bb75SJerome Forissier TEE_PARAM_TYPE_NONE)) 33*5843bb75SJerome Forissier return TEE_ERROR_BAD_PARAMETERS; 34*5843bb75SJerome Forissier 35*5843bb75SJerome Forissier if (!params[0].memref.buffer && (params[0].memref.size > 0)) 36*5843bb75SJerome Forissier return TEE_ERROR_BAD_PARAMETERS; 37*5843bb75SJerome Forissier 38*5843bb75SJerome Forissier device_uuid = (TEE_UUID *)params[0].memref.buffer; 39*5843bb75SJerome Forissier ip_size = params[0].memref.size; 40*5843bb75SJerome Forissier 41*5843bb75SJerome Forissier SCATTERED_ARRAY_FOREACH(ta, pseudo_tas, struct pseudo_ta_head) { 42*5843bb75SJerome Forissier if (ta->flags & TA_FLAG_DEVICE_ENUM) { 43*5843bb75SJerome Forissier if (ip_size < sizeof(TEE_UUID)) { 44*5843bb75SJerome Forissier res = TEE_ERROR_SHORT_BUFFER; 45*5843bb75SJerome Forissier } else { 46*5843bb75SJerome Forissier tee_uuid_to_octets(uuid_octet, &ta->uuid); 47*5843bb75SJerome Forissier memcpy(device_uuid, uuid_octet, 48*5843bb75SJerome Forissier sizeof(TEE_UUID)); 49*5843bb75SJerome Forissier device_uuid++; 50*5843bb75SJerome Forissier ip_size -= sizeof(TEE_UUID); 51*5843bb75SJerome Forissier } 52*5843bb75SJerome Forissier op_size += sizeof(TEE_UUID); 53*5843bb75SJerome Forissier } 54*5843bb75SJerome Forissier } 55*5843bb75SJerome Forissier 56*5843bb75SJerome Forissier params[0].memref.size = op_size; 57*5843bb75SJerome Forissier 58*5843bb75SJerome Forissier return res; 59*5843bb75SJerome Forissier } 60*5843bb75SJerome Forissier 61*5843bb75SJerome Forissier static TEE_Result invoke_command(void *pSessionContext __unused, 62*5843bb75SJerome Forissier uint32_t nCommandID, uint32_t nParamTypes, 63*5843bb75SJerome Forissier TEE_Param pParams[TEE_NUM_PARAMS]) 64*5843bb75SJerome Forissier { 65*5843bb75SJerome Forissier switch (nCommandID) { 66*5843bb75SJerome Forissier case PTA_CMD_GET_DEVICES: 67*5843bb75SJerome Forissier return get_devices(nParamTypes, pParams); 68*5843bb75SJerome Forissier default: 69*5843bb75SJerome Forissier break; 70*5843bb75SJerome Forissier } 71*5843bb75SJerome Forissier 72*5843bb75SJerome Forissier return TEE_ERROR_NOT_IMPLEMENTED; 73*5843bb75SJerome Forissier } 74*5843bb75SJerome Forissier 75*5843bb75SJerome Forissier pseudo_ta_register(.uuid = PTA_DEVICE_UUID, .name = PTA_NAME, 76*5843bb75SJerome Forissier .flags = PTA_DEFAULT_FLAGS, 77*5843bb75SJerome Forissier .invoke_command_entry_point = invoke_command); 78