[PATCH 1/5] tee: define session login identifiers

Define identifiers for clnt_login field in struct tee_open_session_arg based in GlobalPlatform Device TEE IDs and on the REE_KERNEL identifier extension from OP-TEE OS.
Cc: Jens Wiklander jens.wiklander@linaro.org Signed-off-by: Etienne Carriere etienne.carriere@linaro.org --- This change was previously discussed in the U-Boot ML, see v2 at: https://patchwork.ozlabs.org/project/uboot/patch/20210519142613.7668-1-etien...
Changes since this v2 post: - Updated the inline comment describing reserved login Ids - Rephrase 'REE kernel agent' to 'REE kernel/privileged agent' to better apply to U-Boot that is not a kernel but still runs at a privileged execution level. --- include/tee.h | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-)
diff --git a/include/tee.h b/include/tee.h index 44e9cd4321..30ea2ee164 100644 --- a/include/tee.h +++ b/include/tee.h @@ -31,6 +31,25 @@ #define TEE_PARAM_ATTR_MASK (TEE_PARAM_ATTR_TYPE_MASK | \ TEE_PARAM_ATTR_META)
+/* + * Global Platform login identifiers for tee_open_session_arg::clnt_login + */ +#define TEE_LOGIN_PUBLIC 0x00000000 +#define TEE_LOGIN_USER 0x00000001 +#define TEE_LOGIN_GROUP 0x00000002 +#define TEE_LOGIN_APPLICATION 0x00000004 +#define TEE_LOGIN_APPLICATION_USER 0x00000005 +#define TEE_LOGIN_APPLICATION_GROUP 0x00000006 +/* + * Reserve use of GP implementation specific login method range + * (0x80000000 - 0xBFFFFFFF). This range is rather being used + * for REE kernel clients or TEE implementation. + */ +#define TEE_LOGIN_REE_KERNEL_MIN 0x80000000 +#define TEE_LOGIN_REE_KERNEL_MAX 0xBFFFFFFF +/* Private login method for REE kernel/privileged clients */ +#define TEE_LOGIN_REE_KERNEL 0x80000000 + /* * Some Global Platform error codes which has a meaning if the * TEE_GEN_CAP_GP bit is returned by the driver in @@ -135,8 +154,8 @@ struct tee_param { /** * struct tee_open_session_arg - extra arguments for tee_open_session() * @uuid: [in] UUID of the Trusted Application - * @clnt_uuid: [in] Normally zeroes - * @clnt_login: [in] Normally 0 + * @clnt_uuid: [in] UUID of client, zeroes for PUBLIC/REE_KERNEL + * @clnt_login: [in] Class of client TEE_LOGIN_* * @session: [out] Session id * @ret: [out] return value * @ret_origin: [out] origin of the return value

Remove unused OPTEE_MSG_LOGIN_* ID macros as suitable TEE_LOGIN_* ID macros are already defined tee.h.
Cc: Jens Wiklander jens.wiklander@linaro.org Signed-off-by: Etienne Carriere etienne.carriere@linaro.org --- This change was previously discussed in the U-Boot ML, latest is "[PATCH v2 2/2] tee: optee: support session login as REE kernel", at: https://patchwork.ozlabs.org/project/uboot/patch/20210519142613.7668-2-etien...
Changes since this v2 post: - Remove sanitation of the login Id passed to OP-TEE as secure world - Rephrase header line since this change now simply remove duplicated macros. - Update OPTEE_MSG_CMD_OPEN_SESSION inline description comment with a reference to TEE_LOGIN_* macros. --- drivers/tee/optee/optee_msg.h | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-)
diff --git a/drivers/tee/optee/optee_msg.h b/drivers/tee/optee/optee_msg.h index 8d40ce60c2..a8ef926a48 100644 --- a/drivers/tee/optee/optee_msg.h +++ b/drivers/tee/optee/optee_msg.h @@ -86,16 +86,6 @@ #define OPTEE_MSG_ATTR_CACHE_MASK GENMASK(2, 0) #define OPTEE_MSG_ATTR_CACHE_PREDEFINED 0
-/* - * Same values as TEE_LOGIN_* from TEE Internal API - */ -#define OPTEE_MSG_LOGIN_PUBLIC 0x00000000 -#define OPTEE_MSG_LOGIN_USER 0x00000001 -#define OPTEE_MSG_LOGIN_GROUP 0x00000002 -#define OPTEE_MSG_LOGIN_APPLICATION 0x00000004 -#define OPTEE_MSG_LOGIN_APPLICATION_USER 0x00000005 -#define OPTEE_MSG_LOGIN_APPLICATION_GROUP 0x00000006 - /* * Page size used in non-contiguous buffer entries */ @@ -279,7 +269,7 @@ struct optee_msg_arg { * parameters to pass the following information: * param[0].u.value.a-b uuid of Trusted Application * param[1].u.value.a-b uuid of Client - * param[1].u.value.c Login class of client OPTEE_MSG_LOGIN_* + * param[1].u.value.c Login class of client TEE_LOGIN_* * * OPTEE_MSG_CMD_INVOKE_COMMAND invokes a command a previously opened * session to a Trusted Application. struct optee_msg_arg::func is Trusted

