197 lines
5.4 KiB
C
197 lines
5.4 KiB
C
// 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;
|
|
}
|
|
|