xref: /optee_os/lib/libutee/tee_system_pta.c (revision b462a51c9c748df753cb823ce33c58f7bb28ba98)
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_va(vaddr_t va,size_t len,uint32_t flags)32 void *tee_map_zi_va(vaddr_t va, 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 	params[1].value.a = high32_from_64(va);
54 	params[1].value.b = low32_from_64(va);
55 
56 	res = invoke_system_pta(PTA_SYSTEM_MAP_ZI, param_types, params);
57 	if (res)
58 		return NULL;
59 
60 	return (void *)(vaddr_t)reg_pair_to_64(params[1].value.a,
61 					       params[1].value.b);
62 }
63 
tee_map_zi(size_t len,uint32_t flags)64 void *tee_map_zi(size_t len, uint32_t flags)
65 {
66 	return tee_map_zi_va((vaddr_t)0, len, flags);
67 }
68 
tee_unmap(void * buf,size_t len)69 TEE_Result tee_unmap(void *buf, size_t len)
70 {
71 	TEE_Result res = TEE_SUCCESS;
72 	uint32_t param_types = TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT,
73 					       TEE_PARAM_TYPE_VALUE_INPUT,
74 					       TEE_PARAM_TYPE_NONE,
75 					       TEE_PARAM_TYPE_NONE);
76 	TEE_Param params[TEE_NUM_PARAMS] = { };
77 
78 	params[0].value.a = len;
79 	reg_pair_from_64((vaddr_t)buf, &params[1].value.a, &params[1].value.b);
80 
81 	res = invoke_system_pta(PTA_SYSTEM_UNMAP, param_types, params);
82 	if (res)
83 		EMSG("Invoke PTA_SYSTEM_UNMAP: buf %p, len %#zx", buf, len);
84 
85 	return res;
86 }
87 
tee_invoke_supp_plugin(const TEE_UUID * uuid,uint32_t cmd,uint32_t sub_cmd,void * buf,size_t len,size_t * outlen)88 TEE_Result tee_invoke_supp_plugin(const TEE_UUID *uuid, uint32_t cmd,
89 				  uint32_t sub_cmd, void *buf, size_t len,
90 				  size_t *outlen)
91 {
92 	TEE_Result res = TEE_SUCCESS;
93 	uint32_t param_types = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT,
94 					       TEE_PARAM_TYPE_VALUE_INPUT,
95 					       TEE_PARAM_TYPE_MEMREF_INOUT,
96 					       TEE_PARAM_TYPE_VALUE_OUTPUT);
97 	TEE_Param params[TEE_NUM_PARAMS] = { };
98 
99 	if (!uuid || (len && !buf) || (!len && buf))
100 		return TEE_ERROR_BAD_PARAMETERS;
101 
102 	params[0].memref.buffer = (void *)uuid;
103 	params[0].memref.size = sizeof(TEE_UUID);
104 	params[1].value.a = cmd;
105 	params[1].value.b = sub_cmd;
106 	params[2].memref.buffer = buf;
107 	params[2].memref.size = len;
108 
109 	res = invoke_system_pta(PTA_SYSTEM_SUPP_PLUGIN_INVOKE, param_types,
110 				params);
111 	if (res)
112 		EMSG("Invoke tee-supplicant's plugin failed: %#"PRIx32, res);
113 
114 	if (outlen)
115 		*outlen = params[3].value.a;
116 
117 	return res;
118 }
119