Hi,
On 11/4/21 3:14 PM, Etienne Carriere wrote:
Remove unused OPTEE_MSG_LOGIN_* ID macros as suitable TEE_LOGIN_* ID macros are already defined tee.h.
Cc: Jens Wiklander jens.wiklander@linaro.org Signed-off-by: Etienne Carriere etienne.carriere@linaro.org
This change was previously discussed in the U-Boot ML, latest is "[PATCH v2 2/2] tee: optee: support session login as REE kernel", at: https://patchwork.ozlabs.org/project/uboot/patch/20210519142613.7668-2-etien...
Changes since this v2 post:
- Remove sanitation of the login Id passed to OP-TEE as secure world
- Rephrase header line since this change now simply remove duplicated macros.
- Update OPTEE_MSG_CMD_OPEN_SESSION inline description comment with a reference to TEE_LOGIN_* macros.
drivers/tee/optee/optee_msg.h | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-)
Reviewed-by: Patrick Delaunay patrick.delaunay@foss.st.com
Thanks Patrick

On Thu, Nov 4, 2021 at 3:15 PM Etienne Carriere etienne.carriere@linaro.org wrote:
Remove unused OPTEE_MSG_LOGIN_* ID macros as suitable TEE_LOGIN_* ID macros are already defined tee.h.
Cc: Jens Wiklander jens.wiklander@linaro.org Signed-off-by: Etienne Carriere etienne.carriere@linaro.org
This change was previously discussed in the U-Boot ML, latest is "[PATCH v2 2/2] tee: optee: support session login as REE kernel", at: https://patchwork.ozlabs.org/project/uboot/patch/20210519142613.7668-2-etien...
Changes since this v2 post:
- Remove sanitation of the login Id passed to OP-TEE as secure world
- Rephrase header line since this change now simply remove duplicated macros.
- Update OPTEE_MSG_CMD_OPEN_SESSION inline description comment with a reference to TEE_LOGIN_* macros.
drivers/tee/optee/optee_msg.h | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-)
Reviewed-by: Jens Wiklander jens.wiklander@linaro.org
Thanks, Jens

Adds TEE_ERROR_SHORT_BUFFER as TEE error code. This error code is commonly used by TEEs to inform caller that the buffer(s) it provided is too small for the desired operation.
Cc: Jens Wiklander jens.wiklander@linaro.org Signed-off-by: Etienne Carriere etienne.carriere@linaro.org --- include/tee.h | 1 + 1 file changed, 1 insertion(+)
diff --git a/include/tee.h b/include/tee.h index 30ea2ee164..50051496ae 100644 --- a/include/tee.h +++ b/include/tee.h @@ -64,6 +64,7 @@ #define TEE_ERROR_NOT_SUPPORTED 0xffff000a #define TEE_ERROR_COMMUNICATION 0xffff000e #define TEE_ERROR_SECURITY 0xffff000f +#define TEE_ERROR_SHORT_BUFFER 0xffff0010 #define TEE_ERROR_OUT_OF_MEMORY 0xffff000c #define TEE_ERROR_OVERFLOW 0xffff300f #define TEE_ERROR_TARGET_DEAD 0xffff3024

Hi,
On 11/4/21 3:14 PM, Etienne Carriere wrote:
Adds TEE_ERROR_SHORT_BUFFER as TEE error code. This error code is commonly used by TEEs to inform caller that the buffer(s) it provided is too small for the desired operation.
Cc: Jens Wiklander jens.wiklander@linaro.org Signed-off-by: Etienne Carriere etienne.carriere@linaro.org
include/tee.h | 1 + 1 file changed, 1 insertion(+)
Reviewed-by: Patrick Delaunay patrick.delaunay@foss.st.com
Thanks Patrick

On Thu, Nov 4, 2021 at 3:15 PM Etienne Carriere etienne.carriere@linaro.org wrote:
Adds TEE_ERROR_SHORT_BUFFER as TEE error code. This error code is commonly used by TEEs to inform caller that the buffer(s) it provided is too small for the desired operation.
Cc: Jens Wiklander jens.wiklander@linaro.org Signed-off-by: Etienne Carriere etienne.carriere@linaro.org
include/tee.h | 1 + 1 file changed, 1 insertion(+)
Reviewed-by: Jens Wiklander jens.wiklander@linaro.org
Thanks, Jens

