xref: /optee_os/core/pta/device.c (revision 5843bb755f152c7961130e90bba969b8a1ce8f64)
1*5843bb75SJerome Forissier // SPDX-License-Identifier: BSD-2-Clause
2*5843bb75SJerome Forissier /*
3*5843bb75SJerome Forissier  * Copyright (C) 2019, Linaro Limited
4*5843bb75SJerome Forissier  */
5*5843bb75SJerome Forissier 
6*5843bb75SJerome Forissier /*
7*5843bb75SJerome Forissier  * This pseudo TA is used by normal world OS TEE driver to fetch pseudo TA's
8*5843bb75SJerome Forissier  * UUIDs which can act as TEE bus devices.
9*5843bb75SJerome Forissier  */
10*5843bb75SJerome Forissier 
11*5843bb75SJerome Forissier #include <kernel/pseudo_ta.h>
12*5843bb75SJerome Forissier #include <kernel/tee_ta_manager.h>
13*5843bb75SJerome Forissier #include <pta_device.h>
14*5843bb75SJerome Forissier #include <string.h>
15*5843bb75SJerome Forissier #include <tee/uuid.h>
16*5843bb75SJerome Forissier #include <user_ta_header.h>
17*5843bb75SJerome Forissier 
18*5843bb75SJerome Forissier #define PTA_NAME "device.pta"
19*5843bb75SJerome Forissier 
20*5843bb75SJerome Forissier static TEE_Result get_devices(uint32_t types,
21*5843bb75SJerome Forissier 			      TEE_Param params[TEE_NUM_PARAMS])
22*5843bb75SJerome Forissier {
23*5843bb75SJerome Forissier 	const struct pseudo_ta_head *ta;
24*5843bb75SJerome Forissier 	TEE_UUID *device_uuid = NULL;
25*5843bb75SJerome Forissier 	uint8_t uuid_octet[sizeof(TEE_UUID)];
26*5843bb75SJerome Forissier 	size_t ip_size, op_size = 0;
27*5843bb75SJerome Forissier 	TEE_Result res = TEE_SUCCESS;
28*5843bb75SJerome Forissier 
29*5843bb75SJerome Forissier 	if (types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_OUTPUT,
30*5843bb75SJerome Forissier 				     TEE_PARAM_TYPE_NONE,
31*5843bb75SJerome Forissier 				     TEE_PARAM_TYPE_NONE,
32*5843bb75SJerome Forissier 				     TEE_PARAM_TYPE_NONE))
33*5843bb75SJerome Forissier 		return TEE_ERROR_BAD_PARAMETERS;
34*5843bb75SJerome Forissier 
35*5843bb75SJerome Forissier 	if (!params[0].memref.buffer && (params[0].memref.size > 0))
36*5843bb75SJerome Forissier 		return TEE_ERROR_BAD_PARAMETERS;
37*5843bb75SJerome Forissier 
38*5843bb75SJerome Forissier 	device_uuid = (TEE_UUID *)params[0].memref.buffer;
39*5843bb75SJerome Forissier 	ip_size = params[0].memref.size;
40*5843bb75SJerome Forissier 
41*5843bb75SJerome Forissier 	SCATTERED_ARRAY_FOREACH(ta, pseudo_tas, struct pseudo_ta_head) {
42*5843bb75SJerome Forissier 		if (ta->flags & TA_FLAG_DEVICE_ENUM) {
43*5843bb75SJerome Forissier 			if (ip_size < sizeof(TEE_UUID)) {
44*5843bb75SJerome Forissier 				res = TEE_ERROR_SHORT_BUFFER;
45*5843bb75SJerome Forissier 			} else {
46*5843bb75SJerome Forissier 				tee_uuid_to_octets(uuid_octet, &ta->uuid);
47*5843bb75SJerome Forissier 				memcpy(device_uuid, uuid_octet,
48*5843bb75SJerome Forissier 				       sizeof(TEE_UUID));
49*5843bb75SJerome Forissier 				device_uuid++;
50*5843bb75SJerome Forissier 				ip_size -= sizeof(TEE_UUID);
51*5843bb75SJerome Forissier 			}
52*5843bb75SJerome Forissier 			op_size += sizeof(TEE_UUID);
53*5843bb75SJerome Forissier 		}
54*5843bb75SJerome Forissier 	}
55*5843bb75SJerome Forissier 
56*5843bb75SJerome Forissier 	params[0].memref.size = op_size;
57*5843bb75SJerome Forissier 
58*5843bb75SJerome Forissier 	return res;
59*5843bb75SJerome Forissier }
60*5843bb75SJerome Forissier 
61*5843bb75SJerome Forissier static TEE_Result invoke_command(void *pSessionContext __unused,
62*5843bb75SJerome Forissier 				 uint32_t nCommandID, uint32_t nParamTypes,
63*5843bb75SJerome Forissier 				 TEE_Param pParams[TEE_NUM_PARAMS])
64*5843bb75SJerome Forissier {
65*5843bb75SJerome Forissier 	switch (nCommandID) {
66*5843bb75SJerome Forissier 	case PTA_CMD_GET_DEVICES:
67*5843bb75SJerome Forissier 		return get_devices(nParamTypes, pParams);
68*5843bb75SJerome Forissier 	default:
69*5843bb75SJerome Forissier 		break;
70*5843bb75SJerome Forissier 	}
71*5843bb75SJerome Forissier 
72*5843bb75SJerome Forissier 	return TEE_ERROR_NOT_IMPLEMENTED;
73*5843bb75SJerome Forissier }
74*5843bb75SJerome Forissier 
75*5843bb75SJerome Forissier pseudo_ta_register(.uuid = PTA_DEVICE_UUID, .name = PTA_NAME,
76*5843bb75SJerome Forissier 		   .flags = PTA_DEFAULT_FLAGS,
77*5843bb75SJerome Forissier 		   .invoke_command_entry_point = invoke_command);
78