get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

GET /api/patches/961282/?format=api
HTTP 200 OK
Allow: GET, PUT, PATCH, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "id": 961282,
    "url": "http://patchwork.ozlabs.org/api/patches/961282/?format=api",
    "web_url": "http://patchwork.ozlabs.org/project/uboot/patch/20180823104334.16083-8-jens.wiklander@linaro.org/",
    "project": {
        "id": 18,
        "url": "http://patchwork.ozlabs.org/api/projects/18/?format=api",
        "name": "U-Boot",
        "link_name": "uboot",
        "list_id": "u-boot.lists.denx.de",
        "list_email": "u-boot@lists.denx.de",
        "web_url": null,
        "scm_url": null,
        "webscm_url": null,
        "list_archive_url": "",
        "list_archive_url_format": "",
        "commit_url_format": ""
    },
    "msgid": "<20180823104334.16083-8-jens.wiklander@linaro.org>",
    "list_archive_url": null,
    "date": "2018-08-23T10:43:26",
    "name": "[U-Boot,v2,07/15] tee: add OP-TEE driver",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": false,
    "hash": "e4cd9ce767a8e6588060e7332497cd6f046e8d6e",
    "submitter": {
        "id": 66201,
        "url": "http://patchwork.ozlabs.org/api/people/66201/?format=api",
        "name": "Jens Wiklander",
        "email": "jens.wiklander@linaro.org"
    },
    "delegate": {
        "id": 3651,
        "url": "http://patchwork.ozlabs.org/api/users/3651/?format=api",
        "username": "trini",
        "first_name": "Tom",
        "last_name": "Rini",
        "email": "trini@ti.com"
    },
    "mbox": "http://patchwork.ozlabs.org/project/uboot/patch/20180823104334.16083-8-jens.wiklander@linaro.org/mbox/",
    "series": [
        {
            "id": 62144,
            "url": "http://patchwork.ozlabs.org/api/series/62144/?format=api",
            "web_url": "http://patchwork.ozlabs.org/project/uboot/list/?series=62144",
            "date": "2018-08-23T10:43:19",
            "name": "AVB using OP-TEE",
            "version": 2,
            "mbox": "http://patchwork.ozlabs.org/series/62144/mbox/"
        }
    ],
    "comments": "http://patchwork.ozlabs.org/api/patches/961282/comments/",
    "check": "pending",
    "checks": "http://patchwork.ozlabs.org/api/patches/961282/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<u-boot-bounces@lists.denx.de>",
        "X-Original-To": "incoming@patchwork.ozlabs.org",
        "Delivered-To": "patchwork-incoming@bilbo.ozlabs.org",
        "Authentication-Results": [
            "ozlabs.org;\n\tspf=none (mailfrom) smtp.mailfrom=lists.denx.de\n\t(client-ip=81.169.180.215; helo=lists.denx.de;\n\tenvelope-from=u-boot-bounces@lists.denx.de;\n\treceiver=<UNKNOWN>)",
            "ozlabs.org;\n\tdmarc=fail (p=none dis=none) header.from=linaro.org",
            "ozlabs.org;\n\tdkim=fail reason=\"signature verification failed\" (1024-bit key;\n\tunprotected) header.d=linaro.org header.i=@linaro.org\n\theader.b=\"iA5v+M0D\"; dkim-atps=neutral"
        ],
        "Received": [
            "from lists.denx.de (dione.denx.de [81.169.180.215])\n\tby ozlabs.org (Postfix) with ESMTP id 41x1NJ1p5Cz9s5b\n\tfor <incoming@patchwork.ozlabs.org>;\n\tThu, 23 Aug 2018 20:48:16 +1000 (AEST)",
            "by lists.denx.de (Postfix, from userid 105)\n\tid D7A4AC21FCA; Thu, 23 Aug 2018 10:46:32 +0000 (UTC)",
            "from lists.denx.de (localhost [IPv6:::1])\n\tby lists.denx.de (Postfix) with ESMTP id 5A5EDC21F3B;\n\tThu, 23 Aug 2018 10:44:02 +0000 (UTC)",
            "by lists.denx.de (Postfix, from userid 105)\n\tid 0740CC21F42; Thu, 23 Aug 2018 10:43:57 +0000 (UTC)",
            "from mail-lj1-f182.google.com (mail-lj1-f182.google.com\n\t[209.85.208.182])\n\tby lists.denx.de (Postfix) with ESMTPS id CD09DC21F21\n\tfor <u-boot@lists.denx.de>; Thu, 23 Aug 2018 10:43:51 +0000 (UTC)",
            "by mail-lj1-f182.google.com with SMTP id l15-v6so3776837lji.6\n\tfor <u-boot@lists.denx.de>; Thu, 23 Aug 2018 03:43:51 -0700 (PDT)",
            "from jax.ideon.se ([85.235.10.227])\n\tby smtp.gmail.com with ESMTPSA id\n\ty5-v6sm679771ljj.75.2018.08.23.03.43.48\n\t(version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128);\n\tThu, 23 Aug 2018 03:43:49 -0700 (PDT)"
        ],
        "X-Spam-Checker-Version": "SpamAssassin 3.4.0 (2014-02-07) on lists.denx.de",
        "X-Spam-Level": "",
        "X-Spam-Status": "No, score=0.0 required=5.0 tests=RCVD_IN_MSPIKE_H2,\n\tT_DKIM_INVALID autolearn=unavailable autolearn_force=no version=3.4.0",
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google;\n\th=from:to:cc:subject:date:message-id:in-reply-to:references;\n\tbh=JBCqwUpryjhGPZh7h2XkeNu0Bu6i5CX0Nn2ogYvcqrs=;\n\tb=iA5v+M0DUDt9rXJSvvmz1MvUIFSqoVrTwCmVZ5qgvECtRpwtbBuNWJ5iUMdv/q47u4\n\t6OrdgZADzzwq54qkRevm+k16n/KadxZteKKzbE5P7goWMlG1Ja0xYh7zvmkMsAZ5Mgn/\n\tyh8hLNSgVK9nyzUNtKiDAqZ+k32AD+Y5JMZp0=",
        "X-Google-DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=1e100.net; s=20161025;\n\th=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to\n\t:references;\n\tbh=JBCqwUpryjhGPZh7h2XkeNu0Bu6i5CX0Nn2ogYvcqrs=;\n\tb=Ern4GPR4G5SaZ/uxuheMUfREiZVoGJU3oa2TJPR/qQeCQULHwcpeR3wavGsuf0AG2+\n\txSvwQu0VS7ICjJ6parm1kRRl20UW1+lWvgYN05iLSRqiolyx3IJh3HV7fkVPwS6lNdzr\n\ta1bW/27MrJsKM0EtyB99H2p0gzMmk0NJI9BVrEugwM7AFkm044P1YMIvQVa+CpCn9Wwx\n\tzsxojgP1kqtzflv+9TougQA0J4Sp4NrsUQ0ANB/QgA+DzsyCXldrftzummT/gRGESh0I\n\tGNiEv1CpG49MVZExxV0LGuTLFhbz077wENjBhOloTq/NmPEpsk6Er+XgMbNuja/6ngoE\n\tNwsQ==",
        "X-Gm-Message-State": "APzg51BAaAvpLGR6RKj63vNTmR0bCD8uue66hSQPsHaFsg7jctps2J5B\n\td+bxOavWoiuYVAQOg19cG7XYcLAxmAg=",
        "X-Google-Smtp-Source": "ANB0VdZEZMNPkQVrIUyR1nZ1a1IPRp5BOV7s0PZMrGSNruuQoyCO1qh+eF33K2sRcmCbxrCGsn9akQ==",
        "X-Received": "by 2002:a2e:1301:: with SMTP id\n\t1-v6mr2088137ljt.56.1535021030032; \n\tThu, 23 Aug 2018 03:43:50 -0700 (PDT)",
        "From": "Jens Wiklander <jens.wiklander@linaro.org>",
        "To": "u-boot@lists.denx.de",
        "Date": "Thu, 23 Aug 2018 12:43:26 +0200",
        "Message-Id": "<20180823104334.16083-8-jens.wiklander@linaro.org>",
        "X-Mailer": "git-send-email 2.17.1",
        "In-Reply-To": "<20180823104334.16083-1-jens.wiklander@linaro.org>",
        "References": "<20180823104334.16083-1-jens.wiklander@linaro.org>",
        "Cc": "Tom Rini <trini@konsulko.com>, Pierre Aubert <p.aubert@staubli.com>",
        "Subject": "[U-Boot] [PATCH v2 07/15] tee: add OP-TEE driver",
        "X-BeenThere": "u-boot@lists.denx.de",
        "X-Mailman-Version": "2.1.18",
        "Precedence": "list",
        "List-Id": "U-Boot discussion <u-boot.lists.denx.de>",
        "List-Unsubscribe": "<https://lists.denx.de/options/u-boot>,\n\t<mailto:u-boot-request@lists.denx.de?subject=unsubscribe>",
        "List-Archive": "<http://lists.denx.de/pipermail/u-boot/>",
        "List-Post": "<mailto:u-boot@lists.denx.de>",
        "List-Help": "<mailto:u-boot-request@lists.denx.de?subject=help>",
        "List-Subscribe": "<https://lists.denx.de/listinfo/u-boot>,\n\t<mailto:u-boot-request@lists.denx.de?subject=subscribe>",
        "MIME-Version": "1.0",
        "Content-Type": "text/plain; charset=\"utf-8\"",
        "Content-Transfer-Encoding": "base64",
        "Errors-To": "u-boot-bounces@lists.denx.de",
        "Sender": "\"U-Boot\" <u-boot-bounces@lists.denx.de>"
    },
    "content": "Adds a OP-TEE driver.\n\n* Targets ARM and ARM64\n* Supports using any u-boot memory as shared memory\n* Probes OP-TEE version using SMCs\n* Uses OPTEE message protocol version 2 to communicate with secure world\n\nTested-by: Igor Opaniuk <igor.opaniuk@linaro.org>\nSigned-off-by: Jens Wiklander <jens.wiklander@linaro.org>\n---\n drivers/tee/Kconfig                      |  10 +\n drivers/tee/Makefile                     |   1 +\n drivers/tee/optee/Kconfig                |   7 +\n drivers/tee/optee/Makefile               |   4 +\n drivers/tee/optee/core.c                 | 614 +++++++++++++++++++++++\n drivers/tee/optee/optee_msg.h            | 423 ++++++++++++++++\n drivers/tee/optee/optee_msg_supplicant.h | 234 +++++++++\n drivers/tee/optee/optee_private.h        |  12 +\n drivers/tee/optee/optee_smc.h            | 444 ++++++++++++++++\n drivers/tee/optee/supplicant.c           |  89 ++++\n 10 files changed, 1838 insertions(+)\n create mode 100644 drivers/tee/optee/Kconfig\n create mode 100644 drivers/tee/optee/Makefile\n create mode 100644 drivers/tee/optee/core.c\n create mode 100644 drivers/tee/optee/optee_msg.h\n create mode 100644 drivers/tee/optee/optee_msg_supplicant.h\n create mode 100644 drivers/tee/optee/optee_private.h\n create mode 100644 drivers/tee/optee/optee_smc.h\n create mode 100644 drivers/tee/optee/supplicant.c",
    "diff": "diff --git a/drivers/tee/Kconfig b/drivers/tee/Kconfig\nindex 817ab331b0f8..3e7fe6ddcc5d 100644\n--- a/drivers/tee/Kconfig\n+++ b/drivers/tee/Kconfig\n@@ -6,3 +6,13 @@ config TEE\n \thelp\n \t  This implements a generic interface towards a Trusted Execution\n \t  Environment (TEE).\n+\n+if TEE\n+\n+menu \"TEE drivers\"\n+\n+source \"drivers/tee/optee/Kconfig\"\n+\n+endmenu\n+\n+endif\ndiff --git a/drivers/tee/Makefile b/drivers/tee/Makefile\nindex b6d8e16e6211..19633b60f235 100644\n--- a/drivers/tee/Makefile\n+++ b/drivers/tee/Makefile\n@@ -1,3 +1,4 @@\n # SPDX-License-Identifier: GPL-2.0+\n \n obj-y += tee-uclass.o\n+obj-$(CONFIG_OPTEE) += optee/\ndiff --git a/drivers/tee/optee/Kconfig b/drivers/tee/optee/Kconfig\nnew file mode 100644\nindex 000000000000..8f7ebe161111\n--- /dev/null\n+++ b/drivers/tee/optee/Kconfig\n@@ -0,0 +1,7 @@\n+# OP-TEE Trusted Execution Environment Configuration\n+config OPTEE\n+\tbool \"OP-TEE\"\n+\tdepends on ARM_SMCCC\n+\thelp\n+\t  This implements the OP-TEE Trusted Execution Environment (TEE)\n+\t  driver.\ndiff --git a/drivers/tee/optee/Makefile b/drivers/tee/optee/Makefile\nnew file mode 100644\nindex 000000000000..6148feb474a5\n--- /dev/null\n+++ b/drivers/tee/optee/Makefile\n@@ -0,0 +1,4 @@\n+# SPDX-License-Identifier: GPL-2.0+\n+\n+obj-y += core.o\n+obj-y += supplicant.o\ndiff --git a/drivers/tee/optee/core.c b/drivers/tee/optee/core.c\nnew file mode 100644\nindex 000000000000..f2d92d96551b\n--- /dev/null\n+++ b/drivers/tee/optee/core.c\n@@ -0,0 +1,614 @@\n+// SPDX-License-Identifier: GPL-2.0+\n+/*\n+ * Copyright (c) 2018 Linaro Limited\n+ */\n+\n+#include <common.h>\n+#include <dm.h>\n+#include <linux/arm-smccc.h>\n+#include <linux/io.h>\n+#include <log.h>\n+#include <tee.h>\n+\n+#include \"optee_smc.h\"\n+#include \"optee_msg.h\"\n+#include \"optee_private.h\"\n+\n+#define PAGELIST_ENTRIES_PER_PAGE \\\n+\t((OPTEE_MSG_NONCONTIG_PAGE_SIZE / sizeof(u64)) - 1)\n+\n+typedef void (optee_invoke_fn)(unsigned long, unsigned long, unsigned long,\n+\t\t\t       unsigned long, unsigned long, unsigned long,\n+\t\t\t       unsigned long, unsigned long,\n+\t\t\t       struct arm_smccc_res *);\n+\n+struct optee_pdata {\n+\toptee_invoke_fn *invoke_fn;\n+};\n+\n+struct rpc_param {\n+\tu32\ta0;\n+\tu32\ta1;\n+\tu32\ta2;\n+\tu32\ta3;\n+\tu32\ta4;\n+\tu32\ta5;\n+\tu32\ta6;\n+\tu32\ta7;\n+};\n+\n+static void *reg_pair_to_ptr(u32 reg0, u32 reg1)\n+{\n+\treturn (void *)(ulong)(((u64)reg0 << 32) | reg1);\n+}\n+\n+static void reg_pair_from_64(u32 *reg0, u32 *reg1, u64 val)\n+{\n+\t*reg0 = val >> 32;\n+\t*reg1 = val;\n+}\n+\n+void *optee_alloc_and_init_page_list(void *buf, ulong len, u64 *phys_buf_ptr)\n+{\n+\tconst unsigned int page_size = OPTEE_MSG_NONCONTIG_PAGE_SIZE;\n+\tconst phys_addr_t page_mask = page_size - 1;\n+\tu8 *buf_base;\n+\tunsigned int page_offset;\n+\tunsigned int num_pages;\n+\tunsigned int list_size;\n+\tunsigned int n;\n+\tvoid *page_list;\n+\tstruct {\n+\t\tu64 pages_list[PAGELIST_ENTRIES_PER_PAGE];\n+\t\tu64 next_page_data;\n+\t} *pages_data;\n+\n+\tpage_offset = (ulong)buf & page_mask;\n+\tnum_pages = roundup(page_offset + len, page_size) / page_size;\n+\tlist_size = DIV_ROUND_UP(num_pages, PAGELIST_ENTRIES_PER_PAGE) *\n+\t\t    page_size;\n+\tpage_list = memalign(page_size, list_size);\n+\tif (!page_list)\n+\t\treturn NULL;\n+\n+\tpages_data = page_list;\n+\tbuf_base = (u8 *)(rounddown((ulong)buf, page_size));\n+\tn = 0;\n+\twhile (num_pages) {\n+\t\tpages_data->pages_list[n] = virt_to_phys(buf_base);\n+\t\tn++;\n+\t\tbuf_base += page_size;\n+\t\tnum_pages--;\n+\n+\t\tif (n == PAGELIST_ENTRIES_PER_PAGE) {\n+\t\t\tpages_data->next_page_data =\n+\t\t\t\tvirt_to_phys(pages_data + 1);\n+\t\t\tpages_data++;\n+\t\t\tn = 0;\n+\t\t}\n+\t}\n+\n+\t*phys_buf_ptr = virt_to_phys(page_list) | page_offset;\n+\treturn page_list;\n+}\n+\n+static void optee_get_version(struct udevice *dev,\n+\t\t\t      struct tee_version_data *vers)\n+{\n+\tstruct tee_version_data v = {\n+\t\t.gen_caps = TEE_GEN_CAP_GP | TEE_GEN_CAP_REG_MEM,\n+\t};\n+\n+\t*vers = v;\n+}\n+\n+static struct tee_shm *get_msg_arg(struct udevice *dev, ulong num_params,\n+\t\t\t\t   struct optee_msg_arg **msg_arg)\n+{\n+\tstruct tee_shm *shm;\n+\tstruct optee_msg_arg *ma;\n+\n+\tshm = __tee_shm_add(dev, OPTEE_MSG_NONCONTIG_PAGE_SIZE, NULL,\n+\t\t\t    OPTEE_MSG_GET_ARG_SIZE(num_params), TEE_SHM_ALLOC);\n+\tif (!shm)\n+\t\treturn NULL;\n+\n+\tma = shm->addr;\n+\tmemset(ma, 0, OPTEE_MSG_GET_ARG_SIZE(num_params));\n+\tma->num_params = num_params;\n+\t*msg_arg = ma;\n+\n+\treturn shm;\n+}\n+\n+static int to_msg_param(struct optee_msg_param *msg_params, ulong num_params,\n+\t\t\tconst struct tee_param *params)\n+{\n+\tulong n;\n+\n+\tfor (n = 0; n < num_params; n++) {\n+\t\tconst struct tee_param *p = params + n;\n+\t\tstruct optee_msg_param *mp = msg_params + n;\n+\n+\t\tswitch (p->attr) {\n+\t\tcase TEE_PARAM_ATTR_TYPE_NONE:\n+\t\t\tmp->attr = OPTEE_MSG_ATTR_TYPE_NONE;\n+\t\t\tmemset(&mp->u, 0, sizeof(mp->u));\n+\t\t\tbreak;\n+\t\tcase TEE_PARAM_ATTR_TYPE_VALUE_INPUT:\n+\t\tcase TEE_PARAM_ATTR_TYPE_VALUE_OUTPUT:\n+\t\tcase TEE_PARAM_ATTR_TYPE_VALUE_INOUT:\n+\t\t\tmp->attr = OPTEE_MSG_ATTR_TYPE_VALUE_INPUT + p->attr -\n+\t\t\t\t   TEE_PARAM_ATTR_TYPE_VALUE_INPUT;\n+\t\t\tmp->u.value.a = p->u.value.a;\n+\t\t\tmp->u.value.b = p->u.value.b;\n+\t\t\tmp->u.value.c = p->u.value.c;\n+\t\t\tbreak;\n+\t\tcase TEE_PARAM_ATTR_TYPE_MEMREF_INPUT:\n+\t\tcase TEE_PARAM_ATTR_TYPE_MEMREF_OUTPUT:\n+\t\tcase TEE_PARAM_ATTR_TYPE_MEMREF_INOUT:\n+\t\t\tmp->attr = OPTEE_MSG_ATTR_TYPE_RMEM_INPUT + p->attr -\n+\t\t\t\t   TEE_PARAM_ATTR_TYPE_MEMREF_INPUT;\n+\t\t\tmp->u.rmem.shm_ref = (ulong)p->u.memref.shm;\n+\t\t\tmp->u.rmem.size = p->u.memref.size;\n+\t\t\tmp->u.rmem.offs = p->u.memref.shm_offs;\n+\t\t\tbreak;\n+\t\tdefault:\n+\t\t\treturn -EINVAL;\n+\t\t}\n+\t}\n+\treturn 0;\n+}\n+\n+static int from_msg_param(struct tee_param *params, ulong num_params,\n+\t\t\t  const struct optee_msg_param *msg_params)\n+{\n+\tulong n;\n+\tstruct tee_shm *shm;\n+\n+\tfor (n = 0; n < num_params; n++) {\n+\t\tstruct tee_param *p = params + n;\n+\t\tconst struct optee_msg_param *mp = msg_params + n;\n+\t\tu32 attr = mp->attr & OPTEE_MSG_ATTR_TYPE_MASK;\n+\n+\t\tswitch (attr) {\n+\t\tcase OPTEE_MSG_ATTR_TYPE_NONE:\n+\t\t\tp->attr = TEE_PARAM_ATTR_TYPE_NONE;\n+\t\t\tmemset(&p->u, 0, sizeof(p->u));\n+\t\t\tbreak;\n+\t\tcase OPTEE_MSG_ATTR_TYPE_VALUE_INPUT:\n+\t\tcase OPTEE_MSG_ATTR_TYPE_VALUE_OUTPUT:\n+\t\tcase OPTEE_MSG_ATTR_TYPE_VALUE_INOUT:\n+\t\t\tp->attr = TEE_PARAM_ATTR_TYPE_VALUE_INPUT + attr -\n+\t\t\t\t  OPTEE_MSG_ATTR_TYPE_VALUE_INPUT;\n+\t\t\tp->u.value.a = mp->u.value.a;\n+\t\t\tp->u.value.b = mp->u.value.b;\n+\t\t\tp->u.value.c = mp->u.value.c;\n+\t\t\tbreak;\n+\t\tcase OPTEE_MSG_ATTR_TYPE_RMEM_INPUT:\n+\t\tcase OPTEE_MSG_ATTR_TYPE_RMEM_OUTPUT:\n+\t\tcase OPTEE_MSG_ATTR_TYPE_RMEM_INOUT:\n+\t\t\tp->attr = TEE_PARAM_ATTR_TYPE_MEMREF_INPUT + attr -\n+\t\t\t\t  OPTEE_MSG_ATTR_TYPE_RMEM_INPUT;\n+\t\t\tp->u.memref.size = mp->u.rmem.size;\n+\t\t\tshm = (struct tee_shm *)(ulong)mp->u.rmem.shm_ref;\n+\n+\t\t\tif (!shm) {\n+\t\t\t\tp->u.memref.shm_offs = 0;\n+\t\t\t\tp->u.memref.shm = NULL;\n+\t\t\t\tbreak;\n+\t\t\t}\n+\t\t\tp->u.memref.shm_offs = mp->u.rmem.offs;\n+\t\t\tp->u.memref.shm = shm;\n+\t\t\tbreak;\n+\t\tdefault:\n+\t\t\treturn -EINVAL;\n+\t\t}\n+\t}\n+\treturn 0;\n+}\n+\n+static void handle_rpc(struct udevice *dev, struct rpc_param *param,\n+\t\t       void *page_list)\n+{\n+\tstruct tee_shm *shm;\n+\n+\tswitch (OPTEE_SMC_RETURN_GET_RPC_FUNC(param->a0)) {\n+\tcase OPTEE_SMC_RPC_FUNC_ALLOC:\n+\t\tshm = __tee_shm_add(dev, OPTEE_MSG_NONCONTIG_PAGE_SIZE, NULL,\n+\t\t\t\t    param->a1,\n+\t\t\t\t    TEE_SHM_ALLOC | TEE_SHM_REGISTER);\n+\t\tif (shm) {\n+\t\t\treg_pair_from_64(&param->a1, &param->a2,\n+\t\t\t\t\t virt_to_phys(shm->addr));\n+\t\t\t/* \"cookie\" */\n+\t\t\treg_pair_from_64(&param->a4, &param->a5, (ulong)shm);\n+\t\t} else {\n+\t\t\tparam->a1 = 0;\n+\t\t\tparam->a2 = 0;\n+\t\t\tparam->a4 = 0;\n+\t\t\tparam->a5 = 0;\n+\t\t}\n+\t\tbreak;\n+\tcase OPTEE_SMC_RPC_FUNC_FREE:\n+\t\tshm = reg_pair_to_ptr(param->a1, param->a2);\n+\t\ttee_shm_free(shm);\n+\t\tbreak;\n+\tcase OPTEE_SMC_RPC_FUNC_FOREIGN_INTR:\n+\t\tbreak;\n+\tcase OPTEE_SMC_RPC_FUNC_CMD:\n+\t\tshm = reg_pair_to_ptr(param->a1, param->a2);\n+\t\toptee_suppl_cmd(dev, shm, page_list);\n+\t\tbreak;\n+\tdefault:\n+\t\tbreak;\n+\t}\n+\n+\tparam->a0 = OPTEE_SMC_CALL_RETURN_FROM_RPC;\n+}\n+\n+static u32 call_err_to_res(u32 call_err)\n+{\n+\tswitch (call_err) {\n+\tcase OPTEE_SMC_RETURN_OK:\n+\t\treturn TEE_SUCCESS;\n+\tdefault:\n+\t\treturn TEE_ERROR_BAD_PARAMETERS;\n+\t}\n+}\n+\n+static u32 do_call_with_arg(struct udevice *dev, struct optee_msg_arg *arg)\n+{\n+\tstruct optee_pdata *pdata = dev_get_platdata(dev);\n+\tstruct rpc_param param = { .a0 = OPTEE_SMC_CALL_WITH_ARG };\n+\tvoid *page_list = NULL;\n+\n+\treg_pair_from_64(&param.a1, &param.a2, virt_to_phys(arg));\n+\twhile (true) {\n+\t\tstruct arm_smccc_res res;\n+\n+\t\tpdata->invoke_fn(param.a0, param.a1, param.a2, param.a3,\n+\t\t\t\t param.a4, param.a5, param.a6, param.a7, &res);\n+\n+\t\tfree(page_list);\n+\t\tpage_list = NULL;\n+\n+\t\tif (OPTEE_SMC_RETURN_IS_RPC(res.a0)) {\n+\t\t\tparam.a0 = res.a0;\n+\t\t\tparam.a1 = res.a1;\n+\t\t\tparam.a2 = res.a2;\n+\t\t\tparam.a3 = res.a3;\n+\t\t\thandle_rpc(dev, &param, &page_list);\n+\t\t} else {\n+\t\t\treturn call_err_to_res(res.a0);\n+\t\t}\n+\t}\n+}\n+\n+static int optee_close_session(struct udevice *dev, u32 session)\n+{\n+\tstruct tee_shm *shm;\n+\tstruct optee_msg_arg *msg_arg;\n+\n+\tshm = get_msg_arg(dev, 0, &msg_arg);\n+\tif (!shm)\n+\t\treturn -ENOMEM;\n+\n+\tmsg_arg->cmd = OPTEE_MSG_CMD_CLOSE_SESSION;\n+\tmsg_arg->session = session;\n+\tdo_call_with_arg(dev, msg_arg);\n+\n+\ttee_shm_free(shm);\n+\treturn 0;\n+}\n+\n+static int optee_open_session(struct udevice *dev,\n+\t\t\t      struct tee_open_session_arg *arg,\n+\t\t\t      ulong num_params, struct tee_param *params)\n+{\n+\tint rc;\n+\tstruct tee_shm *shm;\n+\tstruct optee_msg_arg *msg_arg;\n+\n+\tshm = get_msg_arg(dev, num_params + 2, &msg_arg);\n+\tif (!shm)\n+\t\treturn -ENOMEM;\n+\n+\tmsg_arg->cmd = OPTEE_MSG_CMD_OPEN_SESSION;\n+\t/*\n+\t * Initialize and add the meta parameters needed when opening a\n+\t * session.\n+\t */\n+\tmsg_arg->params[0].attr = OPTEE_MSG_ATTR_TYPE_VALUE_INPUT |\n+\t\t\t\t  OPTEE_MSG_ATTR_META;\n+\tmsg_arg->params[1].attr = OPTEE_MSG_ATTR_TYPE_VALUE_INPUT |\n+\t\t\t\t  OPTEE_MSG_ATTR_META;\n+\tmemcpy(&msg_arg->params[0].u.value, arg->uuid, sizeof(arg->uuid));\n+\tmemcpy(&msg_arg->params[1].u.value, arg->uuid, sizeof(arg->clnt_uuid));\n+\tmsg_arg->params[1].u.value.c = arg->clnt_login;\n+\n+\trc = to_msg_param(msg_arg->params + 2, num_params, params);\n+\tif (rc)\n+\t\tgoto out;\n+\n+\targ->ret = do_call_with_arg(dev, msg_arg);\n+\tif (arg->ret) {\n+\t\targ->ret_origin = TEE_ORIGIN_COMMS;\n+\t\tgoto out;\n+\t}\n+\n+\tif (from_msg_param(params, num_params, msg_arg->params + 2)) {\n+\t\targ->ret = TEE_ERROR_COMMUNICATION;\n+\t\targ->ret_origin = TEE_ORIGIN_COMMS;\n+\t\t/* Close session again to avoid leakage */\n+\t\toptee_close_session(dev, msg_arg->session);\n+\t\tgoto out;\n+\t}\n+\n+\targ->session = msg_arg->session;\n+\targ->ret = msg_arg->ret;\n+\targ->ret_origin = msg_arg->ret_origin;\n+out:\n+\ttee_shm_free(shm);\n+\n+\treturn rc;\n+}\n+\n+static int optee_invoke_func(struct udevice *dev, struct tee_invoke_arg *arg,\n+\t\t\t     ulong num_params, struct tee_param *params)\n+{\n+\tstruct tee_shm *shm;\n+\tstruct optee_msg_arg *msg_arg;\n+\tint rc;\n+\n+\tshm = get_msg_arg(dev, num_params, &msg_arg);\n+\tif (!shm)\n+\t\treturn -ENOMEM;\n+\tmsg_arg->cmd = OPTEE_MSG_CMD_INVOKE_COMMAND;\n+\tmsg_arg->func = arg->func;\n+\tmsg_arg->session = arg->session;\n+\n+\trc = to_msg_param(msg_arg->params, num_params, params);\n+\tif (rc)\n+\t\tgoto out;\n+\n+\targ->ret = do_call_with_arg(dev, msg_arg);\n+\tif (arg->ret) {\n+\t\targ->ret_origin = TEE_ORIGIN_COMMS;\n+\t\tgoto out;\n+\t}\n+\n+\tif (from_msg_param(params, num_params, msg_arg->params)) {\n+\t\targ->ret = TEE_ERROR_COMMUNICATION;\n+\t\targ->ret_origin = TEE_ORIGIN_COMMS;\n+\t\tgoto out;\n+\t}\n+\n+\targ->ret = msg_arg->ret;\n+\targ->ret_origin = msg_arg->ret_origin;\n+out:\n+\ttee_shm_free(shm);\n+\treturn rc;\n+}\n+\n+static int optee_shm_register(struct udevice *dev, struct tee_shm *shm)\n+{\n+\tstruct tee_shm *shm_arg;\n+\tstruct optee_msg_arg *msg_arg;\n+\tvoid *pl;\n+\tu64 ph_ptr;\n+\tint rc = 0;\n+\n+\tshm_arg = get_msg_arg(dev, 1, &msg_arg);\n+\tif (!shm_arg)\n+\t\treturn -ENOMEM;\n+\n+\tpl = optee_alloc_and_init_page_list(shm->addr, shm->size, &ph_ptr);\n+\tif (!pl) {\n+\t\trc = -ENOMEM;\n+\t\tgoto out;\n+\t}\n+\n+\tmsg_arg->cmd = OPTEE_MSG_CMD_REGISTER_SHM;\n+\tmsg_arg->params->attr = OPTEE_MSG_ATTR_TYPE_TMEM_OUTPUT |\n+\t\t\t\tOPTEE_MSG_ATTR_NONCONTIG;\n+\tmsg_arg->params->u.tmem.buf_ptr = ph_ptr;\n+\tmsg_arg->params->u.tmem.shm_ref = (ulong)shm;\n+\tmsg_arg->params->u.tmem.size = shm->size;\n+\n+\tif (do_call_with_arg(dev, msg_arg) || msg_arg->ret)\n+\t\trc = -EINVAL;\n+\n+\tfree(pl);\n+out:\n+\ttee_shm_free(shm_arg);\n+\treturn rc;\n+}\n+\n+static int optee_shm_unregister(struct udevice *dev, struct tee_shm *shm)\n+{\n+\tstruct tee_shm *shm_arg;\n+\tstruct optee_msg_arg *msg_arg;\n+\tint rc = 0;\n+\n+\tshm_arg = get_msg_arg(dev, 1, &msg_arg);\n+\tif (!shm_arg)\n+\t\treturn -ENOMEM;\n+\n+\tmsg_arg->cmd = OPTEE_MSG_CMD_UNREGISTER_SHM;\n+\tmsg_arg->params[0].attr = OPTEE_MSG_ATTR_TYPE_RMEM_INPUT;\n+\tmsg_arg->params[0].u.rmem.shm_ref = (ulong)shm;\n+\n+\tif (do_call_with_arg(dev, msg_arg) || msg_arg->ret)\n+\t\trc = -EINVAL;\n+\ttee_shm_free(shm_arg);\n+\treturn rc;\n+}\n+\n+static const struct tee_driver_ops optee_ops = {\n+\t.get_version = optee_get_version,\n+\t.open_session = optee_open_session,\n+\t.close_session = optee_close_session,\n+\t.invoke_func = optee_invoke_func,\n+\t.shm_register = optee_shm_register,\n+\t.shm_unregister = optee_shm_unregister,\n+};\n+\n+static bool is_optee_api(optee_invoke_fn *invoke_fn)\n+{\n+\tstruct arm_smccc_res res;\n+\n+\tinvoke_fn(OPTEE_SMC_CALLS_UID, 0, 0, 0, 0, 0, 0, 0, &res);\n+\n+\treturn res.a0 == OPTEE_MSG_UID_0 && res.a1 == OPTEE_MSG_UID_1 &&\n+\t       res.a2 == OPTEE_MSG_UID_2 && res.a3 == OPTEE_MSG_UID_3;\n+}\n+\n+static void print_os_revision(optee_invoke_fn *invoke_fn)\n+{\n+\tunion {\n+\t\tstruct arm_smccc_res smccc;\n+\t\tstruct optee_smc_call_get_os_revision_result result;\n+\t} res = {\n+\t\t.result = {\n+\t\t.build_id = 0\n+\t\t}\n+\t};\n+\n+\tinvoke_fn(OPTEE_SMC_CALL_GET_OS_REVISION, 0, 0, 0, 0, 0, 0, 0,\n+\t\t  &res.smccc);\n+\n+\tif (res.result.build_id)\n+\t\tdebug(\"OP-TEE revision %lu.%lu (%08lx)\\n\", res.result.major,\n+\t\t      res.result.minor, res.result.build_id);\n+\telse\n+\t\tdebug(\"OP-TEE revision %lu.%lu\\n\", res.result.major,\n+\t\t      res.result.minor);\n+}\n+\n+static bool api_revision_is_compatible(optee_invoke_fn *invoke_fn)\n+{\n+\tunion {\n+\t\tstruct arm_smccc_res smccc;\n+\t\tstruct optee_smc_calls_revision_result result;\n+\t} res;\n+\n+\tinvoke_fn(OPTEE_SMC_CALLS_REVISION, 0, 0, 0, 0, 0, 0, 0, &res.smccc);\n+\n+\treturn res.result.major == OPTEE_MSG_REVISION_MAJOR &&\n+\t       (int)res.result.minor >= OPTEE_MSG_REVISION_MINOR;\n+}\n+\n+static bool exchange_capabilities(optee_invoke_fn *invoke_fn, u32 *sec_caps)\n+{\n+\tunion {\n+\t\tstruct arm_smccc_res smccc;\n+\t\tstruct optee_smc_exchange_capabilities_result result;\n+\t} res;\n+\n+\tinvoke_fn(OPTEE_SMC_EXCHANGE_CAPABILITIES,\n+\t\t  OPTEE_SMC_NSEC_CAP_UNIPROCESSOR, 0, 0, 0, 0, 0, 0,\n+\t\t  &res.smccc);\n+\n+\tif (res.result.status != OPTEE_SMC_RETURN_OK)\n+\t\treturn false;\n+\n+\t*sec_caps = res.result.capabilities;\n+\treturn true;\n+}\n+\n+/* Simple wrapper functions to be able to use a function pointer */\n+static void optee_smccc_smc(unsigned long a0, unsigned long a1,\n+\t\t\t    unsigned long a2, unsigned long a3,\n+\t\t\t    unsigned long a4, unsigned long a5,\n+\t\t\t    unsigned long a6, unsigned long a7,\n+\t\t\t    struct arm_smccc_res *res)\n+{\n+\tarm_smccc_smc(a0, a1, a2, a3, a4, a5, a6, a7, res);\n+}\n+\n+static void optee_smccc_hvc(unsigned long a0, unsigned long a1,\n+\t\t\t    unsigned long a2, unsigned long a3,\n+\t\t\t    unsigned long a4, unsigned long a5,\n+\t\t\t    unsigned long a6, unsigned long a7,\n+\t\t\t    struct arm_smccc_res *res)\n+{\n+\tarm_smccc_hvc(a0, a1, a2, a3, a4, a5, a6, a7, res);\n+}\n+\n+static optee_invoke_fn *get_invoke_func(struct udevice *dev)\n+{\n+\tconst char *method;\n+\n+\tdebug(\"optee: looking for conduit method in DT.\\n\");\n+\tmethod = ofnode_get_property(dev->node, \"method\", NULL);\n+\tif (!method) {\n+\t\tdebug(\"optee: missing \\\"method\\\" property\\n\");\n+\t\treturn ERR_PTR(-ENXIO);\n+\t}\n+\n+\tif (!strcmp(\"hvc\", method))\n+\t\treturn optee_smccc_hvc;\n+\telse if (!strcmp(\"smc\", method))\n+\t\treturn optee_smccc_smc;\n+\n+\tdebug(\"optee: invalid \\\"method\\\" property: %s\\n\", method);\n+\treturn ERR_PTR(-EINVAL);\n+}\n+\n+static int optee_ofdata_to_platdata(struct udevice *dev)\n+{\n+\tstruct optee_pdata *pdata = dev_get_platdata(dev);\n+\n+\tpdata->invoke_fn = get_invoke_func(dev);\n+\tif (IS_ERR(pdata->invoke_fn))\n+\t\treturn PTR_ERR(pdata->invoke_fn);\n+\n+\treturn 0;\n+}\n+\n+static int optee_probe(struct udevice *dev)\n+{\n+\tstruct optee_pdata *pdata = dev_get_platdata(dev);\n+\tu32 sec_caps;\n+\n+\tif (!is_optee_api(pdata->invoke_fn)) {\n+\t\tdebug(\"%s: OP-TEE api uid mismatch\\n\", __func__);\n+\t\treturn -ENOENT;\n+\t}\n+\n+\tprint_os_revision(pdata->invoke_fn);\n+\n+\tif (!api_revision_is_compatible(pdata->invoke_fn)) {\n+\t\tdebug(\"%s: OP-TEE api revision mismatch\\n\", __func__);\n+\t\treturn -ENOENT;\n+\t}\n+\n+\t/*\n+\t * OP-TEE can use both shared memory via predefined pool or as\n+\t * dynamic shared memory provided by normal world. To keep things\n+\t * simple we're only using dynamic shared memory in this driver.\n+\t */\n+\tif (!exchange_capabilities(pdata->invoke_fn, &sec_caps) ||\n+\t    !(sec_caps & OPTEE_SMC_SEC_CAP_DYNAMIC_SHM)) {\n+\t\tdebug(\"%s: OP-TEE capabilities mismatch\\n\", __func__);\n+\t\treturn -ENOENT;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static const struct udevice_id optee_match[] = {\n+\t{ .compatible = \"linaro,optee-tz\" },\n+\t{},\n+};\n+\n+U_BOOT_DRIVER(optee) = {\n+\t.name = \"optee\",\n+\t.id = UCLASS_TEE,\n+\t.of_match = optee_match,\n+\t.ofdata_to_platdata = optee_ofdata_to_platdata,\n+\t.probe = optee_probe,\n+\t.ops = &optee_ops,\n+\t.platdata_auto_alloc_size = sizeof(struct optee_pdata),\n+};\ndiff --git a/drivers/tee/optee/optee_msg.h b/drivers/tee/optee/optee_msg.h\nnew file mode 100644\nindex 000000000000..ebc16aa8cc31\n--- /dev/null\n+++ b/drivers/tee/optee/optee_msg.h\n@@ -0,0 +1,423 @@\n+/* SPDX-License-Identifier: BSD-2-Clause */\n+/*\n+ * Copyright (c) 2015-2018, Linaro Limited\n+ */\n+\n+#ifndef _OPTEE_MSG_H\n+#define _OPTEE_MSG_H\n+\n+#include <linux/bitops.h>\n+#include <linux/types.h>\n+\n+/*\n+ * This file defines the OP-TEE message protocol used to communicate\n+ * with an instance of OP-TEE running in secure world.\n+ *\n+ * This file is divided into three sections.\n+ * 1. Formatting of messages.\n+ * 2. Requests from normal world\n+ * 3. Requests from secure world, Remote Procedure Call (RPC), handled by\n+ *    tee-supplicant.\n+ */\n+\n+/*****************************************************************************\n+ * Part 1 - formatting of messages\n+ *****************************************************************************/\n+\n+#define OPTEE_MSG_ATTR_TYPE_NONE\t\t0x0\n+#define OPTEE_MSG_ATTR_TYPE_VALUE_INPUT\t\t0x1\n+#define OPTEE_MSG_ATTR_TYPE_VALUE_OUTPUT\t0x2\n+#define OPTEE_MSG_ATTR_TYPE_VALUE_INOUT\t\t0x3\n+#define OPTEE_MSG_ATTR_TYPE_RMEM_INPUT\t\t0x5\n+#define OPTEE_MSG_ATTR_TYPE_RMEM_OUTPUT\t\t0x6\n+#define OPTEE_MSG_ATTR_TYPE_RMEM_INOUT\t\t0x7\n+#define OPTEE_MSG_ATTR_TYPE_TMEM_INPUT\t\t0x9\n+#define OPTEE_MSG_ATTR_TYPE_TMEM_OUTPUT\t\t0xa\n+#define OPTEE_MSG_ATTR_TYPE_TMEM_INOUT\t\t0xb\n+\n+#define OPTEE_MSG_ATTR_TYPE_MASK\t\tGENMASK(7, 0)\n+\n+/*\n+ * Meta parameter to be absorbed by the Secure OS and not passed\n+ * to the Trusted Application.\n+ *\n+ * Currently only used with OPTEE_MSG_CMD_OPEN_SESSION.\n+ */\n+#define OPTEE_MSG_ATTR_META\t\t\tBIT(8)\n+\n+/*\n+ * Pointer to a list of pages used to register user-defined SHM buffer.\n+ * Used with OPTEE_MSG_ATTR_TYPE_TMEM_*.\n+ * buf_ptr should point to the beginning of the buffer. Buffer will contain\n+ * list of page addresses. OP-TEE core can reconstruct contiguous buffer from\n+ * that page addresses list. Page addresses are stored as 64 bit values.\n+ * Last entry on a page should point to the next page of buffer.\n+ * Every entry in buffer should point to a 4k page beginning (12 least\n+ * significant bits must be equal to zero).\n+ *\n+ * 12 least significant bints of optee_msg_param.u.tmem.buf_ptr should hold page\n+ * offset of the user buffer.\n+ *\n+ * So, entries should be placed like members of this structure:\n+ *\n+ * struct page_data {\n+ *   uint64_t pages_array[OPTEE_MSG_NONCONTIG_PAGE_SIZE/sizeof(uint64_t) - 1];\n+ *   uint64_t next_page_data;\n+ * };\n+ *\n+ * Structure is designed to exactly fit into the page size\n+ * OPTEE_MSG_NONCONTIG_PAGE_SIZE which is a standard 4KB page.\n+ *\n+ * The size of 4KB is chosen because this is the smallest page size for ARM\n+ * architectures. If REE uses larger pages, it should divide them to 4KB ones.\n+ */\n+#define OPTEE_MSG_ATTR_NONCONTIG\t\tBIT(9)\n+\n+/*\n+ * Memory attributes for caching passed with temp memrefs. The actual value\n+ * used is defined outside the message protocol with the exception of\n+ * OPTEE_MSG_ATTR_CACHE_PREDEFINED which means the attributes already\n+ * defined for the memory range should be used. If optee_smc.h is used as\n+ * bearer of this protocol OPTEE_SMC_SHM_* is used for values.\n+ */\n+#define OPTEE_MSG_ATTR_CACHE_SHIFT\t\t16\n+#define OPTEE_MSG_ATTR_CACHE_MASK\t\tGENMASK(2, 0)\n+#define OPTEE_MSG_ATTR_CACHE_PREDEFINED\t\t0\n+\n+/*\n+ * Same values as TEE_LOGIN_* from TEE Internal API\n+ */\n+#define OPTEE_MSG_LOGIN_PUBLIC\t\t\t0x00000000\n+#define OPTEE_MSG_LOGIN_USER\t\t\t0x00000001\n+#define OPTEE_MSG_LOGIN_GROUP\t\t\t0x00000002\n+#define OPTEE_MSG_LOGIN_APPLICATION\t\t0x00000004\n+#define OPTEE_MSG_LOGIN_APPLICATION_USER\t0x00000005\n+#define OPTEE_MSG_LOGIN_APPLICATION_GROUP\t0x00000006\n+\n+/*\n+ * Page size used in non-contiguous buffer entries\n+ */\n+#define OPTEE_MSG_NONCONTIG_PAGE_SIZE\t\t4096\n+\n+/**\n+ * struct optee_msg_param_tmem - temporary memory reference parameter\n+ * @buf_ptr:\tAddress of the buffer\n+ * @size:\tSize of the buffer\n+ * @shm_ref:\tTemporary shared memory reference, pointer to a struct tee_shm\n+ *\n+ * Secure and normal world communicates pointers as physical address\n+ * instead of the virtual address. This is because secure and normal world\n+ * have completely independent memory mapping. Normal world can even have a\n+ * hypervisor which need to translate the guest physical address (AKA IPA\n+ * in ARM documentation) to a real physical address before passing the\n+ * structure to secure world.\n+ */\n+struct optee_msg_param_tmem {\n+\tu64 buf_ptr;\n+\tu64 size;\n+\tu64 shm_ref;\n+};\n+\n+/**\n+ * struct optee_msg_param_rmem - registered memory reference parameter\n+ * @offs:\tOffset into shared memory reference\n+ * @size:\tSize of the buffer\n+ * @shm_ref:\tShared memory reference, pointer to a struct tee_shm\n+ */\n+struct optee_msg_param_rmem {\n+\tu64 offs;\n+\tu64 size;\n+\tu64 shm_ref;\n+};\n+\n+/**\n+ * struct optee_msg_param_value - opaque value parameter\n+ *\n+ * Value parameters are passed unchecked between normal and secure world.\n+ */\n+struct optee_msg_param_value {\n+\tu64 a;\n+\tu64 b;\n+\tu64 c;\n+};\n+\n+/**\n+ * struct optee_msg_param - parameter used together with struct optee_msg_arg\n+ * @attr:\tattributes\n+ * @tmem:\tparameter by temporary memory reference\n+ * @rmem:\tparameter by registered memory reference\n+ * @value:\tparameter by opaque value\n+ *\n+ * @attr & OPTEE_MSG_ATTR_TYPE_MASK indicates if tmem, rmem or value is used in\n+ * the union. OPTEE_MSG_ATTR_TYPE_VALUE_* indicates value,\n+ * OPTEE_MSG_ATTR_TYPE_TMEM_* indicates @tmem and\n+ * OPTEE_MSG_ATTR_TYPE_RMEM_* indicates @rmem,\n+ * OPTEE_MSG_ATTR_TYPE_NONE indicates that none of the members are used.\n+ */\n+struct optee_msg_param {\n+\tu64 attr;\n+\tunion {\n+\t\tstruct optee_msg_param_tmem tmem;\n+\t\tstruct optee_msg_param_rmem rmem;\n+\t\tstruct optee_msg_param_value value;\n+\t} u;\n+};\n+\n+/**\n+ * struct optee_msg_arg - call argument\n+ * @cmd: Command, one of OPTEE_MSG_CMD_* or OPTEE_MSG_RPC_CMD_*\n+ * @func: Trusted Application function, specific to the Trusted Application,\n+ *\t     used if cmd == OPTEE_MSG_CMD_INVOKE_COMMAND\n+ * @session: In parameter for all OPTEE_MSG_CMD_* except\n+ *\t     OPTEE_MSG_CMD_OPEN_SESSION where it's an output parameter instead\n+ * @cancel_id: Cancellation id, a unique value to identify this request\n+ * @ret: return value\n+ * @ret_origin: origin of the return value\n+ * @num_params: number of parameters supplied to the OS Command\n+ * @params: the parameters supplied to the OS Command\n+ *\n+ * All normal calls to Trusted OS uses this struct. If cmd requires further\n+ * information than what these field holds it can be passed as a parameter\n+ * tagged as meta (setting the OPTEE_MSG_ATTR_META bit in corresponding\n+ * attrs field). All parameters tagged as meta has to come first.\n+ *\n+ * Temp memref parameters can be fragmented if supported by the Trusted OS\n+ * (when optee_smc.h is bearer of this protocol this is indicated with\n+ * OPTEE_SMC_SEC_CAP_UNREGISTERED_SHM). If a logical memref parameter is\n+ * fragmented then has all but the last fragment the\n+ * OPTEE_MSG_ATTR_FRAGMENT bit set in attrs. Even if a memref is fragmented\n+ * it will still be presented as a single logical memref to the Trusted\n+ * Application.\n+ */\n+struct optee_msg_arg {\n+\tu32 cmd;\n+\tu32 func;\n+\tu32 session;\n+\tu32 cancel_id;\n+\tu32 pad;\n+\tu32 ret;\n+\tu32 ret_origin;\n+\tu32 num_params;\n+\n+\t/* num_params tells the actual number of element in params */\n+\tstruct optee_msg_param params[0];\n+};\n+\n+/**\n+ * OPTEE_MSG_GET_ARG_SIZE - return size of struct optee_msg_arg\n+ *\n+ * @num_params: Number of parameters embedded in the struct optee_msg_arg\n+ *\n+ * Returns the size of the struct optee_msg_arg together with the number\n+ * of embedded parameters.\n+ */\n+#define OPTEE_MSG_GET_ARG_SIZE(num_params) \\\n+\t(sizeof(struct optee_msg_arg) + \\\n+\t sizeof(struct optee_msg_param) * (num_params))\n+\n+/*****************************************************************************\n+ * Part 2 - requests from normal world\n+ *****************************************************************************/\n+\n+/*\n+ * Return the following UID if using API specified in this file without\n+ * further extensions:\n+ * 384fb3e0-e7f8-11e3-af63-0002a5d5c51b.\n+ * Represented in 4 32-bit words in OPTEE_MSG_UID_0, OPTEE_MSG_UID_1,\n+ * OPTEE_MSG_UID_2, OPTEE_MSG_UID_3.\n+ */\n+#define OPTEE_MSG_UID_0\t\t\t0x384fb3e0\n+#define OPTEE_MSG_UID_1\t\t\t0xe7f811e3\n+#define OPTEE_MSG_UID_2\t\t\t0xaf630002\n+#define OPTEE_MSG_UID_3\t\t\t0xa5d5c51b\n+#define OPTEE_MSG_FUNCID_CALLS_UID\t0xFF01\n+\n+/*\n+ * Returns 2.0 if using API specified in this file without further\n+ * extensions. Represented in 2 32-bit words in OPTEE_MSG_REVISION_MAJOR\n+ * and OPTEE_MSG_REVISION_MINOR\n+ */\n+#define OPTEE_MSG_REVISION_MAJOR\t2\n+#define OPTEE_MSG_REVISION_MINOR\t0\n+#define OPTEE_MSG_FUNCID_CALLS_REVISION\t0xFF03\n+\n+/*\n+ * Get UUID of Trusted OS.\n+ *\n+ * Used by non-secure world to figure out which Trusted OS is installed.\n+ * Note that returned UUID is the UUID of the Trusted OS, not of the API.\n+ *\n+ * Returns UUID in 4 32-bit words in the same way as\n+ * OPTEE_MSG_FUNCID_CALLS_UID described above.\n+ */\n+#define OPTEE_MSG_OS_OPTEE_UUID_0\t0x486178e0\n+#define OPTEE_MSG_OS_OPTEE_UUID_1\t0xe7f811e3\n+#define OPTEE_MSG_OS_OPTEE_UUID_2\t0xbc5e0002\n+#define OPTEE_MSG_OS_OPTEE_UUID_3\t0xa5d5c51b\n+#define OPTEE_MSG_FUNCID_GET_OS_UUID\t0x0000\n+\n+/*\n+ * Get revision of Trusted OS.\n+ *\n+ * Used by non-secure world to figure out which version of the Trusted OS\n+ * is installed. Note that the returned revision is the revision of the\n+ * Trusted OS, not of the API.\n+ *\n+ * Returns revision in 2 32-bit words in the same way as\n+ * OPTEE_MSG_CALLS_REVISION described above.\n+ */\n+#define OPTEE_MSG_FUNCID_GET_OS_REVISION\t0x0001\n+\n+/*\n+ * Do a secure call with struct optee_msg_arg as argument\n+ * The OPTEE_MSG_CMD_* below defines what goes in struct optee_msg_arg::cmd\n+ *\n+ * OPTEE_MSG_CMD_OPEN_SESSION opens a session to a Trusted Application.\n+ * The first two parameters are tagged as meta, holding two value\n+ * parameters to pass the following information:\n+ * param[0].u.value.a-b uuid of Trusted Application\n+ * param[1].u.value.a-b uuid of Client\n+ * param[1].u.value.c Login class of client OPTEE_MSG_LOGIN_*\n+ *\n+ * OPTEE_MSG_CMD_INVOKE_COMMAND invokes a command a previously opened\n+ * session to a Trusted Application.  struct optee_msg_arg::func is Trusted\n+ * Application function, specific to the Trusted Application.\n+ *\n+ * OPTEE_MSG_CMD_CLOSE_SESSION closes a previously opened session to\n+ * Trusted Application.\n+ *\n+ * OPTEE_MSG_CMD_CANCEL cancels a currently invoked command.\n+ *\n+ * OPTEE_MSG_CMD_REGISTER_SHM registers a shared memory reference. The\n+ * information is passed as:\n+ * [in] param[0].attr\t\t\tOPTEE_MSG_ATTR_TYPE_TMEM_INPUT\n+ *\t\t\t\t\t[| OPTEE_MSG_ATTR_FRAGMENT]\n+ * [in] param[0].u.tmem.buf_ptr\t\tphysical address (of first fragment)\n+ * [in] param[0].u.tmem.size\t\tsize (of first fragment)\n+ * [in] param[0].u.tmem.shm_ref\t\tholds shared memory reference\n+ * ...\n+ * The shared memory can optionally be fragmented, temp memrefs can follow\n+ * each other with all but the last with the OPTEE_MSG_ATTR_FRAGMENT bit set.\n+ *\n+ * OPTEE_MSG_CMD_UNREGISTER_SHM unregisteres a previously registered shared\n+ * memory reference. The information is passed as:\n+ * [in] param[0].attr\t\t\tOPTEE_MSG_ATTR_TYPE_RMEM_INPUT\n+ * [in] param[0].u.rmem.shm_ref\t\tholds shared memory reference\n+ * [in] param[0].u.rmem.offs\t\t0\n+ * [in] param[0].u.rmem.size\t\t0\n+ */\n+#define OPTEE_MSG_CMD_OPEN_SESSION\t0\n+#define OPTEE_MSG_CMD_INVOKE_COMMAND\t1\n+#define OPTEE_MSG_CMD_CLOSE_SESSION\t2\n+#define OPTEE_MSG_CMD_CANCEL\t\t3\n+#define OPTEE_MSG_CMD_REGISTER_SHM\t4\n+#define OPTEE_MSG_CMD_UNREGISTER_SHM\t5\n+#define OPTEE_MSG_FUNCID_CALL_WITH_ARG\t0x0004\n+\n+/*****************************************************************************\n+ * Part 3 - Requests from secure world, RPC\n+ *****************************************************************************/\n+\n+/*\n+ * All RPC is done with a struct optee_msg_arg as bearer of information,\n+ * struct optee_msg_arg::arg holds values defined by OPTEE_MSG_RPC_CMD_* below\n+ *\n+ * RPC communication with tee-supplicant is reversed compared to normal\n+ * client communication desribed above. The supplicant receives requests\n+ * and sends responses.\n+ */\n+\n+/*\n+ * Load a TA into memory, defined in tee-supplicant\n+ */\n+#define OPTEE_MSG_RPC_CMD_LOAD_TA\t0\n+\n+/*\n+ * Reserved\n+ */\n+#define OPTEE_MSG_RPC_CMD_RPMB\t\t1\n+\n+/*\n+ * File system access, defined in tee-supplicant\n+ */\n+#define OPTEE_MSG_RPC_CMD_FS\t\t2\n+\n+/*\n+ * Get time\n+ *\n+ * Returns number of seconds and nano seconds since the Epoch,\n+ * 1970-01-01 00:00:00 +0000 (UTC).\n+ *\n+ * [out] param[0].u.value.a\tNumber of seconds\n+ * [out] param[0].u.value.b\tNumber of nano seconds.\n+ */\n+#define OPTEE_MSG_RPC_CMD_GET_TIME\t3\n+\n+/*\n+ * Wait queue primitive, helper for secure world to implement a wait queue.\n+ *\n+ * If secure world need to wait for a secure world mutex it issues a sleep\n+ * request instead of spinning in secure world. Conversely is a wakeup\n+ * request issued when a secure world mutex with a thread waiting thread is\n+ * unlocked.\n+ *\n+ * Waiting on a key\n+ * [in] param[0].u.value.a OPTEE_MSG_RPC_WAIT_QUEUE_SLEEP\n+ * [in] param[0].u.value.b wait key\n+ *\n+ * Waking up a key\n+ * [in] param[0].u.value.a OPTEE_MSG_RPC_WAIT_QUEUE_WAKEUP\n+ * [in] param[0].u.value.b wakeup key\n+ */\n+#define OPTEE_MSG_RPC_CMD_WAIT_QUEUE\t4\n+#define OPTEE_MSG_RPC_WAIT_QUEUE_SLEEP\t0\n+#define OPTEE_MSG_RPC_WAIT_QUEUE_WAKEUP\t1\n+\n+/*\n+ * Suspend execution\n+ *\n+ * [in] param[0].value\t.a number of milliseconds to suspend\n+ */\n+#define OPTEE_MSG_RPC_CMD_SUSPEND\t5\n+\n+/*\n+ * Allocate a piece of shared memory\n+ *\n+ * Shared memory can optionally be fragmented, to support that additional\n+ * spare param entries are allocated to make room for eventual fragments.\n+ * The spare param entries has .attr = OPTEE_MSG_ATTR_TYPE_NONE when\n+ * unused. All returned temp memrefs except the last should have the\n+ * OPTEE_MSG_ATTR_FRAGMENT bit set in the attr field.\n+ *\n+ * [in]  param[0].u.value.a\t\ttype of memory one of\n+ *\t\t\t\t\tOPTEE_MSG_RPC_SHM_TYPE_* below\n+ * [in]  param[0].u.value.b\t\trequested size\n+ * [in]  param[0].u.value.c\t\trequired alignment\n+ *\n+ * [out] param[0].u.tmem.buf_ptr\tphysical address (of first fragment)\n+ * [out] param[0].u.tmem.size\t\tsize (of first fragment)\n+ * [out] param[0].u.tmem.shm_ref\tshared memory reference\n+ * ...\n+ * [out] param[n].u.tmem.buf_ptr\tphysical address\n+ * [out] param[n].u.tmem.size\t\tsize\n+ * [out] param[n].u.tmem.shm_ref\tshared memory reference (same value\n+ *\t\t\t\t\tas in param[n-1].u.tmem.shm_ref)\n+ */\n+#define OPTEE_MSG_RPC_CMD_SHM_ALLOC\t6\n+/* Memory that can be shared with a non-secure user space application */\n+#define OPTEE_MSG_RPC_SHM_TYPE_APPL\t0\n+/* Memory only shared with non-secure kernel */\n+#define OPTEE_MSG_RPC_SHM_TYPE_KERNEL\t1\n+\n+/*\n+ * Free shared memory previously allocated with OPTEE_MSG_RPC_CMD_SHM_ALLOC\n+ *\n+ * [in]  param[0].u.value.a\t\ttype of memory one of\n+ *\t\t\t\t\tOPTEE_MSG_RPC_SHM_TYPE_* above\n+ * [in]  param[0].u.value.b\t\tvalue of shared memory reference\n+ *\t\t\t\t\treturned in param[0].u.tmem.shm_ref\n+ *\t\t\t\t\tabove\n+ */\n+#define OPTEE_MSG_RPC_CMD_SHM_FREE\t7\n+\n+#endif /* _OPTEE_MSG_H */\ndiff --git a/drivers/tee/optee/optee_msg_supplicant.h b/drivers/tee/optee/optee_msg_supplicant.h\nnew file mode 100644\nindex 000000000000..65ca6c0574b9\n--- /dev/null\n+++ b/drivers/tee/optee/optee_msg_supplicant.h\n@@ -0,0 +1,234 @@\n+/* SPDX-License-Identifier: BSD-2-Clause */\n+/*\n+ * Copyright (c) 2016-2018, Linaro Limited\n+ */\n+\n+#ifndef __OPTEE_MSG_SUPPLICANT_H\n+#define __OPTEE_MSG_SUPPLICANT_H\n+\n+/*\n+ * Load a TA into memory\n+ */\n+#define OPTEE_MSG_RPC_CMD_LOAD_TA\t0\n+\n+/*\n+ * Replay Protected Memory Block access\n+ */\n+#define OPTEE_MSG_RPC_CMD_RPMB\t\t1\n+\n+/*\n+ * File system access\n+ */\n+#define OPTEE_MSG_RPC_CMD_FS\t\t2\n+\n+/*\n+ * Define protocol for messages with .cmd == OPTEE_MSG_RPC_CMD_FS and first\n+ * parameter has the attribute OPTEE_MSG_ATTR_TYPE_VALUE_INPUT.\n+ */\n+\n+/*\n+ * Open a file\n+ *\n+ * [in]     param[0].u.value.a\tOPTEE_MRF_OPEN\n+ * [in]     param[1].u.tmem\ta string holding the file name\n+ * [out]    param[2].u.value.a\tfile descriptor of open file\n+ */\n+#define OPTEE_MRF_OPEN\t\t\t0\n+\n+/*\n+ * Create a file\n+ *\n+ * [in]     param[0].u.value.a\tOPTEE_MRF_CREATE\n+ * [in]     param[1].u.tmem\ta string holding the file name\n+ * [out]    param[2].u.value.a\tfile descriptor of open file\n+ */\n+#define OPTEE_MRF_CREATE\t\t1\n+\n+/*\n+ * Close a file\n+ *\n+ * [in]     param[0].u.value.a\tOPTEE_MRF_CLOSE\n+ * [in]     param[0].u.value.b\tfile descriptor of open file.\n+ */\n+#define OPTEE_MRF_CLOSE\t\t\t2\n+\n+/*\n+ * Read from a file\n+ *\n+ * [in]     param[0].u.value.a\tOPTEE_MRF_READ\n+ * [in]     param[0].u.value.b\tfile descriptor of open file\n+ * [in]     param[0].u.value.c\toffset into file\n+ * [out]    param[1].u.tmem\tbuffer to hold returned data\n+ */\n+#define OPTEE_MRF_READ\t\t\t3\n+\n+/*\n+ * Write to a file\n+ *\n+ * [in]     param[0].u.value.a\tOPTEE_MRF_WRITE\n+ * [in]     param[0].u.value.b\tfile descriptor of open file\n+ * [in]     param[0].u.value.c\toffset into file\n+ * [in]     param[1].u.tmem\tbuffer holding data to be written\n+ */\n+#define OPTEE_MRF_WRITE\t\t\t4\n+\n+/*\n+ * Truncate a file\n+ *\n+ * [in]     param[0].u.value.a\tOPTEE_MRF_TRUNCATE\n+ * [in]     param[0].u.value.b\tfile descriptor of open file\n+ * [in]     param[0].u.value.c\tlength of file.\n+ */\n+#define OPTEE_MRF_TRUNCATE\t\t5\n+\n+/*\n+ * Remove a file\n+ *\n+ * [in]  param[0].u.value.a\tOPTEE_MRF_REMOVE\n+ * [in]  param[1].u.tmem\ta string holding the file name\n+ */\n+#define OPTEE_MRF_REMOVE\t\t6\n+\n+/*\n+ * Rename a file\n+ *\n+ * [in]  param[0].u.value.a\tOPTEE_MRF_RENAME\n+ * [in]  param[0].u.value.b\ttrue if existing target should be removed\n+ * [in]  param[1].u.tmem\ta string holding the old file name\n+ * [in]  param[2].u.tmem\ta string holding the new file name\n+ */\n+#define OPTEE_MRF_RENAME\t\t7\n+\n+/*\n+ * Opens a directory for file listing\n+ *\n+ * [in]  param[0].u.value.a\tOPTEE_MRF_OPENDIR\n+ * [in]  param[1].u.tmem\ta string holding the name of the directory\n+ * [out] param[2].u.value.a\thandle to open directory\n+ */\n+#define OPTEE_MRF_OPENDIR\t\t8\n+\n+/*\n+ * Closes a directory handle\n+ *\n+ * [in]  param[0].u.value.a\tOPTEE_MRF_CLOSEDIR\n+ * [in]  param[0].u.value.b\thandle to open directory\n+ */\n+#define OPTEE_MRF_CLOSEDIR\t\t9\n+\n+/*\n+ * Read next file name of directory\n+ *\n+ *\n+ * [in]  param[0].u.value.a\tOPTEE_MRF_READDIR\n+ * [in]  param[0].u.value.b\thandle to open directory\n+ * [out] param[1].u.tmem\ta string holding the file name\n+ */\n+#define OPTEE_MRF_READDIR\t\t10\n+\n+/*\n+ * End of definitions for messages with .cmd == OPTEE_MSG_RPC_CMD_FS\n+ */\n+\n+/*\n+ * Command Ids 3, 4 and 5 of OPTEE_MSG_RPC_CMD_xxx macros are reserved for use\n+ * by the kernel driver.\n+ */\n+\n+/*\n+ * Shared memory allocation\n+ */\n+#define OPTEE_MSG_RPC_CMD_SHM_ALLOC\t6\n+#define OPTEE_MSG_RPC_CMD_SHM_FREE\t7\n+\n+/*\n+ * Was OPTEE_MSG_RPC_CMD_SQL_FS, which isn't supported any longer\n+ */\n+#define OPTEE_MSG_RPC_CMD_SQL_FS_RESERVED\t8\n+\n+/*\n+ * GPROF support management commands\n+ */\n+#define OPTEE_MSG_RPC_CMD_GPROF\t\t9\n+\n+/*\n+ * Socket commands\n+ */\n+#define OPTEE_MSG_RPC_CMD_SOCKET\t10\n+\n+/*\n+ * Define protocol for messages with .cmd == OPTEE_MSG_RPC_CMD_SOCKET\n+ */\n+\n+#define OPTEE_MRC_SOCKET_TIMEOUT_NONBLOCKING\t0\n+#define OPTEE_MRC_SOCKET_TIMEOUT_BLOCKING\t0xffffffff\n+\n+/*\n+ * Open socket\n+ *\n+ * [in]     param[0].u.value.a\tOPTEE_MRC_SOCKET_OPEN\n+ * [in]     param[0].u.value.b\tTA instance id\n+ * [in]     param[1].u.value.a\tserver port number\n+ * [in]     param[1].u.value.b\tprotocol, TEE_ISOCKET_PROTOCOLID_*\n+ * [in]     param[1].u.value.c\tip version TEE_IP_VERSION_* from tee_ipsocket.h\n+ * [in]     param[2].u.tmem\tserver address\n+ * [out]    param[3].u.value.a\tsocket handle (32-bit)\n+ */\n+#define OPTEE_MRC_SOCKET_OPEN\t0\n+\n+/*\n+ * Close socket\n+ *\n+ * [in]     param[0].u.value.a\tOPTEE_MRC_SOCKET_CLOSE\n+ * [in]     param[0].u.value.b\tTA instance id\n+ * [in]     param[0].u.value.c\tsocket handle\n+ */\n+#define OPTEE_MRC_SOCKET_CLOSE\t1\n+\n+/*\n+ * Close all sockets\n+ *\n+ * [in]     param[0].u.value.a\tOPTEE_MRC_SOCKET_CLOSE_ALL\n+ * [in]     param[0].u.value.b\tTA instance id\n+ */\n+#define OPTEE_MRC_SOCKET_CLOSE_ALL 2\n+\n+/*\n+ * Send data on socket\n+ *\n+ * [in]     param[0].u.value.a\tOPTEE_MRC_SOCKET_SEND\n+ * [in]     param[0].u.value.b\tTA instance id\n+ * [in]     param[0].u.value.c\tsocket handle\n+ * [in]     param[1].u.tmem\tbuffer to transmit\n+ * [in]     param[2].u.value.a\ttimeout ms or OPTEE_MRC_SOCKET_TIMEOUT_*\n+ * [out]    param[2].u.value.b\tnumber of transmitted bytes\n+ */\n+#define OPTEE_MRC_SOCKET_SEND\t3\n+\n+/*\n+ * Receive data on socket\n+ *\n+ * [in]     param[0].u.value.a\tOPTEE_MRC_SOCKET_RECV\n+ * [in]     param[0].u.value.b\tTA instance id\n+ * [in]     param[0].u.value.c\tsocket handle\n+ * [out]    param[1].u.tmem\tbuffer to receive\n+ * [in]     param[2].u.value.a\ttimeout ms or OPTEE_MRC_SOCKET_TIMEOUT_*\n+ */\n+#define OPTEE_MRC_SOCKET_RECV\t4\n+\n+/*\n+ * Perform IOCTL on socket\n+ *\n+ * [in]     param[0].u.value.a\tOPTEE_MRC_SOCKET_IOCTL\n+ * [in]     param[0].u.value.b\tTA instance id\n+ * [in]     param[0].u.value.c\tsocket handle\n+ * [in/out] param[1].u.tmem\tbuffer\n+ * [in]     param[2].u.value.a\tioctl command\n+ */\n+#define OPTEE_MRC_SOCKET_IOCTL\t5\n+\n+/*\n+ * End of definitions for messages with .cmd == OPTEE_MSG_RPC_CMD_SOCKET\n+ */\n+\n+#endif /*__OPTEE_MSG_SUPPLICANT_H*/\ndiff --git a/drivers/tee/optee/optee_private.h b/drivers/tee/optee/optee_private.h\nnew file mode 100644\nindex 000000000000..daa470f812a9\n--- /dev/null\n+++ b/drivers/tee/optee/optee_private.h\n@@ -0,0 +1,12 @@\n+/* SPDX-License-Identifier: GPL-2.0+ */\n+/*\n+ * Copyright (c) 2018 Linaro Limited\n+ */\n+\n+#ifndef __OPTEE_PRIVATE_H\n+#define __OPTEE_PRIVATE_H\n+\n+void *optee_alloc_and_init_page_list(void *buf, ulong len, u64 *phys_buf_ptr);\n+void optee_suppl_cmd(struct udevice *dev, void *shm, void **page_list);\n+\n+#endif /*__OPTEE_PRIVATE_H*/\ndiff --git a/drivers/tee/optee/optee_smc.h b/drivers/tee/optee/optee_smc.h\nnew file mode 100644\nindex 000000000000..81069ae6f8ac\n--- /dev/null\n+++ b/drivers/tee/optee/optee_smc.h\n@@ -0,0 +1,444 @@\n+/* SPDX-License-Identifier: BSD-2-Clause */\n+/*\n+ * Copyright (c) 2015-2018, Linaro Limited\n+ */\n+\n+#ifndef OPTEE_SMC_H\n+#define OPTEE_SMC_H\n+\n+#include <linux/arm-smccc.h>\n+#include <linux/bitops.h>\n+\n+#define OPTEE_SMC_STD_CALL_VAL(func_num) \\\n+\tARM_SMCCC_CALL_VAL(ARM_SMCCC_STD_CALL, ARM_SMCCC_SMC_32, \\\n+\t\t\t   ARM_SMCCC_OWNER_TRUSTED_OS, (func_num))\n+#define OPTEE_SMC_FAST_CALL_VAL(func_num) \\\n+\tARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, ARM_SMCCC_SMC_32, \\\n+\t\t\t   ARM_SMCCC_OWNER_TRUSTED_OS, (func_num))\n+\n+/*\n+ * Function specified by SMC Calling convention.\n+ */\n+#define OPTEE_SMC_FUNCID_CALLS_COUNT\t0xFF00\n+#define OPTEE_SMC_CALLS_COUNT \\\n+\tARM_SMCCC_CALL_VAL(OPTEE_SMC_FAST_CALL, SMCCC_SMC_32, \\\n+\t\t\t   SMCCC_OWNER_TRUSTED_OS_END, \\\n+\t\t\t   OPTEE_SMC_FUNCID_CALLS_COUNT)\n+\n+/*\n+ * Normal cached memory (write-back), shareable for SMP systems and not\n+ * shareable for UP systems.\n+ */\n+#define OPTEE_SMC_SHM_CACHED\t\t1\n+\n+/*\n+ * a0..a7 is used as register names in the descriptions below, on arm32\n+ * that translates to r0..r7 and on arm64 to w0..w7. In both cases it's\n+ * 32-bit registers.\n+ */\n+\n+/*\n+ * Function specified by SMC Calling convention\n+ *\n+ * Return one of the following UIDs if using API specified in this file\n+ * without further extentions:\n+ * 65cb6b93-af0c-4617-8ed6-644a8d1140f8\n+ * see also OPTEE_SMC_UID_* in optee_msg.h\n+ */\n+#define OPTEE_SMC_FUNCID_CALLS_UID OPTEE_MSG_FUNCID_CALLS_UID\n+#define OPTEE_SMC_CALLS_UID \\\n+\tARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, ARM_SMCCC_SMC_32, \\\n+\t\t\t   ARM_SMCCC_OWNER_TRUSTED_OS_END, \\\n+\t\t\t   OPTEE_SMC_FUNCID_CALLS_UID)\n+\n+/*\n+ * Function specified by SMC Calling convention\n+ *\n+ * Returns 2.0 if using API specified in this file without further extentions.\n+ * see also OPTEE_MSG_REVISION_* in optee_msg.h\n+ */\n+#define OPTEE_SMC_FUNCID_CALLS_REVISION OPTEE_MSG_FUNCID_CALLS_REVISION\n+#define OPTEE_SMC_CALLS_REVISION \\\n+\tARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, ARM_SMCCC_SMC_32, \\\n+\t\t\t   ARM_SMCCC_OWNER_TRUSTED_OS_END, \\\n+\t\t\t   OPTEE_SMC_FUNCID_CALLS_REVISION)\n+\n+struct optee_smc_calls_revision_result {\n+\tunsigned long major;\n+\tunsigned long minor;\n+\tunsigned long reserved0;\n+\tunsigned long reserved1;\n+};\n+\n+/*\n+ * Get UUID of Trusted OS.\n+ *\n+ * Used by non-secure world to figure out which Trusted OS is installed.\n+ * Note that returned UUID is the UUID of the Trusted OS, not of the API.\n+ *\n+ * Returns UUID in a0-4 in the same way as OPTEE_SMC_CALLS_UID\n+ * described above.\n+ */\n+#define OPTEE_SMC_FUNCID_GET_OS_UUID OPTEE_MSG_FUNCID_GET_OS_UUID\n+#define OPTEE_SMC_CALL_GET_OS_UUID \\\n+\tOPTEE_SMC_FAST_CALL_VAL(OPTEE_SMC_FUNCID_GET_OS_UUID)\n+\n+/*\n+ * Get revision of Trusted OS.\n+ *\n+ * Used by non-secure world to figure out which version of the Trusted OS\n+ * is installed. Note that the returned revision is the revision of the\n+ * Trusted OS, not of the API.\n+ *\n+ * Returns revision in a0-1 in the same way as OPTEE_SMC_CALLS_REVISION\n+ * described above. May optionally return a 32-bit build identifier in a2,\n+ * with zero meaning unspecified.\n+ */\n+#define OPTEE_SMC_FUNCID_GET_OS_REVISION OPTEE_MSG_FUNCID_GET_OS_REVISION\n+#define OPTEE_SMC_CALL_GET_OS_REVISION \\\n+\tOPTEE_SMC_FAST_CALL_VAL(OPTEE_SMC_FUNCID_GET_OS_REVISION)\n+\n+struct optee_smc_call_get_os_revision_result {\n+\tunsigned long major;\n+\tunsigned long minor;\n+\tunsigned long build_id;\n+\tunsigned long reserved1;\n+};\n+\n+/*\n+ * Call with struct optee_msg_arg as argument\n+ *\n+ * Call register usage:\n+ * a0\tSMC Function ID, OPTEE_SMC*CALL_WITH_ARG\n+ * a1\tUpper 32bit of a 64bit physical pointer to a struct optee_msg_arg\n+ * a2\tLower 32bit of a 64bit physical pointer to a struct optee_msg_arg\n+ * a3\tCache settings, not used if physical pointer is in a predefined shared\n+ *\tmemory area else per OPTEE_SMC_SHM_*\n+ * a4-6\tNot used\n+ * a7\tHypervisor Client ID register\n+ *\n+ * Normal return register usage:\n+ * a0\tReturn value, OPTEE_SMC_RETURN_*\n+ * a1-3\tNot used\n+ * a4-7\tPreserved\n+ *\n+ * OPTEE_SMC_RETURN_ETHREAD_LIMIT return register usage:\n+ * a0\tReturn value, OPTEE_SMC_RETURN_ETHREAD_LIMIT\n+ * a1-3\tPreserved\n+ * a4-7\tPreserved\n+ *\n+ * RPC return register usage:\n+ * a0\tReturn value, OPTEE_SMC_RETURN_IS_RPC(val)\n+ * a1-2\tRPC parameters\n+ * a3-7\tResume information, must be preserved\n+ *\n+ * Possible return values:\n+ * OPTEE_SMC_RETURN_UNKNOWN_FUNCTION\tTrusted OS does not recognize this\n+ *\t\t\t\t\tfunction.\n+ * OPTEE_SMC_RETURN_OK\t\t\tCall completed, result updated in\n+ *\t\t\t\t\tthe previously supplied struct\n+ *\t\t\t\t\toptee_msg_arg.\n+ * OPTEE_SMC_RETURN_ETHREAD_LIMIT\tNumber of Trusted OS threads exceeded,\n+ *\t\t\t\t\ttry again later.\n+ * OPTEE_SMC_RETURN_EBADADDR\t\tBad physcial pointer to struct\n+ *\t\t\t\t\toptee_msg_arg.\n+ * OPTEE_SMC_RETURN_EBADCMD\t\tBad/unknown cmd in struct optee_msg_arg\n+ * OPTEE_SMC_RETURN_IS_RPC()\t\tCall suspended by RPC call to normal\n+ *\t\t\t\t\tworld.\n+ */\n+#define OPTEE_SMC_FUNCID_CALL_WITH_ARG OPTEE_MSG_FUNCID_CALL_WITH_ARG\n+#define OPTEE_SMC_CALL_WITH_ARG \\\n+\tOPTEE_SMC_STD_CALL_VAL(OPTEE_SMC_FUNCID_CALL_WITH_ARG)\n+\n+/*\n+ * Get Shared Memory Config\n+ *\n+ * Returns the Secure/Non-secure shared memory config.\n+ *\n+ * Call register usage:\n+ * a0\tSMC Function ID, OPTEE_SMC_GET_SHM_CONFIG\n+ * a1-6\tNot used\n+ * a7\tHypervisor Client ID register\n+ *\n+ * Have config return register usage:\n+ * a0\tOPTEE_SMC_RETURN_OK\n+ * a1\tPhysical address of start of SHM\n+ * a2\tSize of of SHM\n+ * a3\tCache settings of memory, as defined by the\n+ *\tOPTEE_SMC_SHM_* values above\n+ * a4-7\tPreserved\n+ *\n+ * Not available register usage:\n+ * a0\tOPTEE_SMC_RETURN_ENOTAVAIL\n+ * a1-3 Not used\n+ * a4-7\tPreserved\n+ */\n+#define OPTEE_SMC_FUNCID_GET_SHM_CONFIG\t7\n+#define OPTEE_SMC_GET_SHM_CONFIG \\\n+\tOPTEE_SMC_FAST_CALL_VAL(OPTEE_SMC_FUNCID_GET_SHM_CONFIG)\n+\n+struct optee_smc_get_shm_config_result {\n+\tunsigned long status;\n+\tunsigned long start;\n+\tunsigned long size;\n+\tunsigned long settings;\n+};\n+\n+/*\n+ * Exchanges capabilities between normal world and secure world\n+ *\n+ * Call register usage:\n+ * a0\tSMC Function ID, OPTEE_SMC_EXCHANGE_CAPABILITIES\n+ * a1\tbitfield of normal world capabilities OPTEE_SMC_NSEC_CAP_*\n+ * a2-6\tNot used\n+ * a7\tHypervisor Client ID register\n+ *\n+ * Normal return register usage:\n+ * a0\tOPTEE_SMC_RETURN_OK\n+ * a1\tbitfield of secure world capabilities OPTEE_SMC_SEC_CAP_*\n+ * a2-7\tPreserved\n+ *\n+ * Error return register usage:\n+ * a0\tOPTEE_SMC_RETURN_ENOTAVAIL, can't use the capabilities from normal world\n+ * a1\tbitfield of secure world capabilities OPTEE_SMC_SEC_CAP_*\n+ * a2-7 Preserved\n+ */\n+/* Normal world works as a uniprocessor system */\n+#define OPTEE_SMC_NSEC_CAP_UNIPROCESSOR\t\tBIT(0)\n+/* Secure world has reserved shared memory for normal world to use */\n+#define OPTEE_SMC_SEC_CAP_HAVE_RESERVED_SHM\tBIT(0)\n+/* Secure world can communicate via previously unregistered shared memory */\n+#define OPTEE_SMC_SEC_CAP_UNREGISTERED_SHM\tBIT(1)\n+\n+/*\n+ * Secure world supports commands \"register/unregister shared memory\",\n+ * secure world accepts command buffers located in any parts of non-secure RAM\n+ */\n+#define OPTEE_SMC_SEC_CAP_DYNAMIC_SHM\t\tBIT(2)\n+\n+#define OPTEE_SMC_FUNCID_EXCHANGE_CAPABILITIES\t9\n+#define OPTEE_SMC_EXCHANGE_CAPABILITIES \\\n+\tOPTEE_SMC_FAST_CALL_VAL(OPTEE_SMC_FUNCID_EXCHANGE_CAPABILITIES)\n+\n+struct optee_smc_exchange_capabilities_result {\n+\tunsigned long status;\n+\tunsigned long capabilities;\n+\tunsigned long reserved0;\n+\tunsigned long reserved1;\n+};\n+\n+/*\n+ * Disable and empties cache of shared memory objects\n+ *\n+ * Secure world can cache frequently used shared memory objects, for\n+ * example objects used as RPC arguments. When secure world is idle this\n+ * function returns one shared memory reference to free. To disable the\n+ * cache and free all cached objects this function has to be called until\n+ * it returns OPTEE_SMC_RETURN_ENOTAVAIL.\n+ *\n+ * Call register usage:\n+ * a0\tSMC Function ID, OPTEE_SMC_DISABLE_SHM_CACHE\n+ * a1-6\tNot used\n+ * a7\tHypervisor Client ID register\n+ *\n+ * Normal return register usage:\n+ * a0\tOPTEE_SMC_RETURN_OK\n+ * a1\tUpper 32bit of a 64bit Shared memory cookie\n+ * a2\tLower 32bit of a 64bit Shared memory cookie\n+ * a3-7\tPreserved\n+ *\n+ * Cache empty return register usage:\n+ * a0\tOPTEE_SMC_RETURN_ENOTAVAIL\n+ * a1-7\tPreserved\n+ *\n+ * Not idle return register usage:\n+ * a0\tOPTEE_SMC_RETURN_EBUSY\n+ * a1-7\tPreserved\n+ */\n+#define OPTEE_SMC_FUNCID_DISABLE_SHM_CACHE\t10\n+#define OPTEE_SMC_DISABLE_SHM_CACHE \\\n+\tOPTEE_SMC_FAST_CALL_VAL(OPTEE_SMC_FUNCID_DISABLE_SHM_CACHE)\n+\n+struct optee_smc_disable_shm_cache_result {\n+\tunsigned long status;\n+\tunsigned long shm_upper32;\n+\tunsigned long shm_lower32;\n+\tunsigned long reserved0;\n+};\n+\n+/*\n+ * Enable cache of shared memory objects\n+ *\n+ * Secure world can cache frequently used shared memory objects, for\n+ * example objects used as RPC arguments. When secure world is idle this\n+ * function returns OPTEE_SMC_RETURN_OK and the cache is enabled. If\n+ * secure world isn't idle OPTEE_SMC_RETURN_EBUSY is returned.\n+ *\n+ * Call register usage:\n+ * a0\tSMC Function ID, OPTEE_SMC_ENABLE_SHM_CACHE\n+ * a1-6\tNot used\n+ * a7\tHypervisor Client ID register\n+ *\n+ * Normal return register usage:\n+ * a0\tOPTEE_SMC_RETURN_OK\n+ * a1-7\tPreserved\n+ *\n+ * Not idle return register usage:\n+ * a0\tOPTEE_SMC_RETURN_EBUSY\n+ * a1-7\tPreserved\n+ */\n+#define OPTEE_SMC_FUNCID_ENABLE_SHM_CACHE\t11\n+#define OPTEE_SMC_ENABLE_SHM_CACHE \\\n+\tOPTEE_SMC_FAST_CALL_VAL(OPTEE_SMC_FUNCID_ENABLE_SHM_CACHE)\n+\n+/*\n+ * Resume from RPC (for example after processing a foreign interrupt)\n+ *\n+ * Call register usage:\n+ * a0\tSMC Function ID, OPTEE_SMC_CALL_RETURN_FROM_RPC\n+ * a1-3\tValue of a1-3 when OPTEE_SMC_CALL_WITH_ARG returned\n+ *\tOPTEE_SMC_RETURN_RPC in a0\n+ *\n+ * Return register usage is the same as for OPTEE_SMC_*CALL_WITH_ARG above.\n+ *\n+ * Possible return values\n+ * OPTEE_SMC_RETURN_UNKNOWN_FUNCTION\tTrusted OS does not recognize this\n+ *\t\t\t\t\tfunction.\n+ * OPTEE_SMC_RETURN_OK\t\t\tOriginal call completed, result\n+ *\t\t\t\t\tupdated in the previously supplied.\n+ *\t\t\t\t\tstruct optee_msg_arg\n+ * OPTEE_SMC_RETURN_RPC\t\t\tCall suspended by RPC call to normal\n+ *\t\t\t\t\tworld.\n+ * OPTEE_SMC_RETURN_ERESUME\t\tResume failed, the opaque resume\n+ *\t\t\t\t\tinformation was corrupt.\n+ */\n+#define OPTEE_SMC_FUNCID_RETURN_FROM_RPC\t3\n+#define OPTEE_SMC_CALL_RETURN_FROM_RPC \\\n+\tOPTEE_SMC_STD_CALL_VAL(OPTEE_SMC_FUNCID_RETURN_FROM_RPC)\n+\n+#define OPTEE_SMC_RETURN_RPC_PREFIX_MASK\t0xFFFF0000\n+#define OPTEE_SMC_RETURN_RPC_PREFIX\t\t0xFFFF0000\n+#define OPTEE_SMC_RETURN_RPC_FUNC_MASK\t\t0x0000FFFF\n+\n+#define OPTEE_SMC_RETURN_GET_RPC_FUNC(ret) \\\n+\t((ret) & OPTEE_SMC_RETURN_RPC_FUNC_MASK)\n+\n+#define OPTEE_SMC_RPC_VAL(func)\t\t((func) | OPTEE_SMC_RETURN_RPC_PREFIX)\n+\n+/*\n+ * Allocate memory for RPC parameter passing. The memory is used to hold a\n+ * struct optee_msg_arg.\n+ *\n+ * \"Call\" register usage:\n+ * a0\tThis value, OPTEE_SMC_RETURN_RPC_ALLOC\n+ * a1\tSize in bytes of required argument memory\n+ * a2\tNot used\n+ * a3\tResume information, must be preserved\n+ * a4-5\tNot used\n+ * a6-7\tResume information, must be preserved\n+ *\n+ * \"Return\" register usage:\n+ * a0\tSMC Function ID, OPTEE_SMC_CALL_RETURN_FROM_RPC.\n+ * a1\tUpper 32bits of 64bit physical pointer to allocated\n+ *\tmemory, (a1 == 0 && a2 == 0) if size was 0 or if memory can't\n+ *\tbe allocated.\n+ * a2\tLower 32bits of 64bit physical pointer to allocated\n+ *\tmemory, (a1 == 0 && a2 == 0) if size was 0 or if memory can't\n+ *\tbe allocated\n+ * a3\tPreserved\n+ * a4\tUpper 32bits of 64bit Shared memory cookie used when freeing\n+ *\tthe memory or doing an RPC\n+ * a5\tLower 32bits of 64bit Shared memory cookie used when freeing\n+ *\tthe memory or doing an RPC\n+ * a6-7\tPreserved\n+ */\n+#define OPTEE_SMC_RPC_FUNC_ALLOC\t0\n+#define OPTEE_SMC_RETURN_RPC_ALLOC \\\n+\tOPTEE_SMC_RPC_VAL(OPTEE_SMC_RPC_FUNC_ALLOC)\n+\n+/*\n+ * Free memory previously allocated by OPTEE_SMC_RETURN_RPC_ALLOC\n+ *\n+ * \"Call\" register usage:\n+ * a0\tThis value, OPTEE_SMC_RETURN_RPC_FREE\n+ * a1\tUpper 32bits of 64bit shared memory cookie belonging to this\n+ *\targument memory\n+ * a2\tLower 32bits of 64bit shared memory cookie belonging to this\n+ *\targument memory\n+ * a3-7\tResume information, must be preserved\n+ *\n+ * \"Return\" register usage:\n+ * a0\tSMC Function ID, OPTEE_SMC_CALL_RETURN_FROM_RPC.\n+ * a1-2\tNot used\n+ * a3-7\tPreserved\n+ */\n+#define OPTEE_SMC_RPC_FUNC_FREE\t\t2\n+#define OPTEE_SMC_RETURN_RPC_FREE \\\n+\tOPTEE_SMC_RPC_VAL(OPTEE_SMC_RPC_FUNC_FREE)\n+\n+/*\n+ * Deliver foreign interrupt to normal world.\n+ *\n+ * \"Call\" register usage:\n+ * a0\tOPTEE_SMC_RETURN_RPC_FOREIGN_INTR\n+ * a1-7\tResume information, must be preserved\n+ *\n+ * \"Return\" register usage:\n+ * a0\tSMC Function ID, OPTEE_SMC_CALL_RETURN_FROM_RPC.\n+ * a1-7\tPreserved\n+ */\n+#define OPTEE_SMC_RPC_FUNC_FOREIGN_INTR\t\t4\n+#define OPTEE_SMC_RETURN_RPC_FOREIGN_INTR \\\n+\tOPTEE_SMC_RPC_VAL(OPTEE_SMC_RPC_FUNC_FOREIGN_INTR)\n+\n+/*\n+ * Do an RPC request. The supplied struct optee_msg_arg tells which\n+ * request to do and the parameters for the request. The following fields\n+ * are used (the rest are unused):\n+ * - cmd\t\tthe Request ID\n+ * - ret\t\treturn value of the request, filled in by normal world\n+ * - num_params\t\tnumber of parameters for the request\n+ * - params\t\tthe parameters\n+ * - param_attrs\tattributes of the parameters\n+ *\n+ * \"Call\" register usage:\n+ * a0\tOPTEE_SMC_RETURN_RPC_CMD\n+ * a1\tUpper 32bit of a 64bit Shared memory cookie holding a\n+ *\tstruct optee_msg_arg, must be preserved, only the data should\n+ *\tbe updated\n+ * a2\tLower 32bit of a 64bit Shared memory cookie holding a\n+ *\tstruct optee_msg_arg, must be preserved, only the data should\n+ *\tbe updated\n+ * a3-7\tResume information, must be preserved\n+ *\n+ * \"Return\" register usage:\n+ * a0\tSMC Function ID, OPTEE_SMC_CALL_RETURN_FROM_RPC.\n+ * a1-2\tNot used\n+ * a3-7\tPreserved\n+ */\n+#define OPTEE_SMC_RPC_FUNC_CMD\t\t5\n+#define OPTEE_SMC_RETURN_RPC_CMD \\\n+\tOPTEE_SMC_RPC_VAL(OPTEE_SMC_RPC_FUNC_CMD)\n+\n+/* Returned in a0 */\n+#define OPTEE_SMC_RETURN_UNKNOWN_FUNCTION 0xFFFFFFFF\n+\n+/* Returned in a0 only from Trusted OS functions */\n+#define OPTEE_SMC_RETURN_OK\t\t0x0\n+#define OPTEE_SMC_RETURN_ETHREAD_LIMIT\t0x1\n+#define OPTEE_SMC_RETURN_EBUSY\t\t0x2\n+#define OPTEE_SMC_RETURN_ERESUME\t0x3\n+#define OPTEE_SMC_RETURN_EBADADDR\t0x4\n+#define OPTEE_SMC_RETURN_EBADCMD\t0x5\n+#define OPTEE_SMC_RETURN_ENOMEM\t\t0x6\n+#define OPTEE_SMC_RETURN_ENOTAVAIL\t0x7\n+#define OPTEE_SMC_RETURN_IS_RPC(ret)\t__optee_smc_return_is_rpc((ret))\n+\n+static inline bool __optee_smc_return_is_rpc(u32 ret)\n+{\n+\treturn ret != OPTEE_SMC_RETURN_UNKNOWN_FUNCTION &&\n+\t       (ret & OPTEE_SMC_RETURN_RPC_PREFIX_MASK) ==\n+\t\t\tOPTEE_SMC_RETURN_RPC_PREFIX;\n+}\n+\n+#endif /* OPTEE_SMC_H */\ndiff --git a/drivers/tee/optee/supplicant.c b/drivers/tee/optee/supplicant.c\nnew file mode 100644\nindex 000000000000..6965055bd1b5\n--- /dev/null\n+++ b/drivers/tee/optee/supplicant.c\n@@ -0,0 +1,89 @@\n+// SPDX-License-Identifier: BSD-2-Clause\n+/*\n+ * Copyright (c) 2018, Linaro Limited\n+ */\n+\n+#include <common.h>\n+#include <linux/types.h>\n+#include <log.h>\n+#include <tee.h>\n+\n+#include \"optee_msg.h\"\n+#include \"optee_msg_supplicant.h\"\n+#include \"optee_private.h\"\n+#include \"optee_smc.h\"\n+\n+static void cmd_shm_alloc(struct udevice *dev, struct optee_msg_arg *arg,\n+\t\t\t  void **page_list)\n+{\n+\tstruct tee_shm *shm;\n+\tvoid *pl;\n+\tu64 ph_ptr;\n+\n+\targ->ret_origin = TEE_ORIGIN_COMMS;\n+\n+\tif (arg->num_params != 1 ||\n+\t    arg->params[0].attr != OPTEE_MSG_ATTR_TYPE_VALUE_INPUT) {\n+\t\targ->ret = TEE_ERROR_BAD_PARAMETERS;\n+\t\treturn;\n+\t}\n+\n+\tshm = __tee_shm_add(dev, 0, NULL, arg->params[0].u.value.b,\n+\t\t\t    TEE_SHM_REGISTER | TEE_SHM_ALLOC);\n+\tif (!shm) {\n+\t\targ->ret = TEE_ERROR_OUT_OF_MEMORY;\n+\t\treturn;\n+\t}\n+\n+\tpl = optee_alloc_and_init_page_list(shm->addr, shm->size, &ph_ptr);\n+\tif (!pl) {\n+\t\targ->ret = TEE_ERROR_OUT_OF_MEMORY;\n+\t\ttee_shm_free(shm);\n+\t\treturn;\n+\t}\n+\n+\t*page_list = pl;\n+\targ->params[0].attr = OPTEE_MSG_ATTR_TYPE_TMEM_OUTPUT |\n+\t\t\t      OPTEE_MSG_ATTR_NONCONTIG;\n+\targ->params[0].u.tmem.buf_ptr = ph_ptr;\n+\targ->params[0].u.tmem.size = shm->size;\n+\targ->params[0].u.tmem.shm_ref = (ulong)shm;\n+\targ->ret = TEE_SUCCESS;\n+}\n+\n+static void cmd_shm_free(struct optee_msg_arg *arg)\n+{\n+\targ->ret_origin = TEE_ORIGIN_COMMS;\n+\n+\tif (arg->num_params != 1 ||\n+\t    arg->params[0].attr != OPTEE_MSG_ATTR_TYPE_VALUE_INPUT) {\n+\t\targ->ret = TEE_ERROR_BAD_PARAMETERS;\n+\t\treturn;\n+\t}\n+\n+\ttee_shm_free((struct tee_shm *)(ulong)arg->params[0].u.value.b);\n+\targ->ret = TEE_SUCCESS;\n+}\n+\n+void optee_suppl_cmd(struct udevice *dev, struct tee_shm *shm_arg,\n+\t\t     void **page_list)\n+{\n+\tstruct optee_msg_arg *arg = shm_arg->addr;\n+\n+\tswitch (arg->cmd) {\n+\tcase OPTEE_MSG_RPC_CMD_SHM_ALLOC:\n+\t\tcmd_shm_alloc(dev, arg, page_list);\n+\t\tbreak;\n+\tcase OPTEE_MSG_RPC_CMD_SHM_FREE:\n+\t\tcmd_shm_free(arg);\n+\t\tbreak;\n+\tcase OPTEE_MSG_RPC_CMD_FS:\n+\t\tdebug(\"OPTEE_MSG_RPC_CMD_FS not implemented\\n\");\n+\t\targ->ret = TEE_ERROR_NOT_IMPLEMENTED;\n+\t\tbreak;\n+\tdefault:\n+\t\targ->ret = TEE_ERROR_NOT_IMPLEMENTED;\n+\t}\n+\n+\targ->ret_origin = TEE_ORIGIN_COMMS;\n+}\n",
    "prefixes": [
        "U-Boot",
        "v2",
        "07/15"
    ]
}