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