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