aboutsummaryrefslogtreecommitdiffstats
path: root/roms/u-boot/drivers/tee/optee/supplicant.c
diff options
context:
space:
mode:
Diffstat (limited to 'roms/u-boot/drivers/tee/optee/supplicant.c')
-rw-r--r--roms/u-boot/drivers/tee/optee/supplicant.c100
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;
+}