mirror of
https://github.com/RT-Thread/rt-thread.git
synced 2026-08-18 02:58:57 +08:00
[dm][tee] support Trusted Execution Environment (TEE)
Signed-off-by: GuEe-GUI <2991707448@qq.com>
This commit is contained in:
@@ -35,6 +35,7 @@ rsource "block/Kconfig"
|
||||
rsource "scsi/Kconfig"
|
||||
rsource "ufs/Kconfig"
|
||||
rsource "firmware/Kconfig"
|
||||
rsource "tee/Kconfig"
|
||||
rsource "hwcache/Kconfig"
|
||||
rsource "dvfs/Kconfig"
|
||||
rsource "regulator/Kconfig"
|
||||
|
||||
Executable
+187
@@ -0,0 +1,187 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2023, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2023-04-23 GuEe-GUI first version
|
||||
*/
|
||||
|
||||
#ifndef __TEE_H__
|
||||
#define __TEE_H__
|
||||
|
||||
#include <rtthread.h>
|
||||
#include <drivers/misc.h>
|
||||
|
||||
#define RT_TEE_SUCCESS 0x00000000
|
||||
#define RT_TEE_ERROR_STORAGE_NOT_AVAILABLE 0xf0100003
|
||||
#define RT_TEE_ERROR_GENERIC 0xffff0000
|
||||
#define RT_TEE_ERROR_EXCESS_DATA 0xffff0004
|
||||
#define RT_TEE_ERROR_BAD_PARAMETERS 0xffff0006
|
||||
#define RT_TEE_ERROR_ITEM_NOT_FOUND 0xffff0008
|
||||
#define RT_TEE_ERROR_NOT_IMPLEMENTED 0xffff0009
|
||||
#define RT_TEE_ERROR_NOT_SUPPORTED 0xffff000a
|
||||
#define RT_TEE_ERROR_COMMUNICATION 0xffff000e
|
||||
#define RT_TEE_ERROR_SECURITY 0xffff000f
|
||||
#define RT_TEE_ERROR_SHORT_BUFFER 0xffff0010
|
||||
#define RT_TEE_ERROR_OUT_OF_MEMORY 0xffff000c
|
||||
#define RT_TEE_ERROR_OVERFLOW 0xffff300f
|
||||
#define RT_TEE_ERROR_TARGET_DEAD 0xffff3024
|
||||
#define RT_TEE_ERROR_STORAGE_NO_SPACE 0xffff3041
|
||||
|
||||
#define RT_TEE_ORIGIN_COMMS 0x00000002
|
||||
#define RT_TEE_ORIGIN_TEE 0x00000003
|
||||
#define RT_TEE_ORIGIN_TRUSTED_APP 0x00000004
|
||||
|
||||
struct rt_tee_ops;
|
||||
|
||||
struct rt_tee_device
|
||||
{
|
||||
struct rt_device parent;
|
||||
|
||||
rt_list_t shm_nodes;
|
||||
|
||||
const struct rt_tee_ops *ops;
|
||||
struct rt_mutex mutex;
|
||||
};
|
||||
#define rt_device_to_tee_device(dev) rt_container_of(dev, struct rt_tee_device, parent)
|
||||
|
||||
struct rt_tee_version
|
||||
{
|
||||
#define TEE_IMPL_ID_OPTEE 1
|
||||
#define TEE_IMPL_ID_AMDTEE 2
|
||||
/* TEE implementation id */
|
||||
rt_uint32_t impl_id;
|
||||
#define TEE_OPTEE_CAP_TZ RT_BIT(0)
|
||||
/* Implementation specific capabilities */
|
||||
rt_uint32_t impl_caps;
|
||||
#define TEE_GEN_CAP_GP RT_BIT(0) /* GlobalPlatform compliant TEE */
|
||||
#define TEE_GEN_CAP_PRIVILEGED RT_BIT(1) /* Privileged device (for supplicant) */
|
||||
#define TEE_GEN_CAP_REG_MEM RT_BIT(2) /* Supports registering shared memory */
|
||||
#define TEE_GEN_CAP_MEMREF_NULL RT_BIT(3) /* NULL MemRef support */
|
||||
/* Generic capabilities */
|
||||
rt_uint32_t gen_caps;
|
||||
};
|
||||
|
||||
struct rt_tee_shm
|
||||
{
|
||||
rt_list_t list;
|
||||
struct rt_tee_device *tdev;
|
||||
|
||||
void *vaddr;
|
||||
rt_ubase_t paddr;
|
||||
rt_size_t size;
|
||||
rt_size_t align;
|
||||
#define TEE_SHM_DRV RT_BIT(0) /* Memory allocated from pool */
|
||||
#define TEE_SHM_SYS RT_BIT(1) /* Memory allocated from system */
|
||||
#define TEE_SHM_USER RT_BIT(2) /* Memory from user */
|
||||
rt_uint32_t flags;
|
||||
};
|
||||
|
||||
struct rt_tee_param_memref
|
||||
{
|
||||
rt_off_t shm_offs;
|
||||
rt_size_t size;
|
||||
struct rt_tee_shm *shm;
|
||||
};
|
||||
|
||||
struct rt_tee_param_value
|
||||
{
|
||||
rt_uint64_t a;
|
||||
rt_uint64_t b;
|
||||
rt_uint64_t c;
|
||||
};
|
||||
|
||||
struct rt_tee_param
|
||||
{
|
||||
#define TEE_PARAM_ATTR_TYPE_NONE 0
|
||||
#define TEE_PARAM_ATTR_TYPE_VALUE_IN 1
|
||||
#define TEE_PARAM_ATTR_TYPE_VALUE_OUT 2
|
||||
#define TEE_PARAM_ATTR_TYPE_VALUE_IN_OUT 3
|
||||
#define TEE_PARAM_ATTR_TYPE_MEMREF_IN 5
|
||||
#define TEE_PARAM_ATTR_TYPE_MEMREF_OUT 6
|
||||
#define TEE_PARAM_ATTR_TYPE_MEMREF_IN_OUT 7
|
||||
rt_uint64_t attr;
|
||||
|
||||
union
|
||||
{
|
||||
struct rt_tee_param_memref memref;
|
||||
struct rt_tee_param_value value;
|
||||
};
|
||||
};
|
||||
|
||||
rt_packed(struct rt_tee_uuid
|
||||
{
|
||||
rt_uint32_t time_low;
|
||||
rt_uint16_t time_mid;
|
||||
rt_uint16_t time_hi_and_version;
|
||||
rt_uint8_t clock_seq_and_node[8];
|
||||
});
|
||||
|
||||
struct rt_tee_open_session_arg
|
||||
{
|
||||
rt_uint8_t uuid[16];
|
||||
rt_uint8_t clnt_uuid[16];
|
||||
rt_uint32_t clnt_login;
|
||||
rt_uint32_t cancel_id;
|
||||
rt_uint32_t session;
|
||||
rt_uint32_t ret;
|
||||
rt_uint32_t ret_origin;
|
||||
|
||||
rt_uint32_t params_nr;
|
||||
struct rt_tee_param params[];
|
||||
};
|
||||
|
||||
struct rt_tee_invoke_arg
|
||||
{
|
||||
rt_uint32_t func;
|
||||
rt_uint32_t session;
|
||||
rt_uint32_t cancel_id;
|
||||
rt_uint32_t ret;
|
||||
rt_uint32_t ret_origin;
|
||||
|
||||
rt_uint32_t params_nr;
|
||||
struct rt_tee_param params[];
|
||||
};
|
||||
|
||||
struct rt_tee_ops
|
||||
{
|
||||
rt_err_t (*get_version)(struct rt_tee_device *tdev,
|
||||
struct rt_tee_version *out_version);
|
||||
|
||||
rt_err_t (*open_session)(struct rt_tee_device *tdev,
|
||||
struct rt_tee_open_session_arg *arg);
|
||||
rt_err_t (*close_session)(struct rt_tee_device *tdev, rt_uint32_t session);
|
||||
|
||||
rt_err_t (*invoke)(struct rt_tee_device *tdev,
|
||||
struct rt_tee_invoke_arg *arg);
|
||||
rt_err_t (*cancel)(struct rt_tee_device *tdev,
|
||||
rt_uint32_t session, rt_uint32_t cancel_id);
|
||||
|
||||
rt_err_t (*shm_register)(struct rt_tee_device *tdev, struct rt_tee_shm *shm);
|
||||
rt_err_t (*shm_unregister)(struct rt_tee_device *tdev, struct rt_tee_shm *shm);
|
||||
};
|
||||
|
||||
rt_err_t rt_tee_device_register(struct rt_tee_device *tdev);
|
||||
rt_err_t rt_tee_device_unregister(struct rt_tee_device *tdev);
|
||||
|
||||
rt_err_t rt_tee_get_version(struct rt_tee_device *tdev,
|
||||
struct rt_tee_version *out_version);
|
||||
|
||||
rt_err_t rt_tee_open_session(struct rt_tee_device *tdev,
|
||||
struct rt_tee_open_session_arg *arg);
|
||||
rt_err_t rt_tee_close_session(struct rt_tee_device *tdev, rt_uint32_t session);
|
||||
|
||||
rt_err_t rt_tee_invoke(struct rt_tee_device *tdev,
|
||||
struct rt_tee_invoke_arg *arg);
|
||||
|
||||
rt_err_t rt_tee_cancel(struct rt_tee_device *tdev,
|
||||
rt_uint32_t session, rt_uint32_t cancel_id);
|
||||
|
||||
rt_err_t rt_tee_shm_alloc_helper(struct rt_tee_shm *shm);
|
||||
rt_err_t rt_tee_shm_free_helper(struct rt_tee_shm *shm);
|
||||
rt_err_t rt_tee_shm_register(struct rt_tee_device *tdev, struct rt_tee_shm *shm);
|
||||
rt_err_t rt_tee_shm_unregister(struct rt_tee_device *tdev, struct rt_tee_shm *shm);
|
||||
|
||||
#endif /* __TEE_H__ */
|
||||
@@ -153,6 +153,10 @@ extern "C" {
|
||||
#endif /* RT_FIRMWARE_ARM_SCMI */
|
||||
#endif /* RT_USING_FIRMWARE */
|
||||
|
||||
#ifdef RT_USING_TEE
|
||||
#include "drivers/tee.h"
|
||||
#endif /* RT_USING_TEE */
|
||||
|
||||
#ifdef RT_USING_HWCACHE
|
||||
#include "drivers/hwcache.h"
|
||||
#endif /* RT_USING_HWCACHE */
|
||||
|
||||
Executable
+9
@@ -0,0 +1,9 @@
|
||||
menuconfig RT_USING_TEE
|
||||
bool "Using Trusted Execution Environment (TEE) support"
|
||||
depends on RT_USING_DM
|
||||
default n
|
||||
|
||||
if RT_USING_TEE
|
||||
rsource "optee/Kconfig"
|
||||
osource "$(SOC_DM_TEE_DIR)/Kconfig"
|
||||
endif
|
||||
Executable
+21
@@ -0,0 +1,21 @@
|
||||
from building import *
|
||||
|
||||
group = []
|
||||
|
||||
if not GetDepend(['RT_USING_TEE']):
|
||||
Return('group')
|
||||
|
||||
cwd = GetCurrentDir()
|
||||
list = os.listdir(cwd)
|
||||
CPPPATH = [cwd + '/../include']
|
||||
|
||||
src = ['tee.c']
|
||||
|
||||
group = DefineGroup('DeviceDrivers', src, depend = [''], CPPPATH = CPPPATH)
|
||||
|
||||
for d in list:
|
||||
path = os.path.join(cwd, d)
|
||||
if os.path.isfile(os.path.join(path, 'SConscript')):
|
||||
group = group + SConscript(os.path.join(d, 'SConscript'))
|
||||
|
||||
Return('group')
|
||||
Executable
+11
@@ -0,0 +1,11 @@
|
||||
menuconfig RT_TEE_OPTEE
|
||||
bool "OP-TEE"
|
||||
depends on ARCH_ARM_CORTEX_A || ARCH_ARMV8
|
||||
default n
|
||||
|
||||
config RT_TEE_OPTEE_EXAMPLES
|
||||
bool "Examples"
|
||||
depends on RT_TEE_OPTEE
|
||||
depends on RT_USING_CONSOLE
|
||||
depends on RT_USING_FINSH
|
||||
default y
|
||||
Executable
+18
@@ -0,0 +1,18 @@
|
||||
from building import *
|
||||
|
||||
group = []
|
||||
|
||||
if not GetDepend(['RT_TEE_OPTEE']):
|
||||
Return('group')
|
||||
|
||||
cwd = GetCurrentDir()
|
||||
CPPPATH = [cwd + '/../../include']
|
||||
|
||||
src = ['optee.c']
|
||||
|
||||
if GetDepend(['RT_TEE_OPTEE_EXAMPLES']):
|
||||
src += ['optee_examples.c']
|
||||
|
||||
group = DefineGroup('DeviceDrivers', src, depend = [''], CPPPATH = CPPPATH)
|
||||
|
||||
Return('group')
|
||||
Executable
+876
File diff suppressed because it is too large
Load Diff
+178
@@ -0,0 +1,178 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2023, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2023-04-23 GuEe-GUI first version
|
||||
*/
|
||||
|
||||
#include <rthw.h>
|
||||
#include <rtthread.h>
|
||||
#include <rtdevice.h>
|
||||
|
||||
#define DBG_TAG "optee.examples"
|
||||
#define DBG_LVL DBG_INFO
|
||||
#include <rtdbg.h>
|
||||
|
||||
/*
|
||||
* Build the OP-TEE for your platform with the hwrng TA:
|
||||
* https://optee.readthedocs.io/en/latest/building/devices/qemu.html#qemu-v8
|
||||
*/
|
||||
|
||||
static void optee_uuid_copy(rt_uint8_t *d, struct rt_tee_uuid *s)
|
||||
{
|
||||
d[0] = s->time_low >> 24;
|
||||
d[1] = s->time_low >> 16;
|
||||
d[2] = s->time_low >> 8;
|
||||
d[3] = s->time_low;
|
||||
d[4] = s->time_mid >> 8;
|
||||
d[5] = s->time_mid;
|
||||
d[6] = s->time_hi_and_version >> 8;
|
||||
d[7] = s->time_hi_and_version;
|
||||
|
||||
rt_memcpy(d + 8, s->clock_seq_and_node, sizeof(s->clock_seq_and_node));
|
||||
}
|
||||
|
||||
static struct rt_tee_open_session_arg *open_session_arg_alloc(rt_uint32_t params_nr)
|
||||
{
|
||||
return rt_calloc(1, sizeof(struct rt_tee_open_session_arg) +
|
||||
sizeof(struct rt_tee_param) * params_nr);
|
||||
}
|
||||
|
||||
static void open_session_arg_free(struct rt_tee_open_session_arg *arg)
|
||||
{
|
||||
rt_free(arg);
|
||||
}
|
||||
|
||||
static struct rt_tee_invoke_arg *invoke_arg_alloc(rt_uint32_t params_nr)
|
||||
{
|
||||
return rt_calloc(1, sizeof(struct rt_tee_invoke_arg) +
|
||||
sizeof(struct rt_tee_param) * params_nr);
|
||||
}
|
||||
|
||||
static void invoke_arg_free(struct rt_tee_invoke_arg *arg)
|
||||
{
|
||||
rt_free(arg);
|
||||
}
|
||||
|
||||
static struct rt_tee_device *open_tee_device(char *name)
|
||||
{
|
||||
struct rt_device *dev = rt_device_find(name ? : "tee0");
|
||||
|
||||
if (dev && !rt_device_open(dev, 0))
|
||||
{
|
||||
return rt_container_of(dev, struct rt_tee_device, parent);
|
||||
}
|
||||
|
||||
return RT_NULL;
|
||||
}
|
||||
|
||||
static void close_tee_device(struct rt_tee_device *tdev)
|
||||
{
|
||||
rt_device_close(&tdev->parent);
|
||||
}
|
||||
|
||||
/*
|
||||
* This UUID is generated with uuidgen
|
||||
* the ITU-T UUID generator at http://www.itu.int/ITU-T/asn1/uuid.html
|
||||
*/
|
||||
static int optee_example_rng(int argc, char**argv)
|
||||
{
|
||||
rt_err_t err;
|
||||
struct rt_tee_shm shm;
|
||||
struct rt_tee_device *tdev;
|
||||
struct rt_tee_invoke_arg *invoke;
|
||||
struct rt_tee_open_session_arg *open;
|
||||
struct rt_tee_uuid uuid =
|
||||
{
|
||||
0xab7a617c, 0xb8e7, 0x4d8f,
|
||||
{ 0x83, 0x01, 0xd0, 0x9b, 0x61, 0x03, 0x6b, 0x64 }
|
||||
};
|
||||
|
||||
if (!(tdev = open_tee_device(RT_NULL)))
|
||||
{
|
||||
return -RT_EIO;
|
||||
}
|
||||
|
||||
if (!(open = open_session_arg_alloc(0)))
|
||||
{
|
||||
err = -RT_ENOMEM;
|
||||
goto _close_tee;
|
||||
}
|
||||
|
||||
optee_uuid_copy(open->uuid, &uuid);
|
||||
|
||||
if ((err = rt_tee_open_session(tdev, open)) ||
|
||||
open->ret != RT_TEE_SUCCESS)
|
||||
{
|
||||
if (!err)
|
||||
{
|
||||
err = -RT_ERROR;
|
||||
}
|
||||
goto _free_args;
|
||||
}
|
||||
|
||||
shm.size = 32;
|
||||
shm.align = RT_MM_PAGE_SIZE;
|
||||
shm.flags = TEE_SHM_SYS;
|
||||
|
||||
if ((err = rt_tee_shm_register(tdev, &shm)))
|
||||
{
|
||||
goto _close_session;
|
||||
}
|
||||
|
||||
rt_memset(shm.vaddr, 0, shm.size);
|
||||
|
||||
if (!(invoke = invoke_arg_alloc(1)))
|
||||
{
|
||||
err = -RT_ENOMEM;
|
||||
goto _free_shm;
|
||||
}
|
||||
|
||||
/* TA_CMD_GET_ENTROPY */
|
||||
invoke->func = 0x0;
|
||||
invoke->session = open->session;
|
||||
invoke->cancel_id = 0;
|
||||
invoke->params_nr = 1;
|
||||
|
||||
invoke->params[0].attr = TEE_PARAM_ATTR_TYPE_MEMREF_OUT;
|
||||
invoke->params[0].memref.size = shm.size;
|
||||
invoke->params[0].memref.shm = &shm;
|
||||
invoke->params[0].memref.shm_offs = 0;
|
||||
|
||||
err = rt_tee_invoke(tdev, invoke);
|
||||
|
||||
if (!err && invoke->ret == RT_TEE_SUCCESS)
|
||||
{
|
||||
rt_uint8_t *rng = shm.vaddr;
|
||||
|
||||
for (int i = 0; i < shm.size; ++i)
|
||||
{
|
||||
rt_kprintf("RNG[%02d]: %02x\n", i, rng[i]);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
rt_kprintf("Failed to read RNG: err=%x origin=%x\n", invoke->ret, invoke->ret_origin);
|
||||
}
|
||||
|
||||
invoke_arg_free(invoke);
|
||||
|
||||
_free_shm:
|
||||
rt_tee_shm_unregister(tdev, &shm);
|
||||
rt_tee_shm_free_helper(&shm);
|
||||
|
||||
_close_session:
|
||||
rt_tee_close_session(tdev, open->session);
|
||||
|
||||
_free_args:
|
||||
open_session_arg_free(open);
|
||||
|
||||
_close_tee:
|
||||
close_tee_device(tdev);
|
||||
|
||||
return (int)err;
|
||||
}
|
||||
MSH_CMD_EXPORT(optee_example_rng, optee example rng);
|
||||
Executable
+422
@@ -0,0 +1,422 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2023, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2023-04-23 GuEe-GUI first version
|
||||
*/
|
||||
|
||||
#ifndef __OPTEE_MSG_H__
|
||||
#define __OPTEE_MSG_H__
|
||||
|
||||
#include <drivers/misc.h>
|
||||
|
||||
/*****************************************************************************
|
||||
* Part 1 - formatting of messages
|
||||
*****************************************************************************/
|
||||
|
||||
#define OPTEE_MSG_ATTR_TYPE_NONE 0x0
|
||||
#define OPTEE_MSG_ATTR_TYPE_VALUE_INPUT 0x1
|
||||
#define OPTEE_MSG_ATTR_TYPE_VALUE_OUTPUT 0x2
|
||||
#define OPTEE_MSG_ATTR_TYPE_VALUE_INOUT 0x3
|
||||
#define OPTEE_MSG_ATTR_TYPE_RMEM_INPUT 0x5
|
||||
#define OPTEE_MSG_ATTR_TYPE_RMEM_OUTPUT 0x6
|
||||
#define OPTEE_MSG_ATTR_TYPE_RMEM_INOUT 0x7
|
||||
#define OPTEE_MSG_ATTR_TYPE_TMEM_INPUT 0x9
|
||||
#define OPTEE_MSG_ATTR_TYPE_TMEM_OUTPUT 0xa
|
||||
#define OPTEE_MSG_ATTR_TYPE_TMEM_INOUT 0xb
|
||||
|
||||
#define OPTEE_MSG_ATTR_TYPE_MASK RT_GENMASK(7, 0)
|
||||
|
||||
/*
|
||||
* Meta parameter to be absorbed by the Secure OS and not passed
|
||||
* to the Trusted Application.
|
||||
*
|
||||
* Currently only used with OPTEE_MSG_CMD_OPEN_SESSION.
|
||||
*/
|
||||
#define OPTEE_MSG_ATTR_META RT_BIT(8)
|
||||
|
||||
/*
|
||||
* Pointer to a list of pages used to register user-defined SHM buffer.
|
||||
* Used with OPTEE_MSG_ATTR_TYPE_TMEM_*.
|
||||
* buf_ptr should point to the beginning of the buffer. Buffer will contain
|
||||
* list of page addresses. OP-TEE core can reconstruct contiguous buffer from
|
||||
* that page addresses list. Page addresses are stored as 64 bit values.
|
||||
* Last entry on a page should point to the next page of buffer.
|
||||
* Every entry in buffer should point to a 4k page beginning (12 least
|
||||
* significant bits must be equal to zero).
|
||||
*
|
||||
* 12 least significant bints of optee_msg_param.tmem.buf_ptr should hold page
|
||||
* offset of the user buffer.
|
||||
*
|
||||
* So, entries should be placed like members of this structure:
|
||||
*
|
||||
* struct page_data {
|
||||
* uint64_t pages_array[OPTEE_MSG_NONCONTIG_PAGE_SIZE/sizeof(uint64_t) - 1];
|
||||
* uint64_t next_page_data;
|
||||
* };
|
||||
*
|
||||
* Structure is designed to exactly fit into the page size
|
||||
* OPTEE_MSG_NONCONTIG_PAGE_SIZE which is a standard 4KB page.
|
||||
*
|
||||
* The size of 4KB is chosen because this is the smallest page size for ARM
|
||||
* architectures. If REE uses larger pages, it should divide them to 4KB ones.
|
||||
*/
|
||||
#define OPTEE_MSG_ATTR_NONCONTIG RT_BIT(9)
|
||||
|
||||
/*
|
||||
* Memory attributes for caching passed with temp memrefs. The actual value
|
||||
* used is defined outside the message protocol with the exception of
|
||||
* OPTEE_MSG_ATTR_CACHE_PREDEFINED which means the attributes already
|
||||
* defined for the memory range should be used. If optee_smc.h is used as
|
||||
* bearer of this protocol OPTEE_SMC_SHM_* is used for values.
|
||||
*/
|
||||
#define OPTEE_MSG_ATTR_CACHE_SHIFT 16
|
||||
#define OPTEE_MSG_ATTR_CACHE_MASK RT_GENMASK(2, 0)
|
||||
#define OPTEE_MSG_ATTR_CACHE_PREDEFINED 0
|
||||
|
||||
/*
|
||||
* Page size used in non-contiguous buffer entries
|
||||
*/
|
||||
#define OPTEE_MSG_NONCONTIG_PAGE_SIZE 4096
|
||||
|
||||
/**
|
||||
* struct optee_msg_param_tmem - temporary memory reference parameter
|
||||
* @buf_ptr: Address of the buffer
|
||||
* @size: Size of the buffer
|
||||
* @shm_ref: Temporary shared memory reference, pointer to a struct tee_shm
|
||||
*
|
||||
* Secure and normal world communicates pointers as physical address
|
||||
* instead of the virtual address. This is because secure and normal world
|
||||
* have completely independent memory mapping. Normal world can even have a
|
||||
* hypervisor which need to translate the guest physical address (AKA IPA
|
||||
* in ARM documentation) to a real physical address before passing the
|
||||
* structure to secure world.
|
||||
*/
|
||||
struct optee_msg_param_tmem
|
||||
{
|
||||
rt_uint64_t buf_ptr;
|
||||
rt_uint64_t size;
|
||||
rt_uint64_t shm_ref;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct optee_msg_param_rmem - registered memory reference parameter
|
||||
* @offs: Offset into shared memory reference
|
||||
* @size: Size of the buffer
|
||||
* @shm_ref: Shared memory reference, pointer to a struct tee_shm
|
||||
*/
|
||||
struct optee_msg_param_rmem
|
||||
{
|
||||
rt_uint64_t offs;
|
||||
rt_uint64_t size;
|
||||
rt_uint64_t shm_ref;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct optee_msg_param_value - opaque value parameter
|
||||
*
|
||||
* Value parameters are passed unchecked between normal and secure world.
|
||||
*/
|
||||
struct optee_msg_param_value
|
||||
{
|
||||
rt_uint64_t a;
|
||||
rt_uint64_t b;
|
||||
rt_uint64_t c;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct optee_msg_param - parameter used together with struct optee_msg_arg
|
||||
* @attr: attributes
|
||||
* @tmem: parameter by temporary memory reference
|
||||
* @rmem: parameter by registered memory reference
|
||||
* @value: parameter by opaque value
|
||||
*
|
||||
* @attr & OPTEE_MSG_ATTR_TYPE_MASK indicates if tmem, rmem or value is used in
|
||||
* the union. OPTEE_MSG_ATTR_TYPE_VALUE_* indicates value,
|
||||
* OPTEE_MSG_ATTR_TYPE_TMEM_* indicates @tmem and
|
||||
* OPTEE_MSG_ATTR_TYPE_RMEM_* indicates @rmem,
|
||||
* OPTEE_MSG_ATTR_TYPE_NONE indicates that none of the members are used.
|
||||
*/
|
||||
struct optee_msg_param
|
||||
{
|
||||
rt_uint64_t attr;
|
||||
|
||||
union
|
||||
{
|
||||
struct optee_msg_param_tmem tmem;
|
||||
struct optee_msg_param_rmem rmem;
|
||||
struct optee_msg_param_value value;
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* struct optee_msg_arg - call argument
|
||||
* @cmd: Command, one of OPTEE_MSG_CMD_* or OPTEE_MSG_RPC_CMD_*
|
||||
* @func: Trusted Application function, specific to the Trusted Application,
|
||||
* used if cmd == OPTEE_MSG_CMD_INVOKE_COMMAND
|
||||
* @session: In parameter for all OPTEE_MSG_CMD_* except
|
||||
* OPTEE_MSG_CMD_OPEN_SESSION where it's an output parameter instead
|
||||
* @cancel_id: Cancellation id, a unique value to identify this request
|
||||
* @ret: return value
|
||||
* @ret_origin: origin of the return value
|
||||
* @params_nr: number of parameters supplied to the OS Command
|
||||
* @params: the parameters supplied to the OS Command
|
||||
*
|
||||
* All normal calls to Trusted OS uses this struct. If cmd requires further
|
||||
* information than what these field holds it can be passed as a parameter
|
||||
* tagged as meta (setting the OPTEE_MSG_ATTR_META bit in corresponding
|
||||
* attrs field). All parameters tagged as meta has to come first.
|
||||
*
|
||||
* Temp memref parameters can be fragmented if supported by the Trusted OS
|
||||
* (when optee_smc.h is bearer of this protocol this is indicated with
|
||||
* OPTEE_SMC_SEC_CAP_UNREGISTERED_SHM). If a logical memref parameter is
|
||||
* fragmented then has all but the last fragment the
|
||||
* OPTEE_MSG_ATTR_FRAGMENT bit set in attrs. Even if a memref is fragmented
|
||||
* it will still be presented as a single logical memref to the Trusted
|
||||
* Application.
|
||||
*/
|
||||
struct optee_msg_arg
|
||||
{
|
||||
rt_uint32_t cmd;
|
||||
rt_uint32_t func;
|
||||
rt_uint32_t session;
|
||||
rt_uint32_t cancel_id;
|
||||
rt_uint32_t pad;
|
||||
rt_uint32_t ret;
|
||||
rt_uint32_t ret_origin;
|
||||
|
||||
rt_uint32_t params_nr;
|
||||
struct optee_msg_param params[0];
|
||||
};
|
||||
|
||||
/**
|
||||
* OPTEE_MSG_GET_ARG_SIZE - return size of struct optee_msg_arg
|
||||
*
|
||||
* @params_nr: Number of parameters embedded in the struct optee_msg_arg
|
||||
*
|
||||
* Returns the size of the struct optee_msg_arg together with the number
|
||||
* of embedded parameters.
|
||||
*/
|
||||
#define OPTEE_MSG_GET_ARG_SIZE(params_nr) \
|
||||
(sizeof(struct optee_msg_arg) + sizeof(struct optee_msg_param) * (params_nr))
|
||||
|
||||
/*****************************************************************************
|
||||
* Part 2 - requests from normal world
|
||||
*****************************************************************************/
|
||||
|
||||
/*
|
||||
* Return the following UID if using API specified in this file without
|
||||
* further extensions:
|
||||
* 384fb3e0-e7f8-11e3-af63-0002a5d5c51b.
|
||||
* Represented in 4 32-bit words in OPTEE_MSG_UID_0, OPTEE_MSG_UID_1,
|
||||
* OPTEE_MSG_UID_2, OPTEE_MSG_UID_3.
|
||||
*/
|
||||
#define OPTEE_MSG_UID_0 0x384fb3e0
|
||||
#define OPTEE_MSG_UID_1 0xe7f811e3
|
||||
#define OPTEE_MSG_UID_2 0xaf630002
|
||||
#define OPTEE_MSG_UID_3 0xa5d5c51b
|
||||
#define OPTEE_MSG_FUNCID_CALLS_UID 0xff01
|
||||
|
||||
/*
|
||||
* Returns 2.0 if using API specified in this file without further
|
||||
* extensions. Represented in 2 32-bit words in OPTEE_MSG_REVISION_MAJOR
|
||||
* and OPTEE_MSG_REVISION_MINOR
|
||||
*/
|
||||
#define OPTEE_MSG_REVISION_MAJOR 2
|
||||
#define OPTEE_MSG_REVISION_MINOR 0
|
||||
#define OPTEE_MSG_FUNCID_CALLS_REVISION 0xff03
|
||||
|
||||
/*
|
||||
* Get UUID of Trusted OS.
|
||||
*
|
||||
* Used by non-secure world to figure out which Trusted OS is installed.
|
||||
* Note that returned UUID is the UUID of the Trusted OS, not of the API.
|
||||
*
|
||||
* Returns UUID in 4 32-bit words in the same way as
|
||||
* OPTEE_MSG_FUNCID_CALLS_UID described above.
|
||||
*/
|
||||
#define OPTEE_MSG_OS_OPTEE_UUID_0 0x486178e0
|
||||
#define OPTEE_MSG_OS_OPTEE_UUID_1 0xe7f811e3
|
||||
#define OPTEE_MSG_OS_OPTEE_UUID_2 0xbc5e0002
|
||||
#define OPTEE_MSG_OS_OPTEE_UUID_3 0xa5d5c51b
|
||||
#define OPTEE_MSG_FUNCID_GET_OS_UUID 0x0000
|
||||
|
||||
/*
|
||||
* Get revision of Trusted OS.
|
||||
*
|
||||
* Used by non-secure world to figure out which version of the Trusted OS
|
||||
* is installed. Note that the returned revision is the revision of the
|
||||
* Trusted OS, not of the API.
|
||||
*
|
||||
* Returns revision in 2 32-bit words in the same way as
|
||||
* OPTEE_MSG_CALLS_REVISION described above.
|
||||
*/
|
||||
#define OPTEE_MSG_FUNCID_GET_OS_REVISION 0x0001
|
||||
|
||||
/*
|
||||
* Do a secure call with struct optee_msg_arg as argument
|
||||
* The OPTEE_MSG_CMD_* below defines what goes in struct optee_msg_arg::cmd
|
||||
*
|
||||
* OPTEE_MSG_CMD_OPEN_SESSION opens a session to a Trusted Application.
|
||||
* The first two parameters are tagged as meta, holding two value
|
||||
* parameters to pass the following information:
|
||||
* param[0].value.a-b uuid of Trusted Application
|
||||
* param[1].value.a-b uuid of Client
|
||||
* param[1].value.c Login class of client TEE_LOGIN_*
|
||||
*
|
||||
* OPTEE_MSG_CMD_INVOKE_COMMAND invokes a command a previously opened
|
||||
* session to a Trusted Application. struct optee_msg_arg::func is Trusted
|
||||
* Application function, specific to the Trusted Application.
|
||||
*
|
||||
* OPTEE_MSG_CMD_CLOSE_SESSION closes a previously opened session to
|
||||
* Trusted Application.
|
||||
*
|
||||
* OPTEE_MSG_CMD_CANCEL cancels a currently invoked command.
|
||||
*
|
||||
* OPTEE_MSG_CMD_REGISTER_SHM registers a shared memory reference. The
|
||||
* information is passed as:
|
||||
* [in] param[0].attr OPTEE_MSG_ATTR_TYPE_TMEM_INPUT
|
||||
* [| OPTEE_MSG_ATTR_FRAGMENT]
|
||||
* [in] param[0].tmem.buf_ptr physical address (of first fragment)
|
||||
* [in] param[0].tmem.size size (of first fragment)
|
||||
* [in] param[0].tmem.shm_ref holds shared memory reference
|
||||
* ...
|
||||
* The shared memory can optionally be fragmented, temp memrefs can follow
|
||||
* each other with all but the last with the OPTEE_MSG_ATTR_FRAGMENT bit set.
|
||||
*
|
||||
* OPTEE_MSG_CMD_UNREGISTER_SHM unregisteres a previously registered shared
|
||||
* memory reference. The information is passed as:
|
||||
* [in] param[0].attr OPTEE_MSG_ATTR_TYPE_RMEM_INPUT
|
||||
* [in] param[0].rmem.shm_ref holds shared memory reference
|
||||
* [in] param[0].rmem.offs 0
|
||||
* [in] param[0].rmem.size 0
|
||||
*/
|
||||
#define OPTEE_MSG_CMD_OPEN_SESSION 0
|
||||
#define OPTEE_MSG_CMD_INVOKE_COMMAND 1
|
||||
#define OPTEE_MSG_CMD_CLOSE_SESSION 2
|
||||
#define OPTEE_MSG_CMD_CANCEL 3
|
||||
#define OPTEE_MSG_CMD_REGISTER_SHM 4
|
||||
#define OPTEE_MSG_CMD_UNREGISTER_SHM 5
|
||||
#define OPTEE_MSG_FUNCID_CALL_WITH_ARG 0x0004
|
||||
|
||||
/*****************************************************************************
|
||||
* Part 3 - Requests from secure world, RPC
|
||||
*****************************************************************************/
|
||||
|
||||
/*
|
||||
* All RPC is done with a struct optee_msg_arg as bearer of information,
|
||||
* struct optee_msg_arg::arg holds values defined by OPTEE_MSG_RPC_CMD_* below
|
||||
*
|
||||
* RPC communication with tee-supplicant is reversed compared to normal
|
||||
* client communication desribed above. The supplicant receives requests
|
||||
* and sends responses.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Load a TA into memory, defined in tee-supplicant
|
||||
*/
|
||||
#define OPTEE_MSG_RPC_CMD_LOAD_TA 0
|
||||
|
||||
/*
|
||||
* Get time
|
||||
*
|
||||
* Returns number of seconds and nano seconds since the Epoch,
|
||||
* 1970-01-01 00:00:00 +0000 (UTC).
|
||||
*
|
||||
* [out] param[0].value.a Number of seconds
|
||||
* [out] param[0].value.b Number of nano seconds.
|
||||
*/
|
||||
#define OPTEE_MSG_RPC_CMD_GET_TIME 3
|
||||
|
||||
/*
|
||||
* Wait queue primitive, helper for secure world to implement a wait queue.
|
||||
*
|
||||
* If secure world need to wait for a secure world mutex it issues a sleep
|
||||
* request instead of spinning in secure world. Conversely is a wakeup
|
||||
* request issued when a secure world mutex with a thread waiting thread is
|
||||
* unlocked.
|
||||
*
|
||||
* Waiting on a key
|
||||
* [in] param[0].value.a OPTEE_MSG_RPC_WAIT_QUEUE_SLEEP
|
||||
* [in] param[0].value.b wait key
|
||||
*
|
||||
* Waking up a key
|
||||
* [in] param[0].value.a OPTEE_MSG_RPC_WAIT_QUEUE_WAKEUP
|
||||
* [in] param[0].value.b wakeup key
|
||||
*/
|
||||
#define OPTEE_MSG_RPC_CMD_WAIT_QUEUE 4
|
||||
#define OPTEE_MSG_RPC_WAIT_QUEUE_SLEEP 0
|
||||
#define OPTEE_MSG_RPC_WAIT_QUEUE_WAKEUP 1
|
||||
|
||||
/*
|
||||
* Suspend execution
|
||||
*
|
||||
* [in] param[0].value .a number of milliseconds to suspend
|
||||
*/
|
||||
#define OPTEE_MSG_RPC_CMD_SUSPEND 5
|
||||
|
||||
/*
|
||||
* Allocate a piece of shared memory
|
||||
*
|
||||
* Shared memory can optionally be fragmented, to support that additional
|
||||
* spare param entries are allocated to make room for eventual fragments.
|
||||
* The spare param entries has .attr = OPTEE_MSG_ATTR_TYPE_NONE when
|
||||
* unused. All returned temp memrefs except the last should have the
|
||||
* OPTEE_MSG_ATTR_FRAGMENT bit set in the attr field.
|
||||
*
|
||||
* [in] param[0].value.a type of memory one of
|
||||
* OPTEE_MSG_RPC_SHM_TYPE_* below
|
||||
* [in] param[0].value.b requested size
|
||||
* [in] param[0].value.c required alignment
|
||||
*
|
||||
* [out] param[0].tmem.buf_ptr physical address (of first fragment)
|
||||
* [out] param[0].tmem.size size (of first fragment)
|
||||
* [out] param[0].tmem.shm_ref shared memory reference
|
||||
* ...
|
||||
* [out] param[n].tmem.buf_ptr physical address
|
||||
* [out] param[n].tmem.size size
|
||||
* [out] param[n].tmem.shm_ref shared memory reference (same value
|
||||
* as in param[n-1].tmem.shm_ref)
|
||||
*/
|
||||
#define OPTEE_MSG_RPC_CMD_SHM_ALLOC 6
|
||||
/* Memory that can be shared with a non-secure user space application */
|
||||
#define OPTEE_MSG_RPC_SHM_TYPE_APPL 0
|
||||
/* Memory only shared with non-secure kernel */
|
||||
#define OPTEE_MSG_RPC_SHM_TYPE_KERNEL 1
|
||||
|
||||
/*
|
||||
* Free shared memory previously allocated with OPTEE_MSG_RPC_CMD_SHM_ALLOC
|
||||
*
|
||||
* [in] param[0].value.a type of memory one of
|
||||
* OPTEE_MSG_RPC_SHM_TYPE_* above
|
||||
* [in] param[0].value.b value of shared memory reference
|
||||
* returned in param[0].tmem.shm_ref
|
||||
* above
|
||||
*/
|
||||
#define OPTEE_MSG_RPC_CMD_SHM_FREE 7
|
||||
|
||||
/*
|
||||
* Access a device on an i2c bus
|
||||
*
|
||||
* [in] param[0].value.a mode: RD(0), WR(1)
|
||||
* [in] param[0].value.b i2c adapter
|
||||
* [in] param[0].value.c i2c chip
|
||||
*
|
||||
* [in] param[1].value.a i2c control flags
|
||||
*
|
||||
* [in/out] memref[2] buffer to exchange the transfer data
|
||||
* with the secure world
|
||||
*
|
||||
* [out] param[3].value.a bytes transferred by the driver
|
||||
*/
|
||||
#define OPTEE_MSG_RPC_CMD_I2C_TRANSFER 21
|
||||
/* I2C master transfer modes */
|
||||
#define OPTEE_MSG_RPC_CMD_I2C_TRANSFER_RD 0
|
||||
#define OPTEE_MSG_RPC_CMD_I2C_TRANSFER_WR 1
|
||||
/* I2C master control flags */
|
||||
#define OPTEE_MSG_RPC_CMD_I2C_FLAGS_TEN_BIT RT_BIT(0)
|
||||
|
||||
#endif /* __OPTEE_MSG_H__ */
|
||||
Executable
+476
@@ -0,0 +1,476 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2023, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2023-04-23 GuEe-GUI first version
|
||||
*/
|
||||
|
||||
#ifndef __OPTEE_SMC_H__
|
||||
#define __OPTEE_SMC_H__
|
||||
|
||||
#include <drivers/misc.h>
|
||||
|
||||
#ifndef ARM_SMCCC
|
||||
#define ARM_SMCCC_STD_CALL 0U
|
||||
#define ARM_SMCCC_FAST_CALL 1U
|
||||
#define ARM_SMCCC_TYPE_SHIFT 31
|
||||
|
||||
#define ARM_SMCCC_SMC_32 0
|
||||
#define ARM_SMCCC_SMC_64 1
|
||||
#define ARM_SMCCC_CALL_CONV_SHIFT 30
|
||||
|
||||
#define ARM_SMCCC_OWNER_MASK 0x3f
|
||||
#define ARM_SMCCC_OWNER_SHIFT 24
|
||||
|
||||
#define ARM_SMCCC_FUNC_MASK 0xffff
|
||||
|
||||
#define ARM_SMCCC_CALL_VAL(type, calling_convention, owner, func_num) \
|
||||
(((type) << ARM_SMCCC_TYPE_SHIFT) | \
|
||||
((calling_convention) << ARM_SMCCC_CALL_CONV_SHIFT) | \
|
||||
(((owner) & ARM_SMCCC_OWNER_MASK) << ARM_SMCCC_OWNER_SHIFT) | \
|
||||
((func_num) & ARM_SMCCC_FUNC_MASK))
|
||||
|
||||
#define ARM_SMCCC_OWNER_ARCH 0
|
||||
#define ARM_SMCCC_OWNER_CPU 1
|
||||
#define ARM_SMCCC_OWNER_SIP 2
|
||||
#define ARM_SMCCC_OWNER_OEM 3
|
||||
#define ARM_SMCCC_OWNER_STANDARD 4
|
||||
#define ARM_SMCCC_OWNER_TRUSTED_APP 48
|
||||
#define ARM_SMCCC_OWNER_TRUSTED_APP_END 49
|
||||
#define ARM_SMCCC_OWNER_TRUSTED_OS 50
|
||||
#define ARM_SMCCC_OWNER_TRUSTED_OS_END 63
|
||||
#endif /* ARM_SMCCC */
|
||||
|
||||
#define OPTEE_SMC_STD_CALL_VAL(func_num) \
|
||||
ARM_SMCCC_CALL_VAL(ARM_SMCCC_STD_CALL, \
|
||||
ARM_SMCCC_SMC_32, \
|
||||
ARM_SMCCC_OWNER_TRUSTED_OS, \
|
||||
(func_num))
|
||||
#define OPTEE_SMC_FAST_CALL_VAL(func_num) \
|
||||
ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \
|
||||
ARM_SMCCC_SMC_32, \
|
||||
ARM_SMCCC_OWNER_TRUSTED_OS, \
|
||||
(func_num))
|
||||
|
||||
/*
|
||||
* Function specified by SMC Calling convention.
|
||||
*/
|
||||
#define OPTEE_SMC_FUNCID_CALLS_COUNT 0xff00
|
||||
#define OPTEE_SMC_CALLS_COUNT \
|
||||
ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \
|
||||
ARM_SMCCC_SMC_32, \
|
||||
ARM_SMCCC_OWNER_TRUSTED_OS_END, \
|
||||
OPTEE_SMC_FUNCID_CALLS_COUNT)
|
||||
|
||||
/*
|
||||
* Normal cached memory (write-back), shareable for SMP systems and not
|
||||
* shareable for UP systems.
|
||||
*/
|
||||
#define OPTEE_SMC_SHM_CACHED 1
|
||||
|
||||
/*
|
||||
* a0..a7 is used as register names in the descriptions below, on arm32
|
||||
* that translates to r0..r7 and on arm64 to w0..w7. In both cases it's
|
||||
* 32-bit registers.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Function specified by SMC Calling convention
|
||||
*
|
||||
* Return one of the following UIDs if using API specified in this file
|
||||
* without further extentions:
|
||||
* 65cb6b93-af0c-4617-8ed6-644a8d1140f8
|
||||
* see also OPTEE_SMC_UID_* in optee_msg.h
|
||||
*/
|
||||
#define OPTEE_SMC_FUNCID_CALLS_UID OPTEE_MSG_FUNCID_CALLS_UID
|
||||
#define OPTEE_SMC_CALLS_UID \
|
||||
ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \
|
||||
ARM_SMCCC_SMC_32, \
|
||||
ARM_SMCCC_OWNER_TRUSTED_OS_END, \
|
||||
OPTEE_SMC_FUNCID_CALLS_UID)
|
||||
|
||||
/*
|
||||
* Function specified by SMC Calling convention
|
||||
*
|
||||
* Returns 2.0 if using API specified in this file without further extentions.
|
||||
* see also OPTEE_MSG_REVISION_* in optee_msg.h
|
||||
*/
|
||||
#define OPTEE_SMC_FUNCID_CALLS_REVISION OPTEE_MSG_FUNCID_CALLS_REVISION
|
||||
#define OPTEE_SMC_CALLS_REVISION \
|
||||
ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \
|
||||
ARM_SMCCC_SMC_32, \
|
||||
ARM_SMCCC_OWNER_TRUSTED_OS_END, \
|
||||
OPTEE_SMC_FUNCID_CALLS_REVISION)
|
||||
|
||||
struct optee_smc_calls_revision_result
|
||||
{
|
||||
unsigned long major;
|
||||
unsigned long minor;
|
||||
unsigned long reserved0;
|
||||
unsigned long reserved1;
|
||||
};
|
||||
|
||||
/*
|
||||
* Get UUID of Trusted OS.
|
||||
*
|
||||
* Used by non-secure world to figure out which Trusted OS is installed.
|
||||
* Note that returned UUID is the UUID of the Trusted OS, not of the API.
|
||||
*
|
||||
* Returns UUID in a0-4 in the same way as OPTEE_SMC_CALLS_UID
|
||||
* described above.
|
||||
*/
|
||||
#define OPTEE_SMC_FUNCID_GET_OS_UUID OPTEE_MSG_FUNCID_GET_OS_UUID
|
||||
#define OPTEE_SMC_CALL_GET_OS_UUID OPTEE_SMC_FAST_CALL_VAL(OPTEE_SMC_FUNCID_GET_OS_UUID)
|
||||
|
||||
/*
|
||||
* Get revision of Trusted OS.
|
||||
*
|
||||
* Used by non-secure world to figure out which version of the Trusted OS
|
||||
* is installed. Note that the returned revision is the revision of the
|
||||
* Trusted OS, not of the API.
|
||||
*
|
||||
* Returns revision in a0-1 in the same way as OPTEE_SMC_CALLS_REVISION
|
||||
* described above. May optionally return a 32-bit build identifier in a2,
|
||||
* with zero meaning unspecified.
|
||||
*/
|
||||
#define OPTEE_SMC_FUNCID_GET_OS_REVISION OPTEE_MSG_FUNCID_GET_OS_REVISION
|
||||
#define OPTEE_SMC_CALL_GET_OS_REVISION OPTEE_SMC_FAST_CALL_VAL(OPTEE_SMC_FUNCID_GET_OS_REVISION)
|
||||
|
||||
struct optee_smc_call_get_os_revision_result
|
||||
{
|
||||
unsigned long major;
|
||||
unsigned long minor;
|
||||
unsigned long build_id;
|
||||
unsigned long reserved1;
|
||||
};
|
||||
|
||||
/*
|
||||
* Call with struct optee_msg_arg as argument
|
||||
*
|
||||
* Call register usage:
|
||||
* a0 SMC Function ID, OPTEE_SMC*CALL_WITH_ARG
|
||||
* a1 Upper 32bit of a 64bit physical pointer to a struct optee_msg_arg
|
||||
* a2 Lower 32bit of a 64bit physical pointer to a struct optee_msg_arg
|
||||
* a3 Cache settings, not used if physical pointer is in a predefined shared
|
||||
* memory area else per OPTEE_SMC_SHM_*
|
||||
* a4-6 Not used
|
||||
* a7 Hypervisor Client ID register
|
||||
*
|
||||
* Normal return register usage:
|
||||
* a0 Return value, OPTEE_SMC_RETURN_*
|
||||
* a1-3 Not used
|
||||
* a4-7 Preserved
|
||||
*
|
||||
* OPTEE_SMC_RETURN_ETHREAD_LIMIT return register usage:
|
||||
* a0 Return value, OPTEE_SMC_RETURN_ETHREAD_LIMIT
|
||||
* a1-3 Preserved
|
||||
* a4-7 Preserved
|
||||
*
|
||||
* RPC return register usage:
|
||||
* a0 Return value, OPTEE_SMC_RETURN_IS_RPC(val)
|
||||
* a1-2 RPC parameters
|
||||
* a3-7 Resume information, must be preserved
|
||||
*
|
||||
* Possible return values:
|
||||
* OPTEE_SMC_RETURN_UNKNOWN_FUNCTION Trusted OS does not recognize this
|
||||
* function.
|
||||
* OPTEE_SMC_RETURN_OK Call completed, result updated in
|
||||
* the previously supplied struct
|
||||
* optee_msg_arg.
|
||||
* OPTEE_SMC_RETURN_ETHREAD_LIMIT Number of Trusted OS threads exceeded,
|
||||
* try again later.
|
||||
* OPTEE_SMC_RETURN_EBADADDR Bad physcial pointer to struct
|
||||
* optee_msg_arg.
|
||||
* OPTEE_SMC_RETURN_EBADCMD Bad/unknown cmd in struct optee_msg_arg
|
||||
* OPTEE_SMC_RETURN_IS_RPC() Call suspended by RPC call to normal
|
||||
* world.
|
||||
*/
|
||||
#define OPTEE_SMC_FUNCID_CALL_WITH_ARG OPTEE_MSG_FUNCID_CALL_WITH_ARG
|
||||
#define OPTEE_SMC_CALL_WITH_ARG OPTEE_SMC_STD_CALL_VAL(OPTEE_SMC_FUNCID_CALL_WITH_ARG)
|
||||
|
||||
/*
|
||||
* Get Shared Memory Config
|
||||
*
|
||||
* Returns the Secure/Non-secure shared memory config.
|
||||
*
|
||||
* Call register usage:
|
||||
* a0 SMC Function ID, OPTEE_SMC_GET_SHM_CONFIG
|
||||
* a1-6 Not used
|
||||
* a7 Hypervisor Client ID register
|
||||
*
|
||||
* Have config return register usage:
|
||||
* a0 OPTEE_SMC_RETURN_OK
|
||||
* a1 Physical address of start of SHM
|
||||
* a2 Size of of SHM
|
||||
* a3 Cache settings of memory, as defined by the
|
||||
* OPTEE_SMC_SHM_* values above
|
||||
* a4-7 Preserved
|
||||
*
|
||||
* Not available register usage:
|
||||
* a0 OPTEE_SMC_RETURN_ENOTAVAIL
|
||||
* a1-3 Not used
|
||||
* a4-7 Preserved
|
||||
*/
|
||||
#define OPTEE_SMC_FUNCID_GET_SHM_CONFIG 7
|
||||
#define OPTEE_SMC_GET_SHM_CONFIG OPTEE_SMC_FAST_CALL_VAL(OPTEE_SMC_FUNCID_GET_SHM_CONFIG)
|
||||
|
||||
struct optee_smc_get_shm_config_result
|
||||
{
|
||||
unsigned long status;
|
||||
unsigned long start;
|
||||
unsigned long size;
|
||||
unsigned long settings;
|
||||
};
|
||||
|
||||
/*
|
||||
* Exchanges capabilities between normal world and secure world
|
||||
*
|
||||
* Call register usage:
|
||||
* a0 SMC Function ID, OPTEE_SMC_EXCHANGE_CAPABILITIES
|
||||
* a1 bitfield of normal world capabilities OPTEE_SMC_NSEC_CAP_*
|
||||
* a2-6 Not used
|
||||
* a7 Hypervisor Client ID register
|
||||
*
|
||||
* Normal return register usage:
|
||||
* a0 OPTEE_SMC_RETURN_OK
|
||||
* a1 bitfield of secure world capabilities OPTEE_SMC_SEC_CAP_*
|
||||
* a2-7 Preserved
|
||||
*
|
||||
* Error return register usage:
|
||||
* a0 OPTEE_SMC_RETURN_ENOTAVAIL, can't use the capabilities from normal world
|
||||
* a1 bitfield of secure world capabilities OPTEE_SMC_SEC_CAP_*
|
||||
* a2-7 Preserved
|
||||
*/
|
||||
/* Normal world works as a uniprocessor system */
|
||||
#define OPTEE_SMC_NSEC_CAP_UNIPROCESSOR RT_BIT(0)
|
||||
/* Secure world has reserved shared memory for normal world to use */
|
||||
#define OPTEE_SMC_SEC_CAP_HAVE_RESERVED_SHM RT_BIT(0)
|
||||
/* Secure world can communicate via previously unregistered shared memory */
|
||||
#define OPTEE_SMC_SEC_CAP_UNREGISTERED_SHM RT_BIT(1)
|
||||
|
||||
/*
|
||||
* Secure world supports commands "register/unregister shared memory",
|
||||
* secure world accepts command buffers located in any parts of non-secure RAM
|
||||
*/
|
||||
#define OPTEE_SMC_SEC_CAP_DYNAMIC_SHM RT_BIT(2)
|
||||
|
||||
#define OPTEE_SMC_FUNCID_EXCHANGE_CAPABILITIES 9
|
||||
#define OPTEE_SMC_EXCHANGE_CAPABILITIES OPTEE_SMC_FAST_CALL_VAL(OPTEE_SMC_FUNCID_EXCHANGE_CAPABILITIES)
|
||||
|
||||
struct optee_smc_exchange_capabilities_result
|
||||
{
|
||||
unsigned long status;
|
||||
unsigned long capabilities;
|
||||
unsigned long reserved0;
|
||||
unsigned long reserved1;
|
||||
};
|
||||
|
||||
/*
|
||||
* Disable and empties cache of shared memory objects
|
||||
*
|
||||
* Secure world can cache frequently used shared memory objects, for
|
||||
* example objects used as RPC arguments. When secure world is idle this
|
||||
* function returns one shared memory reference to free. To disable the
|
||||
* cache and free all cached objects this function has to be called until
|
||||
* it returns OPTEE_SMC_RETURN_ENOTAVAIL.
|
||||
*
|
||||
* Call register usage:
|
||||
* a0 SMC Function ID, OPTEE_SMC_DISABLE_SHM_CACHE
|
||||
* a1-6 Not used
|
||||
* a7 Hypervisor Client ID register
|
||||
*
|
||||
* Normal return register usage:
|
||||
* a0 OPTEE_SMC_RETURN_OK
|
||||
* a1 Upper 32bit of a 64bit Shared memory cookie
|
||||
* a2 Lower 32bit of a 64bit Shared memory cookie
|
||||
* a3-7 Preserved
|
||||
*
|
||||
* Cache empty return register usage:
|
||||
* a0 OPTEE_SMC_RETURN_ENOTAVAIL
|
||||
* a1-7 Preserved
|
||||
*
|
||||
* Not idle return register usage:
|
||||
* a0 OPTEE_SMC_RETURN_EBUSY
|
||||
* a1-7 Preserved
|
||||
*/
|
||||
#define OPTEE_SMC_FUNCID_DISABLE_SHM_CACHE 10
|
||||
#define OPTEE_SMC_DISABLE_SHM_CACHE OPTEE_SMC_FAST_CALL_VAL(OPTEE_SMC_FUNCID_DISABLE_SHM_CACHE)
|
||||
|
||||
struct optee_smc_disable_shm_cache_result
|
||||
{
|
||||
unsigned long status;
|
||||
unsigned long shm_upper32;
|
||||
unsigned long shm_lower32;
|
||||
unsigned long reserved0;
|
||||
};
|
||||
|
||||
/*
|
||||
* Enable cache of shared memory objects
|
||||
*
|
||||
* Secure world can cache frequently used shared memory objects, for
|
||||
* example objects used as RPC arguments. When secure world is idle this
|
||||
* function returns OPTEE_SMC_RETURN_OK and the cache is enabled. If
|
||||
* secure world isn't idle OPTEE_SMC_RETURN_EBUSY is returned.
|
||||
*
|
||||
* Call register usage:
|
||||
* a0 SMC Function ID, OPTEE_SMC_ENABLE_SHM_CACHE
|
||||
* a1-6 Not used
|
||||
* a7 Hypervisor Client ID register
|
||||
*
|
||||
* Normal return register usage:
|
||||
* a0 OPTEE_SMC_RETURN_OK
|
||||
* a1-7 Preserved
|
||||
*
|
||||
* Not idle return register usage:
|
||||
* a0 OPTEE_SMC_RETURN_EBUSY
|
||||
* a1-7 Preserved
|
||||
*/
|
||||
#define OPTEE_SMC_FUNCID_ENABLE_SHM_CACHE 11
|
||||
#define OPTEE_SMC_ENABLE_SHM_CACHE OPTEE_SMC_FAST_CALL_VAL(OPTEE_SMC_FUNCID_ENABLE_SHM_CACHE)
|
||||
|
||||
/*
|
||||
* Resume from RPC (for example after processing a foreign interrupt)
|
||||
*
|
||||
* Call register usage:
|
||||
* a0 SMC Function ID, OPTEE_SMC_CALL_RETURN_FROM_RPC
|
||||
* a1-3 Value of a1-3 when OPTEE_SMC_CALL_WITH_ARG returned
|
||||
* OPTEE_SMC_RETURN_RPC in a0
|
||||
*
|
||||
* Return register usage is the same as for OPTEE_SMC_*CALL_WITH_ARG above.
|
||||
*
|
||||
* Possible return values
|
||||
* OPTEE_SMC_RETURN_UNKNOWN_FUNCTION Trusted OS does not recognize this
|
||||
* function.
|
||||
* OPTEE_SMC_RETURN_OK Original call completed, result
|
||||
* updated in the previously supplied.
|
||||
* struct optee_msg_arg
|
||||
* OPTEE_SMC_RETURN_RPC Call suspended by RPC call to normal
|
||||
* world.
|
||||
* OPTEE_SMC_RETURN_ERESUME Resume failed, the opaque resume
|
||||
* information was corrupt.
|
||||
*/
|
||||
#define OPTEE_SMC_FUNCID_RETURN_FROM_RPC 3
|
||||
#define OPTEE_SMC_CALL_RETURN_FROM_RPC OPTEE_SMC_STD_CALL_VAL(OPTEE_SMC_FUNCID_RETURN_FROM_RPC)
|
||||
|
||||
#define OPTEE_SMC_RETURN_RPC_PREFIX_MASK 0xffff0000
|
||||
#define OPTEE_SMC_RETURN_RPC_PREFIX 0xffff0000
|
||||
#define OPTEE_SMC_RETURN_RPC_FUNC_MASK 0x0000ffff
|
||||
|
||||
#define OPTEE_SMC_RETURN_GET_RPC_FUNC(ret) ((ret) & OPTEE_SMC_RETURN_RPC_FUNC_MASK)
|
||||
|
||||
#define OPTEE_SMC_RPC_VAL(func) ((func) | OPTEE_SMC_RETURN_RPC_PREFIX)
|
||||
|
||||
/*
|
||||
* Allocate memory for RPC parameter passing. The memory is used to hold a
|
||||
* struct optee_msg_arg.
|
||||
*
|
||||
* "Call" register usage:
|
||||
* a0 This value, OPTEE_SMC_RETURN_RPC_ALLOC
|
||||
* a1 Size in bytes of required argument memory
|
||||
* a2 Not used
|
||||
* a3 Resume information, must be preserved
|
||||
* a4-5 Not used
|
||||
* a6-7 Resume information, must be preserved
|
||||
*
|
||||
* "Return" register usage:
|
||||
* a0 SMC Function ID, OPTEE_SMC_CALL_RETURN_FROM_RPC.
|
||||
* a1 Upper 32bits of 64bit physical pointer to allocated
|
||||
* memory, (a1 == 0 && a2 == 0) if size was 0 or if memory can't
|
||||
* be allocated.
|
||||
* a2 Lower 32bits of 64bit physical pointer to allocated
|
||||
* memory, (a1 == 0 && a2 == 0) if size was 0 or if memory can't
|
||||
* be allocated
|
||||
* a3 Preserved
|
||||
* a4 Upper 32bits of 64bit Shared memory cookie used when freeing
|
||||
* the memory or doing an RPC
|
||||
* a5 Lower 32bits of 64bit Shared memory cookie used when freeing
|
||||
* the memory or doing an RPC
|
||||
* a6-7 Preserved
|
||||
*/
|
||||
#define OPTEE_SMC_RPC_FUNC_ALLOC 0
|
||||
#define OPTEE_SMC_RETURN_RPC_ALLOC OPTEE_SMC_RPC_VAL(OPTEE_SMC_RPC_FUNC_ALLOC)
|
||||
|
||||
/*
|
||||
* Free memory previously allocated by OPTEE_SMC_RETURN_RPC_ALLOC
|
||||
*
|
||||
* "Call" register usage:
|
||||
* a0 This value, OPTEE_SMC_RETURN_RPC_FREE
|
||||
* a1 Upper 32bits of 64bit shared memory cookie belonging to this
|
||||
* argument memory
|
||||
* a2 Lower 32bits of 64bit shared memory cookie belonging to this
|
||||
* argument memory
|
||||
* a3-7 Resume information, must be preserved
|
||||
*
|
||||
* "Return" register usage:
|
||||
* a0 SMC Function ID, OPTEE_SMC_CALL_RETURN_FROM_RPC.
|
||||
* a1-2 Not used
|
||||
* a3-7 Preserved
|
||||
*/
|
||||
#define OPTEE_SMC_RPC_FUNC_FREE 2
|
||||
#define OPTEE_SMC_RETURN_RPC_FREE OPTEE_SMC_RPC_VAL(OPTEE_SMC_RPC_FUNC_FREE)
|
||||
|
||||
/*
|
||||
* Deliver foreign interrupt to normal world.
|
||||
*
|
||||
* "Call" register usage:
|
||||
* a0 OPTEE_SMC_RETURN_RPC_FOREIGN_INTR
|
||||
* a1-7 Resume information, must be preserved
|
||||
*
|
||||
* "Return" register usage:
|
||||
* a0 SMC Function ID, OPTEE_SMC_CALL_RETURN_FROM_RPC.
|
||||
* a1-7 Preserved
|
||||
*/
|
||||
#define OPTEE_SMC_RPC_FUNC_FOREIGN_INTR 4
|
||||
#define OPTEE_SMC_RETURN_RPC_FOREIGN_INTR OPTEE_SMC_RPC_VAL(OPTEE_SMC_RPC_FUNC_FOREIGN_INTR)
|
||||
|
||||
/*
|
||||
* Do an RPC request. The supplied struct optee_msg_arg tells which
|
||||
* request to do and the parameters for the request. The following fields
|
||||
* are used (the rest are unused):
|
||||
* - cmd the Request ID
|
||||
* - ret return value of the request, filled in by normal world
|
||||
* - num_params number of parameters for the request
|
||||
* - params the parameters
|
||||
* - param_attrs attributes of the parameters
|
||||
*
|
||||
* "Call" register usage:
|
||||
* a0 OPTEE_SMC_RETURN_RPC_CMD
|
||||
* a1 Upper 32bit of a 64bit Shared memory cookie holding a
|
||||
* struct optee_msg_arg, must be preserved, only the data should
|
||||
* be updated
|
||||
* a2 Lower 32bit of a 64bit Shared memory cookie holding a
|
||||
* struct optee_msg_arg, must be preserved, only the data should
|
||||
* be updated
|
||||
* a3-7 Resume information, must be preserved
|
||||
*
|
||||
* "Return" register usage:
|
||||
* a0 SMC Function ID, OPTEE_SMC_CALL_RETURN_FROM_RPC.
|
||||
* a1-2 Not used
|
||||
* a3-7 Preserved
|
||||
*/
|
||||
#define OPTEE_SMC_RPC_FUNC_CMD 5
|
||||
#define OPTEE_SMC_RETURN_RPC_CMD OPTEE_SMC_RPC_VAL(OPTEE_SMC_RPC_FUNC_CMD)
|
||||
|
||||
/* Returned in a0 */
|
||||
#define OPTEE_SMC_RETURN_UNKNOWN_FUNCTION 0xffffffff
|
||||
|
||||
/* Returned in a0 only from Trusted OS functions */
|
||||
#define OPTEE_SMC_RETURN_OK 0x0
|
||||
#define OPTEE_SMC_RETURN_ETHREAD_LIMIT 0x1
|
||||
#define OPTEE_SMC_RETURN_EBUSY 0x2
|
||||
#define OPTEE_SMC_RETURN_ERESUME 0x3
|
||||
#define OPTEE_SMC_RETURN_EBADADDR 0x4
|
||||
#define OPTEE_SMC_RETURN_EBADCMD 0x5
|
||||
#define OPTEE_SMC_RETURN_ENOMEM 0x6
|
||||
#define OPTEE_SMC_RETURN_ENOTAVAIL 0x7
|
||||
#define OPTEE_SMC_RETURN_IS_RPC(ret) \
|
||||
({ \
|
||||
ret != OPTEE_SMC_RETURN_UNKNOWN_FUNCTION && \
|
||||
(ret & OPTEE_SMC_RETURN_RPC_PREFIX_MASK) == \
|
||||
OPTEE_SMC_RETURN_RPC_PREFIX; \
|
||||
})
|
||||
|
||||
#endif /* __OPTEE_SMC_H__ */
|
||||
Executable
+331
@@ -0,0 +1,331 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2023, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2023-04-23 GuEe-GUI first version
|
||||
*/
|
||||
|
||||
#include <rthw.h>
|
||||
#include <rtthread.h>
|
||||
#include <rtdevice.h>
|
||||
|
||||
#define DBG_TAG "rtdm.tee"
|
||||
#define DBG_LVL DBG_INFO
|
||||
#include <rtdbg.h>
|
||||
|
||||
#include <mm_aspace.h>
|
||||
#include <mm_page.h>
|
||||
|
||||
static struct rt_dm_ida tee_ida = RT_DM_IDA_INIT(TEE);
|
||||
|
||||
#ifdef RT_USING_DEVICE_OPS
|
||||
const static struct rt_device_ops _tee_ops =
|
||||
{
|
||||
};
|
||||
#endif
|
||||
|
||||
rt_err_t rt_tee_device_register(struct rt_tee_device *tdev)
|
||||
{
|
||||
rt_err_t err;
|
||||
int device_id;
|
||||
const char *dev_name;
|
||||
|
||||
if (!tdev || !tdev->ops)
|
||||
{
|
||||
return -RT_EINVAL;
|
||||
}
|
||||
|
||||
if ((device_id = rt_dm_ida_alloc(&tee_ida)) < 0)
|
||||
{
|
||||
return -RT_EFULL;
|
||||
}
|
||||
|
||||
rt_dm_dev_set_name(&tdev->parent, "tee%u", device_id);
|
||||
dev_name = rt_dm_dev_get_name(&tdev->parent);
|
||||
|
||||
rt_list_init(&tdev->shm_nodes);
|
||||
rt_mutex_init(&tdev->mutex, dev_name, RT_IPC_FLAG_PRIO);
|
||||
|
||||
/* Just make a search interface */
|
||||
tdev->parent.type = RT_Device_Class_Char;
|
||||
#ifdef RT_USING_DEVICE_OPS
|
||||
tdev->parent.ops = tdev->parent.ops ? : &_tee_ops;
|
||||
#endif
|
||||
tdev->parent.master_id = tee_ida.master_id;
|
||||
tdev->parent.device_id = device_id;
|
||||
|
||||
if ((err = rt_device_register(&tdev->parent, dev_name, RT_DEVICE_FLAG_DEACTIVATE)))
|
||||
{
|
||||
goto _fail;
|
||||
}
|
||||
|
||||
return RT_EOK;
|
||||
|
||||
_fail:
|
||||
rt_dm_ida_free(&tee_ida, device_id);
|
||||
|
||||
rt_mutex_detach(&tdev->mutex);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
rt_err_t rt_tee_device_unregister(struct rt_tee_device *tdev)
|
||||
{
|
||||
rt_err_t err;
|
||||
struct rt_tee_shm *shm, *shm_next;
|
||||
|
||||
if (!tdev)
|
||||
{
|
||||
return -RT_EINVAL;
|
||||
}
|
||||
|
||||
if (tdev->parent.ref_count)
|
||||
{
|
||||
LOG_E("%s: there is %u user",
|
||||
rt_dm_dev_get_name(&tdev->parent), tdev->parent.ref_count);
|
||||
return -RT_EINVAL;
|
||||
}
|
||||
|
||||
rt_mutex_take(&tdev->mutex, RT_WAITING_FOREVER);
|
||||
|
||||
if (!rt_list_isempty(&tdev->shm_nodes))
|
||||
{
|
||||
LOG_W("%s: shm not unregister", rt_dm_dev_get_name(&tdev->parent));
|
||||
|
||||
rt_list_for_each_entry_safe(shm, shm_next, &tdev->shm_nodes, list)
|
||||
{
|
||||
if (!tdev->ops->shm_unregister(tdev, shm))
|
||||
{
|
||||
rt_list_remove(&shm->list);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
rt_mutex_release(&tdev->mutex);
|
||||
|
||||
rt_dm_ida_free(&tee_ida, tdev->parent.device_id);
|
||||
|
||||
if (!(err = rt_device_unregister(&tdev->parent)))
|
||||
{
|
||||
rt_mutex_detach(&tdev->mutex);
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
rt_err_t rt_tee_get_version(struct rt_tee_device *tdev,
|
||||
struct rt_tee_version *out_version)
|
||||
{
|
||||
rt_err_t err;
|
||||
|
||||
if (!tdev || !out_version)
|
||||
{
|
||||
return -RT_EINVAL;
|
||||
}
|
||||
|
||||
rt_mutex_take(&tdev->mutex, RT_WAITING_FOREVER);
|
||||
|
||||
err = tdev->ops->get_version(tdev, out_version);
|
||||
|
||||
rt_mutex_release(&tdev->mutex);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
rt_err_t rt_tee_open_session(struct rt_tee_device *tdev,
|
||||
struct rt_tee_open_session_arg *arg)
|
||||
{
|
||||
rt_err_t err;
|
||||
|
||||
if (!tdev || !arg)
|
||||
{
|
||||
return -RT_EINVAL;
|
||||
}
|
||||
|
||||
rt_mutex_take(&tdev->mutex, RT_WAITING_FOREVER);
|
||||
|
||||
err = tdev->ops->open_session(tdev, arg);
|
||||
|
||||
rt_mutex_release(&tdev->mutex);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
rt_err_t rt_tee_close_session(struct rt_tee_device *tdev, rt_uint32_t session)
|
||||
{
|
||||
rt_err_t err;
|
||||
|
||||
if (!tdev)
|
||||
{
|
||||
return -RT_EINVAL;
|
||||
}
|
||||
|
||||
rt_mutex_take(&tdev->mutex, RT_WAITING_FOREVER);
|
||||
|
||||
err = tdev->ops->close_session(tdev, session);
|
||||
|
||||
rt_mutex_release(&tdev->mutex);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
rt_err_t rt_tee_invoke(struct rt_tee_device *tdev,
|
||||
struct rt_tee_invoke_arg *arg)
|
||||
{
|
||||
rt_err_t err;
|
||||
|
||||
if (!tdev || !arg)
|
||||
{
|
||||
return -RT_EINVAL;
|
||||
}
|
||||
|
||||
rt_mutex_take(&tdev->mutex, RT_WAITING_FOREVER);
|
||||
|
||||
err = tdev->ops->invoke(tdev, arg);
|
||||
|
||||
rt_mutex_release(&tdev->mutex);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
rt_err_t rt_tee_cancel(struct rt_tee_device *tdev,
|
||||
rt_uint32_t session, rt_uint32_t cancel_id)
|
||||
{
|
||||
rt_err_t err;
|
||||
|
||||
if (!tdev)
|
||||
{
|
||||
return -RT_EINVAL;
|
||||
}
|
||||
|
||||
rt_mutex_take(&tdev->mutex, RT_WAITING_FOREVER);
|
||||
|
||||
err = tdev->ops->cancel(tdev, session, cancel_id);
|
||||
|
||||
rt_mutex_release(&tdev->mutex);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
rt_err_t rt_tee_shm_alloc_helper(struct rt_tee_shm *shm)
|
||||
{
|
||||
if (!shm || !shm->size)
|
||||
{
|
||||
return -RT_EINVAL;
|
||||
}
|
||||
|
||||
if (shm->align && shm->align != RT_MM_PAGE_SIZE)
|
||||
{
|
||||
shm->vaddr = rt_malloc_align(shm->size, shm->align);
|
||||
}
|
||||
else
|
||||
{
|
||||
shm->vaddr = rt_pages_alloc(rt_page_bits(shm->size));
|
||||
}
|
||||
|
||||
if (!shm->vaddr)
|
||||
{
|
||||
return -RT_ENOMEM;
|
||||
}
|
||||
|
||||
if (!shm->paddr)
|
||||
{
|
||||
shm->paddr = (rt_ubase_t)rt_kmem_v2p(shm->vaddr);
|
||||
}
|
||||
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
rt_err_t rt_tee_shm_free_helper(struct rt_tee_shm *shm)
|
||||
{
|
||||
if (!shm || !shm->size)
|
||||
{
|
||||
return -RT_EINVAL;
|
||||
}
|
||||
|
||||
if (shm->align && shm->align != RT_MM_PAGE_SIZE)
|
||||
{
|
||||
rt_free_align(shm->vaddr);
|
||||
}
|
||||
else
|
||||
{
|
||||
rt_pages_free(shm->vaddr, rt_page_bits(shm->size));
|
||||
}
|
||||
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
rt_err_t rt_tee_shm_register(struct rt_tee_device *tdev, struct rt_tee_shm *shm)
|
||||
{
|
||||
rt_err_t err;
|
||||
rt_bool_t allocated = RT_FALSE;
|
||||
|
||||
if (!tdev || !shm || !shm->size)
|
||||
{
|
||||
return -RT_EINVAL;
|
||||
}
|
||||
|
||||
if (shm->flags & TEE_SHM_USER)
|
||||
{
|
||||
if (!shm->vaddr)
|
||||
{
|
||||
return -RT_EINVAL;
|
||||
}
|
||||
|
||||
if (!shm->paddr)
|
||||
{
|
||||
shm->paddr = (rt_ubase_t)rt_kmem_v2p(shm->vaddr);
|
||||
}
|
||||
}
|
||||
else if ((shm->flags & TEE_SHM_SYS) && !(shm->flags & TEE_SHM_DRV))
|
||||
{
|
||||
if ((err = rt_tee_shm_alloc_helper(shm)))
|
||||
{
|
||||
return err;
|
||||
}
|
||||
allocated = RT_TRUE;
|
||||
}
|
||||
|
||||
rt_mutex_take(&tdev->mutex, RT_WAITING_FOREVER);
|
||||
|
||||
if (!(err = tdev->ops->shm_register(tdev, shm)))
|
||||
{
|
||||
rt_list_init(&shm->list);
|
||||
rt_list_insert_before(&tdev->shm_nodes, &shm->list);
|
||||
}
|
||||
|
||||
rt_mutex_release(&tdev->mutex);
|
||||
|
||||
if (err && allocated)
|
||||
{
|
||||
rt_tee_shm_free_helper(shm);
|
||||
shm->vaddr = RT_NULL;
|
||||
shm->paddr = 0;
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
rt_err_t rt_tee_shm_unregister(struct rt_tee_device *tdev, struct rt_tee_shm *shm)
|
||||
{
|
||||
rt_err_t err;
|
||||
|
||||
if (!tdev || !shm)
|
||||
{
|
||||
return -RT_EINVAL;
|
||||
}
|
||||
|
||||
rt_mutex_take(&tdev->mutex, RT_WAITING_FOREVER);
|
||||
|
||||
if (!(err = tdev->ops->shm_unregister(tdev, shm)))
|
||||
{
|
||||
rt_list_remove(&shm->list);
|
||||
}
|
||||
|
||||
rt_mutex_release(&tdev->mutex);
|
||||
|
||||
return err;
|
||||
}
|
||||
Reference in New Issue
Block a user