xref: /optee_os/core/pta/device.c (revision bc5921cdab538c8ae48422f5ffd600f1cbdd95b2)
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>
155843bb75SJerome Forissier #include <kernel/tee_ta_manager.h>
165843bb75SJerome Forissier #include <pta_device.h>
175843bb75SJerome Forissier #include <string.h>
185843bb75SJerome Forissier #include <tee/uuid.h>
195843bb75SJerome Forissier #include <user_ta_header.h>
205843bb75SJerome Forissier 
215843bb75SJerome Forissier #define PTA_NAME "device.pta"
225843bb75SJerome Forissier 
239389d803SMaxim Uvarov static void add_ta(uint32_t flags, const TEE_UUID *uuid, uint8_t *buf,
24*bc5921cdSMaxim Uvarov 		   uint32_t blen, uint32_t *pos, uint32_t rflags)
259389d803SMaxim Uvarov {
26*bc5921cdSMaxim Uvarov 	if ((flags & TA_FLAG_DEVICE_ENUM) &&
27*bc5921cdSMaxim Uvarov 	    (flags & TA_FLAG_DEVICE_ENUM_SUPP)) {
28*bc5921cdSMaxim Uvarov 		EMSG(PTA_NAME ": skipping TA %pUl, inconsistent flags", uuid);
29*bc5921cdSMaxim Uvarov 		return;
30*bc5921cdSMaxim Uvarov 	}
31*bc5921cdSMaxim Uvarov 
32*bc5921cdSMaxim Uvarov 	if (flags & rflags) {
339389d803SMaxim Uvarov 		if (*pos + sizeof(*uuid) <= blen)
349389d803SMaxim Uvarov 			tee_uuid_to_octets(buf + *pos, uuid);
359389d803SMaxim Uvarov 
369389d803SMaxim Uvarov 		*pos += sizeof(*uuid);
379389d803SMaxim Uvarov 	}
389389d803SMaxim Uvarov }
399389d803SMaxim Uvarov 
405843bb75SJerome Forissier static TEE_Result get_devices(uint32_t types,
41*bc5921cdSMaxim Uvarov 			      TEE_Param params[TEE_NUM_PARAMS],
42*bc5921cdSMaxim Uvarov 			      uint32_t rflags)
435843bb75SJerome Forissier {
449389d803SMaxim Uvarov 	const struct pseudo_ta_head *ta = NULL;
459389d803SMaxim Uvarov 	const struct early_ta *eta = NULL;
469389d803SMaxim Uvarov 	void *buf = NULL;
479389d803SMaxim Uvarov 	uint32_t blen = 0;
489389d803SMaxim Uvarov 	uint32_t pos = 0;
495843bb75SJerome Forissier 
505843bb75SJerome Forissier 	if (types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_OUTPUT,
515843bb75SJerome Forissier 				     TEE_PARAM_TYPE_NONE,
525843bb75SJerome Forissier 				     TEE_PARAM_TYPE_NONE,
535843bb75SJerome Forissier 				     TEE_PARAM_TYPE_NONE))
545843bb75SJerome Forissier 		return TEE_ERROR_BAD_PARAMETERS;
555843bb75SJerome Forissier 
565843bb75SJerome Forissier 	if (!params[0].memref.buffer && (params[0].memref.size > 0))
575843bb75SJerome Forissier 		return TEE_ERROR_BAD_PARAMETERS;
585843bb75SJerome Forissier 
599389d803SMaxim Uvarov 	buf =  params[0].memref.buffer;
609389d803SMaxim Uvarov 	blen = params[0].memref.size;
615843bb75SJerome Forissier 
629389d803SMaxim Uvarov 	SCATTERED_ARRAY_FOREACH(ta, pseudo_tas, struct pseudo_ta_head)
63*bc5921cdSMaxim Uvarov 		add_ta(ta->flags, &ta->uuid, buf, blen, &pos, rflags);
645843bb75SJerome Forissier 
659389d803SMaxim Uvarov 	if (IS_ENABLED(CFG_EARLY_TA))
669389d803SMaxim Uvarov 		for_each_early_ta(eta)
67*bc5921cdSMaxim Uvarov 			add_ta(eta->flags, &eta->uuid, buf, blen, &pos,
68*bc5921cdSMaxim Uvarov 			       rflags);
695843bb75SJerome Forissier 
709389d803SMaxim Uvarov 	params[0].memref.size = pos;
719389d803SMaxim Uvarov 	if (pos > blen)
729389d803SMaxim Uvarov 		return TEE_ERROR_SHORT_BUFFER;
739389d803SMaxim Uvarov 
749389d803SMaxim Uvarov 	return TEE_SUCCESS;
755843bb75SJerome Forissier }
765843bb75SJerome Forissier 
775843bb75SJerome Forissier static TEE_Result invoke_command(void *pSessionContext __unused,
785843bb75SJerome Forissier 				 uint32_t nCommandID, uint32_t nParamTypes,
795843bb75SJerome Forissier 				 TEE_Param pParams[TEE_NUM_PARAMS])
805843bb75SJerome Forissier {
815843bb75SJerome Forissier 	switch (nCommandID) {
825843bb75SJerome Forissier 	case PTA_CMD_GET_DEVICES:
83*bc5921cdSMaxim Uvarov 		return get_devices(nParamTypes, pParams,
84*bc5921cdSMaxim Uvarov 				   TA_FLAG_DEVICE_ENUM);
85*bc5921cdSMaxim Uvarov 	case PTA_CMD_GET_DEVICES_SUPP:
86*bc5921cdSMaxim Uvarov 		return get_devices(nParamTypes, pParams,
87*bc5921cdSMaxim Uvarov 				   TA_FLAG_DEVICE_ENUM_SUPP);
885843bb75SJerome Forissier 	default:
895843bb75SJerome Forissier 		break;
905843bb75SJerome Forissier 	}
915843bb75SJerome Forissier 
925843bb75SJerome Forissier 	return TEE_ERROR_NOT_IMPLEMENTED;
935843bb75SJerome Forissier }
945843bb75SJerome Forissier 
955843bb75SJerome Forissier pseudo_ta_register(.uuid = PTA_DEVICE_UUID, .name = PTA_NAME,
965843bb75SJerome Forissier 		   .flags = PTA_DEFAULT_FLAGS,
975843bb75SJerome Forissier 		   .invoke_command_entry_point = invoke_command);
98