blob: bd146ef28997d667a70756e0dfa6cc627fb6f273 [file] [log] [blame]
// SPDX-License-Identifier: BSD-2-Clause
/*
* Copyright 2020 Broadcom.
*/
#include <tee.h>
#include <broadcom/chimp.h>
#include <linux/errno.h>
#include <string.h>
#ifdef CONFIG_CHIMP_OPTEE
#define CHMIP_BOOT_UUID { 0x6272636D, 0x2019, 0x0716, \
{ 0x42, 0x43, 0x4D, 0x5F, 0x53, 0x43, 0x48, 0x49 } }
enum {
TEE_CHIMP_FASTBOOT = 0,
TEE_CHIMP_HEALTH_STATUS,
TEE_CHIMP_HANDSHAKE_STATUS,
} tee_chmip_cmd;
struct bcm_chimp_data {
struct udevice *tee;
u32 session;
} chimp_data;
static int get_open_session(struct bcm_chimp_data *b_data)
{
const struct tee_optee_ta_uuid uuid = CHMIP_BOOT_UUID;
struct tee_open_session_arg arg;
struct udevice *tee = NULL;
int rc;
tee = tee_find_device(NULL, NULL, NULL, NULL);
if (!tee)
return -ENODEV;
memset(&arg, 0, sizeof(arg));
tee_optee_ta_uuid_to_octets(arg.uuid, &uuid);
rc = tee_open_session(tee, &arg, 0, NULL);
if (rc < 0)
return -ENODEV;
b_data->tee = tee;
b_data->session = arg.session;
return 0;
}
static int init_arg(struct tee_invoke_arg *arg, u32 func)
{
if (get_open_session(&chimp_data))
return -EINVAL;
memset(arg, 0, sizeof(struct tee_invoke_arg));
arg->func = func;
arg->session = chimp_data.session;
return 0;
}
int chimp_handshake_status_optee(u32 timeout, u32 *hs)
{
struct tee_invoke_arg arg;
struct tee_param param[1];
int ret;
ret = init_arg(&arg, TEE_CHIMP_HANDSHAKE_STATUS);
if (ret < 0)
return ret;
param[0].attr = TEE_PARAM_ATTR_TYPE_VALUE_INOUT;
param[0].u.value.a = timeout;
ret = tee_invoke_func(chimp_data.tee, &arg, ARRAY_SIZE(param), param);
if (ret < 0) {
printf("Handshake status command failed\n");
goto out;
}
switch (arg.ret) {
case TEE_SUCCESS:
*hs = param[0].u.value.a;
ret = 0;
break;
default:
ret = -EINVAL;
break;
}
out:
tee_close_session(chimp_data.tee, chimp_data.session);
chimp_data.tee = NULL;
return ret;
}
int chimp_health_status_optee(u32 *health)
{
struct tee_invoke_arg arg;
struct tee_param param[1];
int ret;
ret = init_arg(&arg, TEE_CHIMP_HEALTH_STATUS);
if (ret < 0)
return ret;
param[0].attr = TEE_PARAM_ATTR_TYPE_VALUE_OUTPUT;
ret = tee_invoke_func(chimp_data.tee, &arg, ARRAY_SIZE(param), param);
if (ret < 0) {
printf("Helath status command failed\n");
goto out;
}
switch (arg.ret) {
case TEE_SUCCESS:
*health = param[0].u.value.a;
ret = 0;
break;
default:
ret = -EINVAL;
break;
}
out:
tee_close_session(chimp_data.tee, chimp_data.session);
chimp_data.tee = NULL;
return ret;
}
int chimp_fastboot_optee(void)
{
struct tee_invoke_arg arg;
int ret;
ret = init_arg(&arg, TEE_CHIMP_FASTBOOT);
if (ret < 0)
return ret;
ret = tee_invoke_func(chimp_data.tee, &arg, 0, NULL);
if (ret < 0) {
printf("Chimp boot_fail\n");
goto out;
}
switch (arg.ret) {
case TEE_SUCCESS:
ret = 0;
break;
default:
ret = -EINVAL;
break;
}
out:
tee_close_session(chimp_data.tee, chimp_data.session);
chimp_data.tee = NULL;
return ret;
}
#else
int chimp_handshake_status_optee(u32 timeout, u32 *status)
{
printf("ChiMP handshake status fail (OPTEE not enabled)\n");
return -EINVAL;
}
int chimp_health_status_optee(u32 *status)
{
printf("ChiMP health status fail (OPTEE not enabled)\n");
return -EINVAL;
}
int chimp_fastboot_optee(void)
{
printf("ChiMP secure boot fail (OPTEE not enabled)\n");
return -EINVAL;
}
#endif /* CONFIG_CHIMP_OPTEE */