blob: 9011e989ba0b3ae070d992474da83c0e58414923 [file] [log] [blame]
// 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 <kernel/pseudo_ta.h>
#include <kernel/tee_ta_manager.h>
#include <pta_device.h>
#include <string.h>
#include <tee/uuid.h>
#include <user_ta_header.h>
#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);