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 <config.h> 12 #include <kernel/early_ta.h> 13 #include <kernel/linker.h> 14 #include <kernel/pseudo_ta.h> 15 #include <kernel/stmm_sp.h> 16 #include <kernel/tee_ta_manager.h> 17 #include <pta_device.h> 18 #include <tee/tee_fs.h> 19 #include <tee/uuid.h> 20 #include <user_ta_header.h> 21 22 #define PTA_NAME "device.pta" 23 24 static void add_ta(uint32_t flags, const TEE_UUID *uuid, uint8_t *buf, 25 uint32_t blen, uint32_t *pos, uint32_t rflags) 26 { 27 flags &= (TA_FLAG_DEVICE_ENUM | TA_FLAG_DEVICE_ENUM_SUPP | 28 TA_FLAG_DEVICE_ENUM_TEE_STORAGE_PRIVATE); 29 if (flags && flags != TA_FLAG_DEVICE_ENUM && 30 flags != TA_FLAG_DEVICE_ENUM_SUPP && 31 flags != TA_FLAG_DEVICE_ENUM_TEE_STORAGE_PRIVATE) { 32 EMSG(PTA_NAME ": skipping TA %pUl, inconsistent flags", uuid); 33 return; 34 } 35 36 if (flags & rflags) { 37 if (*pos + sizeof(*uuid) <= blen) 38 tee_uuid_to_octets(buf + *pos, uuid); 39 40 *pos += sizeof(*uuid); 41 } 42 } 43 44 static TEE_Result get_devices(uint32_t types, 45 TEE_Param params[TEE_NUM_PARAMS], 46 uint32_t rflags) 47 { 48 const struct pseudo_ta_head *ta = NULL; 49 const struct embedded_ts *eta = NULL; 50 void *buf = NULL; 51 uint32_t blen = 0; 52 uint32_t pos = 0; 53 54 if (types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_OUTPUT, 55 TEE_PARAM_TYPE_NONE, 56 TEE_PARAM_TYPE_NONE, 57 TEE_PARAM_TYPE_NONE)) 58 return TEE_ERROR_BAD_PARAMETERS; 59 60 if (!params[0].memref.buffer && (params[0].memref.size > 0)) 61 return TEE_ERROR_BAD_PARAMETERS; 62 63 buf = params[0].memref.buffer; 64 blen = params[0].memref.size; 65 66 SCATTERED_ARRAY_FOREACH(ta, pseudo_tas, struct pseudo_ta_head) 67 add_ta(ta->flags, &ta->uuid, buf, blen, &pos, rflags); 68 69 if (stmm_get_uuid()) 70 add_ta(TA_FLAG_DEVICE_ENUM_SUPP, stmm_get_uuid(), buf, blen, 71 &pos, rflags); 72 73 if (IS_ENABLED(CFG_EARLY_TA)) 74 for_each_early_ta(eta) 75 add_ta(eta->flags, &eta->uuid, buf, blen, &pos, 76 rflags); 77 78 params[0].memref.size = pos; 79 if (pos > blen) 80 return TEE_ERROR_SHORT_BUFFER; 81 82 return TEE_SUCCESS; 83 } 84 85 static TEE_Result invoke_command(void *pSessionContext __unused, 86 uint32_t nCommandID, uint32_t nParamTypes, 87 TEE_Param pParams[TEE_NUM_PARAMS]) 88 { 89 TEE_Result res = TEE_SUCCESS; 90 uint32_t rflags = 0; 91 92 switch (nCommandID) { 93 case PTA_CMD_GET_DEVICES: 94 rflags = TA_FLAG_DEVICE_ENUM; 95 break; 96 case PTA_CMD_GET_DEVICES_SUPP: 97 rflags = TA_FLAG_DEVICE_ENUM_SUPP; 98 if (IS_ENABLED(CFG_REE_FS)) 99 rflags |= TA_FLAG_DEVICE_ENUM_TEE_STORAGE_PRIVATE; 100 break; 101 case PTA_CMD_GET_DEVICES_RPMB: 102 if (!IS_ENABLED(CFG_REE_FS)) { 103 res = tee_rpmb_reinit(); 104 if (res) 105 return TEE_ERROR_STORAGE_NOT_AVAILABLE; 106 rflags = TA_FLAG_DEVICE_ENUM_TEE_STORAGE_PRIVATE; 107 } 108 break; 109 default: 110 return TEE_ERROR_NOT_IMPLEMENTED; 111 } 112 113 return get_devices(nParamTypes, pParams, rflags); 114 } 115 116 pseudo_ta_register(.uuid = PTA_DEVICE_UUID, .name = PTA_NAME, 117 .flags = PTA_DEFAULT_FLAGS, 118 .invoke_command_entry_point = invoke_command); 119