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, ¶ms); 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, ¶ms); 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, ¶ms); 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, ¶ms); 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, ¶ms); 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, ¶ms); 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, ¶ms); 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, ¶ms); 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