You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
708 lines
23 KiB
708 lines
23 KiB
/*
|
|
* Copyright (c) Hisilicon Technologies Co., Ltd. 2019-2020. All rights reserved.
|
|
* Description: SSM function file for Huanglong SSM
|
|
* Author: ssm group
|
|
* Create: 2019/12/11
|
|
*/
|
|
|
|
#include "linux/huanglong/securec.h"
|
|
#include "linux/dma-buf.h"
|
|
#include "drv_ssm.h"
|
|
#include "drv_sys_ext.h"
|
|
#include "osal_ext.h"
|
|
#ifdef CONFIG_SOCT_TEE_SUPPORT
|
|
#include "teek_client_api.h"
|
|
#endif
|
|
#include "ssm_version.h"
|
|
|
|
#define SSM_TEEC_NAME "tee_ssm_session"
|
|
#define ssm_check_pointer_return_if_fail(pointer) \
|
|
do { \
|
|
if ((pointer) == TD_NULL) { \
|
|
soc_log_err("pointer %s is null\n", #pointer); \
|
|
return TD_FAILURE; \
|
|
} \
|
|
} while (0)
|
|
|
|
typedef struct {
|
|
td_handle session_handle;
|
|
ext_drv_ssm_buffer_id buf_id;
|
|
td_u64 fd;
|
|
td_u32 buf_len;
|
|
td_handle module_handle;
|
|
} ssm_teek_attach_buf_ctl;
|
|
|
|
#ifdef SSM_TEST_SUPPORT
|
|
typedef struct {
|
|
td_handle session_handle;
|
|
td_handle module_handle;
|
|
ext_drv_ssm_buffer_id buf_id;
|
|
td_u64 buf_smmu_fd;
|
|
td_u64 buf_len;
|
|
} ssm_teek_check_buf_ctl;
|
|
#endif
|
|
|
|
typedef struct {
|
|
struct file *filp;
|
|
td_handle ssm_handle;
|
|
} ssm_info;
|
|
|
|
typedef struct {
|
|
td_u32 ssm_num;
|
|
ssm_info chan_info[SSM_MAX_SESSION_NUM];
|
|
} ssm_dev_handler;
|
|
|
|
#ifdef CONFIG_SOCT_TEE_SUPPORT
|
|
static TEEC_Context g_teec_context = {0};
|
|
TEEC_Session g_teec_session = {0};
|
|
TEEC_UUID g_teec_uuid = {
|
|
0x90ae48e5,
|
|
0xc757,
|
|
0x44a7,
|
|
{
|
|
0xb5, 0x13, 0xde, 0x4b, 0x2b, 0x14, 0xa0, 0x7c
|
|
}
|
|
};
|
|
#endif
|
|
static ssm_dev_handler g_ssm_dev = {0};
|
|
static osal_mutex g_ssm_lock = {0};
|
|
|
|
/****************************************************************
|
|
*
|
|
* static functions which are defined only in this file
|
|
* All functions name are started with "ssm_"
|
|
*
|
|
****************************************************************/
|
|
static td_bool ssm_check_support(td_void)
|
|
{
|
|
ext_chip_name_id chip_name_id;
|
|
|
|
ext_drv_sys_get_chip_name_id(&chip_name_id);
|
|
|
|
if (chip_name_id == CHIP_NAME_RESERVED5 || chip_name_id == CHIP_NAME_RESERVED17 ||
|
|
chip_name_id == CHIP_NAME_RESERVED19 || chip_name_id == CHIP_NAME_HI3751V811) {
|
|
soc_log_warn("can not support ssm\n");
|
|
return TD_FALSE;
|
|
}
|
|
return TD_TRUE;
|
|
}
|
|
|
|
static td_s32 ssm_do_destroy(td_handle ssm_handle)
|
|
{
|
|
#ifdef CONFIG_SOCT_TEE_SUPPORT
|
|
TEEC_Operation operation = {0};
|
|
TEEC_Result result;
|
|
td_u32 origin = 0;
|
|
td_u32 i;
|
|
|
|
soc_info_func_enter();
|
|
soc_log_info("%s %d ssm_handle=0x%x\n", __func__, __LINE__, ssm_handle);
|
|
operation.started = 1;
|
|
operation.params[0].value.a = (td_u32)ssm_handle;
|
|
operation.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT, TEEC_NONE, TEEC_NONE, TEEC_NONE);
|
|
result = TEEK_InvokeCommand(&g_teec_session,
|
|
TEEC_CMD_SSM_DESTROY,
|
|
&operation,
|
|
&origin);
|
|
if (result != TEEC_SUCCESS) {
|
|
soc_log_err("TEEC invoke destroy fail:%x\n", result);
|
|
return result;
|
|
}
|
|
|
|
(td_void)osal_mutex_lock(&g_ssm_lock);
|
|
for (i = 0; i < SSM_MAX_SESSION_NUM; i++) {
|
|
if (g_ssm_dev.chan_info[i].ssm_handle != ssm_handle) {
|
|
continue;
|
|
}
|
|
|
|
g_ssm_dev.chan_info[i].ssm_handle = 0;
|
|
g_ssm_dev.chan_info[i].filp = TD_NULL;
|
|
g_ssm_dev.ssm_num--;
|
|
break;
|
|
}
|
|
(td_void)osal_mutex_unlock(&g_ssm_lock);
|
|
soc_info_func_exit();
|
|
return TD_SUCCESS;
|
|
#else
|
|
return TD_FAILURE;
|
|
#endif
|
|
}
|
|
|
|
static td_s32 ssm_do_teec_attach_buffer(ssm_teek_attach_buf_ctl *teek_attach_info, td_u64 *addr)
|
|
{
|
|
#ifdef CONFIG_SOCT_TEE_SUPPORT
|
|
TEEC_Operation operation = {0};
|
|
TEEC_Result result;
|
|
td_u32 origin = 0;
|
|
|
|
soc_info_func_enter();
|
|
ssm_check_pointer_return_if_fail(teek_attach_info);
|
|
ssm_check_pointer_return_if_fail(addr);
|
|
|
|
soc_log_info("%s %d session_handle=0x%x module_handle=0x%x buf_id=%d buf_len=%d fd=0x%llx\n", __func__, __LINE__,
|
|
teek_attach_info->session_handle, teek_attach_info->module_handle, teek_attach_info->buf_id,
|
|
teek_attach_info->buf_len, teek_attach_info->fd);
|
|
operation.started = 1;
|
|
|
|
operation.params[0].tmpref.buffer = (void *)teek_attach_info; /* the fd in this struct is useless */
|
|
operation.params[0].tmpref.size = sizeof(ssm_teek_attach_buf_ctl);
|
|
operation.params[1].memfd.fd = teek_attach_info->fd; /* fd has to be sent in this way */
|
|
operation.params[2].value.a = 0; /* 2 is the 3rd param */
|
|
operation.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INPUT, TEEC_SECSMMU_HAND_INPUT,
|
|
TEEC_VALUE_INOUT, TEEC_NONE);
|
|
|
|
result = TEEK_InvokeCommand(&g_teec_session,
|
|
TEEC_CMD_SSM_ATTACH_BUFFER,
|
|
&operation,
|
|
&origin);
|
|
if (result != TEEC_SUCCESS) {
|
|
soc_log_err("TEEC invoke attach buffer fail:%x\n", result);
|
|
return result;
|
|
}
|
|
|
|
(*addr) = operation.params[2].value.b; /* 2 is the 3rd param */
|
|
soc_log_info("%s %d addr=0x%llx\n", __func__, __LINE__, *addr);
|
|
soc_info_func_exit();
|
|
return TD_SUCCESS;
|
|
#else
|
|
return TD_FAILURE;
|
|
#endif
|
|
}
|
|
|
|
static td_s32 ssm_dump_context(td_void)
|
|
{
|
|
#ifdef CONFIG_SOCT_TEE_SUPPORT
|
|
TEEC_Operation operation = {0};
|
|
TEEC_Result result;
|
|
td_u32 origin = 0;
|
|
|
|
soc_info_func_enter();
|
|
operation.started = 1;
|
|
operation.paramTypes = TEEC_PARAM_TYPES(TEEC_NONE, TEEC_NONE, TEEC_NONE, TEEC_NONE);
|
|
result = TEEK_InvokeCommand(&g_teec_session,
|
|
TEEC_CMD_SSM_DUMP_CONTEXT,
|
|
&operation,
|
|
&origin);
|
|
if (result != TEEC_SUCCESS) {
|
|
soc_log_err("TEEC invoke dump context fail:%x\n", result);
|
|
return result;
|
|
}
|
|
soc_info_func_exit();
|
|
return TD_SUCCESS;
|
|
#else
|
|
return TD_FAILURE;
|
|
#endif
|
|
}
|
|
|
|
/****************************************************************
|
|
*
|
|
* exported driver ssm APIs, which are defined in drv_ssm.h
|
|
* All functions name are started with "drv_ssm_"
|
|
*
|
|
****************************************************************/
|
|
td_s32 drv_ssm_teec_init(td_void)
|
|
{
|
|
#ifdef CONFIG_SOCT_TEE_SUPPORT
|
|
TEEC_Result teec_ret;
|
|
TEEC_Operation teec_operation = {0};
|
|
uint32_t teec_ret_origion = 0;
|
|
td_u32 root_id = 0;
|
|
td_s32 ret;
|
|
|
|
soc_info_func_enter();
|
|
ret = osal_mutex_init(&g_ssm_lock);
|
|
if (ret != TD_SUCCESS) {
|
|
soc_log_err("cannot init osal lock! : 0x%x\n", ret);
|
|
return ret;
|
|
}
|
|
|
|
teec_ret = TEEK_InitializeContext(TD_NULL, &g_teec_context);
|
|
if (teec_ret != TEEC_SUCCESS) {
|
|
soc_log_fatal("teec init content fail:%x\n", teec_ret);
|
|
return teec_ret;
|
|
}
|
|
|
|
teec_operation.started = 1;
|
|
teec_operation.cancel_flag = 0;
|
|
teec_operation.paramTypes = TEEC_PARAM_TYPES(TEEC_NONE, TEEC_NONE, TEEC_MEMREF_TEMP_INPUT, TEEC_MEMREF_TEMP_INPUT);
|
|
teec_operation.params[2].tmpref.buffer = (void *)&root_id; /* 2 is offset */
|
|
teec_operation.params[2].tmpref.size = sizeof(root_id); /* 2 is offset */
|
|
teec_operation.params[3].tmpref.buffer = (void *)SSM_TEEC_NAME; /* 3 is offset */
|
|
teec_operation.params[3].tmpref.size = strlen(SSM_TEEC_NAME) + 1; /* 3 is offset */
|
|
|
|
teec_ret = TEEK_OpenSession(&g_teec_context, &g_teec_session, &g_teec_uuid, TEEC_LOGIN_IDENTIFY,
|
|
TD_NULL, &teec_operation, &teec_ret_origion);
|
|
if (teec_ret != TEEC_SUCCESS) {
|
|
soc_log_fatal("TEEK_OpenSession fail:%x\n", teec_ret);
|
|
TEEK_FinalizeContext(&g_teec_context);
|
|
}
|
|
|
|
if (ssm_check_support() == TD_FALSE) {
|
|
return TD_SUCCESS;
|
|
}
|
|
memset_s(&teec_operation, sizeof(TEEC_Operation), 0, sizeof(TEEC_Operation));
|
|
|
|
teec_operation.started = 1;
|
|
teec_operation.paramTypes = TEEC_PARAM_TYPES(TEEC_NONE, TEEC_NONE, TEEC_NONE, TEEC_NONE);
|
|
teec_ret = TEEK_InvokeCommand(&g_teec_session, TEEC_CMD_SSM_INIT, &teec_operation, &teec_ret_origion);
|
|
if (teec_ret != TEEC_SUCCESS) {
|
|
soc_log_err("TEEC invoke fail:%x\n", teec_ret);
|
|
TEEK_CloseSession(&g_teec_session);
|
|
TEEK_FinalizeContext(&g_teec_context);
|
|
return teec_ret;
|
|
}
|
|
soc_info_func_exit();
|
|
return TD_SUCCESS;
|
|
#else
|
|
return TD_FAILURE;
|
|
#endif
|
|
}
|
|
|
|
td_void drv_ssm_teec_deinit(td_void)
|
|
{
|
|
#ifdef CONFIG_SOCT_TEE_SUPPORT
|
|
soc_info_func_enter();
|
|
(td_void)TEEK_CloseSession(&g_teec_session);
|
|
(td_void)TEEK_FinalizeContext(&g_teec_context);
|
|
soc_info_func_exit();
|
|
#endif
|
|
return;
|
|
}
|
|
|
|
td_s32 drv_ssm_teec_create(struct file *ssm_filp, ext_ssm_intent intent, td_handle *handle)
|
|
{
|
|
#ifdef CONFIG_SOCT_TEE_SUPPORT
|
|
TEEC_Operation operation = {0};
|
|
TEEC_Result result;
|
|
td_u32 origin = 0;
|
|
td_u32 i;
|
|
|
|
soc_info_func_enter();
|
|
ssm_check_pointer_return_if_fail(handle);
|
|
if (ssm_check_support() == TD_FALSE) {
|
|
*handle = (SOC_ID_SSM << 24) | (SOC_ID_SSM << 16) | (SOC_ID_SSM << 8) | 0; /* 24 & 16 & 8 used to get handle */
|
|
return TD_SUCCESS;
|
|
}
|
|
|
|
soc_log_info("%s %d intent=%d\n", __func__, __LINE__, intent);
|
|
operation.started = 1;
|
|
operation.params[0].value.a = (td_u32)(intent);
|
|
operation.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INOUT, TEEC_NONE, TEEC_NONE, TEEC_NONE);
|
|
result = TEEK_InvokeCommand(&g_teec_session, TEEC_CMD_SSM_CREATE, &operation, &origin);
|
|
if (result != TEEC_SUCCESS) {
|
|
soc_log_err("TEEC invoke fail:%x\n", result);
|
|
return result;
|
|
}
|
|
(*handle) = operation.params[0].value.b;
|
|
|
|
(td_void)osal_mutex_lock(&g_ssm_lock);
|
|
for (i = 0; i < SSM_MAX_SESSION_NUM; i++) {
|
|
if (g_ssm_dev.chan_info[i].ssm_handle != 0) {
|
|
continue;
|
|
}
|
|
|
|
g_ssm_dev.chan_info[i].ssm_handle = operation.params[0].value.b;
|
|
g_ssm_dev.chan_info[i].filp = ssm_filp;
|
|
g_ssm_dev.ssm_num++;
|
|
|
|
break;
|
|
}
|
|
(td_void)osal_mutex_unlock(&g_ssm_lock);
|
|
|
|
if (i >= SSM_MAX_SESSION_NUM) {
|
|
soc_log_err("drv_ssm_teec_create fail:%x\n", result);
|
|
(td_void)ssm_do_destroy(*handle);
|
|
*handle = TD_INVALID_HANDLE;
|
|
return TD_FAILURE;
|
|
}
|
|
soc_info_func_exit();
|
|
return TD_SUCCESS;
|
|
#else
|
|
return TD_FAILURE;
|
|
#endif
|
|
}
|
|
|
|
td_s32 drv_ssm_teec_destroy(td_handle ssm_handle)
|
|
{
|
|
if (ssm_check_support() == TD_FALSE) {
|
|
return TD_SUCCESS;
|
|
}
|
|
return ssm_do_destroy(ssm_handle);
|
|
}
|
|
|
|
td_s32 drv_ssm_teec_add_resource(td_handle ssm_handle, ext_ssm_module_resource res_info)
|
|
{
|
|
#ifdef CONFIG_SOCT_TEE_SUPPORT
|
|
TEEC_Operation operation = {0};
|
|
TEEC_Result result;
|
|
td_u32 origin = 0;
|
|
|
|
soc_info_func_enter();
|
|
if (ssm_check_support() == TD_FALSE) {
|
|
return TD_SUCCESS;
|
|
}
|
|
soc_log_info("%s %d ssm_handle=0x%x module_handle=0x%x\n", __func__, __LINE__, ssm_handle, res_info.module_handle);
|
|
operation.started = 1;
|
|
operation.params[0].value.a = (td_u32)ssm_handle;
|
|
operation.params[1].tmpref.buffer = (void *)&res_info;
|
|
operation.params[1].tmpref.size = sizeof(res_info);
|
|
operation.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT, TEEC_MEMREF_TEMP_INPUT, TEEC_NONE, TEEC_NONE);
|
|
result = TEEK_InvokeCommand(&g_teec_session,
|
|
TEEC_CMD_SSM_ADD_RESOUCE,
|
|
&operation,
|
|
&origin);
|
|
if (result != TEEC_SUCCESS) {
|
|
soc_log_err("TEEC invoke add resource fail:%x\n", result);
|
|
return result;
|
|
}
|
|
soc_info_func_exit();
|
|
return TD_SUCCESS;
|
|
#else
|
|
return TD_FAILURE;
|
|
#endif
|
|
}
|
|
|
|
td_s32 drv_ssm_teec_attach_buffer(ext_ssm_buffer_attach_info attach_info, td_u64 *addr)
|
|
{
|
|
#ifdef CONFIG_SOCT_TEE_SUPPORT
|
|
ssm_teek_attach_buf_ctl teek_attach_info = {0};
|
|
struct dma_buf *dma_buf_addr = TD_NULL;
|
|
td_s32 ret;
|
|
|
|
if (ssm_check_support() == TD_FALSE) {
|
|
return TD_SUCCESS;
|
|
}
|
|
ssm_check_pointer_return_if_fail(addr);
|
|
|
|
teek_attach_info.session_handle = attach_info.session_handle;
|
|
teek_attach_info.buf_id = attach_info.buf_id;
|
|
teek_attach_info.module_handle = attach_info.module_handle;
|
|
|
|
dma_buf_addr = osal_mem_handle_get(attach_info.dma_buf_handle, SOC_ID_SSM);
|
|
if (dma_buf_addr == TD_NULL) {
|
|
soc_log_err("get dma buf addr fail\n");
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
teek_attach_info.fd = attach_info.dma_buf_handle;
|
|
teek_attach_info.buf_len = dma_buf_addr->size;
|
|
|
|
osal_mem_ref_put(dma_buf_addr, SOC_ID_SSM);
|
|
ret = ssm_do_teec_attach_buffer(&teek_attach_info, addr);
|
|
if (ret != TD_SUCCESS) {
|
|
soc_log_err("tec attach buffer\n");
|
|
return ret;
|
|
}
|
|
|
|
return TD_SUCCESS;
|
|
#else
|
|
return TD_FAILURE;
|
|
#endif
|
|
}
|
|
|
|
td_s32 drv_ssm_teec_get_intent(td_handle ssm_handle, ext_ssm_intent *get_intent)
|
|
{
|
|
#ifdef CONFIG_SOCT_TEE_SUPPORT
|
|
TEEC_Operation operation = {0};
|
|
TEEC_Result result;
|
|
td_u32 origin = 0;
|
|
|
|
soc_info_func_enter();
|
|
if (ssm_check_support() == TD_FALSE) {
|
|
return TD_SUCCESS;
|
|
}
|
|
ssm_check_pointer_return_if_fail(get_intent);
|
|
|
|
operation.started = 1;
|
|
operation.params[0].value.a = (td_u32)(ssm_handle);
|
|
operation.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INOUT, TEEC_NONE, TEEC_NONE, TEEC_NONE);
|
|
result = TEEK_InvokeCommand(&g_teec_session,
|
|
TEEC_CMD_SSM_GET_INTENT,
|
|
&operation,
|
|
&origin);
|
|
if (result != TEEC_SUCCESS) {
|
|
soc_log_err("TEEC invoke get intent fail:%x\n", result);
|
|
return result;
|
|
}
|
|
|
|
(*get_intent) = operation.params[0].value.b;
|
|
soc_log_info("%s %d ssm_handle=0x%x get_intent=%d\n", __func__, __LINE__, ssm_handle, *get_intent);
|
|
soc_info_func_exit();
|
|
return TD_SUCCESS;
|
|
#else
|
|
return TD_FAILURE;
|
|
#endif
|
|
}
|
|
|
|
#ifdef SSM_TEST_SUPPORT
|
|
td_s32 drv_ssm_teec_check_buffer(ext_ssm_buffer_check_info check_info)
|
|
{
|
|
ssm_teek_check_buf_ctl teek_check_info = {0};
|
|
struct dma_buf *dma_buf_addr = TD_NULL;
|
|
TEEC_Operation operation = {0};
|
|
TEEC_Result result;
|
|
td_u32 origin = 0;
|
|
|
|
soc_info_func_enter();
|
|
if (ssm_check_support() == TD_FALSE) {
|
|
return TD_SUCCESS;
|
|
}
|
|
dma_buf_addr = osal_mem_handle_get(check_info.dma_buf_handle, SOC_ID_SSM);
|
|
if (dma_buf_addr == TD_NULL) {
|
|
soc_log_err("get dma buf addr fail\n");
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
soc_log_info("%s %d session_handle=0x%x module_handle=0x%x buf_id=%d buf_len=%d dma_buf_handle=0x%llx\n",
|
|
__func__, __LINE__, check_info.session_handle, check_info.module_handle, check_info.buf_id,
|
|
dma_buf_addr->size, check_info.dma_buf_handle);
|
|
teek_check_info.session_handle = check_info.session_handle;
|
|
teek_check_info.module_handle = check_info.module_handle;
|
|
teek_check_info.buf_id = check_info.buf_id;
|
|
teek_check_info.buf_smmu_fd = check_info.dma_buf_handle;
|
|
teek_check_info.buf_len = dma_buf_addr->size;
|
|
|
|
operation.started = 1;
|
|
operation.params[0].tmpref.buffer = (void *)&teek_check_info;
|
|
operation.params[0].tmpref.size = sizeof(ssm_teek_check_buf_ctl);
|
|
operation.params[1].memfd.fd = teek_check_info.buf_smmu_fd;
|
|
operation.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INPUT, TEEC_SECSMMU_HAND_INPUT, TEEC_NONE, TEEC_NONE);
|
|
result = TEEK_InvokeCommand(&g_teec_session,
|
|
TEEC_CMD_SSM_CHECK_BUF,
|
|
&operation,
|
|
&origin);
|
|
if (result != TEEC_SUCCESS) {
|
|
soc_log_err("TEEC invoke get intent fail:%x\n", result);
|
|
return result;
|
|
}
|
|
|
|
soc_info_func_exit();
|
|
return TD_SUCCESS;
|
|
}
|
|
|
|
td_s32 drv_ssm_teec_send_tbl(td_handle session_handle, ext_ssm_send_policy_tbl *p)
|
|
{
|
|
TEEC_Operation operation = {0};
|
|
TEEC_Result result;
|
|
td_u32 origin = 0;
|
|
|
|
soc_info_func_enter();
|
|
if (ssm_check_support() == TD_FALSE) {
|
|
return TD_SUCCESS;
|
|
}
|
|
soc_log_info("%s %d session_handle=0x%x\n", __func__, __LINE__, session_handle);
|
|
operation.started = 1;
|
|
operation.params[0].tmpref.buffer = (void *)p; /* the fd in this struct is useless */
|
|
operation.params[0].tmpref.size = sizeof(ext_ssm_send_policy_tbl);
|
|
operation.params[1].value.a = session_handle;
|
|
operation.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INPUT, TEEC_VALUE_INOUT, TEEC_NONE, TEEC_NONE);
|
|
result = TEEK_InvokeCommand(&g_teec_session,
|
|
TEEC_CMD_SSM_SEND_POLICY_TBL,
|
|
&operation,
|
|
&origin);
|
|
if (result != TEEC_SUCCESS) {
|
|
soc_log_err("TEEC drv_ssm_teec_send_tblfail:%x\n", result);
|
|
return result;
|
|
}
|
|
|
|
soc_info_func_exit();
|
|
return TD_SUCCESS;
|
|
}
|
|
#endif
|
|
|
|
td_s32 drv_ssm_teec_set_spread_cfg(soc_logic_mod_id module_id, td_u32 val)
|
|
{
|
|
#ifdef CONFIG_SOCT_TEE_SUPPORT
|
|
TEEC_Operation operation = {0};
|
|
TEEC_Result result;
|
|
td_u32 origin = 0;
|
|
|
|
soc_dbg_func_enter();
|
|
soc_log_dbg("%s %d module_id=%d, val=0x%x\n", __func__, __LINE__, module_id, val);
|
|
operation.started = 1;
|
|
operation.params[0].value.a = (td_u32)(module_id);
|
|
operation.params[0].value.b = (td_u32)(val);
|
|
operation.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INOUT, TEEC_NONE, TEEC_NONE, TEEC_NONE);
|
|
result = TEEK_InvokeCommand(&g_teec_session,
|
|
TEEC_CMD_SSM_SET_SPREAD_CFG,
|
|
&operation,
|
|
&origin);
|
|
if (result != TEEC_SUCCESS) {
|
|
soc_log_err("TEEC invoke set spread_cfg fail:%x\n", result);
|
|
return result;
|
|
}
|
|
soc_dbg_func_exit();
|
|
return TD_SUCCESS;
|
|
#else
|
|
return TD_FAILURE;
|
|
#endif
|
|
}
|
|
|
|
td_s32 drv_ssm_teec_iommu_config(soc_logic_mod_id module_id)
|
|
{
|
|
#ifdef CONFIG_SOCT_TEE_SUPPORT
|
|
TEEC_Operation operation = {0};
|
|
TEEC_Result result;
|
|
td_u32 origin = 0;
|
|
|
|
soc_info_func_enter();
|
|
soc_log_info("%s %d module_id=%d\n", __func__, __LINE__, module_id);
|
|
operation.started = 1;
|
|
operation.params[0].value.a = (td_u32)(module_id);
|
|
operation.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INOUT, TEEC_NONE, TEEC_NONE, TEEC_NONE);
|
|
result = TEEK_InvokeCommand(&g_teec_session,
|
|
TEEC_CMD_SSM_IOMMU_CONFIG,
|
|
&operation,
|
|
&origin);
|
|
if (result != TEEC_SUCCESS) {
|
|
soc_log_err("TEEC invoke set iommu tag fail:%x\n", result);
|
|
return result;
|
|
}
|
|
soc_info_func_exit();
|
|
return TD_SUCCESS;
|
|
#else
|
|
return TD_FAILURE;
|
|
#endif
|
|
}
|
|
|
|
td_void drv_ssm_error_handler(struct file *ssm_filp)
|
|
{
|
|
td_u32 i;
|
|
|
|
if (ssm_check_support() == TD_FALSE) {
|
|
return;
|
|
}
|
|
for (i = 0; i < SSM_MAX_SESSION_NUM; i++) {
|
|
if (g_ssm_dev.chan_info[i].filp != ssm_filp) {
|
|
continue;
|
|
}
|
|
|
|
(td_void)ssm_do_destroy(g_ssm_dev.chan_info[i].ssm_handle);
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
td_s32 drv_ssm_proc_read(td_void *fp)
|
|
{
|
|
if (fp == TD_NULL) {
|
|
soc_log_err("drv_ssm_proc_read args is null\n");
|
|
return TD_FAILURE;
|
|
}
|
|
osal_seq_printf(fp, "ree_version :%s\n", g_ssm_ree_version);
|
|
osal_seq_printf(fp, "tee_version :%s\n", g_ssm_tee_version);
|
|
osal_seq_printf(fp, "sa_version :%s\n", g_ssm_sa_version);
|
|
ssm_dump_context();
|
|
return TD_SUCCESS;
|
|
}
|
|
|
|
td_s32 drv_ssm_create_proc(td_char *name, fn_ssm_proc_read read_fn, osal_proc_cmd *cmd_list, td_u32 cmd_cnt)
|
|
{
|
|
osal_proc_entry *item = TD_NULL;
|
|
|
|
if (name == TD_NULL) {
|
|
soc_log_err("drv_ssm_create_proc args is null\n");
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
item = osal_proc_add(name, strlen(name));
|
|
if (item == TD_NULL) {
|
|
soc_log_err("drv_ssm_create_proc osal_proc_add failed\n");
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
item->read = read_fn;
|
|
item->cmd_list = cmd_list;
|
|
item->cmd_cnt = cmd_cnt;
|
|
|
|
return TD_SUCCESS;
|
|
}
|
|
|
|
td_void drv_ssm_destroy_proc(td_char *name)
|
|
{
|
|
if (name == TD_NULL) {
|
|
soc_log_err("drv_ssm_destroy_proc args is null\n");
|
|
return;
|
|
}
|
|
osal_proc_remove(name, strlen(name));
|
|
}
|
|
|
|
td_s32 drv_ssm_set_tee_log_level(td_u32 level)
|
|
{
|
|
#ifdef CONFIG_SOCT_TEE_SUPPORT
|
|
TEEC_Operation operation = {0};
|
|
TEEC_Result result;
|
|
td_u32 origin = 0;
|
|
|
|
soc_info_func_enter();
|
|
operation.started = 1;
|
|
operation.params[0].value.a = level;
|
|
operation.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT, TEEC_NONE, TEEC_NONE, TEEC_NONE);
|
|
result = TEEK_InvokeCommand(&g_teec_session,
|
|
TEEC_CMD_SSM_TEE_LOG_LEVEL,
|
|
&operation,
|
|
&origin);
|
|
if (result != TEEC_SUCCESS) {
|
|
soc_log_err("TEEC invoke log level fail:%x\n", result);
|
|
return result;
|
|
}
|
|
soc_info_func_exit();
|
|
return TD_SUCCESS;
|
|
#else
|
|
return TD_FAILURE;
|
|
#endif
|
|
}
|
|
|
|
/****************************************************************
|
|
*
|
|
* external driver ssm APIs, which can be called by other modules
|
|
* All functions name are started with "ext_"
|
|
*
|
|
****************************************************************/
|
|
td_s32 ext_drv_ssm_iommu_config(soc_logic_mod_id mod_id)
|
|
{
|
|
return drv_ssm_teec_iommu_config(mod_id);
|
|
}
|
|
|
|
td_s32 ext_drv_ssm_set_spread_cfg(soc_logic_mod_id mod_id, td_u32 val)
|
|
{
|
|
return drv_ssm_teec_set_spread_cfg(mod_id, val);
|
|
}
|
|
|
|
td_s32 ext_drv_ssm_attach_buffer(ext_drv_ssm_buf_attach_info attach_info, td_u64 *sec_info_addr)
|
|
{
|
|
ssm_teek_attach_buf_ctl attach_ctl = {0};
|
|
td_s64 fd;
|
|
td_s32 ret;
|
|
|
|
if (ssm_check_support() == TD_FALSE) {
|
|
return TD_SUCCESS;
|
|
}
|
|
ssm_check_pointer_return_if_fail(sec_info_addr);
|
|
|
|
attach_ctl.buf_id = attach_info.buf_id;
|
|
attach_ctl.module_handle = attach_info.module_handle;
|
|
attach_ctl.session_handle = attach_info.session_handle;
|
|
|
|
fd = osal_mem_create_fd((struct dma_buf *)(uintptr_t)attach_info.dma_buf_addr, OSAL_O_CLOEXEC);
|
|
if (fd < 0) {
|
|
soc_log_err("cannot get sec buffer fd\n");
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
attach_ctl.fd = fd;
|
|
attach_ctl.buf_len = ((struct dma_buf *)(uintptr_t)attach_info.dma_buf_addr)->size;
|
|
|
|
ret = ssm_do_teec_attach_buffer(&attach_ctl, sec_info_addr);
|
|
if (ret != TD_SUCCESS) {
|
|
soc_log_err("cannot attach buffer!\n");
|
|
}
|
|
|
|
osal_mem_close_fd(fd);
|
|
return TD_SUCCESS;
|
|
}
|
|
|
|
EXPORT_SYMBOL(ext_drv_ssm_attach_buffer);
|
|
EXPORT_SYMBOL(ext_drv_ssm_iommu_config);
|
|
EXPORT_SYMBOL(ext_drv_ssm_set_spread_cfg);
|