xref: /optee_os/ldelf/sys.c (revision 5a913ee74d3c71af2a2860ce8a4e7aeab2916f9b)
1 // SPDX-License-Identifier: BSD-2-Clause
2 /*
3  * Copyright (c) 2019, Linaro Limited
4  */
5 
6 #include <trace.h>
7 #include <utee_syscalls.h>
8 #include <pta_system.h>
9 
10 #include "sys.h"
11 
12 int trace_level = TRACE_LEVEL;
13 const char trace_ext_prefix[]  = "LD";
14 
15 static uint32_t sess;
16 
17 void __panic(const char *file __maybe_unused, const int line __maybe_unused,
18 	     const char *func __maybe_unused)
19 {
20 	if (!file && !func)
21 		EMSG_RAW("Panic");
22 	else
23 		EMSG_RAW("Panic at %s:%d %s%s%s",
24 			 file ? file : "?", file ? line : 0,
25 			 func ? "<" : "", func ? func : "", func ? ">" : "");
26 
27 	utee_panic(1);
28 	/*NOTREACHED*/
29 	while (true)
30 		;
31 }
32 
33 void sys_return_cleanup(void)
34 {
35 	if (sess) {
36 		if (utee_close_ta_session(sess))
37 			panic();
38 		sess = 0;
39 	}
40 
41 	utee_return(0);
42 	/*NOTREACHED*/
43 	while (true)
44 		;
45 }
46 
47 static TEE_Result invoke_sys_ta(uint32_t cmdid, struct utee_params *params)
48 {
49 	TEE_Result res = TEE_SUCCESS;
50 	uint32_t ret_orig = 0;
51 
52 	if (!sess) {
53 		uint32_t s = 0;
54 
55 		res = utee_open_ta_session(&(const TEE_UUID)PTA_SYSTEM_UUID,
56 					   0, NULL, &s, &ret_orig);
57 		if (res)
58 			return res;
59 		sess = s;
60 	}
61 
62 	return utee_invoke_ta_command(sess, 0, cmdid, params, &ret_orig);
63 }
64 
65 TEE_Result sys_map_zi(size_t num_bytes, uint32_t flags, vaddr_t *va,
66 		      size_t pad_begin, size_t pad_end)
67 {
68 	TEE_Result res = TEE_SUCCESS;
69 	struct utee_params params = {
70 		.types = TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT,
71 					 TEE_PARAM_TYPE_VALUE_INOUT,
72 					 TEE_PARAM_TYPE_VALUE_INPUT,
73 					 TEE_PARAM_TYPE_NONE),
74 	};
75 	uint32_t r[2] = { 0 };
76 
77 	params.vals[0] = num_bytes;
78 	params.vals[1] = flags;
79 	reg_pair_from_64(*va, r, r + 1);
80 	params.vals[2] = r[0];
81 	params.vals[3] = r[1];
82 	params.vals[4] = pad_begin;
83 	params.vals[5] = pad_end;
84 
85 	res = invoke_sys_ta(PTA_SYSTEM_MAP_ZI, &params);
86 	if (!res)
87 		*va = reg_pair_to_64(params.vals[2], params.vals[3]);
88 	return res;
89 }
90 
91 TEE_Result sys_unmap(vaddr_t va, size_t num_bytes)
92 {
93 	struct utee_params params = {
94 		.types = TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT,
95 					 TEE_PARAM_TYPE_VALUE_INPUT,
96 					 TEE_PARAM_TYPE_NONE,
97 					 TEE_PARAM_TYPE_NONE),
98 	};
99 	uint32_t r[2] = { 0 };
100 
101 	params.vals[0] = num_bytes;
102 	reg_pair_from_64(va, r, r + 1);
103 	params.vals[2] = r[0];
104 	params.vals[3] = r[1];
105 
106 	return invoke_sys_ta(PTA_SYSTEM_UNMAP, &params);
107 }
108 
109 TEE_Result sys_open_ta_bin(const TEE_UUID *uuid, uint32_t *handle)
110 {
111 	TEE_Result res = TEE_SUCCESS;
112 	struct utee_params params = {
113 		.types = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT,
114 					 TEE_PARAM_TYPE_VALUE_OUTPUT,
115 					 TEE_PARAM_TYPE_NONE,
116 					 TEE_PARAM_TYPE_NONE),
117 	};
118 
119 	params.vals[0] = (vaddr_t)uuid;
120 	params.vals[1] = sizeof(*uuid);
121 
122 	res = invoke_sys_ta(PTA_SYSTEM_OPEN_TA_BINARY, &params);
123 	if (!res)
124 		*handle = params.vals[2];
125 	return res;
126 }
127 
128 TEE_Result sys_close_ta_bin(uint32_t handle)
129 {
130 	struct utee_params params = {
131 		.types = TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT,
132 					 TEE_PARAM_TYPE_NONE,
133 					 TEE_PARAM_TYPE_NONE,
134 					 TEE_PARAM_TYPE_NONE),
135 	};
136 
137 	params.vals[0] = handle;
138 
139 	return invoke_sys_ta(PTA_SYSTEM_CLOSE_TA_BINARY, &params);
140 }
141 
142 TEE_Result sys_map_ta_bin(vaddr_t *va, size_t num_bytes, uint32_t flags,
143 			  uint32_t handle, size_t offs, size_t pad_begin,
144 			  size_t pad_end)
145 {
146 	TEE_Result res = TEE_SUCCESS;
147 	struct utee_params params = {
148 		.types = TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT,
149 					 TEE_PARAM_TYPE_VALUE_INPUT,
150 					 TEE_PARAM_TYPE_VALUE_INOUT,
151 					 TEE_PARAM_TYPE_VALUE_INPUT),
152 	};
153 	uint32_t r[2] = { 0 };
154 
155 	params.vals[0] = handle;
156 	params.vals[1] = flags;
157 	params.vals[2] = offs;
158 	params.vals[3] = num_bytes;
159 	reg_pair_from_64(*va, r, r + 1);
160 	params.vals[4] = r[0];
161 	params.vals[5] = r[1];
162 	params.vals[6] = pad_begin;
163 	params.vals[7] = pad_end;
164 
165 	res = invoke_sys_ta(PTA_SYSTEM_MAP_TA_BINARY, &params);
166 	if (!res)
167 		*va = reg_pair_to_64(params.vals[4], params.vals[5]);
168 	return res;
169 }
170 
171 
172 TEE_Result sys_copy_from_ta_bin(void *dst, size_t num_bytes, uint32_t handle,
173 				size_t offs)
174 {
175 	struct utee_params params = {
176 		.types = TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT,
177 					 TEE_PARAM_TYPE_MEMREF_OUTPUT,
178 					 TEE_PARAM_TYPE_NONE,
179 					 TEE_PARAM_TYPE_NONE),
180 	};
181 
182 	params.vals[0] = handle;
183 	params.vals[1] = offs;
184 	params.vals[2] = (vaddr_t)dst;
185 	params.vals[3] = num_bytes;
186 
187 	return invoke_sys_ta(PTA_SYSTEM_COPY_FROM_TA_BINARY, &params);
188 }
189 
190 TEE_Result sys_set_prot(vaddr_t va, size_t num_bytes, uint32_t flags)
191 {
192 	struct utee_params params = {
193 		.types = TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT,
194 					 TEE_PARAM_TYPE_VALUE_INPUT,
195 					 TEE_PARAM_TYPE_NONE,
196 					 TEE_PARAM_TYPE_NONE),
197 	};
198 	uint32_t r[2] = { 0 };
199 
200 	params.vals[0] = num_bytes;
201 	params.vals[1] = flags;
202 	reg_pair_from_64(va, r, r + 1);
203 	params.vals[2] = r[0];
204 	params.vals[3] = r[1];
205 
206 	return invoke_sys_ta(PTA_SYSTEM_SET_PROT, &params);
207 }
208 
209 TEE_Result sys_remap(vaddr_t old_va, vaddr_t *new_va, size_t num_bytes,
210 		     size_t pad_begin, size_t pad_end)
211 {
212 	TEE_Result res = TEE_SUCCESS;
213 	struct utee_params params = {
214 		.types = TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT,
215 					 TEE_PARAM_TYPE_VALUE_INPUT,
216 					 TEE_PARAM_TYPE_VALUE_INOUT,
217 					 TEE_PARAM_TYPE_VALUE_INPUT),
218 	};
219 	uint32_t r[2] = { 0 };
220 
221 	params.vals[0] = num_bytes;
222 	reg_pair_from_64(old_va, r, r + 1);
223 	params.vals[2] = r[0];
224 	params.vals[3] = r[1];
225 	reg_pair_from_64(*new_va, r, r + 1);
226 	params.vals[4] = r[0];
227 	params.vals[5] = r[1];
228 	params.vals[6] = pad_begin;
229 	params.vals[7] = pad_end;
230 
231 	res = invoke_sys_ta(PTA_SYSTEM_REMAP, &params);
232 	if (!res)
233 		*new_va = reg_pair_to_64(params.vals[4], params.vals[5]);
234 	return res;
235 }
236