Introduce compatible "linaro,scmi-optee" for SCMI transport channel based on an OP-TEE service invocation.
Define "linaro,optee-channel-id" property to identify the OP-TEE SCMI channel used by the protocol(s). OP-TEE SCMI transport can either use shared memory or a static shared memory buffer identified by the DT.
These bindings were posted to the Linux kernel DT bindings mailing list and acked by maintainer [1].
Link: [1] https://lore.kernel.org/linux-arm-kernel/20211029102118.GG6526@e120937-lin/T... Cc: Jaehoon Chung jh80.chung@samsung.com Signed-off-by: Etienne Carriere etienne.carriere@linaro.org --- doc/device-tree-bindings/arm/arm,scmi.txt | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-)
diff --git a/doc/device-tree-bindings/arm/arm,scmi.txt b/doc/device-tree-bindings/arm/arm,scmi.txt index a76124f4a3..92572eabb5 100644 --- a/doc/device-tree-bindings/arm/arm,scmi.txt +++ b/doc/device-tree-bindings/arm/arm,scmi.txt @@ -14,7 +14,8 @@ Required properties:
The scmi node with the following properties shall be under the /firmware/ node.
-- compatible : shall be "arm,scmi" or "arm,scmi-smc" for smc/hvc transports +- compatible : shall be "arm,scmi" or "arm,scmi-smc" for smc/hvc transports, + or "linaro,scmi-optee" for OP-TEE transport. - mboxes: List of phandle and mailbox channel specifiers. It should contain exactly one or two mailboxes, one for transmitting messages("tx") and another optional for receiving the notifications("rx") if @@ -26,6 +27,8 @@ The scmi node with the following properties shall be under the /firmware/ node. - #size-cells : should be '0' as 'reg' property doesn't have any size associated with it. - arm,smc-id : SMC id required when using smc or hvc transports +- linaro,optee-channel-id : Channel specifier required when using OP-TEE + transport.
Optional properties:
@@ -33,16 +36,16 @@ Optional properties:
See Documentation/devicetree/bindings/mailbox/mailbox.txt for more details about the generic mailbox controller and client driver bindings. - -The mailbox is the only permitted method of calling the SCMI firmware. Mailbox doorbell is used as a mechanism to alert the presence of a messages and/or notification.
Each protocol supported shall have a sub-node with corresponding compatible as described in the following sections. If the platform supports dedicated -communication channel for a particular protocol, the 3 properties namely: -mboxes, mbox-names and shmem shall be present in the sub-node corresponding -to that protocol. +communication channel for a particular protocol, properties shall be present +in the sub-node corresponding to that protocol. These properties are: +- mboxes, mbox-names and shmem for mailbox transport +- arm,smc-id and shmem for smc/hvc transport +- linaro,optee-channel-id and possibly shmem for OP-TEE transport
Clock/Performance bindings for the clocks/OPPs based on SCMI Message Protocol ------------------------------------------------------------

Hi,
On 11/4/21 3:14 PM, Etienne Carriere wrote:
Introduce compatible "linaro,scmi-optee" for SCMI transport channel based on an OP-TEE service invocation.
Define "linaro,optee-channel-id" property to identify the OP-TEE SCMI channel used by the protocol(s). OP-TEE SCMI transport can either use shared memory or a static shared memory buffer identified by the DT.
These bindings were posted to the Linux kernel DT bindings mailing list and acked by maintainer [1].
Link: [1] https://lore.kernel.org/linux-arm-kernel/20211029102118.GG6526@e120937-lin/T... Cc: Jaehoon Chung jh80.chung@samsung.com Signed-off-by: Etienne Carriere etienne.carriere@linaro.org
doc/device-tree-bindings/arm/arm,scmi.txt | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-)
Reviewed-by: Patrick Delaunay patrick.delaunay@foss.st.com
Thanks Patrick

