1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111
|
// SPDX-License-Identifier: BSD-2-Clause
/*
* Copyright (c) 2019, Linaro Limited
* Copyright (c) 2020, Open Mobile Platform LLC
*/
#include <pta_system.h>
#include <string.h>
#include <tee_internal_api_extensions.h>
#include <tee_internal_api.h>
#include <types_ext.h>
#include <util.h>
static TEE_Result invoke_system_pta(uint32_t cmd_id, uint32_t param_types,
TEE_Param params[TEE_NUM_PARAMS])
{
static TEE_TASessionHandle sess = TEE_HANDLE_NULL;
static const TEE_UUID uuid = PTA_SYSTEM_UUID;
if (sess == TEE_HANDLE_NULL) {
TEE_Result res = TEE_OpenTASession(&uuid, TEE_TIMEOUT_INFINITE,
0, NULL, &sess, NULL);
if (res)
return res;
}
return TEE_InvokeTACommand(sess, TEE_TIMEOUT_INFINITE, cmd_id,
param_types, params, NULL);
}
void *tee_map_zi(size_t len, uint32_t flags)
{
uint32_t param_types = TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT,
TEE_PARAM_TYPE_VALUE_INOUT,
TEE_PARAM_TYPE_VALUE_INPUT,
TEE_PARAM_TYPE_NONE);
TEE_Param params[TEE_NUM_PARAMS] = { };
TEE_Result res = TEE_SUCCESS;
params[0].value.a = len;
if (params[0].value.a != len)
return NULL;
switch (flags) {
case 0:
break;
case TEE_MEMORY_ACCESS_ANY_OWNER:
params[0].value.b = PTA_SYSTEM_MAP_FLAG_SHAREABLE;
break;
default:
return NULL;
}
res = invoke_system_pta(PTA_SYSTEM_MAP_ZI, param_types, params);
if (res)
return NULL;
return (void *)(vaddr_t)reg_pair_to_64(params[1].value.a,
params[1].value.b);
}
TEE_Result tee_unmap(void *buf, size_t len)
{
TEE_Result res = TEE_SUCCESS;
uint32_t param_types = TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT,
TEE_PARAM_TYPE_VALUE_INPUT,
TEE_PARAM_TYPE_NONE,
TEE_PARAM_TYPE_NONE);
TEE_Param params[TEE_NUM_PARAMS] = { };
params[0].value.a = len;
reg_pair_from_64((vaddr_t)buf, ¶ms[1].value.a, ¶ms[1].value.b);
res = invoke_system_pta(PTA_SYSTEM_UNMAP, param_types, params);
if (res)
EMSG("Invoke PTA_SYSTEM_UNMAP: buf %p, len %#zx", buf, len);
return res;
}
TEE_Result tee_invoke_supp_plugin(const TEE_UUID *uuid, uint32_t cmd,
uint32_t sub_cmd, void *buf, size_t len,
size_t *outlen)
{
TEE_Result res = TEE_SUCCESS;
uint32_t param_types = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT,
TEE_PARAM_TYPE_VALUE_INPUT,
TEE_PARAM_TYPE_MEMREF_INOUT,
TEE_PARAM_TYPE_VALUE_OUTPUT);
TEE_Param params[TEE_NUM_PARAMS] = { };
if (!uuid || (len && !buf) || (!len && buf))
return TEE_ERROR_BAD_PARAMETERS;
params[0].memref.buffer = (void *)uuid;
params[0].memref.size = sizeof(TEE_UUID);
params[1].value.a = cmd;
params[1].value.b = sub_cmd;
params[2].memref.buffer = buf;
params[2].memref.size = len;
res = invoke_system_pta(PTA_SYSTEM_SUPP_PLUGIN_INVOKE, param_types,
params);
if (res)
EMSG("Invoke tee-supplicant's plugin failed: %#"PRIx32, res);
if (outlen)
*outlen = params[3].value.a;
return res;
}
|