diff options
Diffstat (limited to 'roms/u-boot/drivers/tee/optee/supplicant.c')
-rw-r--r-- | roms/u-boot/drivers/tee/optee/supplicant.c | 100 |
1 files changed, 100 insertions, 0 deletions
diff --git a/roms/u-boot/drivers/tee/optee/supplicant.c b/roms/u-boot/drivers/tee/optee/supplicant.c new file mode 100644 index 000000000..f9dd874b5 --- /dev/null +++ b/roms/u-boot/drivers/tee/optee/supplicant.c @@ -0,0 +1,100 @@ +// SPDX-License-Identifier: BSD-2-Clause +/* + * Copyright (c) 2018, Linaro Limited + */ + +#include <common.h> +#include <log.h> +#include <malloc.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("REE FS storage isn't available\n"); + arg->ret = TEE_ERROR_STORAGE_NOT_AVAILABLE; + break; + case OPTEE_MSG_RPC_CMD_RPMB: + optee_suppl_cmd_rpmb(dev, arg); + break; + case OPTEE_MSG_RPC_CMD_I2C_TRANSFER: + optee_suppl_cmd_i2c_transfer(arg); + break; + default: + arg->ret = TEE_ERROR_NOT_IMPLEMENTED; + } + + arg->ret_origin = TEE_ORIGIN_COMMS; +} |