15843bb75SJerome Forissier // SPDX-License-Identifier: BSD-2-Clause 25843bb75SJerome Forissier /* 35843bb75SJerome Forissier * Copyright (C) 2019, Linaro Limited 45843bb75SJerome Forissier */ 55843bb75SJerome Forissier 65843bb75SJerome Forissier /* 75843bb75SJerome Forissier * This pseudo TA is used by normal world OS TEE driver to fetch pseudo TA's 85843bb75SJerome Forissier * UUIDs which can act as TEE bus devices. 95843bb75SJerome Forissier */ 105843bb75SJerome Forissier 119389d803SMaxim Uvarov #include <config.h> 129389d803SMaxim Uvarov #include <kernel/early_ta.h> 139389d803SMaxim Uvarov #include <kernel/linker.h> 145843bb75SJerome Forissier #include <kernel/pseudo_ta.h> 158f31ccb0SJens Wiklander #include <kernel/stmm_sp.h> 165843bb75SJerome Forissier #include <kernel/tee_ta_manager.h> 175843bb75SJerome Forissier #include <pta_device.h> 18*a96033caSJens Wiklander #include <tee/tee_fs.h> 195843bb75SJerome Forissier #include <tee/uuid.h> 205843bb75SJerome Forissier #include <user_ta_header.h> 215843bb75SJerome Forissier 225843bb75SJerome Forissier #define PTA_NAME "device.pta" 235843bb75SJerome Forissier 249389d803SMaxim Uvarov static void add_ta(uint32_t flags, const TEE_UUID *uuid, uint8_t *buf, 25bc5921cdSMaxim Uvarov uint32_t blen, uint32_t *pos, uint32_t rflags) 269389d803SMaxim Uvarov { 27*a96033caSJens Wiklander flags &= (TA_FLAG_DEVICE_ENUM | TA_FLAG_DEVICE_ENUM_SUPP | 28*a96033caSJens Wiklander TA_FLAG_DEVICE_ENUM_TEE_STORAGE_PRIVATE); 29*a96033caSJens Wiklander if (flags && flags != TA_FLAG_DEVICE_ENUM && 30*a96033caSJens Wiklander flags != TA_FLAG_DEVICE_ENUM_SUPP && 31*a96033caSJens Wiklander flags != TA_FLAG_DEVICE_ENUM_TEE_STORAGE_PRIVATE) { 32bc5921cdSMaxim Uvarov EMSG(PTA_NAME ": skipping TA %pUl, inconsistent flags", uuid); 33bc5921cdSMaxim Uvarov return; 34bc5921cdSMaxim Uvarov } 35bc5921cdSMaxim Uvarov 36bc5921cdSMaxim Uvarov if (flags & rflags) { 379389d803SMaxim Uvarov if (*pos + sizeof(*uuid) <= blen) 389389d803SMaxim Uvarov tee_uuid_to_octets(buf + *pos, uuid); 399389d803SMaxim Uvarov 409389d803SMaxim Uvarov *pos += sizeof(*uuid); 419389d803SMaxim Uvarov } 429389d803SMaxim Uvarov } 439389d803SMaxim Uvarov 445843bb75SJerome Forissier static TEE_Result get_devices(uint32_t types, 45bc5921cdSMaxim Uvarov TEE_Param params[TEE_NUM_PARAMS], 46bc5921cdSMaxim Uvarov uint32_t rflags) 475843bb75SJerome Forissier { 489389d803SMaxim Uvarov const struct pseudo_ta_head *ta = NULL; 49880d8d8eSJelle Sels const struct embedded_ts *eta = NULL; 509389d803SMaxim Uvarov void *buf = NULL; 519389d803SMaxim Uvarov uint32_t blen = 0; 529389d803SMaxim Uvarov uint32_t pos = 0; 535843bb75SJerome Forissier 545843bb75SJerome Forissier if (types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_OUTPUT, 555843bb75SJerome Forissier TEE_PARAM_TYPE_NONE, 565843bb75SJerome Forissier TEE_PARAM_TYPE_NONE, 575843bb75SJerome Forissier TEE_PARAM_TYPE_NONE)) 585843bb75SJerome Forissier return TEE_ERROR_BAD_PARAMETERS; 595843bb75SJerome Forissier 605843bb75SJerome Forissier if (!params[0].memref.buffer && (params[0].memref.size > 0)) 615843bb75SJerome Forissier return TEE_ERROR_BAD_PARAMETERS; 625843bb75SJerome Forissier 639389d803SMaxim Uvarov buf = params[0].memref.buffer; 649389d803SMaxim Uvarov blen = params[0].memref.size; 655843bb75SJerome Forissier 669389d803SMaxim Uvarov SCATTERED_ARRAY_FOREACH(ta, pseudo_tas, struct pseudo_ta_head) 67bc5921cdSMaxim Uvarov add_ta(ta->flags, &ta->uuid, buf, blen, &pos, rflags); 685843bb75SJerome Forissier 698f31ccb0SJens Wiklander if (stmm_get_uuid()) 708f31ccb0SJens Wiklander add_ta(TA_FLAG_DEVICE_ENUM_SUPP, stmm_get_uuid(), buf, blen, 718f31ccb0SJens Wiklander &pos, rflags); 728f31ccb0SJens Wiklander 739389d803SMaxim Uvarov if (IS_ENABLED(CFG_EARLY_TA)) 749389d803SMaxim Uvarov for_each_early_ta(eta) 75bc5921cdSMaxim Uvarov add_ta(eta->flags, &eta->uuid, buf, blen, &pos, 76bc5921cdSMaxim Uvarov rflags); 775843bb75SJerome Forissier 789389d803SMaxim Uvarov params[0].memref.size = pos; 799389d803SMaxim Uvarov if (pos > blen) 809389d803SMaxim Uvarov return TEE_ERROR_SHORT_BUFFER; 819389d803SMaxim Uvarov 829389d803SMaxim Uvarov return TEE_SUCCESS; 835843bb75SJerome Forissier } 845843bb75SJerome Forissier 855843bb75SJerome Forissier static TEE_Result invoke_command(void *pSessionContext __unused, 865843bb75SJerome Forissier uint32_t nCommandID, uint32_t nParamTypes, 875843bb75SJerome Forissier TEE_Param pParams[TEE_NUM_PARAMS]) 885843bb75SJerome Forissier { 89*a96033caSJens Wiklander TEE_Result res = TEE_SUCCESS; 90*a96033caSJens Wiklander uint32_t rflags = 0; 91*a96033caSJens Wiklander 925843bb75SJerome Forissier switch (nCommandID) { 935843bb75SJerome Forissier case PTA_CMD_GET_DEVICES: 94*a96033caSJens Wiklander rflags = TA_FLAG_DEVICE_ENUM; 955843bb75SJerome Forissier break; 96*a96033caSJens Wiklander case PTA_CMD_GET_DEVICES_SUPP: 97*a96033caSJens Wiklander rflags = TA_FLAG_DEVICE_ENUM_SUPP; 98*a96033caSJens Wiklander if (IS_ENABLED(CFG_REE_FS)) 99*a96033caSJens Wiklander rflags |= TA_FLAG_DEVICE_ENUM_TEE_STORAGE_PRIVATE; 100*a96033caSJens Wiklander break; 101*a96033caSJens Wiklander case PTA_CMD_GET_DEVICES_RPMB: 102*a96033caSJens Wiklander if (!IS_ENABLED(CFG_REE_FS)) { 103*a96033caSJens Wiklander res = tee_rpmb_reinit(); 104*a96033caSJens Wiklander if (res) 105*a96033caSJens Wiklander return TEE_ERROR_STORAGE_NOT_AVAILABLE; 106*a96033caSJens Wiklander rflags = TA_FLAG_DEVICE_ENUM_TEE_STORAGE_PRIVATE; 107*a96033caSJens Wiklander } 108*a96033caSJens Wiklander break; 109*a96033caSJens Wiklander default: 110*a96033caSJens Wiklander return TEE_ERROR_NOT_IMPLEMENTED; 1115843bb75SJerome Forissier } 1125843bb75SJerome Forissier 113*a96033caSJens Wiklander return get_devices(nParamTypes, pParams, rflags); 1145843bb75SJerome Forissier } 1155843bb75SJerome Forissier 1165843bb75SJerome Forissier pseudo_ta_register(.uuid = PTA_DEVICE_UUID, .name = PTA_NAME, 1175843bb75SJerome Forissier .flags = PTA_DEFAULT_FLAGS, 1185843bb75SJerome Forissier .invoke_command_entry_point = invoke_command); 119