xref: /optee_os/core/pta/device.c (revision 8f31ccb04cb26a8f25c5f6928c5d50879eaf47e6)
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>
15*8f31ccb0SJens Wiklander #include <kernel/stmm_sp.h>
165843bb75SJerome Forissier #include <kernel/tee_ta_manager.h>
175843bb75SJerome Forissier #include <pta_device.h>
185843bb75SJerome Forissier #include <string.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 {
27bc5921cdSMaxim Uvarov 	if ((flags & TA_FLAG_DEVICE_ENUM) &&
28bc5921cdSMaxim Uvarov 	    (flags & TA_FLAG_DEVICE_ENUM_SUPP)) {
29bc5921cdSMaxim Uvarov 		EMSG(PTA_NAME ": skipping TA %pUl, inconsistent flags", uuid);
30bc5921cdSMaxim Uvarov 		return;
31bc5921cdSMaxim Uvarov 	}
32bc5921cdSMaxim Uvarov 
33bc5921cdSMaxim Uvarov 	if (flags & rflags) {
349389d803SMaxim Uvarov 		if (*pos + sizeof(*uuid) <= blen)
359389d803SMaxim Uvarov 			tee_uuid_to_octets(buf + *pos, uuid);
369389d803SMaxim Uvarov 
379389d803SMaxim Uvarov 		*pos += sizeof(*uuid);
389389d803SMaxim Uvarov 	}
399389d803SMaxim Uvarov }
409389d803SMaxim Uvarov 
415843bb75SJerome Forissier static TEE_Result get_devices(uint32_t types,
42bc5921cdSMaxim Uvarov 			      TEE_Param params[TEE_NUM_PARAMS],
43bc5921cdSMaxim Uvarov 			      uint32_t rflags)
445843bb75SJerome Forissier {
459389d803SMaxim Uvarov 	const struct pseudo_ta_head *ta = NULL;
46880d8d8eSJelle Sels 	const struct embedded_ts *eta = NULL;
479389d803SMaxim Uvarov 	void *buf = NULL;
489389d803SMaxim Uvarov 	uint32_t blen = 0;
499389d803SMaxim Uvarov 	uint32_t pos = 0;
505843bb75SJerome Forissier 
515843bb75SJerome Forissier 	if (types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_OUTPUT,
525843bb75SJerome Forissier 				     TEE_PARAM_TYPE_NONE,
535843bb75SJerome Forissier 				     TEE_PARAM_TYPE_NONE,
545843bb75SJerome Forissier 				     TEE_PARAM_TYPE_NONE))
555843bb75SJerome Forissier 		return TEE_ERROR_BAD_PARAMETERS;
565843bb75SJerome Forissier 
575843bb75SJerome Forissier 	if (!params[0].memref.buffer && (params[0].memref.size > 0))
585843bb75SJerome Forissier 		return TEE_ERROR_BAD_PARAMETERS;
595843bb75SJerome Forissier 
609389d803SMaxim Uvarov 	buf =  params[0].memref.buffer;
619389d803SMaxim Uvarov 	blen = params[0].memref.size;
625843bb75SJerome Forissier 
639389d803SMaxim Uvarov 	SCATTERED_ARRAY_FOREACH(ta, pseudo_tas, struct pseudo_ta_head)
64bc5921cdSMaxim Uvarov 		add_ta(ta->flags, &ta->uuid, buf, blen, &pos, rflags);
655843bb75SJerome Forissier 
66*8f31ccb0SJens Wiklander 	if (stmm_get_uuid())
67*8f31ccb0SJens Wiklander 		add_ta(TA_FLAG_DEVICE_ENUM_SUPP, stmm_get_uuid(), buf, blen,
68*8f31ccb0SJens Wiklander 		       &pos, rflags);
69*8f31ccb0SJens Wiklander 
709389d803SMaxim Uvarov 	if (IS_ENABLED(CFG_EARLY_TA))
719389d803SMaxim Uvarov 		for_each_early_ta(eta)
72bc5921cdSMaxim Uvarov 			add_ta(eta->flags, &eta->uuid, buf, blen, &pos,
73bc5921cdSMaxim Uvarov 			       rflags);
745843bb75SJerome Forissier 
759389d803SMaxim Uvarov 	params[0].memref.size = pos;
769389d803SMaxim Uvarov 	if (pos > blen)
779389d803SMaxim Uvarov 		return TEE_ERROR_SHORT_BUFFER;
789389d803SMaxim Uvarov 
799389d803SMaxim Uvarov 	return TEE_SUCCESS;
805843bb75SJerome Forissier }
815843bb75SJerome Forissier 
825843bb75SJerome Forissier static TEE_Result invoke_command(void *pSessionContext __unused,
835843bb75SJerome Forissier 				 uint32_t nCommandID, uint32_t nParamTypes,
845843bb75SJerome Forissier 				 TEE_Param pParams[TEE_NUM_PARAMS])
855843bb75SJerome Forissier {
865843bb75SJerome Forissier 	switch (nCommandID) {
875843bb75SJerome Forissier 	case PTA_CMD_GET_DEVICES:
88bc5921cdSMaxim Uvarov 		return get_devices(nParamTypes, pParams,
89bc5921cdSMaxim Uvarov 				   TA_FLAG_DEVICE_ENUM);
90bc5921cdSMaxim Uvarov 	case PTA_CMD_GET_DEVICES_SUPP:
91bc5921cdSMaxim Uvarov 		return get_devices(nParamTypes, pParams,
92bc5921cdSMaxim Uvarov 				   TA_FLAG_DEVICE_ENUM_SUPP);
935843bb75SJerome Forissier 	default:
945843bb75SJerome Forissier 		break;
955843bb75SJerome Forissier 	}
965843bb75SJerome Forissier 
975843bb75SJerome Forissier 	return TEE_ERROR_NOT_IMPLEMENTED;
985843bb75SJerome Forissier }
995843bb75SJerome Forissier 
1005843bb75SJerome Forissier pseudo_ta_register(.uuid = PTA_DEVICE_UUID, .name = PTA_NAME,
1015843bb75SJerome Forissier 		   .flags = PTA_DEFAULT_FLAGS,
1025843bb75SJerome Forissier 		   .invoke_command_entry_point = invoke_command);
103