xref: /optee_os/ldelf/sys.c (revision 88796f89484340777b3a507cd78b0896b7ab105b)
17509ff7cSJens Wiklander // SPDX-License-Identifier: BSD-2-Clause
27509ff7cSJens Wiklander /*
37509ff7cSJens Wiklander  * Copyright (c) 2019, Linaro Limited
47509ff7cSJens Wiklander  */
57509ff7cSJens Wiklander 
67509ff7cSJens Wiklander #include <trace.h>
77509ff7cSJens Wiklander #include <utee_syscalls.h>
87509ff7cSJens Wiklander #include <pta_system.h>
97509ff7cSJens Wiklander 
107509ff7cSJens Wiklander #include "sys.h"
117509ff7cSJens Wiklander 
127509ff7cSJens Wiklander int trace_level = TRACE_LEVEL;
137509ff7cSJens Wiklander const char trace_ext_prefix[]  = "LD";
147509ff7cSJens Wiklander 
157509ff7cSJens Wiklander static uint32_t sess;
167509ff7cSJens Wiklander 
177509ff7cSJens Wiklander void __panic(const char *file __maybe_unused, const int line __maybe_unused,
187509ff7cSJens Wiklander 	     const char *func __maybe_unused)
197509ff7cSJens Wiklander {
207509ff7cSJens Wiklander 	if (!file && !func)
217509ff7cSJens Wiklander 		EMSG_RAW("Panic");
227509ff7cSJens Wiklander 	else
237509ff7cSJens Wiklander 		EMSG_RAW("Panic at %s:%d %s%s%s",
247509ff7cSJens Wiklander 			 file ? file : "?", file ? line : 0,
257509ff7cSJens Wiklander 			 func ? "<" : "", func ? func : "", func ? ">" : "");
267509ff7cSJens Wiklander 
277509ff7cSJens Wiklander 	utee_panic(1);
287509ff7cSJens Wiklander 	/*NOTREACHED*/
297509ff7cSJens Wiklander 	while (true)
307509ff7cSJens Wiklander 		;
317509ff7cSJens Wiklander }
327509ff7cSJens Wiklander 
337509ff7cSJens Wiklander void sys_return_cleanup(void)
347509ff7cSJens Wiklander {
357509ff7cSJens Wiklander 	if (sess) {
367509ff7cSJens Wiklander 		if (utee_close_ta_session(sess))
377509ff7cSJens Wiklander 			panic();
387509ff7cSJens Wiklander 		sess = 0;
397509ff7cSJens Wiklander 	}
407509ff7cSJens Wiklander 
417509ff7cSJens Wiklander 	utee_return(0);
427509ff7cSJens Wiklander 	/*NOTREACHED*/
437509ff7cSJens Wiklander 	while (true)
447509ff7cSJens Wiklander 		;
457509ff7cSJens Wiklander }
467509ff7cSJens Wiklander 
477509ff7cSJens Wiklander static TEE_Result invoke_sys_ta(uint32_t cmdid, struct utee_params *params)
487509ff7cSJens Wiklander {
497509ff7cSJens Wiklander 	TEE_Result res = TEE_SUCCESS;
507509ff7cSJens Wiklander 	uint32_t ret_orig = 0;
517509ff7cSJens Wiklander 
527509ff7cSJens Wiklander 	if (!sess) {
537509ff7cSJens Wiklander 		uint32_t s = 0;
547509ff7cSJens Wiklander 
557509ff7cSJens Wiklander 		res = utee_open_ta_session(&(const TEE_UUID)PTA_SYSTEM_UUID,
567509ff7cSJens Wiklander 					   0, NULL, &s, &ret_orig);
577509ff7cSJens Wiklander 		if (res)
587509ff7cSJens Wiklander 			return res;
597509ff7cSJens Wiklander 		sess = s;
607509ff7cSJens Wiklander 	}
617509ff7cSJens Wiklander 
627509ff7cSJens Wiklander 	return utee_invoke_ta_command(sess, 0, cmdid, params, &ret_orig);
637509ff7cSJens Wiklander }
647509ff7cSJens Wiklander 
657509ff7cSJens Wiklander TEE_Result sys_map_zi(size_t num_bytes, uint32_t flags, vaddr_t *va,
667509ff7cSJens Wiklander 		      size_t pad_begin, size_t pad_end)
677509ff7cSJens Wiklander {
687509ff7cSJens Wiklander 	TEE_Result res = TEE_SUCCESS;
697509ff7cSJens Wiklander 	struct utee_params params = {
707509ff7cSJens Wiklander 		.types = TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT,
717509ff7cSJens Wiklander 					 TEE_PARAM_TYPE_VALUE_INOUT,
727509ff7cSJens Wiklander 					 TEE_PARAM_TYPE_VALUE_INPUT,
737509ff7cSJens Wiklander 					 TEE_PARAM_TYPE_NONE),
747509ff7cSJens Wiklander 	};
757509ff7cSJens Wiklander 	uint32_t r[2] = { 0 };
767509ff7cSJens Wiklander 
777509ff7cSJens Wiklander 	params.vals[0] = num_bytes;
787509ff7cSJens Wiklander 	params.vals[1] = flags;
797509ff7cSJens Wiklander 	reg_pair_from_64(*va, r, r + 1);
807509ff7cSJens Wiklander 	params.vals[2] = r[0];
817509ff7cSJens Wiklander 	params.vals[3] = r[1];
827509ff7cSJens Wiklander 	params.vals[4] = pad_begin;
837509ff7cSJens Wiklander 	params.vals[5] = pad_end;
847509ff7cSJens Wiklander 
857509ff7cSJens Wiklander 	res = invoke_sys_ta(PTA_SYSTEM_MAP_ZI, &params);
867509ff7cSJens Wiklander 	if (!res)
877509ff7cSJens Wiklander 		*va = reg_pair_to_64(params.vals[2], params.vals[3]);
887509ff7cSJens Wiklander 	return res;
897509ff7cSJens Wiklander }
907509ff7cSJens Wiklander 
917509ff7cSJens Wiklander TEE_Result sys_unmap(vaddr_t va, size_t num_bytes)
927509ff7cSJens Wiklander {
937509ff7cSJens Wiklander 	struct utee_params params = {
947509ff7cSJens Wiklander 		.types = TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT,
957509ff7cSJens Wiklander 					 TEE_PARAM_TYPE_VALUE_INPUT,
967509ff7cSJens Wiklander 					 TEE_PARAM_TYPE_NONE,
977509ff7cSJens Wiklander 					 TEE_PARAM_TYPE_NONE),
987509ff7cSJens Wiklander 	};
997509ff7cSJens Wiklander 	uint32_t r[2] = { 0 };
1007509ff7cSJens Wiklander 
1017509ff7cSJens Wiklander 	params.vals[0] = num_bytes;
1027509ff7cSJens Wiklander 	reg_pair_from_64(va, r, r + 1);
1037509ff7cSJens Wiklander 	params.vals[2] = r[0];
1047509ff7cSJens Wiklander 	params.vals[3] = r[1];
1057509ff7cSJens Wiklander 
1067509ff7cSJens Wiklander 	return invoke_sys_ta(PTA_SYSTEM_UNMAP, &params);
1077509ff7cSJens Wiklander }
1087509ff7cSJens Wiklander 
1097509ff7cSJens Wiklander TEE_Result sys_open_ta_bin(const TEE_UUID *uuid, uint32_t *handle)
1107509ff7cSJens Wiklander {
1117509ff7cSJens Wiklander 	TEE_Result res = TEE_SUCCESS;
1127509ff7cSJens Wiklander 	struct utee_params params = {
1137509ff7cSJens Wiklander 		.types = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT,
1147509ff7cSJens Wiklander 					 TEE_PARAM_TYPE_VALUE_OUTPUT,
1157509ff7cSJens Wiklander 					 TEE_PARAM_TYPE_NONE,
1167509ff7cSJens Wiklander 					 TEE_PARAM_TYPE_NONE),
1177509ff7cSJens Wiklander 	};
1187509ff7cSJens Wiklander 
1197509ff7cSJens Wiklander 	params.vals[0] = (vaddr_t)uuid;
1207509ff7cSJens Wiklander 	params.vals[1] = sizeof(*uuid);
1217509ff7cSJens Wiklander 
1227509ff7cSJens Wiklander 	res = invoke_sys_ta(PTA_SYSTEM_OPEN_TA_BINARY, &params);
1237509ff7cSJens Wiklander 	if (!res)
1247509ff7cSJens Wiklander 		*handle = params.vals[2];
1257509ff7cSJens Wiklander 	return res;
1267509ff7cSJens Wiklander }
1277509ff7cSJens Wiklander 
1287509ff7cSJens Wiklander TEE_Result sys_close_ta_bin(uint32_t handle)
1297509ff7cSJens Wiklander {
1307509ff7cSJens Wiklander 	struct utee_params params = {
1317509ff7cSJens Wiklander 		.types = TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT,
1327509ff7cSJens Wiklander 					 TEE_PARAM_TYPE_NONE,
1337509ff7cSJens Wiklander 					 TEE_PARAM_TYPE_NONE,
1347509ff7cSJens Wiklander 					 TEE_PARAM_TYPE_NONE),
1357509ff7cSJens Wiklander 	};
1367509ff7cSJens Wiklander 
1377509ff7cSJens Wiklander 	params.vals[0] = handle;
1387509ff7cSJens Wiklander 
1397509ff7cSJens Wiklander 	return invoke_sys_ta(PTA_SYSTEM_CLOSE_TA_BINARY, &params);
1407509ff7cSJens Wiklander }
1417509ff7cSJens Wiklander 
1427509ff7cSJens Wiklander TEE_Result sys_map_ta_bin(vaddr_t *va, size_t num_bytes, uint32_t flags,
1437509ff7cSJens Wiklander 			  uint32_t handle, size_t offs, size_t pad_begin,
1447509ff7cSJens Wiklander 			  size_t pad_end)
1457509ff7cSJens Wiklander {
1467509ff7cSJens Wiklander 	TEE_Result res = TEE_SUCCESS;
1477509ff7cSJens Wiklander 	struct utee_params params = {
1487509ff7cSJens Wiklander 		.types = TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT,
1497509ff7cSJens Wiklander 					 TEE_PARAM_TYPE_VALUE_INPUT,
1507509ff7cSJens Wiklander 					 TEE_PARAM_TYPE_VALUE_INOUT,
1517509ff7cSJens Wiklander 					 TEE_PARAM_TYPE_VALUE_INPUT),
1527509ff7cSJens Wiklander 	};
1537509ff7cSJens Wiklander 	uint32_t r[2] = { 0 };
1547509ff7cSJens Wiklander 
1557509ff7cSJens Wiklander 	params.vals[0] = handle;
1567509ff7cSJens Wiklander 	params.vals[1] = flags;
1577509ff7cSJens Wiklander 	params.vals[2] = offs;
1587509ff7cSJens Wiklander 	params.vals[3] = num_bytes;
1597509ff7cSJens Wiklander 	reg_pair_from_64(*va, r, r + 1);
1607509ff7cSJens Wiklander 	params.vals[4] = r[0];
1617509ff7cSJens Wiklander 	params.vals[5] = r[1];
1627509ff7cSJens Wiklander 	params.vals[6] = pad_begin;
1637509ff7cSJens Wiklander 	params.vals[7] = pad_end;
1647509ff7cSJens Wiklander 
1657509ff7cSJens Wiklander 	res = invoke_sys_ta(PTA_SYSTEM_MAP_TA_BINARY, &params);
1667509ff7cSJens Wiklander 	if (!res)
1677509ff7cSJens Wiklander 		*va = reg_pair_to_64(params.vals[4], params.vals[5]);
1687509ff7cSJens Wiklander 	return res;
1697509ff7cSJens Wiklander }
1707509ff7cSJens Wiklander 
1717509ff7cSJens Wiklander 
1727509ff7cSJens Wiklander TEE_Result sys_copy_from_ta_bin(void *dst, size_t num_bytes, uint32_t handle,
1737509ff7cSJens Wiklander 				size_t offs)
1747509ff7cSJens Wiklander {
1757509ff7cSJens Wiklander 	struct utee_params params = {
1767509ff7cSJens Wiklander 		.types = TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT,
1777509ff7cSJens Wiklander 					 TEE_PARAM_TYPE_MEMREF_OUTPUT,
1787509ff7cSJens Wiklander 					 TEE_PARAM_TYPE_NONE,
1797509ff7cSJens Wiklander 					 TEE_PARAM_TYPE_NONE),
1807509ff7cSJens Wiklander 	};
1817509ff7cSJens Wiklander 
1827509ff7cSJens Wiklander 	params.vals[0] = handle;
1837509ff7cSJens Wiklander 	params.vals[1] = offs;
1847509ff7cSJens Wiklander 	params.vals[2] = (vaddr_t)dst;
1857509ff7cSJens Wiklander 	params.vals[3] = num_bytes;
1867509ff7cSJens Wiklander 
1877509ff7cSJens Wiklander 	return invoke_sys_ta(PTA_SYSTEM_COPY_FROM_TA_BINARY, &params);
1887509ff7cSJens Wiklander }
1897509ff7cSJens Wiklander 
1907509ff7cSJens Wiklander TEE_Result sys_set_prot(vaddr_t va, size_t num_bytes, uint32_t flags)
1917509ff7cSJens Wiklander {
1927509ff7cSJens Wiklander 	struct utee_params params = {
1937509ff7cSJens Wiklander 		.types = TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT,
1947509ff7cSJens Wiklander 					 TEE_PARAM_TYPE_VALUE_INPUT,
1957509ff7cSJens Wiklander 					 TEE_PARAM_TYPE_NONE,
1967509ff7cSJens Wiklander 					 TEE_PARAM_TYPE_NONE),
1977509ff7cSJens Wiklander 	};
1987509ff7cSJens Wiklander 	uint32_t r[2] = { 0 };
1997509ff7cSJens Wiklander 
2007509ff7cSJens Wiklander 	params.vals[0] = num_bytes;
2017509ff7cSJens Wiklander 	params.vals[1] = flags;
2027509ff7cSJens Wiklander 	reg_pair_from_64(va, r, r + 1);
2037509ff7cSJens Wiklander 	params.vals[2] = r[0];
2047509ff7cSJens Wiklander 	params.vals[3] = r[1];
2057509ff7cSJens Wiklander 
2067509ff7cSJens Wiklander 	return invoke_sys_ta(PTA_SYSTEM_SET_PROT, &params);
2077509ff7cSJens Wiklander }
208*88796f89SJens Wiklander 
209*88796f89SJens Wiklander TEE_Result sys_remap(vaddr_t old_va, vaddr_t *new_va, size_t num_bytes,
210*88796f89SJens Wiklander 		     size_t pad_begin, size_t pad_end)
211*88796f89SJens Wiklander {
212*88796f89SJens Wiklander 	TEE_Result res = TEE_SUCCESS;
213*88796f89SJens Wiklander 	struct utee_params params = {
214*88796f89SJens Wiklander 		.types = TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT,
215*88796f89SJens Wiklander 					 TEE_PARAM_TYPE_VALUE_INPUT,
216*88796f89SJens Wiklander 					 TEE_PARAM_TYPE_VALUE_INOUT,
217*88796f89SJens Wiklander 					 TEE_PARAM_TYPE_VALUE_INPUT),
218*88796f89SJens Wiklander 	};
219*88796f89SJens Wiklander 	uint32_t r[2] = { 0 };
220*88796f89SJens Wiklander 
221*88796f89SJens Wiklander 	params.vals[0] = num_bytes;
222*88796f89SJens Wiklander 	reg_pair_from_64(old_va, r, r + 1);
223*88796f89SJens Wiklander 	params.vals[2] = r[0];
224*88796f89SJens Wiklander 	params.vals[3] = r[1];
225*88796f89SJens Wiklander 	reg_pair_from_64(*new_va, r, r + 1);
226*88796f89SJens Wiklander 	params.vals[4] = r[0];
227*88796f89SJens Wiklander 	params.vals[5] = r[1];
228*88796f89SJens Wiklander 	params.vals[6] = pad_begin;
229*88796f89SJens Wiklander 	params.vals[7] = pad_end;
230*88796f89SJens Wiklander 
231*88796f89SJens Wiklander 	res = invoke_sys_ta(PTA_SYSTEM_REMAP, &params);
232*88796f89SJens Wiklander 	if (!res)
233*88796f89SJens Wiklander 		*new_va = reg_pair_to_64(params.vals[4], params.vals[5]);
234*88796f89SJens Wiklander 	return res;
235*88796f89SJens Wiklander }
236