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