xref: /optee_os/lib/libutee/tee_system_pta.c (revision e4ad5ccd3994b1abe0fd638c786b8d719732e2a5)
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, &params[1].value.a, &params[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