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 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 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 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 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 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