1 // SPDX-License-Identifier: BSD-2-Clause
2 /*
3  * Copyright (c) 2019, Linaro Limited
4  * Copyright (c) 2020, Open Mobile Platform LLC
5  */
6 
7 #include <pta_system.h>
8 #include <string.h>
9 #include <tee_internal_api_extensions.h>
10 #include <tee_internal_api.h>
11 #include <types_ext.h>
12 #include <util.h>
13 
invoke_system_pta(uint32_t cmd_id,uint32_t param_types,TEE_Param params[TEE_NUM_PARAMS])14 static TEE_Result invoke_system_pta(uint32_t cmd_id, uint32_t param_types,
15 				    TEE_Param params[TEE_NUM_PARAMS])
16 {
17 	static TEE_TASessionHandle sess = TEE_HANDLE_NULL;
18 	static const TEE_UUID uuid = PTA_SYSTEM_UUID;
19 
20 	if (sess == TEE_HANDLE_NULL) {
21 		TEE_Result res = TEE_OpenTASession(&uuid, TEE_TIMEOUT_INFINITE,
22 						   0, NULL, &sess, NULL);
23 
24 		if (res)
25 			return res;
26 	}
27 
28 	return TEE_InvokeTACommand(sess, TEE_TIMEOUT_INFINITE, cmd_id,
29 				   param_types, params, NULL);
30 }
31 
tee_map_zi(size_t len,uint32_t flags)32 void *tee_map_zi(size_t len, uint32_t flags)
33 {
34 	uint32_t param_types = TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT,
35 					       TEE_PARAM_TYPE_VALUE_INOUT,
36 					       TEE_PARAM_TYPE_VALUE_INPUT,
37 					       TEE_PARAM_TYPE_NONE);
38 	TEE_Param params[TEE_NUM_PARAMS] = { };
39 	TEE_Result res = TEE_SUCCESS;
40 
41 	params[0].value.a = len;
42 	if (params[0].value.a != len)
43 		return NULL;
44 	switch (flags) {
45 	case 0:
46 		break;
47 	case TEE_MEMORY_ACCESS_ANY_OWNER:
48 		params[0].value.b = PTA_SYSTEM_MAP_FLAG_SHAREABLE;
49 		break;
50 	default:
51 		return NULL;
52 	}
53 
54 	res = invoke_system_pta(PTA_SYSTEM_MAP_ZI, param_types, params);
55 	if (res)
56 		return NULL;
57 
58 	return (void *)(vaddr_t)reg_pair_to_64(params[1].value.a,
59 					       params[1].value.b);
60 }
61 
tee_unmap(void * buf,size_t len)62 TEE_Result tee_unmap(void *buf, size_t len)
63 {
64 	TEE_Result res = TEE_SUCCESS;
65 	uint32_t param_types = TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT,
66 					       TEE_PARAM_TYPE_VALUE_INPUT,
67 					       TEE_PARAM_TYPE_NONE,
68 					       TEE_PARAM_TYPE_NONE);
69 	TEE_Param params[TEE_NUM_PARAMS] = { };
70 
71 	params[0].value.a = len;
72 	reg_pair_from_64((vaddr_t)buf, &params[1].value.a, &params[1].value.b);
73 
74 	res = invoke_system_pta(PTA_SYSTEM_UNMAP, param_types, params);
75 	if (res)
76 		EMSG("Invoke PTA_SYSTEM_UNMAP: buf %p, len %#zx", buf, len);
77 
78 	return res;
79 }
80 
tee_invoke_supp_plugin(const TEE_UUID * uuid,uint32_t cmd,uint32_t sub_cmd,void * buf,size_t len,size_t * outlen)81 TEE_Result tee_invoke_supp_plugin(const TEE_UUID *uuid, uint32_t cmd,
82 				  uint32_t sub_cmd, void *buf, size_t len,
83 				  size_t *outlen)
84 {
85 	TEE_Result res = TEE_SUCCESS;
86 	uint32_t param_types = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT,
87 					       TEE_PARAM_TYPE_VALUE_INPUT,
88 					       TEE_PARAM_TYPE_MEMREF_INOUT,
89 					       TEE_PARAM_TYPE_VALUE_OUTPUT);
90 	TEE_Param params[TEE_NUM_PARAMS] = { };
91 
92 	if (!uuid || (len && !buf) || (!len && buf))
93 		return TEE_ERROR_BAD_PARAMETERS;
94 
95 	params[0].memref.buffer = (void *)uuid;
96 	params[0].memref.size = sizeof(TEE_UUID);
97 	params[1].value.a = cmd;
98 	params[1].value.b = sub_cmd;
99 	params[2].memref.buffer = buf;
100 	params[2].memref.size = len;
101 
102 	res = invoke_system_pta(PTA_SYSTEM_SUPP_PLUGIN_INVOKE, param_types,
103 				params);
104 	if (res)
105 		EMSG("Invoke tee-supplicant's plugin failed: %#"PRIx32, res);
106 
107 	if (outlen)
108 		*outlen = params[3].value.a;
109 
110 	return res;
111 }
112