diff options
author | Jens Wiklander <jens.wiklander@linaro.org> | 2018-09-25 16:40:11 +0200 |
---|---|---|
committer | Tom Rini <trini@konsulko.com> | 2018-10-07 10:47:38 -0400 |
commit | d4bd3d25d8b032da8de9c79cbe103d47a3d160df (patch) | |
tree | 93c4c2d181803ca73fb0997624e2bbf63c6bc860 /drivers/tee/optee/supplicant.c | |
parent | 53b6aac7b1a1fa057403a619e3716b7f8baed211 (diff) | |
download | u-boot-d4bd3d25d8b032da8de9c79cbe103d47a3d160df.tar.gz |
tee: add OP-TEE driver
Adds a OP-TEE driver.
* Targets ARM and ARM64
* Supports using any U-Boot memory as shared memory
* Probes OP-TEE version using SMCs
* Uses OPTEE message protocol version 2 to communicate with secure world
Reviewed-by: Simon Glass <sjg@chromium.org>
Tested-by: Igor Opaniuk <igor.opaniuk@linaro.org>
Signed-off-by: Jens Wiklander <jens.wiklander@linaro.org>
Diffstat (limited to 'drivers/tee/optee/supplicant.c')
-rw-r--r-- | drivers/tee/optee/supplicant.c | 93 |
1 files changed, 93 insertions, 0 deletions
diff --git a/drivers/tee/optee/supplicant.c b/drivers/tee/optee/supplicant.c new file mode 100644 index 00000000000..2239b1bf7b3 --- /dev/null +++ b/drivers/tee/optee/supplicant.c @@ -0,0 +1,93 @@ +// SPDX-License-Identifier: BSD-2-Clause +/* + * Copyright (c) 2018, Linaro Limited + */ + +#include <common.h> +#include <log.h> +#include <tee.h> +#include <linux/types.h> + +#include "optee_msg.h" +#include "optee_msg_supplicant.h" +#include "optee_private.h" +#include "optee_smc.h" + +static void cmd_shm_alloc(struct udevice *dev, struct optee_msg_arg *arg, + void **page_list) +{ + int rc; + struct tee_shm *shm; + void *pl; + u64 ph_ptr; + + arg->ret_origin = TEE_ORIGIN_COMMS; + + if (arg->num_params != 1 || + arg->params[0].attr != OPTEE_MSG_ATTR_TYPE_VALUE_INPUT) { + arg->ret = TEE_ERROR_BAD_PARAMETERS; + return; + } + + rc = __tee_shm_add(dev, 0, NULL, arg->params[0].u.value.b, + TEE_SHM_REGISTER | TEE_SHM_ALLOC, &shm); + if (rc) { + if (rc == -ENOMEM) + arg->ret = TEE_ERROR_OUT_OF_MEMORY; + else + arg->ret = TEE_ERROR_GENERIC; + return; + } + + pl = optee_alloc_and_init_page_list(shm->addr, shm->size, &ph_ptr); + if (!pl) { + arg->ret = TEE_ERROR_OUT_OF_MEMORY; + tee_shm_free(shm); + return; + } + + *page_list = pl; + arg->params[0].attr = OPTEE_MSG_ATTR_TYPE_TMEM_OUTPUT | + OPTEE_MSG_ATTR_NONCONTIG; + arg->params[0].u.tmem.buf_ptr = ph_ptr; + arg->params[0].u.tmem.size = shm->size; + arg->params[0].u.tmem.shm_ref = (ulong)shm; + arg->ret = TEE_SUCCESS; +} + +static void cmd_shm_free(struct optee_msg_arg *arg) +{ + arg->ret_origin = TEE_ORIGIN_COMMS; + + if (arg->num_params != 1 || + arg->params[0].attr != OPTEE_MSG_ATTR_TYPE_VALUE_INPUT) { + arg->ret = TEE_ERROR_BAD_PARAMETERS; + return; + } + + tee_shm_free((struct tee_shm *)(ulong)arg->params[0].u.value.b); + arg->ret = TEE_SUCCESS; +} + +void optee_suppl_cmd(struct udevice *dev, struct tee_shm *shm_arg, + void **page_list) +{ + struct optee_msg_arg *arg = shm_arg->addr; + + switch (arg->cmd) { + case OPTEE_MSG_RPC_CMD_SHM_ALLOC: + cmd_shm_alloc(dev, arg, page_list); + break; + case OPTEE_MSG_RPC_CMD_SHM_FREE: + cmd_shm_free(arg); + break; + case OPTEE_MSG_RPC_CMD_FS: + debug("OPTEE_MSG_RPC_CMD_FS not implemented\n"); + arg->ret = TEE_ERROR_NOT_IMPLEMENTED; + break; + default: + arg->ret = TEE_ERROR_NOT_IMPLEMENTED; + } + + arg->ret_origin = TEE_ORIGIN_COMMS; +} |