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, ¶ms[1].value.a, ¶ms[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