187065172SJens Wiklander // SPDX-License-Identifier: BSD-2-Clause
287065172SJens Wiklander /*
387065172SJens Wiklander * Copyright (c) 2019, Linaro Limited
4*e4ad5ccdSAleksandr Anisimov * Copyright (c) 2020, Open Mobile Platform LLC
587065172SJens Wiklander */
687065172SJens Wiklander
787065172SJens Wiklander #include <pta_system.h>
887065172SJens Wiklander #include <string.h>
987065172SJens Wiklander #include <tee_internal_api_extensions.h>
1087065172SJens Wiklander #include <tee_internal_api.h>
1187065172SJens Wiklander #include <types_ext.h>
1287065172SJens Wiklander #include <util.h>
1387065172SJens Wiklander
invoke_system_pta(uint32_t cmd_id,uint32_t param_types,TEE_Param params[TEE_NUM_PARAMS])1487065172SJens Wiklander static TEE_Result invoke_system_pta(uint32_t cmd_id, uint32_t param_types,
1587065172SJens Wiklander TEE_Param params[TEE_NUM_PARAMS])
1687065172SJens Wiklander {
1787065172SJens Wiklander static TEE_TASessionHandle sess = TEE_HANDLE_NULL;
1887065172SJens Wiklander static const TEE_UUID uuid = PTA_SYSTEM_UUID;
1987065172SJens Wiklander
2087065172SJens Wiklander if (sess == TEE_HANDLE_NULL) {
21542ae207SCedric Auger TEE_Result res = TEE_OpenTASession(&uuid, TEE_TIMEOUT_INFINITE,
22542ae207SCedric Auger 0, NULL, &sess, NULL);
2387065172SJens Wiklander
2487065172SJens Wiklander if (res)
2587065172SJens Wiklander return res;
2687065172SJens Wiklander }
2787065172SJens Wiklander
28542ae207SCedric Auger return TEE_InvokeTACommand(sess, TEE_TIMEOUT_INFINITE, cmd_id,
29542ae207SCedric Auger param_types, params, NULL);
3087065172SJens Wiklander }
3187065172SJens Wiklander
tee_map_zi(size_t len,uint32_t flags)3287065172SJens Wiklander void *tee_map_zi(size_t len, uint32_t flags)
3387065172SJens Wiklander {
3487065172SJens Wiklander uint32_t param_types = TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT,
3587065172SJens Wiklander TEE_PARAM_TYPE_VALUE_INOUT,
3687065172SJens Wiklander TEE_PARAM_TYPE_VALUE_INPUT,
3787065172SJens Wiklander TEE_PARAM_TYPE_NONE);
3887065172SJens Wiklander TEE_Param params[TEE_NUM_PARAMS] = { };
3987065172SJens Wiklander TEE_Result res = TEE_SUCCESS;
4087065172SJens Wiklander
4187065172SJens Wiklander params[0].value.a = len;
4287065172SJens Wiklander if (params[0].value.a != len)
4387065172SJens Wiklander return NULL;
4487065172SJens Wiklander switch (flags) {
4587065172SJens Wiklander case 0:
4687065172SJens Wiklander break;
4787065172SJens Wiklander case TEE_MEMORY_ACCESS_ANY_OWNER:
4887065172SJens Wiklander params[0].value.b = PTA_SYSTEM_MAP_FLAG_SHAREABLE;
4987065172SJens Wiklander break;
5087065172SJens Wiklander default:
5187065172SJens Wiklander return NULL;
5287065172SJens Wiklander }
5387065172SJens Wiklander
5487065172SJens Wiklander res = invoke_system_pta(PTA_SYSTEM_MAP_ZI, param_types, params);
5587065172SJens Wiklander if (res)
5687065172SJens Wiklander return NULL;
5787065172SJens Wiklander
5887065172SJens Wiklander return (void *)(vaddr_t)reg_pair_to_64(params[1].value.a,
5987065172SJens Wiklander params[1].value.b);
6087065172SJens Wiklander }
6187065172SJens Wiklander
tee_unmap(void * buf,size_t len)6287065172SJens Wiklander TEE_Result tee_unmap(void *buf, size_t len)
6387065172SJens Wiklander {
6487065172SJens Wiklander TEE_Result res = TEE_SUCCESS;
6587065172SJens Wiklander uint32_t param_types = TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT,
6687065172SJens Wiklander TEE_PARAM_TYPE_VALUE_INPUT,
6787065172SJens Wiklander TEE_PARAM_TYPE_NONE,
6887065172SJens Wiklander TEE_PARAM_TYPE_NONE);
6987065172SJens Wiklander TEE_Param params[TEE_NUM_PARAMS] = { };
7087065172SJens Wiklander
7187065172SJens Wiklander params[0].value.a = len;
7287065172SJens Wiklander reg_pair_from_64((vaddr_t)buf, ¶ms[1].value.a, ¶ms[1].value.b);
7387065172SJens Wiklander
7487065172SJens Wiklander res = invoke_system_pta(PTA_SYSTEM_UNMAP, param_types, params);
7587065172SJens Wiklander if (res)
7687065172SJens Wiklander EMSG("Invoke PTA_SYSTEM_UNMAP: buf %p, len %#zx", buf, len);
7787065172SJens Wiklander
7887065172SJens Wiklander return res;
7987065172SJens Wiklander }
80*e4ad5ccdSAleksandr Anisimov
tee_invoke_supp_plugin(const TEE_UUID * uuid,uint32_t cmd,uint32_t sub_cmd,void * buf,size_t len,size_t * outlen)81*e4ad5ccdSAleksandr Anisimov TEE_Result tee_invoke_supp_plugin(const TEE_UUID *uuid, uint32_t cmd,
82*e4ad5ccdSAleksandr Anisimov uint32_t sub_cmd, void *buf, size_t len,
83*e4ad5ccdSAleksandr Anisimov size_t *outlen)
84*e4ad5ccdSAleksandr Anisimov {
85*e4ad5ccdSAleksandr Anisimov TEE_Result res = TEE_SUCCESS;
86*e4ad5ccdSAleksandr Anisimov uint32_t param_types = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT,
87*e4ad5ccdSAleksandr Anisimov TEE_PARAM_TYPE_VALUE_INPUT,
88*e4ad5ccdSAleksandr Anisimov TEE_PARAM_TYPE_MEMREF_INOUT,
89*e4ad5ccdSAleksandr Anisimov TEE_PARAM_TYPE_VALUE_OUTPUT);
90*e4ad5ccdSAleksandr Anisimov TEE_Param params[TEE_NUM_PARAMS] = { };
91*e4ad5ccdSAleksandr Anisimov
92*e4ad5ccdSAleksandr Anisimov if (!uuid || (len && !buf) || (!len && buf))
93*e4ad5ccdSAleksandr Anisimov return TEE_ERROR_BAD_PARAMETERS;
94*e4ad5ccdSAleksandr Anisimov
95*e4ad5ccdSAleksandr Anisimov params[0].memref.buffer = (void *)uuid;
96*e4ad5ccdSAleksandr Anisimov params[0].memref.size = sizeof(TEE_UUID);
97*e4ad5ccdSAleksandr Anisimov params[1].value.a = cmd;
98*e4ad5ccdSAleksandr Anisimov params[1].value.b = sub_cmd;
99*e4ad5ccdSAleksandr Anisimov params[2].memref.buffer = buf;
100*e4ad5ccdSAleksandr Anisimov params[2].memref.size = len;
101*e4ad5ccdSAleksandr Anisimov
102*e4ad5ccdSAleksandr Anisimov res = invoke_system_pta(PTA_SYSTEM_SUPP_PLUGIN_INVOKE, param_types,
103*e4ad5ccdSAleksandr Anisimov params);
104*e4ad5ccdSAleksandr Anisimov if (res)
105*e4ad5ccdSAleksandr Anisimov EMSG("Invoke tee-supplicant's plugin failed: %#"PRIx32, res);
106*e4ad5ccdSAleksandr Anisimov
107*e4ad5ccdSAleksandr Anisimov if (outlen)
108*e4ad5ccdSAleksandr Anisimov *outlen = params[3].value.a;
109*e4ad5ccdSAleksandr Anisimov
110*e4ad5ccdSAleksandr Anisimov return res;
111*e4ad5ccdSAleksandr Anisimov }
112