Linux debugging

Check our new training course

Linux debugging, tracing, profiling & perf. analysis

Check our new training course
with Creative Commons CC-BY-SA
lecture and lab materials

Bootlin logo

Elixir Cross Referencer

// 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);