This change implements an SCMI transport for agent interfacing the OP-TEE SCMI service. OP-TEE provides an SCMI PTA (Pseudo-TA) for non-secure world to send SCMI messages over an identified channel. The driver implemented here uses a SMT shared memory for passing messages between client and server.
The implementation opens and releases channel resources for each passed SCMI message so that resources allocated (sessions) or registered (shared memory areas) in OP-TEE firmware are released for example before relocation as the driver will likely allocate/register them back when probed after relocation.
The integration of the driver using dedicated config switch CONFIG_SCMI_AGENT_OPTEE is designed on the model posted to the U-Boot ML by Patrick Delaunay [1].
Link: [1] https://lore.kernel.org/all/20211028191222.v3.4.Ib2e58ee67f4d023823d8b540433... Cc: Patrick Delaunay patrick.delaunay@foss.st.com Cc: Wolfgang Denk wd@denx.de Signed-off-by: Etienne Carriere etienne.carriere@linaro.org --- drivers/firmware/scmi/Kconfig | 14 +- drivers/firmware/scmi/Makefile | 1 + drivers/firmware/scmi/optee_agent.c | 312 ++++++++++++++++++++++++++++ 3 files changed, 324 insertions(+), 3 deletions(-) create mode 100644 drivers/firmware/scmi/optee_agent.c
diff --git a/drivers/firmware/scmi/Kconfig b/drivers/firmware/scmi/Kconfig index c3a109beac..f9c69e5352 100644 --- a/drivers/firmware/scmi/Kconfig +++ b/drivers/firmware/scmi/Kconfig @@ -2,7 +2,7 @@ config SCMI_FIRMWARE bool "Enable SCMI support" select FIRMWARE select OF_TRANSLATE - depends on SANDBOX || DM_MAILBOX || ARM_SMCCC + depends on SANDBOX || DM_MAILBOX || ARM_SMCCC || OPTEE help System Control and Management Interface (SCMI) is a communication protocol that defines standard interfaces for power, performance @@ -14,6 +14,14 @@ config SCMI_FIRMWARE or a companion host in the CPU system.
Communications between agent (client) and the SCMI server are - based on message exchange. Messages can be exchange over tranport + based on message exchange. Messages can be exchanged over transport channels as a mailbox device or an Arm SMCCC service with some - piece of identified shared memory. + piece of identified shared memory, or an OP-TEE SCMI service. + +config SCMI_AGENT_OPTEE + bool "Enable SCMI agent OP-TEE" + depends on SCMI_FIRMWARE && OPTEE + default y + help + Enable the SCMI communication channel based on OP-TEE transport + for compatible "linaro,scmi-optee". diff --git a/drivers/firmware/scmi/Makefile b/drivers/firmware/scmi/Makefile index 966475ec10..f72d06a400 100644 --- a/drivers/firmware/scmi/Makefile +++ b/drivers/firmware/scmi/Makefile @@ -2,4 +2,5 @@ obj-y += scmi_agent-uclass.o obj-y += smt.o obj-$(CONFIG_ARM_SMCCC) += smccc_agent.o obj-$(CONFIG_DM_MAILBOX) += mailbox_agent.o +obj-$(CONFIG_SCMI_AGENT_OPTEE) += optee_agent.o obj-$(CONFIG_SANDBOX) += sandbox-scmi_agent.o sandbox-scmi_devices.o diff --git a/drivers/firmware/scmi/optee_agent.c b/drivers/firmware/scmi/optee_agent.c new file mode 100644 index 0000000000..8232af2f41 --- /dev/null +++ b/drivers/firmware/scmi/optee_agent.c @@ -0,0 +1,312 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2020-2021 Linaro Limited. + */ + +#define LOG_CATEGORY UCLASS_SCMI_AGENT + +#include <common.h> +#include <dm.h> +#include <errno.h> +#include <scmi_agent.h> +#include <scmi_agent-uclass.h> +#include <string.h> +#include <tee.h> +#include <asm/types.h> +#include <dm/device_compat.h> +#include <dm/devres.h> +#include <linux/arm-smccc.h> +#include <linux/bug.h> +#include <linux/compat.h> + +#include "smt.h" + +#define SCMI_SHM_SIZE 128 + +/** + * struct scmi_optee_channel - Description of an SCMI OP-TEE transport + * @channel_id: Channel identifier + * @smt: Shared memory buffer with synchronisation protocol + * @dyn_shm: True if using dynamically allocated shared memory + */ +struct scmi_optee_channel { + unsigned int channel_id; + struct scmi_smt smt; + bool dyn_shm; +}; + +/** + * struct channel_session - Aggreates SCMI service session context references + * @tee: OP-TEE device to invoke + * @tee_session: OP-TEE session identifier + * @tee_shm: Dynamically allocated OP-TEE shared memory, or NULL + * @channel_hdl: Channel handle provided by OP-TEE SCMI service + */ +struct channel_session { + struct udevice *tee; + u32 tee_session; + struct tee_shm *tee_shm; + u32 channel_hdl; +}; + +#define TA_SCMI_UUID { 0xa8cfe406, 0xd4f5, 0x4a2e, \ + { 0x9f, 0x8d, 0xa2, 0x5d, 0xc7, 0x54, 0xc0, 0x99 } } + +enum optee_smci_pta_cmd { + /* + * PTA_SCMI_CMD_CAPABILITIES - Get channel capabilities + * + * [out] value[0].a: Capability bit mask (enum pta_scmi_caps) + * [out] value[0].b: Extended capabilities or 0 + */ + PTA_SCMI_CMD_CAPABILITIES = 0, + + /* + * PTA_SCMI_CMD_PROCESS_SMT_CHANNEL - Process SCMI message in SMT buffer + * + * [in] value[0].a: Channel handle + * + * Shared memory used for SCMI message/response exhange is expected + * already identified and bound to channel handle in both SCMI agent + * and SCMI server (OP-TEE) parts. + * The memory uses SMT header to carry SCMI meta-data (protocol ID and + * protocol message ID). + */ + PTA_SCMI_CMD_PROCESS_SMT_CHANNEL = 1, + + /* + * PTA_SCMI_CMD_PROCESS_SMT_CHANNEL_MESSAGE - Process SMT/SCMI message + * + * [in] value[0].a: Channel handle + * [in/out] memref[1]: Message/response buffer (SMT and SCMI payload) + * + * Shared memory used for SCMI message/response is a SMT buffer + * referenced by param[1]. It shall be 128 bytes large to fit response + * payload whatever message playload size. + * The memory uses SMT header to carry SCMI meta-data (protocol ID and + * protocol message ID). + */ + PTA_SCMI_CMD_PROCESS_SMT_CHANNEL_MESSAGE = 2, + + /* + * PTA_SCMI_CMD_GET_CHANNEL - Get channel handle + * + * SCMI shm information are 0 if agent expects to use OP-TEE regular SHM + * + * [in] value[0].a: Channel identifier + * [out] value[0].a: Returned channel handle + * [in] value[0].b: Requested capabilities mask (enum pta_scmi_caps) + */ + PTA_SCMI_CMD_GET_CHANNEL = 3, +}; + +/* + * OP-TEE SCMI service capabilities bit flags (32bit) + * + * PTA_SCMI_CAPS_SMT_HEADER + * When set, OP-TEE supports command using SMT header protocol (SCMI shmem) in + * shared memory buffers to carry SCMI protocol synchronisation information. + */ +#define PTA_SCMI_CAPS_NONE 0 +#define PTA_SCMI_CAPS_SMT_HEADER BIT(0) + +static int open_channel(struct udevice *dev, struct channel_session *sess) +{ + const struct tee_optee_ta_uuid uuid = TA_SCMI_UUID; + struct scmi_optee_channel *chan = dev_get_plat(dev); + struct tee_open_session_arg sess_arg = { }; + struct tee_invoke_arg cmd_arg = { }; + struct tee_param param[1] = { }; + int ret; + + memset(sess, 0, sizeof(sess)); + + sess->tee = tee_find_device(NULL, NULL, NULL, NULL); + if (!sess->tee) + return -ENODEV; + + sess_arg.clnt_login = TEE_LOGIN_REE_KERNEL; + tee_optee_ta_uuid_to_octets(sess_arg.uuid, &uuid); + + ret = tee_open_session(sess->tee, &sess_arg, 0, NULL); + if (ret) { + dev_err(dev, "can't open session: %d\n", ret); + return ret; + } + + cmd_arg.func = PTA_SCMI_CMD_GET_CHANNEL; + cmd_arg.session = sess_arg.session; + + param[0].attr = TEE_PARAM_ATTR_TYPE_VALUE_INOUT; + param[0].u.value.a = chan->channel_id; + param[0].u.value.b = PTA_SCMI_CAPS_SMT_HEADER; + + ret = tee_invoke_func(sess->tee, &cmd_arg, ARRAY_SIZE(param), param); + if (ret || cmd_arg.ret) { + dev_err(dev, "Invoke failed: %d, 0x%x\n", ret, cmd_arg.ret); + if (!ret) + ret = -EPROTO; + + tee_close_session(sess->tee, sess_arg.session); + return ret; + } + + sess->tee_session = sess_arg.session; + sess->channel_hdl = param[0].u.value.a; + + return 0; +} + +static void close_channel(struct channel_session *sess) +{ + tee_close_session(sess->tee, sess->tee_session); +} + +static int invoke_cmd(struct udevice *dev, struct channel_session *sess, + struct scmi_msg *msg) +{ + struct scmi_optee_channel *chan = dev_get_plat(dev); + struct tee_invoke_arg arg = { }; + struct tee_param param[2] = { }; + int ret; + + scmi_write_msg_to_smt(dev, &chan->smt, msg); + + arg.session = sess->tee_session; + param[0].attr = TEE_PARAM_ATTR_TYPE_VALUE_INPUT; + param[0].u.value.a = sess->channel_hdl; + + if (chan->dyn_shm) { + arg.func = PTA_SCMI_CMD_PROCESS_SMT_CHANNEL_MESSAGE; + param[1].attr = TEE_PARAM_ATTR_TYPE_MEMREF_INOUT; + param[1].u.memref.shm = sess->tee_shm; + param[1].u.memref.size = SCMI_SHM_SIZE; + } else { + arg.func = PTA_SCMI_CMD_PROCESS_SMT_CHANNEL; + } + + ret = tee_invoke_func(sess->tee, &arg, ARRAY_SIZE(param), param); + if (ret || arg.ret) { + if (!ret) + ret = -EPROTO; + } else { + ret = scmi_read_resp_from_smt(dev, &chan->smt, msg); + } + + scmi_clear_smt_channel(&chan->smt); + + return ret; +} + +static int prepare_shm(struct udevice *dev, struct channel_session *sess) +{ + struct scmi_optee_channel *chan = dev_get_plat(dev); + int ret; + + /* Static shm is already prepared by the firmware: nothing to do */ + if (!chan->dyn_shm) + return 0; + + chan->smt.size = SCMI_SHM_SIZE; + + ret = tee_shm_alloc(sess->tee, chan->smt.size, 0, &sess->tee_shm); + if (ret) { + dev_err(dev, "Failed to allocated shmem: %d\n", ret); + return ret; + } + + chan->smt.buf = sess->tee_shm->addr; + + /* Initialize shm buffer for message exchanges */ + scmi_clear_smt_channel(&chan->smt); + + return 0; +} + +static void release_shm(struct udevice *dev, struct channel_session *sess) +{ + struct scmi_optee_channel *chan = dev_get_plat(dev); + + if (chan->dyn_shm) + tee_shm_free(sess->tee_shm); +} + +static int scmi_optee_process_msg(struct udevice *dev, struct scmi_msg *msg) +{ + struct channel_session sess; + int ret; + + ret = open_channel(dev, &sess); + if (ret) + return ret; + + ret = prepare_shm(dev, &sess); + if (ret) + goto out; + + ret = invoke_cmd(dev, &sess, msg); + + release_shm(dev, &sess); + +out: + close_channel(&sess); + + return ret; +} + +static int scmi_optee_of_to_plat(struct udevice *dev) +{ + struct scmi_optee_channel *chan = dev_get_plat(dev); + int ret; + + if (dev_read_u32(dev, "linaro,optee-channel-id", &chan->channel_id)) { + dev_err(dev, "Missing property linaro,channel-id\n"); + return -EINVAL; + } + + if (dev_read_prop(dev, "shmem", NULL)) { + ret = scmi_dt_get_smt_buffer(dev, &chan->smt); + if (ret) { + dev_err(dev, "Failed to get smt resources: %d\n", ret); + return ret; + } + chan->dyn_shm = false; + } else { + chan->dyn_shm = true; + } + + return 0; +} + +static int scmi_optee_probe(struct udevice *dev) +{ + struct channel_session sess; + int ret; + + /* Check OP-TEE service acknowledges the SCMI channel */ + ret = open_channel(dev, &sess); + if (!ret) + close_channel(&sess); + + return ret; +} + +static const struct udevice_id scmi_optee_ids[] = { + { .compatible = "linaro,scmi-optee" }, + { } +}; + +static const struct scmi_agent_ops scmi_optee_ops = { + .process_msg = scmi_optee_process_msg, +}; + +U_BOOT_DRIVER(scmi_optee) = { + .name = "scmi-over-optee", + .id = UCLASS_SCMI_AGENT, + .of_match = scmi_optee_ids, + .plat_auto = sizeof(struct scmi_optee_channel), + .of_to_plat = scmi_optee_of_to_plat, + .probe = scmi_optee_probe, + .flags = DM_FLAG_OS_PREPARE, + .ops = &scmi_optee_ops, +};

