unplugged-kernel/drivers/misc/mediatek/cmdq/v3/cmdq_sec_gp.c

197 lines
5.4 KiB
C
Raw Normal View History

// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (c) 2015 MediaTek Inc.
*/
#include "cmdq_core.h"
#include "cmdq_sec_gp.h"
#define UUID_STR "09010000000000000000000000000000"
void cmdq_sec_setup_tee_context(struct cmdq_sec_tee_context *tee)
{
/* 09010000 0000 0000 0000000000000000 */
tee->uuid = (struct TEEC_UUID) { 0x09010000, 0x0, 0x0,
{ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 } };
}
s32 cmdq_sec_init_context(struct cmdq_sec_tee_context *tee)
{
s32 status;
CMDQ_MSG("[SEC] enter %s\n", __func__);
#if defined(CONFIG_MICROTRUST_TEE_SUPPORT)
while (!is_teei_ready()) {
CMDQ_MSG("[SEC] Microtrust TEE is not ready, wait...\n");
msleep(1000);
}
#elif defined(CONFIG_TRUSTONIC_TEE_SUPPORT)
while (!is_mobicore_ready()) {
CMDQ_MSG("[SEC] Trustonic TEE is not ready, wait...\n");
msleep(1000);
}
#endif
CMDQ_LOG("[SEC]TEE is ready\n");
status = TEEC_InitializeContext(NULL, &tee->gp_context);
if (status != TEEC_SUCCESS)
CMDQ_ERR("[SEC]init_context fail: status:0x%x\n", status);
else
CMDQ_MSG("[SEC]init_context: status:0x%x\n", status);
return status;
}
s32 cmdq_sec_deinit_context(struct cmdq_sec_tee_context *tee)
{
TEEC_FinalizeContext(&tee->gp_context);
return 0;
}
s32 cmdq_sec_allocate_wsm(struct cmdq_sec_tee_context *tee,
void **wsm_buffer, u32 size, void **wsm_buf_ex, u32 size_ex,
void **wsm_buf_ex2, u32 size_ex2)
{
s32 status;
if (!wsm_buffer || !wsm_buf_ex || !wsm_buf_ex2)
return -EINVAL;
CMDQ_MSG("%s tee:0x%p size:%u size ex:%u size ex2:%u\n",
__func__, tee, size, size_ex, size_ex2);
tee->shared_mem.size = size;
tee->shared_mem.flags = TEEC_MEM_INPUT | TEEC_MEM_OUTPUT;
status = TEEC_AllocateSharedMemory(&tee->gp_context,
&tee->shared_mem);
if (status != TEEC_SUCCESS) {
CMDQ_LOG("[WARN][SEC]allocate_wsm: err:0x%x size:%u\n",
status, size);
} else {
CMDQ_LOG("[SEC]allocate_wsm: status:0x%x wsm:0x%p size:%u\n",
status, tee->shared_mem.buffer, size);
*wsm_buffer = (void *)tee->shared_mem.buffer;
}
tee->shared_mem_ex.size = size_ex;
tee->shared_mem_ex.flags = TEEC_MEM_INPUT | TEEC_MEM_OUTPUT;
status = TEEC_AllocateSharedMemory(&tee->gp_context,
&tee->shared_mem_ex);
if (status != TEEC_SUCCESS) {
CMDQ_LOG("[WARN][SEC]allocate_wsm: err:0x%x size_ex:%u\n",
status, size_ex);
} else {
CMDQ_LOG("[SEC]allocate_wsm: status:0x%x wsm:0x%p size ex:%u\n",
status, tee->shared_mem_ex.buffer, size_ex);
*wsm_buf_ex = (void *)tee->shared_mem_ex.buffer;
}
tee->shared_mem_ex2.size = size_ex2;
tee->shared_mem_ex2.flags = TEEC_MEM_INPUT | TEEC_MEM_OUTPUT;
status = TEEC_AllocateSharedMemory(&tee->gp_context,
&tee->shared_mem_ex2);
if (status != TEEC_SUCCESS) {
CMDQ_LOG("[WARN][SEC]allocate_wsm: err:0x%x size_ex:%u\n",
status, size_ex2);
} else {
CMDQ_LOG("[SEC]allocate_wsm: status:0x%x wsm:0x%p size ex:%u\n",
status, tee->shared_mem_ex2.buffer, size_ex2);
*wsm_buf_ex2 = (void *)tee->shared_mem_ex2.buffer;
}
return status;
}
s32 cmdq_sec_free_wsm(struct cmdq_sec_tee_context *tee,
void **wsm_buffer)
{
if (!wsm_buffer)
return -EINVAL;
TEEC_ReleaseSharedMemory(&tee->shared_mem);
*wsm_buffer = NULL;
return 0;
}
s32 cmdq_sec_open_session(struct cmdq_sec_tee_context *tee,
void *wsm_buffer)
{
s32 status, ret_origin;
if (!wsm_buffer) {
CMDQ_ERR("[SEC]open_session: invalid param wsm buffer:0x%p\n",
wsm_buffer);
return -EINVAL;
}
status = TEEC_OpenSession(&tee->gp_context,
&tee->session, &tee->uuid,
TEEC_LOGIN_PUBLIC, NULL, NULL, &ret_origin);
if (status != TEEC_SUCCESS) {
/* print error message */
CMDQ_ERR(
"[SEC]open_session fail: status:0x%x ret origin:0x%08x\n",
status, ret_origin);
} else {
CMDQ_MSG("[SEC]open_session: status:0x%x\n", status);
}
return status;
}
s32 cmdq_sec_close_session(struct cmdq_sec_tee_context *tee)
{
TEEC_CloseSession(&tee->session);
return 0;
}
s32 cmdq_sec_execute_session(struct cmdq_sec_tee_context *tee,
u32 cmd, s32 timeout_ms, bool share_mem_ex1, bool share_mem_ex2)
{
s32 status;
struct TEEC_Operation operation;
memset(&operation, 0, sizeof(struct TEEC_Operation));
#if defined(CONFIG_TRUSTONIC_TEE_SUPPORT)
operation.param_types = TEEC_PARAM_TYPES(TEEC_MEMREF_PARTIAL_INOUT,
share_mem_ex1 ? TEEC_MEMREF_PARTIAL_INOUT : TEEC_NONE,
share_mem_ex2 ? TEEC_MEMREF_PARTIAL_INOUT : TEEC_NONE,
TEEC_NONE);
#else
operation.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_PARTIAL_INOUT,
share_mem_ex1 ? TEEC_MEMREF_PARTIAL_INOUT : TEEC_NONE,
share_mem_ex2 ? TEEC_MEMREF_PARTIAL_INOUT : TEEC_NONE,
TEEC_NONE);
#endif
operation.params[0].memref.parent = &tee->shared_mem;
operation.params[0].memref.size = tee->shared_mem.size;
operation.params[0].memref.offset = 0;
if (share_mem_ex1) {
operation.params[1].memref.parent = &tee->shared_mem_ex;
operation.params[1].memref.size = tee->shared_mem_ex.size;
operation.params[1].memref.offset = 0;
}
if (share_mem_ex2) {
operation.params[2].memref.parent = &tee->shared_mem_ex2;
operation.params[2].memref.size = tee->shared_mem_ex2.size;
operation.params[2].memref.offset = 0;
}
status = TEEC_InvokeCommand(&tee->session, cmd, &operation,
NULL);
if (status != TEEC_SUCCESS)
CMDQ_ERR(
"[SEC]execute: TEEC_InvokeCommand:%u err:%d memex:%s memex2:%s\n",
cmd, status, share_mem_ex1 ? "true" : "false",
share_mem_ex2 ? "true" : "false");
else
CMDQ_MSG(
"[SEC]execute: TEEC_InvokeCommand:%u ret:%d memex:%s memex2:%s\n",
cmd, status, share_mem_ex1 ? "true" : "false",
share_mem_ex2 ? "true" : "false");
return status;
}