From d96315411cfca7475cd84e6226ca352ca6b53e9b Mon Sep 17 00:00:00 2001 From: Patrick Delaunay Date: Thu, 28 Oct 2021 19:13:12 +0200 Subject: [PATCH 01/15] reset: scmi: define LOG_CATEGORY Define LOG_CATEGORY to allow filtering with log command. Signed-off-by: Patrick Delaunay Acked-by: Etienne Carriere --- drivers/reset/reset-scmi.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/reset/reset-scmi.c b/drivers/reset/reset-scmi.c index 1bff8075ee..ca0135a420 100644 --- a/drivers/reset/reset-scmi.c +++ b/drivers/reset/reset-scmi.c @@ -2,6 +2,9 @@ /* * Copyright (C) 2019-2020 Linaro Limited */ + +#define LOG_CATEGORY UCLASS_RESET + #include #include #include From 31dc56fca55dc364d6c91f67f25eafb8d158c6e7 Mon Sep 17 00:00:00 2001 From: Patrick Delaunay Date: Thu, 28 Oct 2021 19:13:13 +0200 Subject: [PATCH 02/15] clk: scmi: define LOG_CATEGORY Define LOG_CATEGORY to allow filtering with log command. Signed-off-by: Patrick Delaunay Acked-by: Etienne Carriere --- drivers/clk/clk_scmi.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/clk/clk_scmi.c b/drivers/clk/clk_scmi.c index 93a4819501..9a0a6f6643 100644 --- a/drivers/clk/clk_scmi.c +++ b/drivers/clk/clk_scmi.c @@ -2,6 +2,9 @@ /* * Copyright (C) 2019-2020 Linaro Limited */ + +#define LOG_CATEGORY UCLASS_CLK + #include #include #include From d47c4fea8c22d8b5dc16ad3def2877ea15ae4289 Mon Sep 17 00:00:00 2001 From: Patrick Delaunay Date: Thu, 28 Oct 2021 19:13:14 +0200 Subject: [PATCH 03/15] power: regulator: scmi: define LOG_CATEGORY Define LOG_CATEGORY to allow filtering with log command. Signed-off-by: Patrick Delaunay Acked-by: Etienne Carriere Reviewed-by: Jaehoon Chung --- drivers/power/regulator/scmi_regulator.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/power/regulator/scmi_regulator.c b/drivers/power/regulator/scmi_regulator.c index b3142bf4e1..3ddeaf4adc 100644 --- a/drivers/power/regulator/scmi_regulator.c +++ b/drivers/power/regulator/scmi_regulator.c @@ -2,6 +2,9 @@ /* * Copyright (C) 2020-2021 Linaro Limited */ + +#define LOG_CATEGORY UCLASS_REGULATOR + #include #include #include From 73ead2bcc547f72ce5945ac2cd8274b6d1185866 Mon Sep 17 00:00:00 2001 From: Patrick Delaunay Date: Thu, 28 Oct 2021 19:13:15 +0200 Subject: [PATCH 04/15] firmware: scmi: add configs to select the supported agents Add two configs CONFIG_SCMI_AGENT_MAILBOX and CONFIG_SCMI_AGENT_SMCCC to select the supported agents as all the agents are not supported. Signed-off-by: Patrick Delaunay Acked-by: Etienne Carriere --- drivers/firmware/scmi/Kconfig | 16 ++++++++++++++++ drivers/firmware/scmi/Makefile | 4 ++-- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/drivers/firmware/scmi/Kconfig b/drivers/firmware/scmi/Kconfig index c3a109beac..c33de87cd0 100644 --- a/drivers/firmware/scmi/Kconfig +++ b/drivers/firmware/scmi/Kconfig @@ -17,3 +17,19 @@ config SCMI_FIRMWARE based on message exchange. Messages can be exchange over tranport channels as a mailbox device or an Arm SMCCC service with some piece of identified shared memory. + +config SCMI_AGENT_MAILBOX + bool "Enable SCMI agent mailbox" + depends on SCMI_FIRMWARE && DM_MAILBOX + default y + help + Enable the SCMI communication channel based on mailbox + for compatible "arm,scmi". + +config SCMI_AGENT_SMCCC + bool "Enable SCMI agent SMCCC" + depends on SCMI_FIRMWARE && ARM_SMCCC + default y + help + Enable the SCMI communication channel based on Arm SMCCC service for + compatible "arm,scmi-smc". diff --git a/drivers/firmware/scmi/Makefile b/drivers/firmware/scmi/Makefile index 966475ec10..7d6f4df1de 100644 --- a/drivers/firmware/scmi/Makefile +++ b/drivers/firmware/scmi/Makefile @@ -1,5 +1,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_SMCCC) += smccc_agent.o +obj-$(CONFIG_SCMI_AGENT_MAILBOX) += mailbox_agent.o obj-$(CONFIG_SANDBOX) += sandbox-scmi_agent.o sandbox-scmi_devices.o From 7f6743d4f88a84861f51bcd4d830d96bc87503aa Mon Sep 17 00:00:00 2001 From: Patrick Delaunay Date: Thu, 28 Oct 2021 19:13:16 +0200 Subject: [PATCH 05/15] stm32mp15: deactivate CONFIG_SCMI_AGENT_MAILBOX Deactivate the SCMI agent mailbox which is not used on STM32MP15 platforms. Signed-off-by: Patrick Delaunay Acked-by: Etienne Carriere --- configs/stm32mp15_defconfig | 1 + configs/stm32mp15_trusted_defconfig | 1 + 2 files changed, 2 insertions(+) diff --git a/configs/stm32mp15_defconfig b/configs/stm32mp15_defconfig index 4c6a52fc54..7b844a3e46 100644 --- a/configs/stm32mp15_defconfig +++ b/configs/stm32mp15_defconfig @@ -77,6 +77,7 @@ CONFIG_FASTBOOT_MMC_USER_NAME="mmc1" CONFIG_FASTBOOT_CMD_OEM_FORMAT=y CONFIG_FASTBOOT_CMD_OEM_PARTCONF=y CONFIG_FASTBOOT_CMD_OEM_BOOTBUS=y +# CONFIG_SCMI_AGENT_MAILBOX is not set CONFIG_GPIO_HOG=y CONFIG_DM_HWSPINLOCK=y CONFIG_HWSPINLOCK_STM32=y diff --git a/configs/stm32mp15_trusted_defconfig b/configs/stm32mp15_trusted_defconfig index feca26e973..270cbaa733 100644 --- a/configs/stm32mp15_trusted_defconfig +++ b/configs/stm32mp15_trusted_defconfig @@ -78,6 +78,7 @@ CONFIG_FASTBOOT_MMC_USER_NAME="mmc1" CONFIG_FASTBOOT_CMD_OEM_FORMAT=y CONFIG_FASTBOOT_CMD_OEM_PARTCONF=y CONFIG_FASTBOOT_CMD_OEM_BOOTBUS=y +# CONFIG_SCMI_AGENT_MAILBOX is not set CONFIG_GPIO_HOG=y CONFIG_DM_HWSPINLOCK=y CONFIG_HWSPINLOCK_STM32=y From 5ddbbd19576c33f584da056c78778268dcb6ad67 Mon Sep 17 00:00:00 2001 From: Etienne Carriere Date: Mon, 8 Nov 2021 08:56:07 +0100 Subject: [PATCH 06/15] firmware: scmi: fix description of an API function Correct inline comment describing API function devm_scmi_process_msg(). Signed-off-by: Etienne Carriere Reviewed-by: Patrick Delaunay --- include/scmi_agent.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/scmi_agent.h b/include/scmi_agent.h index f1be9ff209..ed40c7360a 100644 --- a/include/scmi_agent.h +++ b/include/scmi_agent.h @@ -45,9 +45,9 @@ struct scmi_msg { } /** - * scmi_send_and_process_msg() - send and process a SCMI message + * devm_scmi_process_msg() - Send and process an SCMI message * - * Send a message to a SCMI server through a target SCMI agent device. + * Send a message to an SCMI server through a target SCMI agent device. * Caller sets scmi_msg::out_msg_sz to the output message buffer size. * On return, scmi_msg::out_msg_sz stores the response payload size. * From 7b4993907a8c6839b14a769b98d56dddbf7cbe88 Mon Sep 17 00:00:00 2001 From: Etienne Carriere Date: Mon, 8 Nov 2021 08:56:08 +0100 Subject: [PATCH 07/15] firmware: scmi: mailbox transport: fix probe failure implementation Correct scmi mailbox probe function that can't free the scmi channel instance since its auto-allocated by the device model framework. Cc: Simon Glass Cc: Patrice Chotard Cc: Patrick Delaunay Signed-off-by: Etienne Carriere Reviewed-by: Patrick Delaunay --- drivers/firmware/scmi/mailbox_agent.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/drivers/firmware/scmi/mailbox_agent.c b/drivers/firmware/scmi/mailbox_agent.c index ea35e7e09e..eb841d692b 100644 --- a/drivers/firmware/scmi/mailbox_agent.c +++ b/drivers/firmware/scmi/mailbox_agent.c @@ -72,17 +72,13 @@ int scmi_mbox_probe(struct udevice *dev) ret = mbox_get_by_index(dev, 0, &chan->mbox); if (ret) { dev_err(dev, "Failed to find mailbox: %d\n", ret); - goto out; + return ret; } ret = scmi_dt_get_smt_buffer(dev, &chan->smt); if (ret) dev_err(dev, "Failed to get shm resources: %d\n", ret); -out: - if (ret) - devm_kfree(dev, chan); - return ret; } From 88a304f864a10e1b716a4e5234af35390cc7a75b Mon Sep 17 00:00:00 2001 From: Etienne Carriere Date: Mon, 8 Nov 2021 08:56:09 +0100 Subject: [PATCH 08/15] firmware: scmi: mailbox transport: use plat data, not priv data Change SCMI mailbox transport drivers to use platform data rather than private data for channel reference since it only stores platform data retrieved from the DT. Consequently the probe handler is replaced with a of_to_plat handler. Cc: Simon Glass Cc: Patrice Chotard Cc: Patrick Delaunay Signed-off-by: Etienne Carriere Reviewed-by: Patrick Delaunay --- drivers/firmware/scmi/mailbox_agent.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/firmware/scmi/mailbox_agent.c b/drivers/firmware/scmi/mailbox_agent.c index eb841d692b..8e4af0c8fa 100644 --- a/drivers/firmware/scmi/mailbox_agent.c +++ b/drivers/firmware/scmi/mailbox_agent.c @@ -33,7 +33,7 @@ struct scmi_mbox_channel { static int scmi_mbox_process_msg(struct udevice *dev, struct scmi_msg *msg) { - struct scmi_mbox_channel *chan = dev_get_priv(dev); + struct scmi_mbox_channel *chan = dev_get_plat(dev); int ret; ret = scmi_write_msg_to_smt(dev, &chan->smt, msg); @@ -62,9 +62,9 @@ out: return ret; } -int scmi_mbox_probe(struct udevice *dev) +int scmi_mbox_of_to_plat(struct udevice *dev) { - struct scmi_mbox_channel *chan = dev_get_priv(dev); + struct scmi_mbox_channel *chan = dev_get_plat(dev); int ret; chan->timeout_us = TIMEOUT_US_10MS; @@ -95,7 +95,7 @@ U_BOOT_DRIVER(scmi_mbox) = { .name = "scmi-over-mailbox", .id = UCLASS_SCMI_AGENT, .of_match = scmi_mbox_ids, - .priv_auto = sizeof(struct scmi_mbox_channel), - .probe = scmi_mbox_probe, + .plat_auto = sizeof(struct scmi_mbox_channel), + .of_to_plat = scmi_mbox_of_to_plat, .ops = &scmi_mbox_ops, }; From 3de5aef451b83412b7104fd611bb94059a741f34 Mon Sep 17 00:00:00 2001 From: Etienne Carriere Date: Mon, 8 Nov 2021 08:56:10 +0100 Subject: [PATCH 09/15] firmware: scmi: smccc transport: use plat data, not priv data Change SCMI smccc transport drivers to use platform data rather than private data for channel reference since it only stores platform data retrieved from the DT. Consequently the probe handler is replaced with a of_to_plat handler. Cc: Simon Glass Cc: Patrice Chotard Cc: Patrick Delaunay Signed-off-by: Etienne Carriere Reviewed-by: Patrick Delaunay --- drivers/firmware/scmi/smccc_agent.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/firmware/scmi/smccc_agent.c b/drivers/firmware/scmi/smccc_agent.c index f185891e8f..f0477b91dc 100644 --- a/drivers/firmware/scmi/smccc_agent.c +++ b/drivers/firmware/scmi/smccc_agent.c @@ -32,7 +32,7 @@ struct scmi_smccc_channel { static int scmi_smccc_process_msg(struct udevice *dev, struct scmi_msg *msg) { - struct scmi_smccc_channel *chan = dev_get_priv(dev); + struct scmi_smccc_channel *chan = dev_get_plat(dev); struct arm_smccc_res res; int ret; @@ -51,9 +51,9 @@ static int scmi_smccc_process_msg(struct udevice *dev, struct scmi_msg *msg) return ret; } -static int scmi_smccc_probe(struct udevice *dev) +static int scmi_smccc_of_to_plat(struct udevice *dev) { - struct scmi_smccc_channel *chan = dev_get_priv(dev); + struct scmi_smccc_channel *chan = dev_get_plat(dev); u32 func_id; int ret; @@ -86,7 +86,7 @@ U_BOOT_DRIVER(scmi_smccc) = { .name = "scmi-over-smccc", .id = UCLASS_SCMI_AGENT, .of_match = scmi_smccc_ids, - .priv_auto = sizeof(struct scmi_smccc_channel), - .probe = scmi_smccc_probe, + .plat_auto = sizeof(struct scmi_smccc_channel), + .of_to_plat = scmi_smccc_of_to_plat, .ops = &scmi_smccc_ops, }; From 32190a959de4c9467008249d0e9fb4b425332a5c Mon Sep 17 00:00:00 2001 From: Etienne Carriere Date: Mon, 8 Nov 2021 08:56:11 +0100 Subject: [PATCH 10/15] firmware: scmi: smccc transport: simplify probe sequence Minor simplification in scmi_smccc_probe() exit sequence. Cc: Simon Glass Cc: Patrice Chotard Cc: Patrick Delaunay Signed-off-by: Etienne Carriere Reviewed-by: Patrick Delaunay --- drivers/firmware/scmi/smccc_agent.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/firmware/scmi/smccc_agent.c b/drivers/firmware/scmi/smccc_agent.c index f0477b91dc..5e166ca93e 100644 --- a/drivers/firmware/scmi/smccc_agent.c +++ b/drivers/firmware/scmi/smccc_agent.c @@ -65,12 +65,10 @@ static int scmi_smccc_of_to_plat(struct udevice *dev) chan->func_id = func_id; ret = scmi_dt_get_smt_buffer(dev, &chan->smt); - if (ret) { + if (ret) dev_err(dev, "Failed to get smt resources: %d\n", ret); - return ret; - } - return 0; + return ret; } static const struct udevice_id scmi_smccc_ids[] = { From 1662ed0c1a464b39ff5b303950c034a352054114 Mon Sep 17 00:00:00 2001 From: Etienne Carriere Date: Tue, 9 Nov 2021 17:08:20 +0100 Subject: [PATCH 11/15] 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 Reviewed-by: Patrick Delaunay Reviewed-by: Jens Wiklander Signed-off-by: Etienne Carriere --- 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 From 7c1a9b2eb92d8af0ff4d46fe4ee70c65f922121e Mon Sep 17 00:00:00 2001 From: Etienne Carriere Date: Tue, 9 Nov 2021 17:08:21 +0100 Subject: [PATCH 12/15] tee: optee: remove unused duplicated login Id macros Remove unused OPTEE_MSG_LOGIN_* ID macros as suitable TEE_LOGIN_* ID macros are already defined tee.h. Cc: Jens Wiklander Reviewed-by: Patrick Delaunay Reviewed-by: Jens Wiklander Signed-off-by: Etienne Carriere --- 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 From 1442e9f33070c962e91eafdc4b591331b17b5588 Mon Sep 17 00:00:00 2001 From: Etienne Carriere Date: Tue, 9 Nov 2021 17:08:22 +0100 Subject: [PATCH 13/15] tee: optee: define TEE error code TEE_ERROR_SHORT_BUFFER 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 Reviewed-by: Patrick Delaunay Reviewed-by: Jens Wiklander Signed-off-by: Etienne Carriere --- 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 From fcb41d4db287129aaac3135881b669ad64e12a69 Mon Sep 17 00:00:00 2001 From: Etienne Carriere Date: Tue, 9 Nov 2021 17:08:23 +0100 Subject: [PATCH 14/15] dt-bindings: arm: scmi: OP-TEE as transport channel for SCMI messages 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 Reviewed-by: Patrick Delaunay Signed-off-by: Etienne Carriere --- 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 ------------------------------------------------------------ From 48108f3a6aa76218ab8b8a0b76f38629d65e1047 Mon Sep 17 00:00:00 2001 From: Etienne Carriere Date: Tue, 9 Nov 2021 17:08:24 +0100 Subject: [PATCH 15/15] firmware: scmi: Add OP-TEE transport 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.Ib2e58ee67f4d023823d8b5404332dc4d7e847277@changeid/ Cc: Patrick Delaunay Cc: Wolfgang Denk Signed-off-by: Etienne Carriere Reviewed-by: Patrick Delaunay --- drivers/firmware/scmi/Kconfig | 12 +- drivers/firmware/scmi/Makefile | 1 + drivers/firmware/scmi/optee_agent.c | 312 ++++++++++++++++++++++++++++ 3 files changed, 323 insertions(+), 2 deletions(-) create mode 100644 drivers/firmware/scmi/optee_agent.c diff --git a/drivers/firmware/scmi/Kconfig b/drivers/firmware/scmi/Kconfig index c33de87cd0..8cf85f0d7a 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,7 +14,7 @@ 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. @@ -33,3 +33,11 @@ config SCMI_AGENT_SMCCC help Enable the SCMI communication channel based on Arm SMCCC service for compatible "arm,scmi-smc". + +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 7d6f4df1de..b2ff483c75 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_SCMI_AGENT_SMCCC) += smccc_agent.o obj-$(CONFIG_SCMI_AGENT_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..1f26592234 --- /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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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,optee-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, +};