Hi,
On 11/4/21 3:14 PM, Etienne Carriere wrote:
This change implements an SCMI transport for agent interfacing the OP-TEE SCMI service. OP-TEE provides an SCMI PTA (Pseudo-TA) for non-secure world to send SCMI messages over an identified channel. The driver implemented here uses a SMT shared memory for passing messages between client and server.
The implementation opens and releases channel resources for each passed SCMI message so that resources allocated (sessions) or registered (shared memory areas) in OP-TEE firmware are released for example before relocation as the driver will likely allocate/register them back when probed after relocation.
The integration of the driver using dedicated config switch CONFIG_SCMI_AGENT_OPTEE is designed on the model posted to the U-Boot ML by Patrick Delaunay [1].
Link: [1] https://lore.kernel.org/all/20211028191222.v3.4.Ib2e58ee67f4d023823d8b540433... Cc: Patrick Delaunay patrick.delaunay@foss.st.com Cc: Wolfgang Denk wd@denx.de Signed-off-by: Etienne Carriere etienne.carriere@linaro.org
drivers/firmware/scmi/Kconfig | 14 +- drivers/firmware/scmi/Makefile | 1 + drivers/firmware/scmi/optee_agent.c | 312 ++++++++++++++++++++++++++++ 3 files changed, 324 insertions(+), 3 deletions(-) create mode 100644 drivers/firmware/scmi/optee_agent.c
Reviewed-by: Patrick Delaunay patrick.delaunay@foss.st.com
Thanks Patrick

Hi Etienne,
one missing remark, don't see in my first review.
On 11/4/21 3:14 PM, Etienne Carriere wrote:
This change implements an SCMI transport for agent interfacing the OP-TEE SCMI service. OP-TEE provides an SCMI PTA (Pseudo-TA) for non-secure world to send SCMI messages over an identified channel. The driver implemented here uses a SMT shared memory for passing messages between client and server.
The implementation opens and releases channel resources for each passed SCMI message so that resources allocated (sessions) or registered (shared memory areas) in OP-TEE firmware are released for example before relocation as the driver will likely allocate/register them back when probed after relocation.
The integration of the driver using dedicated config switch CONFIG_SCMI_AGENT_OPTEE is designed on the model posted to the U-Boot ML by Patrick Delaunay [1].
Link: [1] https://lore.kernel.org/all/20211028191222.v3.4.Ib2e58ee67f4d023823d8b540433... Cc: Patrick Delaunay patrick.delaunay@foss.st.com Cc: Wolfgang Denk wd@denx.de Signed-off-by: Etienne Carriere etienne.carriere@linaro.org
drivers/firmware/scmi/Kconfig | 14 +- drivers/firmware/scmi/Makefile | 1 + drivers/firmware/scmi/optee_agent.c | 312 ++++++++++++++++++++++++++++ 3 files changed, 324 insertions(+), 3 deletions(-) create mode 100644 drivers/firmware/scmi/optee_agent.c
diff --git a/drivers/firmware/scmi/Kconfig b/drivers/firmware/scmi/Kconfig index c3a109beac..f9c69e5352 100644 --- a/drivers/firmware/scmi/Kconfig +++ b/drivers/firmware/scmi/Kconfig @@ -2,7 +2,7 @@ config SCMI_FIRMWARE bool "Enable SCMI support" select FIRMWARE select OF_TRANSLATE
- depends on SANDBOX || DM_MAILBOX || ARM_SMCCC
- depends on SANDBOX || DM_MAILBOX || ARM_SMCCC || OPTEE help System Control and Management Interface (SCMI) is a communication protocol that defines standard interfaces for power, performance
@@ -14,6 +14,14 @@ config SCMI_FIRMWARE or a companion host in the CPU system.
Communications between agent (client) and the SCMI server are
based on message exchange. Messages can be exchange over tranport
channels as a mailbox device or an Arm SMCCC service with somebased on message exchange. Messages can be exchanged over transport
piece of identified shared memory.
piece of identified shared memory, or an OP-TEE SCMI service.
+config SCMI_AGENT_OPTEE
- bool "Enable SCMI agent OP-TEE"
- depends on SCMI_FIRMWARE && OPTEE
- default y
- help
Enable the SCMI communication channel based on OP-TEE transport
for compatible "linaro,scmi-optee".
diff --git a/drivers/firmware/scmi/Makefile b/drivers/firmware/scmi/Makefile index 966475ec10..f72d06a400 100644 --- a/drivers/firmware/scmi/Makefile +++ b/drivers/firmware/scmi/Makefile @@ -2,4 +2,5 @@ obj-y += scmi_agent-uclass.o obj-y += smt.o obj-$(CONFIG_ARM_SMCCC) += smccc_agent.o obj-$(CONFIG_DM_MAILBOX) += mailbox_agent.o +obj-$(CONFIG_SCMI_AGENT_OPTEE) += optee_agent.o obj-$(CONFIG_SANDBOX) += sandbox-scmi_agent.o sandbox-scmi_devices.o diff --git a/drivers/firmware/scmi/optee_agent.c b/drivers/firmware/scmi/optee_agent.c new file mode 100644 index 0000000000..8232af2f41 --- /dev/null +++ b/drivers/firmware/scmi/optee_agent.c @@ -0,0 +1,312 @@ +// SPDX-License-Identifier: GPL-2.0+ +/*
- Copyright (C) 2020-2021 Linaro Limited.
- */
(...)
+static int scmi_optee_of_to_plat(struct udevice *dev) +{
- struct scmi_optee_channel *chan = dev_get_plat(dev);
- int ret;
- if (dev_read_u32(dev, "linaro,optee-channel-id", &chan->channel_id)) {
dev_err(dev, "Missing property linaro,channel-id\n");
Can you use the correct property name in the error message = "linaro,optee-channel-id"
+ dev_err(dev, "Missing property linaro,optee-channel-id\n");
Patrick

On Tue, 9 Nov 2021 at 15:39, Patrick DELAUNAY patrick.delaunay@foss.st.com wrote:
Hi Etienne,
one missing remark, don't see in my first review.
On 11/4/21 3:14 PM, Etienne Carriere wrote:
This change implements an SCMI transport for agent interfacing the OP-TEE SCMI service. OP-TEE provides an SCMI PTA (Pseudo-TA) for non-secure world to send SCMI messages over an identified channel. The driver implemented here uses a SMT shared memory for passing messages between client and server.
The implementation opens and releases channel resources for each passed SCMI message so that resources allocated (sessions) or registered (shared memory areas) in OP-TEE firmware are released for example before relocation as the driver will likely allocate/register them back when probed after relocation.
The integration of the driver using dedicated config switch CONFIG_SCMI_AGENT_OPTEE is designed on the model posted to the U-Boot ML by Patrick Delaunay [1].
Link: [1] https://lore.kernel.org/all/20211028191222.v3.4.Ib2e58ee67f4d023823d8b540433... Cc: Patrick Delaunay patrick.delaunay@foss.st.com Cc: Wolfgang Denk wd@denx.de Signed-off-by: Etienne Carriere etienne.carriere@linaro.org
drivers/firmware/scmi/Kconfig | 14 +- drivers/firmware/scmi/Makefile | 1 + drivers/firmware/scmi/optee_agent.c | 312 ++++++++++++++++++++++++++++ 3 files changed, 324 insertions(+), 3 deletions(-) create mode 100644 drivers/firmware/scmi/optee_agent.c
diff --git a/drivers/firmware/scmi/Kconfig b/drivers/firmware/scmi/Kconfig index c3a109beac..f9c69e5352 100644 --- a/drivers/firmware/scmi/Kconfig +++ b/drivers/firmware/scmi/Kconfig @@ -2,7 +2,7 @@ config SCMI_FIRMWARE bool "Enable SCMI support" select FIRMWARE select OF_TRANSLATE
depends on SANDBOX || DM_MAILBOX || ARM_SMCCC
depends on SANDBOX || DM_MAILBOX || ARM_SMCCC || OPTEE help System Control and Management Interface (SCMI) is a communication protocol that defines standard interfaces for power, performance
@@ -14,6 +14,14 @@ config SCMI_FIRMWARE or a companion host in the CPU system.
Communications between agent (client) and the SCMI server are
based on message exchange. Messages can be exchange over tranport
based on message exchange. Messages can be exchanged over transport channels as a mailbox device or an Arm SMCCC service with some
piece of identified shared memory.
piece of identified shared memory, or an OP-TEE SCMI service.
+config SCMI_AGENT_OPTEE
bool "Enable SCMI agent OP-TEE"
depends on SCMI_FIRMWARE && OPTEE
default y
help
Enable the SCMI communication channel based on OP-TEE transport
for compatible "linaro,scmi-optee".
diff --git a/drivers/firmware/scmi/Makefile b/drivers/firmware/scmi/Makefile index 966475ec10..f72d06a400 100644 --- a/drivers/firmware/scmi/Makefile +++ b/drivers/firmware/scmi/Makefile @@ -2,4 +2,5 @@ obj-y += scmi_agent-uclass.o obj-y += smt.o obj-$(CONFIG_ARM_SMCCC) += smccc_agent.o obj-$(CONFIG_DM_MAILBOX) += mailbox_agent.o +obj-$(CONFIG_SCMI_AGENT_OPTEE) += optee_agent.o obj-$(CONFIG_SANDBOX) += sandbox-scmi_agent.o sandbox-scmi_devices.o diff --git a/drivers/firmware/scmi/optee_agent.c b/drivers/firmware/scmi/optee_agent.c new file mode 100644 index 0000000000..8232af2f41 --- /dev/null +++ b/drivers/firmware/scmi/optee_agent.c @@ -0,0 +1,312 @@ +// SPDX-License-Identifier: GPL-2.0+ +/*
- Copyright (C) 2020-2021 Linaro Limited.
- */
(...)
+static int scmi_optee_of_to_plat(struct udevice *dev) +{
struct scmi_optee_channel *chan = dev_get_plat(dev);
int ret;
if (dev_read_u32(dev, "linaro,optee-channel-id", &chan->channel_id)) {
dev_err(dev, "Missing property linaro,channel-id\n");
Can you use the correct property name in the error message = "linaro,optee-channel-id"
dev_err(dev, "Missing property linaro,optee-channel-id\n");
nice catch. Thanks, I'll post a v2.
Etienne
Patrick

Hi,
On 11/4/21 3:14 PM, Etienne Carriere wrote:
Define identifiers for clnt_login field in struct tee_open_session_arg based in GlobalPlatform Device TEE IDs and on the REE_KERNEL identifier extension from OP-TEE OS.
Cc: Jens Wiklander jens.wiklander@linaro.org Signed-off-by: Etienne Carriere etienne.carriere@linaro.org
This change was previously discussed in the U-Boot ML, see v2 at: https://patchwork.ozlabs.org/project/uboot/patch/20210519142613.7668-1-etien...
Changes since this v2 post:
- Updated the inline comment describing reserved login Ids
- Rephrase 'REE kernel agent' to 'REE kernel/privileged agent' to better apply to U-Boot that is not a kernel but still runs at a privileged execution level.
include/tee.h | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-)
Reviewed-by: Patrick Delaunay patrick.delaunay@foss.st.com
Thanks Patrick

On Thu, Nov 4, 2021 at 3:14 PM Etienne Carriere etienne.carriere@linaro.org wrote:
Define identifiers for clnt_login field in struct tee_open_session_arg based in GlobalPlatform Device TEE IDs and on the REE_KERNEL identifier extension from OP-TEE OS.
Cc: Jens Wiklander jens.wiklander@linaro.org Signed-off-by: Etienne Carriere etienne.carriere@linaro.org
This change was previously discussed in the U-Boot ML, see v2 at: https://patchwork.ozlabs.org/project/uboot/patch/20210519142613.7668-1-etien...
Changes since this v2 post:
- Updated the inline comment describing reserved login Ids
- Rephrase 'REE kernel agent' to 'REE kernel/privileged agent' to better apply to U-Boot that is not a kernel but still runs at a privileged execution level.
include/tee.h | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-)
Reviewed-by: Jens Wiklander jens.wiklander@linaro.org
Thanks, Jens
participants (3)
-
Etienne Carriere
-
Jens Wiklander
-
Patrick DELAUNAY