* [PATCH v5 00/11] firmware: imx: NXP Secure-Enclave FW Driver
@ 2023-08-23 7:33 Pankaj Gupta
2023-08-23 7:33 ` [PATCH v5 01/11] dt-bindings: arm: fsl: add imx-se-fw binding doc Pankaj Gupta
` (10 more replies)
0 siblings, 11 replies; 28+ messages in thread
From: Pankaj Gupta @ 2023-08-23 7:33 UTC (permalink / raw)
To: shawnguo, s.hauer, kernel, clin, conor+dt, pierre.gondois,
ping.bai, xiaoning.wang, wei.fang, peng.fan, haibo.chen, festevam,
linux-imx, davem, robh+dt, krzysztof.kozlowski+dt,
linux-arm-kernel, devicetree, linux-kernel, gaurav.jain,
alexander.stein, sahil.malhotra, aisheng.dong, V.Sethi
Cc: Pankaj Gupta
v5 Changes:
- 1/7 DT Binding: Disposed off comments from .yaml
-- to use "-", instead of "_".
-- to use generic name, concatinated with soc-id.
-- removed mu-did.
-- renamed the ele-mu to se-fw
-- moved the file from .../arm/freescale/ to .../firmware/
- 2/7 Changed the .dtsi, as per the comments.
-- removed mu-did
-- renamed the ele_mu to se-fw.
-- updated the compatible string.
-- tested the DTB.
- 4/7 Changed the .dtsi, as per the comments.
-- removed mu-did
-- renamed the ele_mu to se-fw.
-- updated the compatible string.
-- tested the DTB.
- 6/7 Changes in driver code:
-- replace pr_err with dev_err
-- removed export symbols, except one, which will be used in other driver.
-- Each API, send-recived based on device reference.
-- Divided the commits into smaller commits.
- Base Driver
-- Added ABI file.
- exchange init-fw message with enclave's fw
- enabled TRNG
- read-common-fuses
v4 Changes:
- Post internal review, changed the name from "ele-mu" to "se-fw".
- Disposed-off comments in the dt-binding file.
- Removed the non-hw related dt-bindings from the driver code.
- Corrected the File MAINTAINERS for correct name of yaml file.
v3 Changes:
- update the commit message for documentation.
- Fixed dt-binding checking error for file- fsl,ele_mu.yaml
- Coverity fixes in the ele_mu.c
v2 Changes:
- Fixed Kernel Test Bot issues.
- Removed ".../devicetree/bindings/mailbox/fsl,muap.txt"
The NXP's i.MX EdgeLock Enclave, a HW IP creating an embedded
secure enclave within the SoC boundary to enable features like
- HSM
- SHE
- V2X
Communicates via message unit with linux kernel. This driver
is enables communication ensuring well defined message sequence
protocol between Application Core and enclave's firmware.
Driver configures multiple misc-device on the MU, for multiple
user-space applications can communicate on single MU.
It exists on some i.MX processors. e.g. i.MX8ULP, i.MX93 etc.
Pankaj Gupta (11):
dt-bindings: arm: fsl: add imx-se-fw binding doc
arm64: dts: imx8ulp-evk: added nxp secure enclave firmware
arm64: dts: imx8ulp-evk: reserved mem-ranges to constrain ele_fw
dma-range
arm64: dts: imx93-11x11-evk: added nxp secure enclave fw
arm64: dts: imx93-11x11-evk: reserved mem-ranges to constrain ele_fw
dma-range
firmware: imx: add driver for NXP EdgeLock Enclave
firmware: imx: init-fw api exchange on imx93
firmware: imx: enable trng
firmware: imx: enclave-fw: add handling for save/restore IMEM region
firmware: imx: enclave api to read-common-fuses
MAINTAINERS: Added maintainer details
Documentation/ABI/testing/se-cdev | 29 +
.../bindings/firmware/fsl,imx-se-fw.yaml | 121 ++
MAINTAINERS | 10 +
arch/arm64/boot/dts/freescale/imx8ulp-evk.dts | 15 +
arch/arm64/boot/dts/freescale/imx8ulp.dtsi | 11 +-
.../boot/dts/freescale/imx93-11x11-evk.dts | 15 +
arch/arm64/boot/dts/freescale/imx93.dtsi | 10 +-
drivers/firmware/imx/Kconfig | 21 +
drivers/firmware/imx/Makefile | 3 +
drivers/firmware/imx/ele_base_msg.c | 272 ++++
drivers/firmware/imx/ele_common.c | 188 +++
drivers/firmware/imx/ele_common.h | 31 +
drivers/firmware/imx/ele_fw_api.c | 110 ++
drivers/firmware/imx/ele_trng.c | 48 +
drivers/firmware/imx/se_fw.c | 1274 +++++++++++++++++
drivers/firmware/imx/se_fw.h | 176 +++
include/linux/firmware/imx/ele_base_msg.h | 66 +
include/linux/firmware/imx/ele_fw_api.h | 24 +
include/linux/firmware/imx/ele_mu_ioctl.h | 52 +
19 files changed, 2474 insertions(+), 2 deletions(-)
create mode 100644 Documentation/ABI/testing/se-cdev
create mode 100644 Documentation/devicetree/bindings/firmware/fsl,imx-se-fw.yaml
create mode 100644 drivers/firmware/imx/ele_base_msg.c
create mode 100644 drivers/firmware/imx/ele_common.c
create mode 100644 drivers/firmware/imx/ele_common.h
create mode 100644 drivers/firmware/imx/ele_fw_api.c
create mode 100644 drivers/firmware/imx/ele_trng.c
create mode 100644 drivers/firmware/imx/se_fw.c
create mode 100644 drivers/firmware/imx/se_fw.h
create mode 100644 include/linux/firmware/imx/ele_base_msg.h
create mode 100644 include/linux/firmware/imx/ele_fw_api.h
create mode 100644 include/linux/firmware/imx/ele_mu_ioctl.h
--
2.34.1
^ permalink raw reply [flat|nested] 28+ messages in thread
* [PATCH v5 01/11] dt-bindings: arm: fsl: add imx-se-fw binding doc
2023-08-23 7:33 [PATCH v5 00/11] firmware: imx: NXP Secure-Enclave FW Driver Pankaj Gupta
@ 2023-08-23 7:33 ` Pankaj Gupta
2023-08-23 8:28 ` Rob Herring
2023-08-23 12:43 ` Rob Herring
2023-08-23 7:33 ` [PATCH v5 02/11] arm64: dts: imx8ulp-evk: added nxp secure enclave firmware Pankaj Gupta
` (9 subsequent siblings)
10 siblings, 2 replies; 28+ messages in thread
From: Pankaj Gupta @ 2023-08-23 7:33 UTC (permalink / raw)
To: shawnguo, s.hauer, kernel, clin, conor+dt, pierre.gondois,
ping.bai, xiaoning.wang, wei.fang, peng.fan, haibo.chen, festevam,
linux-imx, davem, robh+dt, krzysztof.kozlowski+dt,
linux-arm-kernel, devicetree, linux-kernel, gaurav.jain,
alexander.stein, sahil.malhotra, aisheng.dong, V.Sethi
Cc: Pankaj Gupta
The NXP's i.MX EdgeLock Enclave, a HW IP creating an embedded
secure enclave within the SoC boundary to enable features like
- HSM
- SHE
- V2X
Communicates via message unit with linux kernel. This driver
is enables communication ensuring well defined message sequence
protocol between Application Core and enclave's firmware.
Driver configures multiple misc-device on the MU, for multiple
user-space applications can communicate on single MU.
It exists on some i.MX processors. e.g. i.MX8ULP, i.MX93 etc.
Signed-off-by: Pankaj Gupta <pankaj.gupta@nxp.com>
---
.../bindings/firmware/fsl,imx-se-fw.yaml | 121 ++++++++++++++++++
1 file changed, 121 insertions(+)
create mode 100644 Documentation/devicetree/bindings/firmware/fsl,imx-se-fw.yaml
diff --git a/Documentation/devicetree/bindings/firmware/fsl,imx-se-fw.yaml b/Documentation/devicetree/bindings/firmware/fsl,imx-se-fw.yaml
new file mode 100644
index 000000000000..f7230f93e56d
--- /dev/null
+++ b/Documentation/devicetree/bindings/firmware/fsl,imx-se-fw.yaml
@@ -0,0 +1,121 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/firmware/fsl,imx-se-fw.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: NXP i.MX EdgeLock Enclave Firmware (ELEFW)
+
+maintainers:
+ - Pankaj Gupta <pankaj.gupta@nxp.com>
+
+description:
+ The NXP's i.MX EdgeLock Enclave, a HW IP creating an embedded
+ secure enclave within the SoC boundary to enable features like
+ - HSM
+ - SHE
+ - V2X
+
+ It uses message unit to communicate and coordinate to pass messages
+ (e.g., data, status and control) through its interfaces.
+
+ This driver configures multiple misc-devices on the MU, to exchange
+ messages from User-space application and NXP's Edgelocke Enclave firmware.
+ The driver ensures that the messages must follow the following protocol
+ defined.
+
+ Non-Secure + Secure
+ |
+ |
+ +---------+ +-------------+ |
+ | ele_mu.c+<---->+imx-mailbox.c| |
+ | | | mailbox.c +<-->+------+ +------+
+ +---+-----+ +-------------+ | MU X +<-->+ ELE |
+ | +------+ +------+
+ +----------------+ |
+ | | |
+ v v |
+ logical logical |
+ receiver waiter |
+ + + |
+ | | |
+ | | |
+ | +----+------+ |
+ | | | |
+ | | | |
+ device_ctx device_ctx device_ctx |
+ |
+ User 0 User 1 User Y |
+ +------+ +------+ +------+ |
+ |misc.c| |misc.c| |misc.c| |
+ kernel space +------+ +------+ +------+ |
+ |
+ +------------------------------------------------------ |
+ | | | |
+ userspace /dev/ele_muXch0 | | |
+ /dev/ele_muXch1 | |
+ /dev/ele_muXchY |
+ |
+
+ When a user sends a command to the firmware, it registers its device_ctx
+ as waiter of a response from firmware.
+
+ A user can be registered as receiver of command from the ELE.
+ Create char devices in /dev as channels of the form /dev/ele_muXchY with X
+ the id of the driver and Y for each users. It allows to send and receive
+ messages to the NXP EdgeLock Enclave IP firmware on NXP SoC, where current
+ possible value, i.e., supported SoC(s) are imx8ulp, imx93.
+
+properties:
+ compatible:
+ enum:
+ - fsl,imx8ulp-se-fw
+ - fsl,imx93-se-fw
+
+ mboxes:
+ description:
+ All MU channels must be within the same MU instance. Cross instances are
+ not allowed. Users need to ensure that used MU instance does not conflict
+ with other execution environments.
+ items:
+ - description: TX0 MU channel
+ - description: RX0 MU channel
+
+ mbox-names:
+ items:
+ - const: tx
+ - const: rx
+
+ fsl,mu-did:
+ $ref: /schemas/types.yaml#/definitions/uint32
+ description:
+ By design, Domain is a clean separated processing island with separate power,
+ clocking and peripheral; but with a tightly integrated bus fabric for efficient
+ communication. The Domain to which this message-unit is associated, is identified
+ via Domain ID or did.
+
+ sram-pool:
+ items:
+ - description: SRAM memory instance.
+
+ memory-region:
+ items:
+ - description: Reserved memory region that can be accessed by firmware. Used for
+ exchanging the buffers between driver and firmware.
+
+required:
+ - compatible
+ - mboxes
+ - mbox-names
+ - mu-id
+
+additionalProperties: false
+
+examples:
+ - |
+ ele_fw: se-fw {
+ compatible = "fsl,imx8ulp-se-fw";
+ mbox-names = "tx", "rx";
+ mboxes = <&s4muap 0 0>, <&s4muap 1 0>;
+ fsl,mu-id = <2>;
+ };
--
2.34.1
^ permalink raw reply related [flat|nested] 28+ messages in thread
* [PATCH v5 02/11] arm64: dts: imx8ulp-evk: added nxp secure enclave firmware
2023-08-23 7:33 [PATCH v5 00/11] firmware: imx: NXP Secure-Enclave FW Driver Pankaj Gupta
2023-08-23 7:33 ` [PATCH v5 01/11] dt-bindings: arm: fsl: add imx-se-fw binding doc Pankaj Gupta
@ 2023-08-23 7:33 ` Pankaj Gupta
2023-08-23 7:33 ` [PATCH v5 03/11] arm64: dts: imx8ulp-evk: reserved mem-ranges to constrain ele_fw dma-range Pankaj Gupta
` (8 subsequent siblings)
10 siblings, 0 replies; 28+ messages in thread
From: Pankaj Gupta @ 2023-08-23 7:33 UTC (permalink / raw)
To: shawnguo, s.hauer, kernel, clin, conor+dt, pierre.gondois,
ping.bai, xiaoning.wang, wei.fang, peng.fan, haibo.chen, festevam,
linux-imx, davem, robh+dt, krzysztof.kozlowski+dt,
linux-arm-kernel, devicetree, linux-kernel, gaurav.jain,
alexander.stein, sahil.malhotra, aisheng.dong, V.Sethi
Cc: Pankaj Gupta
Added support for NXP secure enclave called EdgeLock Enclave
firmware (se-fw) for imx8ulp-evk.
Signed-off-by: Pankaj Gupta <pankaj.gupta@nxp.com>
---
arch/arm64/boot/dts/freescale/imx8ulp.dtsi | 11 ++++++++++-
1 file changed, 10 insertions(+), 1 deletion(-)
diff --git a/arch/arm64/boot/dts/freescale/imx8ulp.dtsi b/arch/arm64/boot/dts/freescale/imx8ulp.dtsi
index 3ddc0f3125b3..d4f03409be1a 100644
--- a/arch/arm64/boot/dts/freescale/imx8ulp.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8ulp.dtsi
@@ -114,7 +114,7 @@ sosc: clock-sosc {
#clock-cells = <0>;
};
- sram@2201f000 {
+ sram0: sram@2201f000 {
compatible = "mmio-sram";
reg = <0x0 0x2201f000 0x0 0x1000>;
@@ -507,4 +507,13 @@ gpiod: gpio@2e200080 {
gpio-ranges = <&iomuxc1 0 0 24>;
};
};
+ ele_fw2: se-fw2 {
+ compatible = "fsl,imx8ulp-se-fw";
+ mbox-names = "tx", "rx";
+ mboxes = <&s4muap 0 0>,
+ <&s4muap 1 0>;
+ fsl,mu-id = <2>;
+ sram-pool = <&sram0>;
+ };
+
};
--
2.34.1
^ permalink raw reply related [flat|nested] 28+ messages in thread
* [PATCH v5 03/11] arm64: dts: imx8ulp-evk: reserved mem-ranges to constrain ele_fw dma-range
2023-08-23 7:33 [PATCH v5 00/11] firmware: imx: NXP Secure-Enclave FW Driver Pankaj Gupta
2023-08-23 7:33 ` [PATCH v5 01/11] dt-bindings: arm: fsl: add imx-se-fw binding doc Pankaj Gupta
2023-08-23 7:33 ` [PATCH v5 02/11] arm64: dts: imx8ulp-evk: added nxp secure enclave firmware Pankaj Gupta
@ 2023-08-23 7:33 ` Pankaj Gupta
2023-08-23 7:33 ` [PATCH v5 04/11] arm64: dts: imx93-11x11-evk: added nxp secure enclave fw Pankaj Gupta
` (7 subsequent siblings)
10 siblings, 0 replies; 28+ messages in thread
From: Pankaj Gupta @ 2023-08-23 7:33 UTC (permalink / raw)
To: shawnguo, s.hauer, kernel, clin, conor+dt, pierre.gondois,
ping.bai, xiaoning.wang, wei.fang, peng.fan, haibo.chen, festevam,
linux-imx, davem, robh+dt, krzysztof.kozlowski+dt,
linux-arm-kernel, devicetree, linux-kernel, gaurav.jain,
alexander.stein, sahil.malhotra, aisheng.dong, V.Sethi
Cc: Pankaj Gupta
EdgeLock Enclave are has a hardware limitation of restricted access
to the DDR memory range:
- 0x90000000 - 0xAFFFFFFF
ELE-FW driver requireis 1MB of memory. In this patch the we are reserving
1MB of ddr memory region from the lower 32-bit range.
Signed-off-by: Dong Aisheng <aisheng.dong@nxp.com>
Signed-off-by: Pankaj Gupta <pankaj.gupta@nxp.com>
---
arch/arm64/boot/dts/freescale/imx8ulp-evk.dts | 15 +++++++++++++++
1 file changed, 15 insertions(+)
diff --git a/arch/arm64/boot/dts/freescale/imx8ulp-evk.dts b/arch/arm64/boot/dts/freescale/imx8ulp-evk.dts
index f1c6d933a17c..747cb9d6b2e9 100644
--- a/arch/arm64/boot/dts/freescale/imx8ulp-evk.dts
+++ b/arch/arm64/boot/dts/freescale/imx8ulp-evk.dts
@@ -19,6 +19,17 @@ memory@80000000 {
device_type = "memory";
reg = <0x0 0x80000000 0 0x80000000>;
};
+ reserved-memory {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ ele_reserved: ele-reserved@90000000 {
+ compatible = "shared-dma-pool";
+ reg = <0 0x90000000 0 0x100000>;
+ no-map;
+ };
+ };
clock_ext_rmii: clock-ext-rmii {
compatible = "fixed-clock";
@@ -53,6 +64,10 @@ &usdhc0 {
status = "okay";
};
+&ele_fw2 {
+ memory-region = <&ele_reserved>;
+};
+
&fec {
pinctrl-names = "default", "sleep";
pinctrl-0 = <&pinctrl_enet>;
--
2.34.1
^ permalink raw reply related [flat|nested] 28+ messages in thread
* [PATCH v5 04/11] arm64: dts: imx93-11x11-evk: added nxp secure enclave fw
2023-08-23 7:33 [PATCH v5 00/11] firmware: imx: NXP Secure-Enclave FW Driver Pankaj Gupta
` (2 preceding siblings ...)
2023-08-23 7:33 ` [PATCH v5 03/11] arm64: dts: imx8ulp-evk: reserved mem-ranges to constrain ele_fw dma-range Pankaj Gupta
@ 2023-08-23 7:33 ` Pankaj Gupta
2023-08-23 7:33 ` [PATCH v5 05/11] arm64: dts: imx93-11x11-evk: reserved mem-ranges to constrain ele_fw dma-range Pankaj Gupta
` (6 subsequent siblings)
10 siblings, 0 replies; 28+ messages in thread
From: Pankaj Gupta @ 2023-08-23 7:33 UTC (permalink / raw)
To: shawnguo, s.hauer, kernel, clin, conor+dt, pierre.gondois,
ping.bai, xiaoning.wang, wei.fang, peng.fan, haibo.chen, festevam,
linux-imx, davem, robh+dt, krzysztof.kozlowski+dt,
linux-arm-kernel, devicetree, linux-kernel, gaurav.jain,
alexander.stein, sahil.malhotra, aisheng.dong, V.Sethi
Cc: Pankaj Gupta
Added support for NXP secure enclave called EdgeLock Enclave
firmware (se-fw) for imx93-11x11-evk.
Signed-off-by: Pankaj Gupta <pankaj.gupta@nxp.com>
---
arch/arm64/boot/dts/freescale/imx93.dtsi | 10 +++++++++-
1 file changed, 9 insertions(+), 1 deletion(-)
diff --git a/arch/arm64/boot/dts/freescale/imx93.dtsi b/arch/arm64/boot/dts/freescale/imx93.dtsi
index 8643612ace8c..d482b66c5fa4 100644
--- a/arch/arm64/boot/dts/freescale/imx93.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx93.dtsi
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
/*
- * Copyright 2022 NXP
+ * Copyright 2022-2023 NXP
*/
#include <dt-bindings/clock/imx93-clock.h>
@@ -864,4 +864,12 @@ ddr-pmu@4e300dc0 {
interrupts = <GIC_SPI 90 IRQ_TYPE_LEVEL_HIGH>;
};
};
+
+ ele_fw2: se-fw2 {
+ compatible = "fsl,imx93-se-fw";
+ mbox-names = "tx", "rx";
+ mboxes = <&s4muap 0 0>,
+ <&s4muap 1 0>;
+ fsl,mu-id = <2>;
+ };
};
--
2.34.1
^ permalink raw reply related [flat|nested] 28+ messages in thread
* [PATCH v5 05/11] arm64: dts: imx93-11x11-evk: reserved mem-ranges to constrain ele_fw dma-range
2023-08-23 7:33 [PATCH v5 00/11] firmware: imx: NXP Secure-Enclave FW Driver Pankaj Gupta
` (3 preceding siblings ...)
2023-08-23 7:33 ` [PATCH v5 04/11] arm64: dts: imx93-11x11-evk: added nxp secure enclave fw Pankaj Gupta
@ 2023-08-23 7:33 ` Pankaj Gupta
2023-08-23 7:33 ` [PATCH v5 06/11] firmware: imx: add driver for NXP EdgeLock Enclave Pankaj Gupta
` (5 subsequent siblings)
10 siblings, 0 replies; 28+ messages in thread
From: Pankaj Gupta @ 2023-08-23 7:33 UTC (permalink / raw)
To: shawnguo, s.hauer, kernel, clin, conor+dt, pierre.gondois,
ping.bai, xiaoning.wang, wei.fang, peng.fan, haibo.chen, festevam,
linux-imx, davem, robh+dt, krzysztof.kozlowski+dt,
linux-arm-kernel, devicetree, linux-kernel, gaurav.jain,
alexander.stein, sahil.malhotra, aisheng.dong, V.Sethi
Cc: Pankaj Gupta
EdgeLock Enclave are has a hardware limitation of restricted access
to the DDR memory range:
- 0x80000000 0x9FFFFFFF
ELE-MU driver requireis 1MB of memory. In this patch the we are reserving
1MB of ddr memory region from the lower 32-bit range.
Signed-off-by: Dong Aisheng <aisheng.dong@nxp.com>
Signed-off-by: Pankaj Gupta <pankaj.gupta@nxp.com>
---
arch/arm64/boot/dts/freescale/imx93-11x11-evk.dts | 15 +++++++++++++++
1 file changed, 15 insertions(+)
diff --git a/arch/arm64/boot/dts/freescale/imx93-11x11-evk.dts b/arch/arm64/boot/dts/freescale/imx93-11x11-evk.dts
index c50f46f06f62..0abff3a55abc 100644
--- a/arch/arm64/boot/dts/freescale/imx93-11x11-evk.dts
+++ b/arch/arm64/boot/dts/freescale/imx93-11x11-evk.dts
@@ -7,6 +7,10 @@
#include "imx93.dtsi"
+&ele_fw2 {
+ memory-region = <&ele_reserved>;
+};
+
/ {
model = "NXP i.MX93 11X11 EVK board";
compatible = "fsl,imx93-11x11-evk", "fsl,imx93";
@@ -22,6 +26,17 @@ reg_vref_1v8: regulator-adc-vref {
regulator-max-microvolt = <1800000>;
};
+ reserved-memory {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+ ele_reserved: ele-reserved@a4120000 {
+ compatible = "shared-dma-pool";
+ reg = <0 0xa4120000 0 0x100000>;
+ no-map;
+ };
+ };
+
reg_usdhc2_vmmc: regulator-usdhc2 {
compatible = "regulator-fixed";
pinctrl-names = "default";
--
2.34.1
^ permalink raw reply related [flat|nested] 28+ messages in thread
* [PATCH v5 06/11] firmware: imx: add driver for NXP EdgeLock Enclave
2023-08-23 7:33 [PATCH v5 00/11] firmware: imx: NXP Secure-Enclave FW Driver Pankaj Gupta
` (4 preceding siblings ...)
2023-08-23 7:33 ` [PATCH v5 05/11] arm64: dts: imx93-11x11-evk: reserved mem-ranges to constrain ele_fw dma-range Pankaj Gupta
@ 2023-08-23 7:33 ` Pankaj Gupta
2023-08-24 18:31 ` Krzysztof Kozlowski
2023-08-25 10:22 ` Stefan Wahren
2023-08-23 7:33 ` [PATCH v5 07/11] firmware: imx: init-fw api exchange on imx93 Pankaj Gupta
` (4 subsequent siblings)
10 siblings, 2 replies; 28+ messages in thread
From: Pankaj Gupta @ 2023-08-23 7:33 UTC (permalink / raw)
To: shawnguo, s.hauer, kernel, clin, conor+dt, pierre.gondois,
ping.bai, xiaoning.wang, wei.fang, peng.fan, haibo.chen, festevam,
linux-imx, davem, robh+dt, krzysztof.kozlowski+dt,
linux-arm-kernel, devicetree, linux-kernel, gaurav.jain,
alexander.stein, sahil.malhotra, aisheng.dong, V.Sethi
Cc: Pankaj Gupta, kernel test robot
The Edgelock Enclave , is the secure enclave embedded in the SoC
to support the features like HSM, SHE & V2X, using message based
communication channel.
ELE FW communicates on a dedicated MU with application core where
kernel is running. It exists on specific i.MX processors. e.g.
i.MX8ULP, i.MX93.
Reported-by: kernel test robot <lkp@intel.com>
Closes:https://lore.kernel.org/oe-kbuild-all/202304120902.bP52A56z-lkp@intel.com
Signed-off-by: Pankaj Gupta <pankaj.gupta@nxp.com>
---
Documentation/ABI/testing/se-cdev | 29 +
drivers/firmware/imx/Kconfig | 12 +
drivers/firmware/imx/Makefile | 2 +
drivers/firmware/imx/ele_base_msg.c | 62 ++
drivers/firmware/imx/ele_common.c | 34 +
drivers/firmware/imx/ele_common.h | 21 +
drivers/firmware/imx/se_fw.c | 1201 +++++++++++++++++++++
drivers/firmware/imx/se_fw.h | 168 +++
include/linux/firmware/imx/ele_base_msg.h | 37 +
include/linux/firmware/imx/ele_mu_ioctl.h | 52 +
10 files changed, 1618 insertions(+)
create mode 100644 Documentation/ABI/testing/se-cdev
create mode 100644 drivers/firmware/imx/ele_base_msg.c
create mode 100644 drivers/firmware/imx/ele_common.c
create mode 100644 drivers/firmware/imx/ele_common.h
create mode 100644 drivers/firmware/imx/se_fw.c
create mode 100644 drivers/firmware/imx/se_fw.h
create mode 100644 include/linux/firmware/imx/ele_base_msg.h
create mode 100644 include/linux/firmware/imx/ele_mu_ioctl.h
diff --git a/Documentation/ABI/testing/se-cdev b/Documentation/ABI/testing/se-cdev
new file mode 100644
index 000000000000..da0655b84376
--- /dev/null
+++ b/Documentation/ABI/testing/se-cdev
@@ -0,0 +1,29 @@
+What: /dev/<se>_mu[0-9]+_ch[0-9]+
+Date: August 2023
+KernelVersion: 6.5
+Contact: linux-imx@nxp.com, pankaj.gupta@nxp.com
+Description:
+ NXP offers multiple secure-enclaves like EdgeLock Enclave(ELE), SECO
+ The character device files /dev/<se>_mu*_ch* are the interface
+ between user-space NXP's secure-enclave shared-library and the kernel
+ driver.
+
+ The ioctl(2)-based ABI is defined and documented in
+ [include]<linux/firmware/imx/ele_mu_ioctl.h>
+
+ The following file operations are supported:
+
+ open(2)
+ Currently the only useful flags are O_RDWR.
+
+ ioctl(2)
+ Initiate various actions.
+
+ See the inline documentation in [include]<linux/firmware/imx/ele_mu_ioctl.h>
+ for descriptions of all ioctls.
+
+ close(2)
+ Stops and free up the I/O contexts that was associated
+ with the file descriptor.
+
+Users: TBD
diff --git a/drivers/firmware/imx/Kconfig b/drivers/firmware/imx/Kconfig
index c027d99f2a59..2822e5d4b24c 100644
--- a/drivers/firmware/imx/Kconfig
+++ b/drivers/firmware/imx/Kconfig
@@ -28,3 +28,15 @@ config IMX_SCU_PD
depends on IMX_SCU
help
The System Controller Firmware (SCFW) based power domain driver.
+
+config IMX_SEC_ENCLAVE
+ tristate "i.MX Embedded Secure Enclave - EdgeLock Enclave Firmware driver."
+ depends on IMX_MBOX && ARCH_MXC && ARM64
+ default m if ARCH_MXC
+
+ help
+ It is possible to use APIs exposed by the iMX Secure Enclave HW IP called:
+ - EdgeLock Enclave Firmware (for i.MX8ULP, i.MX93),
+ like base, HSM, V2X & SHE using the SAB protocol via the shared Messaging
+ Unit. This driver exposes these interfaces via a set of file descriptors
+ allowing to configure shared memory, send and receive messages.
diff --git a/drivers/firmware/imx/Makefile b/drivers/firmware/imx/Makefile
index b76acbade2a0..eab3f03e2e5e 100644
--- a/drivers/firmware/imx/Makefile
+++ b/drivers/firmware/imx/Makefile
@@ -2,3 +2,5 @@
obj-$(CONFIG_IMX_DSP) += imx-dsp.o
obj-$(CONFIG_IMX_SCU) += imx-scu.o misc.o imx-scu-irq.o rm.o imx-scu-soc.o
obj-$(CONFIG_IMX_SCU_PD) += scu-pd.o
+sec_enclave-objs = se_fw.o ele_common.o ele_base_msg.o
+obj-${CONFIG_IMX_SEC_ENCLAVE} += sec_enclave.o
diff --git a/drivers/firmware/imx/ele_base_msg.c b/drivers/firmware/imx/ele_base_msg.c
new file mode 100644
index 000000000000..2eb675a1b389
--- /dev/null
+++ b/drivers/firmware/imx/ele_base_msg.c
@@ -0,0 +1,62 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2021-2023 NXP
+ */
+
+#include <linux/types.h>
+#include <linux/completion.h>
+
+#include <linux/firmware/imx/ele_base_msg.h>
+#include <linux/firmware/imx/ele_mu_ioctl.h>
+
+#include "ele_common.h"
+
+/* Fill a command message header with a given command ID and length in bytes. */
+static int plat_fill_cmd_msg_hdr(struct ele_mu_priv *priv,
+ struct mu_hdr *hdr,
+ uint8_t cmd,
+ uint32_t len)
+{
+ int err = 0;
+
+ hdr->tag = priv->cmd_tag;
+ hdr->ver = ELE_BASE_API_VERSION;
+ hdr->command = cmd;
+ hdr->size = len >> 2;
+
+ return err;
+}
+
+int ele_get_info(struct device *dev, phys_addr_t addr, u32 data_size)
+{
+ struct ele_mu_priv *priv = dev_get_drvdata(dev);
+ int ret;
+ unsigned int tag, command, size, ver, status;
+
+ ret = plat_fill_cmd_msg_hdr(priv,
+ (struct mu_hdr *)&priv->tx_msg.header,
+ ELE_GET_INFO_REQ, 16);
+ if (ret)
+ return ret;
+
+ priv->tx_msg.data[0] = upper_32_bits(addr);
+ priv->tx_msg.data[1] = lower_32_bits(addr);
+ priv->tx_msg.data[2] = data_size;
+ ret = imx_ele_msg_send_rcv(priv);
+ if (ret < 0)
+ return ret;
+
+ tag = MSG_TAG(priv->rx_msg.header);
+ command = MSG_COMMAND(priv->rx_msg.header);
+ size = MSG_SIZE(priv->rx_msg.header);
+ ver = MSG_VER(priv->rx_msg.header);
+ status = RES_STATUS(priv->rx_msg.data[0]);
+ if (tag == priv->rsp_tag &&
+ command == ELE_GET_INFO_REQ &&
+ size == ELE_GET_INFO_REQ_MSG_SZ &&
+ ver == ELE_BASE_API_VERSION &&
+ status == priv->success_tag)
+ return 0;
+
+ return -EINVAL;
+}
diff --git a/drivers/firmware/imx/ele_common.c b/drivers/firmware/imx/ele_common.c
new file mode 100644
index 000000000000..08adc7200ceb
--- /dev/null
+++ b/drivers/firmware/imx/ele_common.c
@@ -0,0 +1,34 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2021-2023 NXP
+ */
+
+#include "se_fw.h"
+
+int imx_ele_msg_send_rcv(struct ele_mu_priv *priv)
+{
+ unsigned int wait;
+ int err;
+
+ mutex_lock(&priv->mu_cmd_lock);
+ mutex_lock(&priv->mu_lock);
+
+ err = mbox_send_message(priv->tx_chan, &priv->tx_msg);
+ if (err < 0) {
+ pr_err("Error: mbox_send_message failure.\n");
+ mutex_unlock(&priv->mu_lock);
+ return err;
+ }
+ mutex_unlock(&priv->mu_lock);
+
+ wait = msecs_to_jiffies(1000);
+ if (!wait_for_completion_timeout(&priv->done, wait)) {
+ pr_err("Error: wait_for_completion timed out.\n");
+ err = -ETIMEDOUT;
+ }
+
+ mutex_unlock(&priv->mu_cmd_lock);
+
+ return err;
+}
+
diff --git a/drivers/firmware/imx/ele_common.h b/drivers/firmware/imx/ele_common.h
new file mode 100644
index 000000000000..6af0296b76fd
--- /dev/null
+++ b/drivers/firmware/imx/ele_common.h
@@ -0,0 +1,21 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright 2023 NXP
+ */
+
+
+#ifndef __ELE_COMMON_H__
+#define __ELE_COMMON_H__
+
+#include "se_fw.h"
+
+int imx_ele_msg_send_rcv(struct ele_mu_priv *priv);
+#ifdef CONFIG_IMX_ELE_TRNG
+int ele_trng_init(struct device *dev);
+#else
+static inline int ele_trng_init(struct device *dev)
+{
+ return 0;
+}
+#endif
+#endif
diff --git a/drivers/firmware/imx/se_fw.c b/drivers/firmware/imx/se_fw.c
new file mode 100644
index 000000000000..2c97b2adf18b
--- /dev/null
+++ b/drivers/firmware/imx/se_fw.c
@@ -0,0 +1,1201 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2021-2023 NXP
+ */
+
+#include <linux/dma-mapping.h>
+#include <linux/completion.h>
+#include <linux/dev_printk.h>
+#include <linux/errno.h>
+#include <linux/export.h>
+#include <linux/firmware/imx/ele_base_msg.h>
+#include <linux/firmware/imx/ele_mu_ioctl.h>
+#include <linux/genalloc.h>
+#include <linux/io.h>
+#include <linux/init.h>
+#include <linux/miscdevice.h>
+#include <linux/mod_devicetable.h>
+#include <linux/module.h>
+#include <linux/of_platform.h>
+#include <linux/of_reserved_mem.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include <linux/sys_soc.h>
+
+#include "se_fw.h"
+
+#define SOC_ID_OF_IMX8ULP 0x084D
+#define SOC_ID_OF_IMX93 0x9300
+#define SOC_VER_MASK 0xFFFF0000
+#define SOC_ID_MASK 0x0000FFFF
+#define RESERVED_DMA_POOL BIT(1)
+
+struct imx_info {
+ bool socdev;
+ uint8_t mu_did;
+ uint8_t max_dev_ctx;
+ uint8_t cmd_tag;
+ uint8_t rsp_tag;
+ uint8_t success_tag;
+ uint8_t *se_name;
+ uint8_t *pool_name;
+ bool reserved_dma_ranges;
+};
+
+static LIST_HEAD(priv_data_list);
+
+static const struct imx_info imx8ulp_info = {
+ .socdev = true,
+ .mu_did = 7,
+ .max_dev_ctx = 4,
+ .cmd_tag = 0x17,
+ .rsp_tag = 0xe1,
+ .success_tag = 0xd6,
+ .se_name = "ele",
+ .pool_name = "sram-pool",
+ .reserved_dma_ranges = true,
+};
+
+static const struct imx_info imx93_info = {
+ .socdev = true,
+ .mu_did = 3,
+ .max_dev_ctx = 4,
+ .cmd_tag = 0x17,
+ .rsp_tag = 0xe1,
+ .success_tag = 0xd6,
+ .se_name = "ele",
+ .pool_name = NULL,
+ .reserved_dma_ranges = true,
+};
+
+static const struct of_device_id se_fw_match[] = {
+ { .compatible = "fsl,imx8ulp-se-fw", .data = (void *)&imx8ulp_info},
+ { .compatible = "fsl,imx93-se-fw", .data = (void *)&imx93_info},
+ {},
+};
+
+/*
+ * Callback called by mailbox FW when data are received
+ */
+static void ele_mu_rx_callback(struct mbox_client *c, void *msg)
+{
+ struct device *dev = c->dev;
+ struct ele_mu_priv *priv = dev_get_drvdata(dev);
+ struct ele_mu_device_ctx *dev_ctx;
+ bool is_response = false;
+ int msg_size;
+ struct mu_hdr header;
+
+ /* The function can be called with NULL msg */
+ if (!msg) {
+ dev_err(dev, "Message is invalid\n");
+ return;
+ }
+
+ header.tag = ((u8 *)msg)[TAG_OFFSET];
+ header.command = ((u8 *)msg)[CMD_OFFSET];
+ header.size = ((u8 *)msg)[SZ_OFFSET];
+ header.ver = ((u8 *)msg)[VER_OFFSET];
+
+ /* Incoming command: wake up the receiver if any. */
+ if (header.tag == priv->cmd_tag) {
+ dev_dbg(dev, "Selecting cmd receiver\n");
+ dev_ctx = priv->cmd_receiver_dev;
+ } else if (header.tag == priv->rsp_tag) {
+ if (priv->waiting_rsp_dev) {
+ dev_dbg(dev, "Selecting rsp waiter\n");
+ dev_ctx = priv->waiting_rsp_dev;
+ is_response = true;
+ } else {
+ /* Reading the EdgeLock Enclave response
+ * to the command sent by other
+ * linux kernel services.
+ */
+ spin_lock(&priv->lock);
+ priv->rx_msg = *(struct ele_api_msg *)msg;
+ complete(&priv->done);
+ spin_unlock(&priv->lock);
+ return;
+ }
+ } else {
+ dev_err(dev, "Failed to select a device for message: %.8x\n",
+ *((u32 *) &header));
+ return;
+ }
+
+ if (!dev_ctx) {
+ dev_err(dev, "No device context selected for message: %.8x\n",
+ *((u32 *)&header));
+ return;
+ }
+ /* Init reception */
+ msg_size = header.size;
+ if (msg_size > MAX_RECV_SIZE) {
+ devctx_err(dev_ctx, "Message is too big (%d > %d)", msg_size,
+ MAX_RECV_SIZE);
+ return;
+ }
+
+ memcpy(dev_ctx->temp_resp, msg, msg_size << 2);
+ dev_ctx->temp_resp_size = msg_size;
+
+ /* Allow user to read */
+ dev_ctx->pending_hdr = dev_ctx->temp_resp[0];
+ wake_up_interruptible(&dev_ctx->wq);
+
+ if (is_response)
+ priv->waiting_rsp_dev = NULL;
+
+}
+
+static phys_addr_t get_phy_buf_mem_pool(struct device *dev,
+ char *mem_pool_name,
+ u32 **buf,
+ uint32_t size)
+{
+ struct device_node *of_node = dev->of_node;
+ struct gen_pool *mem_pool = of_gen_pool_get(of_node,
+ mem_pool_name, 0);
+ if (!mem_pool) {
+ dev_err(dev, "Unable to get sram pool\n");
+ return 0;
+ }
+
+ *buf = (u32 *)gen_pool_alloc(mem_pool, size);
+ if (!buf) {
+ dev_err(dev, "Unable to alloc sram from sram pool\n");
+ return 0;
+ }
+
+ return gen_pool_virt_to_phys(mem_pool, (ulong)*buf);
+}
+
+static void free_phybuf_mem_pool(struct device *dev,
+ char *mem_pool_name,
+ u32 *buf,
+ uint32_t size)
+{
+ struct device_node *of_node = dev->of_node;
+ struct gen_pool *mem_pool = of_gen_pool_get(of_node,
+ mem_pool_name, 0);
+
+ if (!mem_pool)
+ dev_err(dev, "%s failed: Unable to get sram pool.\n", __func__);
+
+ gen_pool_free(mem_pool, (unsigned long)buf, size);
+}
+
+static int imx_soc_device_register(struct device *dev,
+ struct imx_info *info)
+{
+ struct soc_device_attribute *attr;
+ struct soc_device *sdev = NULL;
+ phys_addr_t get_info_addr = 0;
+ u32 *get_info_data = NULL;
+ u8 major_ver, minor_ver;
+ int err;
+
+ if (info->pool_name) {
+ get_info_addr = get_phy_buf_mem_pool(dev,
+ info->pool_name,
+ &get_info_data,
+ DEVICE_GET_INFO_SZ);
+ } else {
+ get_info_data = dmam_alloc_coherent(dev,
+ DEVICE_GET_INFO_SZ,
+ &get_info_addr,
+ GFP_KERNEL);
+ }
+ if (!get_info_addr) {
+ dev_err(dev, "Unable to alloc buffer for device info.\n");
+ return -ENOMEM;
+ }
+
+ attr = kzalloc(sizeof(*attr), GFP_KERNEL);
+ if (!attr)
+ return -ENOMEM;
+
+ err = ele_get_info(dev, get_info_addr, ELE_GET_INFO_READ_SZ);
+ if (err) {
+ attr->revision = kasprintf(GFP_KERNEL, "A0");
+ } else {
+ major_ver = (get_info_data[GET_INFO_SOC_INFO_WORD_OFFSET]
+ & SOC_VER_MASK) >> 24;
+ minor_ver = ((get_info_data[GET_INFO_SOC_INFO_WORD_OFFSET]
+ & SOC_VER_MASK) >> 16) & 0xFF;
+ if (minor_ver)
+ attr->revision = kasprintf(GFP_KERNEL,
+ "%x.%x",
+ major_ver,
+ minor_ver);
+ else
+ attr->revision = kasprintf(GFP_KERNEL,
+ "%x",
+ major_ver);
+
+ switch (get_info_data[GET_INFO_SOC_INFO_WORD_OFFSET]
+ & SOC_ID_MASK) {
+ case SOC_ID_OF_IMX8ULP:
+ attr->soc_id = kasprintf(GFP_KERNEL,
+ "i.MX8ULP");
+ break;
+ case SOC_ID_OF_IMX93:
+ attr->soc_id = kasprintf(GFP_KERNEL,
+ "i.MX93");
+ break;
+ }
+ }
+
+ err = of_property_read_string(of_root, "model",
+ &attr->machine);
+ if (err) {
+ kfree(attr);
+ return -EINVAL;
+ }
+ attr->family = kasprintf(GFP_KERNEL, "Freescale i.MX");
+
+ attr->serial_number
+ = kasprintf(GFP_KERNEL, "%016llX",
+ (u64)get_info_data[GET_INFO_SL_NUM_MSB_WORD_OFF] << 32
+ | get_info_data[GET_INFO_SL_NUM_LSB_WORD_OFF]);
+
+ if (info->pool_name) {
+ free_phybuf_mem_pool(dev, info->pool_name,
+ get_info_data, DEVICE_GET_INFO_SZ);
+ } else {
+ dmam_free_coherent(dev,
+ DEVICE_GET_INFO_SZ,
+ get_info_data,
+ get_info_addr);
+ }
+
+ sdev = soc_device_register(attr);
+ if (IS_ERR(sdev)) {
+ kfree(attr->soc_id);
+ kfree(attr->serial_number);
+ kfree(attr->revision);
+ kfree(attr->family);
+ kfree(attr->machine);
+ kfree(attr);
+ return PTR_ERR(sdev);
+ }
+
+ return 0;
+}
+
+/*
+ * File operations for user-space
+ */
+
+/* Write a message to the MU. */
+static ssize_t ele_mu_fops_write(struct file *fp, const char __user *buf,
+ size_t size, loff_t *ppos)
+{
+ struct ele_mu_device_ctx *dev_ctx
+ = container_of(fp->private_data,
+ struct ele_mu_device_ctx,
+ miscdev);
+ struct ele_mu_priv *ele_mu_priv = dev_ctx->priv;
+ u32 nb_words = 0;
+ struct mu_hdr header;
+ int err;
+
+ devctx_dbg(dev_ctx, "write from buf (%p)%zu, ppos=%lld\n", buf, size,
+ ((ppos) ? *ppos : 0));
+
+ if (down_interruptible(&dev_ctx->fops_lock))
+ return -EBUSY;
+
+ if (dev_ctx->status != MU_OPENED) {
+ err = -EINVAL;
+ goto exit;
+ }
+
+ if (size < ELE_MU_HDR_SZ) {
+ devctx_err(dev_ctx, "User buffer too small(%zu < %d)\n",
+ size, ELE_MU_HDR_SZ);
+ err = -ENOSPC;
+ goto exit;
+ }
+
+ if (size > MAX_MESSAGE_SIZE_BYTES) {
+ devctx_err(dev_ctx, "User buffer too big(%zu > %d)\n", size,
+ MAX_MESSAGE_SIZE_BYTES);
+ err = -ENOSPC;
+ goto exit;
+ }
+
+ /* Copy data to buffer */
+ if (copy_from_user(dev_ctx->temp_cmd, buf, size)) {
+ err = -EFAULT;
+ devctx_err(dev_ctx, "Fail copy message from user\n");
+ goto exit;
+ }
+
+ print_hex_dump_debug("from user ", DUMP_PREFIX_OFFSET, 4, 4,
+ dev_ctx->temp_cmd, size, false);
+
+ header = *((struct mu_hdr *) (&dev_ctx->temp_cmd[0]));
+
+ /* Check the message is valid according to tags */
+ if (header.tag == ele_mu_priv->cmd_tag) {
+ /*
+ * unlocked in ele_mu_fops_read when the
+ * response to this command is read.
+ */
+ mutex_lock(&ele_mu_priv->mu_cmd_lock);
+ ele_mu_priv->waiting_rsp_dev = dev_ctx;
+ } else if (header.tag == ele_mu_priv->rsp_tag) {
+ /* Check the device context can send the command */
+ if (dev_ctx != ele_mu_priv->cmd_receiver_dev) {
+ devctx_err(dev_ctx,
+ "Channel not configured to send resp to FW.");
+ err = -EPERM;
+ goto exit;
+ }
+ } else {
+ devctx_err(dev_ctx, "The message does not have a valid TAG\n");
+ err = -EINVAL;
+ goto exit;
+ }
+
+ /*
+ * Check that the size passed as argument matches the size
+ * carried in the message.
+ */
+ nb_words = header.size;
+ if (nb_words << 2 != size) {
+ devctx_err(dev_ctx, "User buffer too small\n");
+ goto exit;
+ }
+
+ mutex_lock(&ele_mu_priv->mu_lock);
+
+ /* Send message */
+ devctx_dbg(dev_ctx, "sending message\n");
+ err = mbox_send_message(ele_mu_priv->tx_chan, dev_ctx->temp_cmd);
+ if (err < 0) {
+ devctx_err(dev_ctx, "Failed to send message\n");
+ goto unlock;
+ }
+
+ err = nb_words << 2;
+
+unlock:
+ mutex_unlock(&ele_mu_priv->mu_lock);
+
+exit:
+ if (err < 0)
+ mutex_unlock(&ele_mu_priv->mu_cmd_lock);
+ up(&dev_ctx->fops_lock);
+ return err;
+}
+
+/*
+ * Read a message from the MU.
+ * Blocking until a message is available.
+ */
+static ssize_t ele_mu_fops_read(struct file *fp, char __user *buf,
+ size_t size, loff_t *ppos)
+{
+ struct ele_mu_device_ctx *dev_ctx
+ = container_of(fp->private_data,
+ struct ele_mu_device_ctx,
+ miscdev);
+ struct ele_mu_priv *ele_mu_priv = dev_ctx->priv;
+ u32 data_size = 0, size_to_copy = 0;
+ struct ele_buf_desc *b_desc;
+ int err;
+ struct mu_hdr header = {0};
+
+ devctx_dbg(dev_ctx, "read to buf %p(%zu), ppos=%lld\n", buf, size,
+ ((ppos) ? *ppos : 0));
+
+ if (down_interruptible(&dev_ctx->fops_lock))
+ return -EBUSY;
+
+ if (dev_ctx->status != MU_OPENED) {
+ err = -EINVAL;
+ goto exit;
+ }
+
+ /* Wait until the complete message is received on the MU. */
+ if (wait_event_interruptible(dev_ctx->wq, dev_ctx->pending_hdr != 0)) {
+ devctx_err(dev_ctx, "Err[0x%x]:Interrupted by signal.\n", err);
+ err = -EINTR;
+ goto exit;
+ }
+
+ devctx_dbg(dev_ctx, "%s %s\n", __func__,
+ "message received, start transmit to user");
+
+ /* Check that the size passed as argument is larger than
+ * the one carried in the message.
+ */
+ data_size = dev_ctx->temp_resp_size << 2;
+ size_to_copy = data_size;
+ if (size_to_copy > size) {
+ devctx_dbg(dev_ctx, "User buffer too small (%zu < %d)\n",
+ size, size_to_copy);
+ size_to_copy = size;
+ }
+
+ /* We may need to copy the output data to user before
+ * delivering the completion message.
+ */
+ while (!list_empty(&dev_ctx->pending_out)) {
+ b_desc = list_first_entry_or_null(&dev_ctx->pending_out,
+ struct ele_buf_desc,
+ link);
+ if (!b_desc)
+ continue;
+
+ if (b_desc->usr_buf_ptr && b_desc->shared_buf_ptr) {
+
+ devctx_dbg(dev_ctx, "Copy output data to user\n");
+ if (copy_to_user(b_desc->usr_buf_ptr,
+ b_desc->shared_buf_ptr,
+ b_desc->size)) {
+ devctx_err(dev_ctx,
+ "Failure copying output data to user.");
+ err = -EFAULT;
+ goto exit;
+ }
+ }
+
+ if (b_desc->shared_buf_ptr)
+ memset(b_desc->shared_buf_ptr, 0, b_desc->size);
+
+ __list_del_entry(&b_desc->link);
+ devm_kfree(dev_ctx->dev, b_desc);
+ }
+
+ header = *((struct mu_hdr *) (&dev_ctx->temp_resp[0]));
+
+ /* Copy data from the buffer */
+ print_hex_dump_debug("to user ", DUMP_PREFIX_OFFSET, 4, 4,
+ dev_ctx->temp_resp, size_to_copy, false);
+ if (copy_to_user(buf, dev_ctx->temp_resp, size_to_copy)) {
+ devctx_err(dev_ctx, "Failed to copy to user\n");
+ err = -EFAULT;
+ goto exit;
+ }
+
+ err = size_to_copy;
+
+ /* free memory allocated on the shared buffers. */
+ dev_ctx->secure_mem.pos = 0;
+ dev_ctx->non_secure_mem.pos = 0;
+
+ dev_ctx->pending_hdr = 0;
+
+exit:
+ /*
+ * Clean the used Shared Memory space,
+ * whether its Input Data copied from user buffers, or
+ * Data received from FW.
+ */
+ while (!list_empty(&dev_ctx->pending_in) ||
+ !list_empty(&dev_ctx->pending_out)) {
+ if (!list_empty(&dev_ctx->pending_in))
+ b_desc = list_first_entry_or_null(&dev_ctx->pending_in,
+ struct ele_buf_desc,
+ link);
+ else
+ b_desc = list_first_entry_or_null(&dev_ctx->pending_out,
+ struct ele_buf_desc,
+ link);
+
+ if (!b_desc)
+ continue;
+
+ if (b_desc->shared_buf_ptr)
+ memset(b_desc->shared_buf_ptr, 0, b_desc->size);
+
+ __list_del_entry(&b_desc->link);
+ devm_kfree(dev_ctx->dev, b_desc);
+ }
+ if (header.tag == ele_mu_priv->rsp_tag)
+ mutex_unlock(&ele_mu_priv->mu_cmd_lock);
+
+ up(&dev_ctx->fops_lock);
+ return err;
+}
+
+/* Give access to EdgeLock Enclave, to the memory we want to share */
+static int ele_mu_setup_ele_mem_access(struct ele_mu_device_ctx *dev_ctx,
+ u64 addr, u32 len)
+{
+ /* Assuming EdgeLock Enclave has access to all the memory regions */
+ int ret = 0;
+
+ if (ret) {
+ devctx_err(dev_ctx, "Fail find memreg\n");
+ goto exit;
+ }
+
+ if (ret) {
+ devctx_err(dev_ctx, "Fail set permission for resource\n");
+ goto exit;
+ }
+
+exit:
+ return ret;
+}
+
+static int ele_mu_ioctl_get_mu_info(struct ele_mu_device_ctx *dev_ctx,
+ unsigned long arg)
+{
+ struct ele_mu_priv *priv = dev_get_drvdata(dev_ctx->dev);
+ struct ele_mu_ioctl_get_mu_info info;
+ int err = -EINVAL;
+
+ info.ele_mu_id = priv->ele_mu_id;
+ info.interrupt_idx = 0;
+ info.tz = 0;
+ info.did = priv->ele_mu_did;
+
+ devctx_dbg(dev_ctx,
+ "info [mu_idx: %d, irq_idx: %d, tz: 0x%x, did: 0x%x]\n",
+ info.ele_mu_id, info.interrupt_idx, info.tz, info.did);
+
+ if (copy_to_user((u8 *)arg, &info, sizeof(info))) {
+ devctx_err(dev_ctx, "Failed to copy mu info to user\n");
+ err = -EFAULT;
+ goto exit;
+ }
+
+exit:
+ return err;
+}
+
+/*
+ * Copy a buffer of data to/from the user and return the address to use in
+ * messages
+ */
+static int ele_mu_ioctl_setup_iobuf_handler(struct ele_mu_device_ctx *dev_ctx,
+ unsigned long arg)
+{
+ struct ele_buf_desc *b_desc;
+ struct ele_mu_ioctl_setup_iobuf io = {0};
+ struct ele_shared_mem *shared_mem;
+ int err = 0;
+ u32 pos;
+
+ if (copy_from_user(&io, (u8 *)arg, sizeof(io))) {
+ devctx_err(dev_ctx, "Failed copy iobuf config from user\n");
+ err = -EFAULT;
+ goto exit;
+ }
+
+ devctx_dbg(dev_ctx, "io [buf: %p(%d) flag: %x]\n",
+ io.user_buf, io.length, io.flags);
+
+ if (io.length == 0 || !io.user_buf) {
+ /*
+ * Accept NULL pointers since some buffers are optional
+ * in FW commands. In this case we should return 0 as
+ * pointer to be embedded into the message.
+ * Skip all data copy part of code below.
+ */
+ io.ele_addr = 0;
+ goto copy;
+ }
+
+ /* Select the shared memory to be used for this buffer. */
+ if (io.flags & ELE_MU_IO_FLAGS_USE_SEC_MEM) {
+ /* App requires to use secure memory for this buffer.*/
+ devctx_err(dev_ctx, "Failed allocate SEC MEM memory\n");
+ err = -EFAULT;
+ goto exit;
+ } else {
+ /* No specific requirement for this buffer. */
+ shared_mem = &dev_ctx->non_secure_mem;
+ }
+
+ /* Check there is enough space in the shared memory. */
+ if (shared_mem->size < shared_mem->pos
+ || io.length >= shared_mem->size - shared_mem->pos) {
+ devctx_err(dev_ctx, "Not enough space in shared memory\n");
+ err = -ENOMEM;
+ goto exit;
+ }
+
+ /* Allocate space in shared memory. 8 bytes aligned. */
+ pos = shared_mem->pos;
+ shared_mem->pos += round_up(io.length, 8u);
+ io.ele_addr = (u64)shared_mem->dma_addr + pos;
+
+ if ((io.flags & ELE_MU_IO_FLAGS_USE_SEC_MEM) &&
+ !(io.flags & ELE_MU_IO_FLAGS_USE_SHORT_ADDR)) {
+ /*Add base address to get full address.*/
+ devctx_err(dev_ctx, "Failed allocate SEC MEM memory\n");
+ err = -EFAULT;
+ goto exit;
+ }
+
+ memset(shared_mem->ptr + pos, 0, io.length);
+ if ((io.flags & ELE_MU_IO_FLAGS_IS_INPUT) ||
+ (io.flags & ELE_MU_IO_FLAGS_IS_IN_OUT)) {
+ /*
+ * buffer is input:
+ * copy data from user space to this allocated buffer.
+ */
+ if (copy_from_user(shared_mem->ptr + pos, io.user_buf,
+ io.length)) {
+ devctx_err(dev_ctx,
+ "Failed copy data to shared memory\n");
+ err = -EFAULT;
+ goto exit;
+ }
+ }
+
+ b_desc = devm_kmalloc(dev_ctx->dev, sizeof(*b_desc), GFP_KERNEL);
+ if (!b_desc) {
+ err = -ENOMEM;
+ devctx_err(dev_ctx,
+ "Failed allocating mem for pending buffer\n"
+ );
+ goto exit;
+ }
+
+ b_desc->shared_buf_ptr = shared_mem->ptr + pos;
+ b_desc->usr_buf_ptr = io.user_buf;
+ b_desc->size = io.length;
+
+ if (io.flags & ELE_MU_IO_FLAGS_IS_INPUT) {
+ /*
+ * buffer is input:
+ * add an entry in the "pending input buffers" list so
+ * that copied data can be cleaned from shared memory
+ * later.
+ */
+ list_add_tail(&b_desc->link, &dev_ctx->pending_in);
+ } else {
+ /*
+ * buffer is output:
+ * add an entry in the "pending out buffers" list so data
+ * can be copied to user space when receiving ELE
+ * response.
+ */
+ list_add_tail(&b_desc->link, &dev_ctx->pending_out);
+ }
+
+copy:
+ /* Provide the EdgeLock Enclave address to user space only if success.*/
+ if (copy_to_user((u8 *)arg, &io, sizeof(io))) {
+ devctx_err(dev_ctx, "Failed to copy iobuff setup to user\n");
+ err = -EFAULT;
+ goto exit;
+ }
+exit:
+ return err;
+}
+
+/* Open a char device. */
+static int ele_mu_fops_open(struct inode *nd, struct file *fp)
+{
+ struct ele_mu_device_ctx *dev_ctx
+ = container_of(fp->private_data,
+ struct ele_mu_device_ctx,
+ miscdev);
+ int err;
+
+ /* Avoid race if opened at the same time */
+ if (down_trylock(&dev_ctx->fops_lock))
+ return -EBUSY;
+
+ /* Authorize only 1 instance. */
+ if (dev_ctx->status != MU_FREE) {
+ err = -EBUSY;
+ goto exit;
+ }
+
+ /*
+ * Allocate some memory for data exchanges with S40x.
+ * This will be used for data not requiring secure memory.
+ */
+ dev_ctx->non_secure_mem.ptr = dmam_alloc_coherent(dev_ctx->dev,
+ MAX_DATA_SIZE_PER_USER,
+ &dev_ctx->non_secure_mem.dma_addr,
+ GFP_KERNEL);
+ if (!dev_ctx->non_secure_mem.ptr) {
+ err = -ENOMEM;
+ devctx_err(dev_ctx, "Failed to map shared memory with S40x\n");
+ goto exit;
+ }
+
+ err = ele_mu_setup_ele_mem_access(dev_ctx,
+ dev_ctx->non_secure_mem.dma_addr,
+ MAX_DATA_SIZE_PER_USER);
+ if (err) {
+ err = -EPERM;
+ devctx_err(dev_ctx,
+ "Failed to share access to shared memory\n");
+ goto free_coherent;
+ }
+
+ dev_ctx->non_secure_mem.size = MAX_DATA_SIZE_PER_USER;
+ dev_ctx->non_secure_mem.pos = 0;
+ dev_ctx->status = MU_OPENED;
+
+ dev_ctx->pending_hdr = 0;
+
+ goto exit;
+
+free_coherent:
+ dmam_free_coherent(dev_ctx->priv->dev, MAX_DATA_SIZE_PER_USER,
+ dev_ctx->non_secure_mem.ptr,
+ dev_ctx->non_secure_mem.dma_addr);
+
+exit:
+ up(&dev_ctx->fops_lock);
+ return err;
+}
+
+/* Close a char device. */
+static int ele_mu_fops_close(struct inode *nd, struct file *fp)
+{
+ struct ele_mu_device_ctx *dev_ctx = container_of(fp->private_data,
+ struct ele_mu_device_ctx, miscdev);
+ struct ele_mu_priv *priv = dev_ctx->priv;
+ struct ele_buf_desc *b_desc;
+
+ /* Avoid race if closed at the same time */
+ if (down_trylock(&dev_ctx->fops_lock))
+ return -EBUSY;
+
+ /* The device context has not been opened */
+ if (dev_ctx->status != MU_OPENED)
+ goto exit;
+
+ /* check if this device was registered as command receiver. */
+ if (priv->cmd_receiver_dev == dev_ctx)
+ priv->cmd_receiver_dev = NULL;
+
+ /* check if this device was registered as waiting response. */
+ if (priv->waiting_rsp_dev == dev_ctx) {
+ priv->waiting_rsp_dev = NULL;
+ mutex_unlock(&priv->mu_cmd_lock);
+ }
+
+ /* Unmap secure memory shared buffer. */
+ if (dev_ctx->secure_mem.ptr)
+ devm_iounmap(dev_ctx->dev, dev_ctx->secure_mem.ptr);
+
+ dev_ctx->secure_mem.ptr = NULL;
+ dev_ctx->secure_mem.dma_addr = 0;
+ dev_ctx->secure_mem.size = 0;
+ dev_ctx->secure_mem.pos = 0;
+
+ /* Free non-secure shared buffer. */
+ dmam_free_coherent(dev_ctx->priv->dev, MAX_DATA_SIZE_PER_USER,
+ dev_ctx->non_secure_mem.ptr,
+ dev_ctx->non_secure_mem.dma_addr);
+
+ dev_ctx->non_secure_mem.ptr = NULL;
+ dev_ctx->non_secure_mem.dma_addr = 0;
+ dev_ctx->non_secure_mem.size = 0;
+ dev_ctx->non_secure_mem.pos = 0;
+
+ while (!list_empty(&dev_ctx->pending_in) ||
+ !list_empty(&dev_ctx->pending_out)) {
+ if (!list_empty(&dev_ctx->pending_in))
+ b_desc = list_first_entry_or_null(&dev_ctx->pending_in,
+ struct ele_buf_desc,
+ link);
+ else
+ b_desc = list_first_entry_or_null(&dev_ctx->pending_out,
+ struct ele_buf_desc,
+ link);
+
+ if (!b_desc)
+ continue;
+
+ if (b_desc->shared_buf_ptr)
+ memset(b_desc->shared_buf_ptr, 0, b_desc->size);
+
+ __list_del_entry(&b_desc->link);
+ devm_kfree(dev_ctx->dev, b_desc);
+ }
+
+ dev_ctx->status = MU_FREE;
+
+exit:
+ up(&dev_ctx->fops_lock);
+ return 0;
+}
+
+/* IOCTL entry point of a char device */
+static long ele_mu_ioctl(struct file *fp, unsigned int cmd, unsigned long arg)
+{
+ struct ele_mu_device_ctx *dev_ctx
+ = container_of(fp->private_data,
+ struct ele_mu_device_ctx,
+ miscdev);
+ struct ele_mu_priv *ele_mu_priv = dev_ctx->priv;
+ int err = -EINVAL;
+
+ /* Prevent race during change of device context */
+ if (down_interruptible(&dev_ctx->fops_lock))
+ return -EBUSY;
+
+ switch (cmd) {
+ case ELE_MU_IOCTL_ENABLE_CMD_RCV:
+ if (!ele_mu_priv->cmd_receiver_dev) {
+ ele_mu_priv->cmd_receiver_dev = dev_ctx;
+ err = 0;
+ };
+ break;
+ case ELE_MU_IOCTL_GET_MU_INFO:
+ err = ele_mu_ioctl_get_mu_info(dev_ctx, arg);
+ break;
+ case ELE_MU_IOCTL_SHARED_BUF_CFG:
+ devctx_err(dev_ctx,
+ "ELE_MU_IOCTL_SHARED_BUF_CFG not supported [0x%x].\n",
+ err);
+ break;
+ case ELE_MU_IOCTL_SETUP_IOBUF:
+ err = ele_mu_ioctl_setup_iobuf_handler(dev_ctx, arg);
+ break;
+ case ELE_MU_IOCTL_SIGNED_MESSAGE:
+ devctx_err(dev_ctx,
+ "ELE_MU_IOCTL_SIGNED_MESSAGE not supported [0x%x].\n",
+ err);
+ break;
+ default:
+ err = -EINVAL;
+ devctx_dbg(dev_ctx, "IOCTL %.8x not supported\n", cmd);
+ }
+
+ up(&dev_ctx->fops_lock);
+ return (long)err;
+}
+
+/* Char driver setup */
+static const struct file_operations ele_mu_fops = {
+ .open = ele_mu_fops_open,
+ .owner = THIS_MODULE,
+ .release = ele_mu_fops_close,
+ .unlocked_ioctl = ele_mu_ioctl,
+ .read = ele_mu_fops_read,
+ .write = ele_mu_fops_write,
+};
+
+/* interface for managed res to free a mailbox channel */
+static void if_mbox_free_channel(void *mbox_chan)
+{
+ mbox_free_channel(mbox_chan);
+}
+
+/* interface for managed res to unregister a char device */
+static void if_misc_deregister(void *miscdevice)
+{
+ misc_deregister(miscdevice);
+}
+
+static int ele_mu_request_channel(struct device *dev,
+ struct mbox_chan **chan,
+ struct mbox_client *cl,
+ const char *name)
+{
+ struct mbox_chan *t_chan;
+ int ret = 0;
+
+ t_chan = mbox_request_channel_byname(cl, name);
+ if (IS_ERR(t_chan)) {
+ ret = PTR_ERR(t_chan);
+ if (ret != -EPROBE_DEFER)
+ dev_err(dev,
+ "Failed to request chan %s ret %d\n", name,
+ ret);
+ goto exit;
+ }
+
+ ret = devm_add_action(dev, if_mbox_free_channel, t_chan);
+ if (ret) {
+ dev_err(dev, "failed to add devm removal of mbox %s\n", name);
+ goto exit;
+ }
+
+ *chan = t_chan;
+
+exit:
+ return ret;
+}
+
+static int se_probe_cleanup(struct platform_device *pdev)
+{
+ int ret;
+ int i;
+ struct device *dev = &pdev->dev;
+ struct ele_mu_priv *priv = dev_get_drvdata(dev);
+
+ if (!priv) {
+ ret = -EINVAL;
+ dev_err(dev, "Invalid ELE-MU Priv data");
+ return ret;
+ }
+
+ if (priv->tx_chan)
+ mbox_free_channel(priv->tx_chan);
+ if (priv->rx_chan)
+ mbox_free_channel(priv->rx_chan);
+
+ if (priv->flags & RESERVED_DMA_POOL) {
+ of_reserved_mem_device_release(dev);
+ priv->flags &= (~RESERVED_DMA_POOL);
+ }
+
+ if (priv->ctxs) {
+ for (i = 0; i < priv->max_dev_ctx; i++) {
+ if (priv->ctxs[i])
+ devm_kfree(dev, priv->ctxs[i]);
+ }
+ devm_kfree(dev, priv->ctxs);
+ }
+
+ list_del(&priv->priv_data);
+
+ devm_kfree(dev, priv);
+ return ret;
+}
+
+static int se_fw_probe(struct platform_device *pdev)
+{
+ struct ele_mu_device_ctx *dev_ctx;
+ struct device *dev = &pdev->dev;
+ struct ele_mu_priv *priv;
+ const struct of_device_id *of_id = of_match_device(se_fw_match, dev);
+ struct imx_info *info = NULL;
+ char *devname;
+ int ret;
+ int i;
+ struct device_node *np;
+
+ priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+ if (!priv) {
+ ret = -ENOMEM;
+ dev_err(dev, "Fail allocate mem for private data\n");
+ return ret;
+ }
+ memset(priv, 0x0, sizeof(*priv));
+ priv->dev = dev;
+ dev_set_drvdata(dev, priv);
+
+ /*
+ * Get the address of MU.
+ */
+ np = pdev->dev.of_node;
+ if (!np) {
+ dev_err(dev, "Cannot find MU User entry in device tree\n");
+ ret = -EOPNOTSUPP;
+ goto exit;
+ }
+
+ /* Initialize the mutex. */
+ mutex_init(&priv->mu_cmd_lock);
+ mutex_init(&priv->mu_lock);
+
+ priv->cmd_receiver_dev = NULL;
+ priv->waiting_rsp_dev = NULL;
+
+ /* Mailbox client configuration */
+ priv->ele_mb_cl.dev = dev;
+ priv->ele_mb_cl.tx_block = false;
+ priv->ele_mb_cl.knows_txdone = true;
+ priv->ele_mb_cl.rx_callback = ele_mu_rx_callback;
+
+ ret = ele_mu_request_channel(dev, &priv->tx_chan,
+ &priv->ele_mb_cl, "tx");
+ if (ret) {
+ if (ret != -EPROBE_DEFER)
+ dev_err(dev, "Failed to request tx channel\n");
+
+ goto exit;
+ }
+
+ ret = ele_mu_request_channel(dev, &priv->rx_chan,
+ &priv->ele_mb_cl, "rx");
+ if (ret) {
+ if (ret != -EPROBE_DEFER)
+ dev_err(dev, "Failed to request rx channel\n");
+
+ goto exit;
+ }
+
+ ret = of_property_read_u32(np, "fsl,mu-id", &priv->ele_mu_id);
+ if (ret) {
+ ret = -EINVAL;
+ dev_err(dev, "Not able to read mu-id.\n");
+ goto exit;
+ }
+
+ info = (struct imx_info *)of_id->data;
+ priv->ele_mu_did = info->mu_did;
+ priv->max_dev_ctx = info->max_dev_ctx;
+ priv->cmd_tag = info->cmd_tag;
+ priv->rsp_tag = info->rsp_tag;
+ priv->success_tag = info->success_tag;
+
+ priv->ctxs = devm_kzalloc(dev, sizeof(dev_ctx) * priv->max_dev_ctx,
+ GFP_KERNEL);
+
+ if (!priv->ctxs) {
+ ret = -ENOMEM;
+ dev_err(dev, "Fail allocate mem for private dev-ctxs.\n");
+ goto exit;
+ }
+
+ /* Create users */
+ for (i = 0; i < priv->max_dev_ctx; i++) {
+ dev_ctx = devm_kzalloc(dev, sizeof(*dev_ctx), GFP_KERNEL);
+ if (!dev_ctx) {
+ ret = -ENOMEM;
+ dev_err(dev,
+ "Fail to allocate memory for device context\n");
+ goto exit;
+ }
+
+ dev_ctx->dev = dev;
+ dev_ctx->status = MU_FREE;
+ dev_ctx->priv = priv;
+
+ priv->ctxs[i] = dev_ctx;
+
+ /* Default value invalid for an header. */
+ init_waitqueue_head(&dev_ctx->wq);
+
+ INIT_LIST_HEAD(&dev_ctx->pending_out);
+ INIT_LIST_HEAD(&dev_ctx->pending_in);
+ sema_init(&dev_ctx->fops_lock, 1);
+
+ devname = devm_kasprintf(dev, GFP_KERNEL, "%s_mu%d_ch%d",
+ info->se_name,
+ priv->ele_mu_id, i);
+ if (!devname) {
+ ret = -ENOMEM;
+ dev_err(dev,
+ "Fail to allocate memory for misc dev name\n");
+ goto exit;
+ }
+
+ dev_ctx->miscdev.name = devname;
+ dev_ctx->miscdev.minor = MISC_DYNAMIC_MINOR;
+ dev_ctx->miscdev.fops = &ele_mu_fops;
+ dev_ctx->miscdev.parent = dev;
+ ret = misc_register(&dev_ctx->miscdev);
+ if (ret) {
+ dev_err(dev, "failed to register misc device %d\n",
+ ret);
+ goto exit;
+ }
+
+ ret = devm_add_action(dev, if_misc_deregister,
+ &dev_ctx->miscdev);
+ if (ret) {
+ dev_err(dev,
+ "failed[%d] to add action to the misc-dev\n",
+ ret);
+ goto exit;
+ }
+ }
+
+ init_completion(&priv->done);
+ spin_lock_init(&priv->lock);
+
+ list_add_tail(&priv->priv_data, &priv_data_list);
+ dev_set_drvdata(dev, priv);
+
+ if (info->reserved_dma_ranges) {
+ ret = of_reserved_mem_device_init(dev);
+ if (ret) {
+ dev_err(dev,
+ "failed to init reserved memory region %d\n",
+ ret);
+ priv->flags &= (~RESERVED_DMA_POOL);
+ goto exit;
+ }
+ priv->flags |= RESERVED_DMA_POOL;
+ }
+
+ if (info->socdev) {
+ ret = imx_soc_device_register(dev, info);
+ if (ret) {
+ dev_err(dev,
+ "failed[%d] to register SoC device\n", ret);
+ goto exit;
+ }
+ }
+
+ pr_info("i.MX secure-enclave: %s's mu#%d interface to firmware, configured.\n",
+ info->se_name,
+ priv->ele_mu_id);
+ return devm_of_platform_populate(dev);
+
+exit:
+ /* if execution control reaches here, ele-mu probe fail.
+ * hence doing the cleanup
+ */
+ return se_probe_cleanup(pdev);
+}
+
+struct device *get_se_dev(uint32_t mu_id)
+{
+ struct ele_mu_priv *priv;
+
+ list_for_each_entry(priv, &priv_data_list, priv_data) {
+ if (priv->ele_mu_id == mu_id)
+ return priv->dev;
+ }
+
+ return NULL;
+}
+EXPORT_SYMBOL(get_se_dev);
+
+static int se_fw_remove(struct platform_device *pdev)
+{
+ se_probe_cleanup(pdev);
+
+ return 0;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int se_fw_suspend(struct device *dev)
+{
+ return 0;
+}
+
+static int se_fw_resume(struct device *dev)
+{
+ struct ele_mu_priv *priv = dev_get_drvdata(dev);
+ int i;
+
+ for (i = 0; i < priv->max_dev_ctx; i++)
+ wake_up_interruptible(&priv->ctxs[i]->wq);
+
+ return 0;
+}
+#endif
+
+static const struct dev_pm_ops se_fw_pm = {
+ SET_SYSTEM_SLEEP_PM_OPS(se_fw_suspend, se_fw_resume)
+};
+
+static struct platform_driver se_fw_driver = {
+ .driver = {
+ .name = "fsl-se-fw",
+ .of_match_table = se_fw_match,
+ .pm = &se_fw_pm,
+ },
+ .probe = se_fw_probe,
+ .remove = se_fw_remove,
+};
+MODULE_DEVICE_TABLE(of, se_fw_match);
+
+module_platform_driver(se_fw_driver);
+
+MODULE_AUTHOR("Pankaj Gupta <pankaj.gupta@nxp.com>");
+MODULE_DESCRIPTION("iMX Secure Enclave FW Driver.");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/firmware/imx/se_fw.h b/drivers/firmware/imx/se_fw.h
new file mode 100644
index 000000000000..b3502affbc85
--- /dev/null
+++ b/drivers/firmware/imx/se_fw.h
@@ -0,0 +1,168 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright 2021-2023 NXP
+ */
+
+#ifndef SE_MU_H
+#define SE_MU_H
+
+#include <linux/miscdevice.h>
+#include <linux/semaphore.h>
+#include <linux/mailbox_client.h>
+
+/* macro to log operation of a misc device */
+#define miscdev_dbg(p_miscdev, fmt, va_args...) \
+ ({ \
+ struct miscdevice *_p_miscdev = p_miscdev; \
+ dev_dbg((_p_miscdev)->parent, "%s: " fmt, (_p_miscdev)->name, \
+ ##va_args); \
+ })
+
+#define miscdev_info(p_miscdev, fmt, va_args...) \
+ ({ \
+ struct miscdevice *_p_miscdev = p_miscdev; \
+ dev_info((_p_miscdev)->parent, "%s: " fmt, (_p_miscdev)->name, \
+ ##va_args); \
+ })
+
+#define miscdev_err(p_miscdev, fmt, va_args...) \
+ ({ \
+ struct miscdevice *_p_miscdev = p_miscdev; \
+ dev_err((_p_miscdev)->parent, "%s: " fmt, (_p_miscdev)->name, \
+ ##va_args); \
+ })
+/* macro to log operation of a device context */
+#define devctx_dbg(p_devctx, fmt, va_args...) \
+ miscdev_dbg(&((p_devctx)->miscdev), fmt, ##va_args)
+#define devctx_info(p_devctx, fmt, va_args...) \
+ miscdev_info(&((p_devctx)->miscdev), fmt, ##va_args)
+#define devctx_err(p_devctx, fmt, va_args...) \
+ miscdev_err((&(p_devctx)->miscdev), fmt, ##va_args)
+
+#define MAX_MESSAGE_SIZE 31
+#define MAX_RECV_SIZE MAX_MESSAGE_SIZE
+#define MAX_RECV_SIZE_BYTES (MAX_RECV_SIZE << 2)
+#define MAX_MESSAGE_SIZE_BYTES (MAX_MESSAGE_SIZE << 2)
+
+#define ELE_MSG_DATA_NUM 10
+
+#define MSG_TAG(x) (((x) & 0xff000000) >> 24)
+#define MSG_COMMAND(x) (((x) & 0x00ff0000) >> 16)
+#define MSG_SIZE(x) (((x) & 0x0000ff00) >> 8)
+#define MSG_VER(x) ((x) & 0x000000ff)
+#define RES_STATUS(x) ((x) & 0x000000ff)
+#define MAX_DATA_SIZE_PER_USER (65 * 1024)
+#define S4_DEFAULT_MUAP_INDEX (2)
+#define S4_MUAP_DEFAULT_MAX_USERS (4)
+
+#define DEFAULT_MESSAGING_TAG_COMMAND (0x17u)
+#define DEFAULT_MESSAGING_TAG_RESPONSE (0xe1u)
+
+#define ELE_MU_IO_FLAGS_USE_SEC_MEM (0x02u)
+#define ELE_MU_IO_FLAGS_USE_SHORT_ADDR (0x04u)
+
+struct ele_imem_buf {
+ u8 *buf;
+ phys_addr_t phyaddr;
+ u32 size;
+};
+
+struct ele_buf_desc {
+ u8 *shared_buf_ptr;
+ u8 *usr_buf_ptr;
+ u32 size;
+ struct list_head link;
+};
+
+/* Status of a char device */
+enum mu_device_status_t {
+ MU_FREE,
+ MU_OPENED
+};
+
+struct ele_shared_mem {
+ dma_addr_t dma_addr;
+ u32 size;
+ u32 pos;
+ u8 *ptr;
+};
+
+/* Private struct for each char device instance. */
+struct ele_mu_device_ctx {
+ struct device *dev;
+ struct ele_mu_priv *priv;
+ struct miscdevice miscdev;
+
+ enum mu_device_status_t status;
+ wait_queue_head_t wq;
+ struct semaphore fops_lock;
+
+ u32 pending_hdr;
+ struct list_head pending_in;
+ struct list_head pending_out;
+
+ struct ele_shared_mem secure_mem;
+ struct ele_shared_mem non_secure_mem;
+
+ u32 temp_cmd[MAX_MESSAGE_SIZE];
+ u32 temp_resp[MAX_RECV_SIZE];
+ u32 temp_resp_size;
+ struct notifier_block ele_notify;
+};
+
+/* Header of the messages exchange with the EdgeLock Enclave */
+struct mu_hdr {
+ u8 ver;
+ u8 size;
+ u8 command;
+ u8 tag;
+} __packed;
+
+#define ELE_MU_HDR_SZ 4
+#define TAG_OFFSET (ELE_MU_HDR_SZ - 1)
+#define CMD_OFFSET (ELE_MU_HDR_SZ - 2)
+#define SZ_OFFSET (ELE_MU_HDR_SZ - 3)
+#define VER_OFFSET (ELE_MU_HDR_SZ - 4)
+
+struct ele_api_msg {
+ u32 header; /* u8 Tag; u8 Command; u8 Size; u8 Ver; */
+ u32 data[ELE_MSG_DATA_NUM];
+};
+
+struct ele_mu_priv {
+ struct list_head priv_data;
+ struct ele_mu_device_ctx *cmd_receiver_dev;
+ struct ele_mu_device_ctx *waiting_rsp_dev;
+ /*
+ * prevent parallel access to the MU registers
+ * e.g. a user trying to send a command while the other one is
+ * sending a response.
+ */
+ struct mutex mu_lock;
+ /*
+ * prevent a command to be sent on the MU while another one is still
+ * processing. (response to a command is allowed)
+ */
+ struct mutex mu_cmd_lock;
+ struct device *dev;
+ u8 ele_mu_did;
+ u32 ele_mu_id;
+ u8 cmd_tag;
+ u8 rsp_tag;
+ u8 success_tag;
+
+ struct mbox_client ele_mb_cl;
+ struct mbox_chan *tx_chan, *rx_chan;
+ struct ele_api_msg tx_msg, rx_msg;
+ struct completion done;
+ spinlock_t lock;
+ /* Flag to retain the state of initialization done at
+ * the time of ele-mu probe.
+ */
+ uint32_t flags;
+ u8 max_dev_ctx;
+ struct ele_mu_device_ctx **ctxs;
+ struct ele_imem_buf imem;
+};
+
+#endif
diff --git a/include/linux/firmware/imx/ele_base_msg.h b/include/linux/firmware/imx/ele_base_msg.h
new file mode 100644
index 000000000000..9c05936ba813
--- /dev/null
+++ b/include/linux/firmware/imx/ele_base_msg.h
@@ -0,0 +1,37 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright 2021-2023 NXP
+ *
+ * Header file for the ELE Base API(s).
+ */
+
+#ifndef ELE_BASE_MSG_H
+#define ELE_BASE_MSG_H
+
+#include <linux/types.h>
+
+#define WORD_SZ 4
+#define MESSAGING_VERSION_7 0x7
+#define ELE_NONE_VAL 0x0
+
+#define ELE_GET_INFO_BUFF_SZ 0x100
+#define ELE_GET_INFO_READ_SZ 0xA0
+#define DEVICE_GET_INFO_SZ 0x100
+
+#define GET_INFO_SOC_INFO_WORD_OFFSET 1
+#define GET_INFO_UUID_WORD_OFFSET 3
+#define GET_INFO_SL_NUM_MSB_WORD_OFF \
+ (GET_INFO_UUID_WORD_OFFSET + 3)
+#define GET_INFO_SL_NUM_LSB_WORD_OFF \
+ (GET_INFO_UUID_WORD_OFFSET + 0)
+
+#define ELE_GET_INFO_REQ 0xDA
+#define ELE_GET_INFO_REQ_MSG_SZ 0x02
+
+#define ELE_BASE_API_VERSION 0x6
+#define ELE_SUCCESS_IND 0xD6
+#define ELE_FAILURE_IND 0x29
+
+int ele_get_info(struct device *dev, phys_addr_t addr, u32 data_size);
+
+#endif
diff --git a/include/linux/firmware/imx/ele_mu_ioctl.h b/include/linux/firmware/imx/ele_mu_ioctl.h
new file mode 100644
index 000000000000..b0f00acddecc
--- /dev/null
+++ b/include/linux/firmware/imx/ele_mu_ioctl.h
@@ -0,0 +1,52 @@
+/* SPDX-License-Identifier: (GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause*/
+/*
+ * Copyright 2019-2023 NXP
+ */
+
+#ifndef ELE_MU_IOCTL_H
+#define ELE_MU_IOCTL_H
+
+/* IOCTL definitions. */
+
+struct ele_mu_ioctl_setup_iobuf {
+ u8 *user_buf;
+ u32 length;
+ u32 flags;
+ u64 ele_addr;
+};
+
+struct ele_mu_ioctl_shared_mem_cfg {
+ u32 base_offset;
+ u32 size;
+};
+
+struct ele_mu_ioctl_get_mu_info {
+ u8 ele_mu_id;
+ u8 interrupt_idx;
+ u8 tz;
+ u8 did;
+};
+
+struct ele_mu_ioctl_signed_message {
+ u8 *message;
+ u32 msg_size;
+ u32 error_code;
+};
+
+#define ELE_MU_IO_FLAGS_IS_OUTPUT (0x00u)
+#define ELE_MU_IO_FLAGS_IS_INPUT (0x01u)
+#define ELE_MU_IO_FLAGS_USE_SEC_MEM (0x02u)
+#define ELE_MU_IO_FLAGS_USE_SHORT_ADDR (0x04u)
+#define ELE_MU_IO_FLAGS_IS_IN_OUT (0x08u)
+
+#define ELE_MU_IOCTL 0x0A /* like MISC_MAJOR. */
+#define ELE_MU_IOCTL_ENABLE_CMD_RCV _IO(ELE_MU_IOCTL, 0x01)
+#define ELE_MU_IOCTL_SHARED_BUF_CFG _IOW(ELE_MU_IOCTL, 0x02, \
+ struct ele_mu_ioctl_shared_mem_cfg)
+#define ELE_MU_IOCTL_SETUP_IOBUF _IOWR(ELE_MU_IOCTL, 0x03, \
+ struct ele_mu_ioctl_setup_iobuf)
+#define ELE_MU_IOCTL_GET_MU_INFO _IOR(ELE_MU_IOCTL, 0x04, \
+ struct ele_mu_ioctl_get_mu_info)
+#define ELE_MU_IOCTL_SIGNED_MESSAGE _IOWR(ELE_MU_IOCTL, 0x05, \
+ struct ele_mu_ioctl_signed_message)
+#endif
--
2.34.1
^ permalink raw reply related [flat|nested] 28+ messages in thread
* [PATCH v5 07/11] firmware: imx: init-fw api exchange on imx93
2023-08-23 7:33 [PATCH v5 00/11] firmware: imx: NXP Secure-Enclave FW Driver Pankaj Gupta
` (5 preceding siblings ...)
2023-08-23 7:33 ` [PATCH v5 06/11] firmware: imx: add driver for NXP EdgeLock Enclave Pankaj Gupta
@ 2023-08-23 7:33 ` Pankaj Gupta
2023-08-24 18:35 ` Krzysztof Kozlowski
2023-08-23 7:33 ` [PATCH v5 08/11] firmware: imx: enable trng Pankaj Gupta
` (3 subsequent siblings)
10 siblings, 1 reply; 28+ messages in thread
From: Pankaj Gupta @ 2023-08-23 7:33 UTC (permalink / raw)
To: shawnguo, s.hauer, kernel, clin, conor+dt, pierre.gondois,
ping.bai, xiaoning.wang, wei.fang, peng.fan, haibo.chen, festevam,
linux-imx, davem, robh+dt, krzysztof.kozlowski+dt,
linux-arm-kernel, devicetree, linux-kernel, gaurav.jain,
alexander.stein, sahil.malhotra, aisheng.dong, V.Sethi
Cc: Pankaj Gupta
On imx93 platforms, exchange init-fw message with enclave's firmware
is to be done.
Signed-off-by: Pankaj Gupta <pankaj.gupta@nxp.com>
---
drivers/firmware/imx/Makefile | 2 +-
drivers/firmware/imx/ele_fw_api.c | 56 +++++++++++++++++++++++++
drivers/firmware/imx/se_fw.c | 11 +++++
include/linux/firmware/imx/ele_fw_api.h | 19 +++++++++
4 files changed, 87 insertions(+), 1 deletion(-)
create mode 100644 drivers/firmware/imx/ele_fw_api.c
create mode 100644 include/linux/firmware/imx/ele_fw_api.h
diff --git a/drivers/firmware/imx/Makefile b/drivers/firmware/imx/Makefile
index eab3f03e2e5e..bc6ed5514a19 100644
--- a/drivers/firmware/imx/Makefile
+++ b/drivers/firmware/imx/Makefile
@@ -2,5 +2,5 @@
obj-$(CONFIG_IMX_DSP) += imx-dsp.o
obj-$(CONFIG_IMX_SCU) += imx-scu.o misc.o imx-scu-irq.o rm.o imx-scu-soc.o
obj-$(CONFIG_IMX_SCU_PD) += scu-pd.o
-sec_enclave-objs = se_fw.o ele_common.o ele_base_msg.o
+sec_enclave-objs = se_fw.o ele_common.o ele_base_msg.o ele_fw_api.o
obj-${CONFIG_IMX_SEC_ENCLAVE} += sec_enclave.o
diff --git a/drivers/firmware/imx/ele_fw_api.c b/drivers/firmware/imx/ele_fw_api.c
new file mode 100644
index 000000000000..1df1fbcb6d9e
--- /dev/null
+++ b/drivers/firmware/imx/ele_fw_api.c
@@ -0,0 +1,56 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright 2023 NXP
+ */
+
+#include <linux/dma-mapping.h>
+#include <linux/firmware/imx/ele_fw_api.h>
+
+#include "ele_common.h"
+
+/* Fill a command message header with a given command ID and length in bytes. */
+static int plat_fill_cmd_msg_hdr(struct ele_mu_priv *priv,
+ struct mu_hdr *hdr,
+ uint8_t cmd, uint32_t len)
+{
+ int err = 0;
+
+ hdr->tag = priv->cmd_tag;
+ hdr->ver = MESSAGING_VERSION_7;
+ hdr->command = cmd;
+ hdr->size = (uint8_t)(len / sizeof(uint32_t));
+
+ return err;
+}
+
+int ele_init_fw(struct device *dev)
+{
+ struct ele_mu_priv *priv = dev_get_drvdata(dev);
+ int ret;
+ unsigned int tag, command, size, ver, status;
+
+ ret = plat_fill_cmd_msg_hdr(priv,
+ (struct mu_hdr *)&priv->tx_msg.header,
+ ELE_INIT_FW_REQ, 4);
+ if (ret)
+ return ret;
+
+ ret = imx_ele_msg_send_rcv(priv);
+ if (ret < 0)
+ return ret;
+
+ tag = MSG_TAG(priv->rx_msg.header);
+ command = MSG_COMMAND(priv->rx_msg.header);
+ size = MSG_SIZE(priv->rx_msg.header);
+ ver = MSG_VER(priv->rx_msg.header);
+ status = RES_STATUS(priv->rx_msg.data[0]);
+
+ if (tag == priv->rsp_tag
+ && command == ELE_INIT_FW_REQ
+ && size == ELE_INIT_FW_RSP_SZ
+ && ver == MESSAGING_VERSION_7
+ && status == priv->success_tag)
+ return 0;
+
+ return -EINVAL;
+}
diff --git a/drivers/firmware/imx/se_fw.c b/drivers/firmware/imx/se_fw.c
index 2c97b2adf18b..88300c41d62b 100644
--- a/drivers/firmware/imx/se_fw.c
+++ b/drivers/firmware/imx/se_fw.c
@@ -8,6 +8,7 @@
#include <linux/dev_printk.h>
#include <linux/errno.h>
#include <linux/export.h>
+#include <linux/firmware/imx/ele_fw_api.h>
#include <linux/firmware/imx/ele_base_msg.h>
#include <linux/firmware/imx/ele_mu_ioctl.h>
#include <linux/genalloc.h>
@@ -41,6 +42,7 @@ struct imx_info {
uint8_t *se_name;
uint8_t *pool_name;
bool reserved_dma_ranges;
+ bool init_fw;
};
static LIST_HEAD(priv_data_list);
@@ -55,6 +57,7 @@ static const struct imx_info imx8ulp_info = {
.se_name = "ele",
.pool_name = "sram-pool",
.reserved_dma_ranges = true,
+ .init_fw = false,
};
static const struct imx_info imx93_info = {
@@ -67,6 +70,7 @@ static const struct imx_info imx93_info = {
.se_name = "ele",
.pool_name = NULL,
.reserved_dma_ranges = true,
+ .init_fw = true,
};
static const struct of_device_id se_fw_match[] = {
@@ -1120,6 +1124,13 @@ static int se_fw_probe(struct platform_device *pdev)
priv->flags |= RESERVED_DMA_POOL;
}
+ if (info->init_fw) {
+ /* start initializing ele fw */
+ ret = ele_init_fw(dev);
+ if (ret)
+ dev_err(dev, "Failed to initialize ele fw.\n");
+ }
+
if (info->socdev) {
ret = imx_soc_device_register(dev, info);
if (ret) {
diff --git a/include/linux/firmware/imx/ele_fw_api.h b/include/linux/firmware/imx/ele_fw_api.h
new file mode 100644
index 000000000000..36c3f743cb38
--- /dev/null
+++ b/include/linux/firmware/imx/ele_fw_api.h
@@ -0,0 +1,19 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright 2023 NXP
+ */
+
+#ifndef ELE_FW_API_H
+#define ELE_FW_API_H
+
+#include <linux/hw_random.h>
+
+#define MESSAGING_VERSION_7 0x7
+
+#define ELE_INIT_FW_REQ 0x17
+#define ELE_INIT_FW_RSP_SZ 0x2
+
+
+int ele_init_fw(struct device *dev);
+
+#endif /* ELE_FW_API_H */
--
2.34.1
^ permalink raw reply related [flat|nested] 28+ messages in thread
* [PATCH v5 08/11] firmware: imx: enable trng
2023-08-23 7:33 [PATCH v5 00/11] firmware: imx: NXP Secure-Enclave FW Driver Pankaj Gupta
` (6 preceding siblings ...)
2023-08-23 7:33 ` [PATCH v5 07/11] firmware: imx: init-fw api exchange on imx93 Pankaj Gupta
@ 2023-08-23 7:33 ` Pankaj Gupta
2023-08-24 18:23 ` Krzysztof Kozlowski
2023-08-23 7:33 ` [PATCH v5 09/11] firmware: imx: enclave-fw: add handling for save/restore IMEM region Pankaj Gupta
` (2 subsequent siblings)
10 siblings, 1 reply; 28+ messages in thread
From: Pankaj Gupta @ 2023-08-23 7:33 UTC (permalink / raw)
To: shawnguo, s.hauer, kernel, clin, conor+dt, pierre.gondois,
ping.bai, xiaoning.wang, wei.fang, peng.fan, haibo.chen, festevam,
linux-imx, davem, robh+dt, krzysztof.kozlowski+dt,
linux-arm-kernel, devicetree, linux-kernel, gaurav.jain,
alexander.stein, sahil.malhotra, aisheng.dong, V.Sethi
Cc: Pankaj Gupta
Enabled trng on imx93 platform through enclave fw.
Signed-off-by: Gaurav Jain <gaurav.jain@nxp.com>
Signed-off-by: Pankaj Gupta <pankaj.gupta@nxp.com>
---
drivers/firmware/imx/Kconfig | 9 +++
drivers/firmware/imx/Makefile | 3 +-
drivers/firmware/imx/ele_base_msg.c | 88 +++++++++++++++++++++++
drivers/firmware/imx/ele_common.c | 44 +++++++++++-
drivers/firmware/imx/ele_common.h | 2 +
drivers/firmware/imx/ele_fw_api.c | 54 ++++++++++++++
drivers/firmware/imx/ele_trng.c | 48 +++++++++++++
drivers/firmware/imx/se_fw.c | 23 +++++-
include/linux/firmware/imx/ele_base_msg.h | 11 +++
include/linux/firmware/imx/ele_fw_api.h | 5 ++
10 files changed, 283 insertions(+), 4 deletions(-)
create mode 100644 drivers/firmware/imx/ele_trng.c
diff --git a/drivers/firmware/imx/Kconfig b/drivers/firmware/imx/Kconfig
index 2822e5d4b24c..ffc02593293c 100644
--- a/drivers/firmware/imx/Kconfig
+++ b/drivers/firmware/imx/Kconfig
@@ -40,3 +40,12 @@ config IMX_SEC_ENCLAVE
like base, HSM, V2X & SHE using the SAB protocol via the shared Messaging
Unit. This driver exposes these interfaces via a set of file descriptors
allowing to configure shared memory, send and receive messages.
+
+config IMX_ELE_TRNG
+ tristate "i.MX ELE True Random Number Generator"
+ default y
+ select CRYPTO_RNG
+ select HW_RANDOM
+ help
+ This driver provides kernel-side support for the Random Number generation,
+ through NXP hardware IP for secure-enclave called EdgeLock Enclave.
diff --git a/drivers/firmware/imx/Makefile b/drivers/firmware/imx/Makefile
index bc6ed5514a19..e46f3053707f 100644
--- a/drivers/firmware/imx/Makefile
+++ b/drivers/firmware/imx/Makefile
@@ -2,5 +2,6 @@
obj-$(CONFIG_IMX_DSP) += imx-dsp.o
obj-$(CONFIG_IMX_SCU) += imx-scu.o misc.o imx-scu-irq.o rm.o imx-scu-soc.o
obj-$(CONFIG_IMX_SCU_PD) += scu-pd.o
-sec_enclave-objs = se_fw.o ele_common.o ele_base_msg.o ele_fw_api.o
+sec_enclave-objs = ele_common.o se_fw.o ele_base_msg.o ele_fw_api.o
obj-${CONFIG_IMX_SEC_ENCLAVE} += sec_enclave.o
+sec_enclave-${CONFIG_IMX_ELE_TRNG} += ele_trng.o
diff --git a/drivers/firmware/imx/ele_base_msg.c b/drivers/firmware/imx/ele_base_msg.c
index 2eb675a1b389..c42e29e14662 100644
--- a/drivers/firmware/imx/ele_base_msg.c
+++ b/drivers/firmware/imx/ele_base_msg.c
@@ -60,3 +60,91 @@ int ele_get_info(struct device *dev, phys_addr_t addr, u32 data_size)
return -EINVAL;
}
+
+/*
+ * ele_get_trng_state() - prepare and send the command to read
+ * crypto lib and TRNG state
+ * TRNG state
+ * 0x1 TRNG is in program mode
+ * 0x2 TRNG is still generating entropy
+ * 0x3 TRNG entropy is valid and ready to be read
+ * 0x4 TRNG encounter an error while generating entropy
+ *
+ * CSAL state
+ * 0x0 Crypto Lib random context initialization is not done yet
+ * 0x1 Crypto Lib random context initialization is on-going
+ * 0x2 Crypto Lib random context initialization succeed
+ * 0x3 Crypto Lib random context initialization failed
+ *
+ * returns: csal and trng state.
+ *
+ */
+int ele_get_trng_state(struct device *dev)
+{
+ struct ele_mu_priv *priv = dev_get_drvdata(dev);
+ int ret;
+ unsigned int tag, command, size, ver, status;
+
+ ret = plat_fill_cmd_msg_hdr(priv,
+ (struct mu_hdr *)&priv->tx_msg.header,
+ ELE_GET_TRNG_STATE_REQ, 4);
+ if (ret)
+ return ret;
+
+ ret = imx_ele_msg_send_rcv(priv);
+ if (ret < 0)
+ return ret;
+
+ tag = MSG_TAG(priv->rx_msg.header);
+ command = MSG_COMMAND(priv->rx_msg.header);
+ size = MSG_SIZE(priv->rx_msg.header);
+ ver = MSG_VER(priv->rx_msg.header);
+ status = RES_STATUS(priv->rx_msg.data[0]);
+ if (tag == priv->rsp_tag &&
+ command == ELE_GET_TRNG_STATE_REQ &&
+ size == ELE_GET_TRNG_STATE_REQ_MSG_SZ &&
+ ver == ELE_BASE_API_VERSION &&
+ status == priv->success_tag) {
+ return (priv->rx_msg.data[1] & CSAL_TRNG_STATE_MASK);
+ }
+
+ return -EINVAL;
+}
+
+/*
+ * ele_start_rng() - prepare and send the command to start
+ * initialization of the ELE RNG context
+ *
+ * returns: 0 on success.
+ */
+int ele_start_rng(struct device *dev)
+{
+ struct ele_mu_priv *priv = dev_get_drvdata(dev);
+ int ret;
+ unsigned int tag, command, size, ver, status;
+
+ ret = plat_fill_cmd_msg_hdr(priv,
+ (struct mu_hdr *)&priv->tx_msg.header,
+ ELE_START_RNG_REQ, 4);
+ if (ret)
+ return ret;
+
+ ret = imx_ele_msg_send_rcv(priv);
+ if (ret < 0)
+ return ret;
+
+ tag = MSG_TAG(priv->rx_msg.header);
+ command = MSG_COMMAND(priv->rx_msg.header);
+ size = MSG_SIZE(priv->rx_msg.header);
+ ver = MSG_VER(priv->rx_msg.header);
+ status = RES_STATUS(priv->rx_msg.data[0]);
+ if (tag == priv->rsp_tag &&
+ command == ELE_START_RNG_REQ &&
+ size == ELE_START_RNG_REQ_MSG_SZ &&
+ ver == ELE_BASE_API_VERSION &&
+ status == priv->success_tag) {
+ return 0;
+ }
+
+ return -EINVAL;
+}
diff --git a/drivers/firmware/imx/ele_common.c b/drivers/firmware/imx/ele_common.c
index 08adc7200ceb..f01e5e3255f9 100644
--- a/drivers/firmware/imx/ele_common.c
+++ b/drivers/firmware/imx/ele_common.c
@@ -1,9 +1,13 @@
// SPDX-License-Identifier: GPL-2.0+
/*
- * Copyright 2021-2023 NXP
+ * Copyright 2023 NXP
*/
-#include "se_fw.h"
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/firmware/imx/ele_base_msg.h>
+
+#include "ele_common.h"
int imx_ele_msg_send_rcv(struct ele_mu_priv *priv)
{
@@ -32,3 +36,39 @@ int imx_ele_msg_send_rcv(struct ele_mu_priv *priv)
return err;
}
+int ele_do_start_rng(struct device *dev)
+{
+ int ret;
+ int count = ELE_GET_TRNG_STATE_RETRY_COUNT;
+
+ ret = ele_get_trng_state(dev);
+ if (ret < 0) {
+ dev_err(dev, "Failed to get trng state\n");
+ return ret;
+ } else if (ret != ELE_TRNG_STATE_OK) {
+ /* call start rng */
+ ret = ele_start_rng(dev);
+ if (ret) {
+ dev_err(dev, "Failed to start rng\n");
+ return ret;
+ }
+
+ /* poll get trng state API, ELE_GET_TRNG_STATE_RETRY_COUNT times
+ * or while trng state != 0x203
+ */
+ do {
+ msleep(10);
+ ret = ele_get_trng_state(dev);
+ if (ret < 0) {
+ dev_err(dev, "Failed to get trng state\n");
+ return ret;
+ }
+ count--;
+ } while ((ret != ELE_TRNG_STATE_OK) && count);
+ if (ret != ELE_TRNG_STATE_OK)
+ return -EIO;
+ }
+
+ return 0;
+}
+
diff --git a/drivers/firmware/imx/ele_common.h b/drivers/firmware/imx/ele_common.h
index 6af0296b76fd..ed68e5cf9638 100644
--- a/drivers/firmware/imx/ele_common.h
+++ b/drivers/firmware/imx/ele_common.h
@@ -18,4 +18,6 @@ static inline int ele_trng_init(struct device *dev)
return 0;
}
#endif
+
+int ele_do_start_rng(struct device *dev);
#endif
diff --git a/drivers/firmware/imx/ele_fw_api.c b/drivers/firmware/imx/ele_fw_api.c
index 1df1fbcb6d9e..8e0b331531a2 100644
--- a/drivers/firmware/imx/ele_fw_api.c
+++ b/drivers/firmware/imx/ele_fw_api.c
@@ -54,3 +54,57 @@ int ele_init_fw(struct device *dev)
return -EINVAL;
}
+
+/*
+ * ele_get_random() - prepare and send the command to proceed
+ * with a random number generation operation
+ *
+ * returns: size of the rondom number generated
+ */
+int ele_get_random(struct device *dev,
+ void *data, size_t len)
+{
+ struct ele_mu_priv *priv = dev_get_drvdata(dev);
+ unsigned int tag, command, size, ver, status;
+ dma_addr_t dst_dma;
+ u8 *buf;
+ int ret;
+
+ buf = dmam_alloc_coherent(priv->dev, len, &dst_dma, GFP_KERNEL);
+ if (!buf) {
+ dev_err(priv->dev, "Failed to map destination buffer memory\n");
+ return -ENOMEM;
+ }
+
+ ret = plat_fill_cmd_msg_hdr(priv,
+ (struct mu_hdr *)&priv->tx_msg.header,
+ ELE_GET_RANDOM_REQ, 16);
+ if (ret)
+ goto exit;
+
+ priv->tx_msg.data[0] = 0x0;
+ priv->tx_msg.data[1] = dst_dma;
+ priv->tx_msg.data[2] = len;
+ ret = imx_ele_msg_send_rcv(priv);
+ if (ret < 0)
+ goto exit;
+
+ tag = MSG_TAG(priv->rx_msg.header);
+ command = MSG_COMMAND(priv->rx_msg.header);
+ size = MSG_SIZE(priv->rx_msg.header);
+ ver = MSG_VER(priv->rx_msg.header);
+ status = RES_STATUS(priv->rx_msg.data[0]);
+ if (tag == priv->rsp_tag
+ && command == ELE_GET_RANDOM_REQ
+ && size == ELE_GET_RANDOM_REQ_SZ
+ && ver == MESSAGING_VERSION_7
+ && status == priv->success_tag) {
+ memcpy(data, buf, len);
+ ret = len;
+ } else
+ ret = -EINVAL;
+
+exit:
+ dmam_free_coherent(priv->dev, len, buf, dst_dma);
+ return ret;
+}
diff --git a/drivers/firmware/imx/ele_trng.c b/drivers/firmware/imx/ele_trng.c
new file mode 100644
index 000000000000..23d5891f9569
--- /dev/null
+++ b/drivers/firmware/imx/ele_trng.c
@@ -0,0 +1,48 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * ELE Random Number Generator Driver NXP's Platforms
+ *
+ * Copyright 2023 NXP
+ */
+
+#include <linux/firmware/imx/ele_fw_api.h>
+
+#include "ele_common.h"
+
+struct ele_trng {
+ struct hwrng rng;
+ struct device *dev;
+};
+
+int ele_trng_init(struct device *dev)
+{
+ struct ele_trng *trng;
+ int ret;
+
+ trng = devm_kzalloc(dev, sizeof(*trng), GFP_KERNEL);
+ if (!trng)
+ return -ENOMEM;
+
+ trng->dev = dev;
+ trng->rng.name = "ele-trng";
+ trng->rng.read = ele_get_hwrng;
+ trng->rng.priv = (unsigned long)trng;
+ trng->rng.quality = 1024;
+
+ dev_dbg(dev, "registering ele-trng\n");
+
+ ret = devm_hwrng_register(dev, &trng->rng);
+ if (ret)
+ return ret;
+
+ dev_info(dev, "Successfully registered ele-trng\n");
+ return 0;
+}
+
+int ele_get_hwrng(struct hwrng *rng,
+ void *data, size_t len, bool wait)
+{
+ struct ele_trng *trng = (struct ele_trng *)rng->priv;
+
+ return ele_get_random(trng->dev, data, len);
+}
diff --git a/drivers/firmware/imx/se_fw.c b/drivers/firmware/imx/se_fw.c
index 88300c41d62b..6083c42dcda3 100644
--- a/drivers/firmware/imx/se_fw.c
+++ b/drivers/firmware/imx/se_fw.c
@@ -21,10 +21,10 @@
#include <linux/of_reserved_mem.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
-#include <linux/delay.h>
#include <linux/sys_soc.h>
#include "se_fw.h"
+#include "ele_common.h"
#define SOC_ID_OF_IMX8ULP 0x084D
#define SOC_ID_OF_IMX93 0x9300
@@ -43,6 +43,9 @@ struct imx_info {
uint8_t *pool_name;
bool reserved_dma_ranges;
bool init_fw;
+ /* platform specific flag to enable/disable the ELE True RNG */
+ bool start_rng;
+ bool enable_ele_trng;
};
static LIST_HEAD(priv_data_list);
@@ -58,6 +61,8 @@ static const struct imx_info imx8ulp_info = {
.pool_name = "sram-pool",
.reserved_dma_ranges = true,
.init_fw = false,
+ .start_rng = true,
+ .enable_ele_trng = false,
};
static const struct imx_info imx93_info = {
@@ -71,6 +76,8 @@ static const struct imx_info imx93_info = {
.pool_name = NULL,
.reserved_dma_ranges = true,
.init_fw = true,
+ .start_rng = true,
+ .enable_ele_trng = true,
};
static const struct of_device_id se_fw_match[] = {
@@ -1140,9 +1147,23 @@ static int se_fw_probe(struct platform_device *pdev)
}
}
+ /* start ele rng */
+ if (info->start_rng) {
+ ret = ele_do_start_rng(dev);
+ if (ret)
+ dev_err(dev, "Failed to start ele rng\n");
+ }
+
+ if (!ret && info->enable_ele_trng) {
+ ret = ele_trng_init(dev);
+ if (ret)
+ dev_err(dev, "Failed to init ele-trng\n");
+ }
+
pr_info("i.MX secure-enclave: %s's mu#%d interface to firmware, configured.\n",
info->se_name,
priv->ele_mu_id);
+
return devm_of_platform_populate(dev);
exit:
diff --git a/include/linux/firmware/imx/ele_base_msg.h b/include/linux/firmware/imx/ele_base_msg.h
index 9c05936ba813..8a5c385210fc 100644
--- a/include/linux/firmware/imx/ele_base_msg.h
+++ b/include/linux/firmware/imx/ele_base_msg.h
@@ -28,10 +28,21 @@
#define ELE_GET_INFO_REQ 0xDA
#define ELE_GET_INFO_REQ_MSG_SZ 0x02
+#define ELE_START_RNG_REQ 0xA3
+#define ELE_START_RNG_REQ_MSG_SZ 0x02
+
+#define ELE_GET_TRNG_STATE_REQ 0xA4
+#define ELE_GET_TRNG_STATE_REQ_MSG_SZ 0x03
+#define ELE_TRNG_STATE_OK 0x203
+#define ELE_GET_TRNG_STATE_RETRY_COUNT 0x5
+#define CSAL_TRNG_STATE_MASK 0x0000ffff
+
#define ELE_BASE_API_VERSION 0x6
#define ELE_SUCCESS_IND 0xD6
#define ELE_FAILURE_IND 0x29
int ele_get_info(struct device *dev, phys_addr_t addr, u32 data_size);
+int ele_start_rng(struct device *dev);
+int ele_get_trng_state(struct device *dev);
#endif
diff --git a/include/linux/firmware/imx/ele_fw_api.h b/include/linux/firmware/imx/ele_fw_api.h
index 36c3f743cb38..5e640148e211 100644
--- a/include/linux/firmware/imx/ele_fw_api.h
+++ b/include/linux/firmware/imx/ele_fw_api.h
@@ -13,7 +13,12 @@
#define ELE_INIT_FW_REQ 0x17
#define ELE_INIT_FW_RSP_SZ 0x2
+#define ELE_GET_RANDOM_REQ 0xCD
+#define ELE_GET_RANDOM_REQ_SZ 0x2
+
int ele_init_fw(struct device *dev);
+int ele_get_random(struct device *dev, void *data, size_t len);
+int ele_get_hwrng(struct hwrng *rng, void *data, size_t len, bool wait);
#endif /* ELE_FW_API_H */
--
2.34.1
^ permalink raw reply related [flat|nested] 28+ messages in thread
* [PATCH v5 09/11] firmware: imx: enclave-fw: add handling for save/restore IMEM region
2023-08-23 7:33 [PATCH v5 00/11] firmware: imx: NXP Secure-Enclave FW Driver Pankaj Gupta
` (7 preceding siblings ...)
2023-08-23 7:33 ` [PATCH v5 08/11] firmware: imx: enable trng Pankaj Gupta
@ 2023-08-23 7:33 ` Pankaj Gupta
2023-08-24 18:37 ` Krzysztof Kozlowski
2023-08-23 7:33 ` [PATCH v5 10/11] firmware: imx: enclave api to read-common-fuses Pankaj Gupta
2023-08-23 7:33 ` [PATCH v5 11/11] MAINTAINERS: Added maintainer details Pankaj Gupta
10 siblings, 1 reply; 28+ messages in thread
From: Pankaj Gupta @ 2023-08-23 7:33 UTC (permalink / raw)
To: shawnguo, s.hauer, kernel, clin, conor+dt, pierre.gondois,
ping.bai, xiaoning.wang, wei.fang, peng.fan, haibo.chen, festevam,
linux-imx, davem, robh+dt, krzysztof.kozlowski+dt,
linux-arm-kernel, devicetree, linux-kernel, gaurav.jain,
alexander.stein, sahil.malhotra, aisheng.dong, V.Sethi
Cc: Pankaj Gupta
Some IMEM region is lost during kernel power down. Due to this,
firmware's functionaity cannot work correctly.
Saving encrypted IMEM region in kernel memory during power down,
and restore IMEM region on resume.
Signed-off-by: Gaurav Jain <gaurav.jain@nxp.com>
Signed-off-by: Pankaj Gupta <pankaj.gupta@nxp.com>
---
drivers/firmware/imx/ele_base_msg.c | 42 ++++++++
drivers/firmware/imx/ele_common.c | 114 ++++++++++++++++++++++
drivers/firmware/imx/ele_common.h | 8 ++
drivers/firmware/imx/se_fw.c | 45 ++++++++-
drivers/firmware/imx/se_fw.h | 8 ++
include/linux/firmware/imx/ele_base_msg.h | 15 ++-
6 files changed, 228 insertions(+), 4 deletions(-)
diff --git a/drivers/firmware/imx/ele_base_msg.c b/drivers/firmware/imx/ele_base_msg.c
index c42e29e14662..b19ab8abeeb8 100644
--- a/drivers/firmware/imx/ele_base_msg.c
+++ b/drivers/firmware/imx/ele_base_msg.c
@@ -148,3 +148,45 @@ int ele_start_rng(struct device *dev)
return -EINVAL;
}
+
+int ele_service_swap(struct device *dev,
+ phys_addr_t addr,
+ u32 addr_size, u16 flag)
+{
+ struct ele_mu_priv *priv = dev_get_drvdata(dev);
+ int ret;
+ unsigned int tag, command, size, ver, status;
+
+ ret = plat_fill_cmd_msg_hdr(priv,
+ (struct mu_hdr *)&priv->tx_msg.header,
+ ELE_SERVICE_SWAP_REQ, 24);
+ if (ret)
+ return ret;
+
+ priv->tx_msg.data[0] = flag;
+ priv->tx_msg.data[1] = addr_size;
+ priv->tx_msg.data[2] = ELE_NONE_VAL;
+ priv->tx_msg.data[3] = lower_32_bits(addr);
+ priv->tx_msg.data[4] = plat_add_msg_crc((uint32_t *)&priv->tx_msg, 24);
+ ret = imx_ele_msg_send_rcv(priv);
+ if (ret < 0)
+ return ret;
+
+ tag = MSG_TAG(priv->rx_msg.header);
+ command = MSG_COMMAND(priv->rx_msg.header);
+ size = MSG_SIZE(priv->rx_msg.header);
+ ver = MSG_VER(priv->rx_msg.header);
+ status = RES_STATUS(priv->rx_msg.data[0]);
+ if (tag == priv->rsp_tag &&
+ command == ELE_SERVICE_SWAP_REQ &&
+ size == ELE_SERVICE_SWAP_REQ_MSG_SZ &&
+ ver == ELE_BASE_API_VERSION &&
+ status == priv->success_tag) {
+ if (flag == ELE_IMEM_EXPORT)
+ return priv->rx_msg.data[1];
+ else
+ return 0;
+ }
+
+ return -EINVAL;
+}
diff --git a/drivers/firmware/imx/ele_common.c b/drivers/firmware/imx/ele_common.c
index f01e5e3255f9..f6feb8f986a7 100644
--- a/drivers/firmware/imx/ele_common.c
+++ b/drivers/firmware/imx/ele_common.c
@@ -9,6 +9,18 @@
#include "ele_common.h"
+uint32_t plat_add_msg_crc(uint32_t *msg, uint32_t msg_len)
+{
+ uint32_t i;
+ uint32_t crc = 0;
+ uint32_t nb_words = msg_len / (uint32_t)sizeof(uint32_t);
+
+ for (i = 0; i < nb_words - 1; i++)
+ crc ^= *(msg + i);
+
+ return crc;
+}
+
int imx_ele_msg_send_rcv(struct ele_mu_priv *priv)
{
unsigned int wait;
@@ -72,3 +84,105 @@ int ele_do_start_rng(struct device *dev)
return 0;
}
+#ifdef CONFIG_PM_SLEEP
+int save_imem(struct device *dev)
+{
+ int ret;
+ struct ele_mu_priv *priv = dev_get_drvdata(dev);
+
+ /* EXPORT command will save encrypted IMEM to given address,
+ * so later in resume, IMEM can be restored from the given
+ * address.
+ *
+ * Size must be at least 64 kB.
+ */
+ ret = ele_service_swap(dev,
+ priv->imem.phyaddr,
+ ELE_IMEM_SIZE,
+ ELE_IMEM_EXPORT);
+ if (ret < 0)
+ dev_err(dev, "Failed to export IMEM\n");
+ else
+ dev_info(dev,
+ "Exported %d bytes of encrypted IMEM\n",
+ ret);
+
+ return ret;
+}
+
+int restore_imem(struct device *dev,
+ uint8_t *pool_name)
+{
+ int ret;
+ u32 imem_state;
+ u32 *get_info_buf = NULL;
+ phys_addr_t get_info_phyaddr = 0;
+ struct ele_mu_priv *priv = dev_get_drvdata(dev);
+
+ get_info_phyaddr
+ = pool_name ? get_phy_buf_mem_pool(dev,
+ pool_name,
+ &get_info_buf,
+ DEVICE_GET_INFO_SZ)
+ : 0x0;
+
+ if (!get_info_buf) {
+ dev_err(dev, "Unable to alloc sram from sram pool\n");
+ return -ENOMEM;
+ }
+
+ ret = ele_do_start_rng(dev);
+ if (ret)
+ goto exit;
+
+ /* get info from ELE */
+ ret = ele_get_info(dev, get_info_phyaddr, ELE_GET_INFO_READ_SZ);
+ if (ret) {
+ dev_err(dev, "Failed to get info from ELE.\n");
+ goto exit;
+ }
+
+ /* Get IMEM state, if 0xFE then import IMEM */
+ imem_state = (get_info_buf[ELE_IMEM_STATE_WORD]
+ & ELE_IMEM_STATE_MASK) >> 16;
+ if (imem_state == ELE_IMEM_STATE_BAD) {
+ /* IMPORT command will restore IMEM from the given
+ * address, here size is the actual size returned by ELE
+ * during the export operation
+ */
+ ret = ele_service_swap(dev,
+ priv->imem.phyaddr,
+ priv->imem.size,
+ ELE_IMEM_IMPORT);
+ if (ret) {
+ dev_err(dev, "Failed to import IMEM\n");
+ goto exit;
+ }
+ } else
+ goto exit;
+
+ /* After importing IMEM, check if IMEM state is equal to 0xCA
+ * to ensure IMEM is fully loaded and
+ * ELE functionality can be used.
+ */
+ ret = ele_get_info(dev, get_info_phyaddr, ELE_GET_INFO_READ_SZ);
+ if (ret) {
+ dev_err(dev, "Failed to get info from ELE.\n");
+ goto exit;
+ }
+
+ imem_state = (get_info_buf[ELE_IMEM_STATE_WORD]
+ & ELE_IMEM_STATE_MASK) >> 16;
+ if (imem_state == ELE_IMEM_STATE_OK)
+ dev_info(dev, "Successfully restored IMEM\n");
+ else
+ dev_err(dev, "Failed to restore IMEM\n");
+
+exit:
+ if (pool_name && get_info_buf)
+ free_phybuf_mem_pool(dev, pool_name,
+ get_info_buf, DEVICE_GET_INFO_SZ);
+
+ return ret;
+}
+#endif
diff --git a/drivers/firmware/imx/ele_common.h b/drivers/firmware/imx/ele_common.h
index ed68e5cf9638..55bcbb9fc261 100644
--- a/drivers/firmware/imx/ele_common.h
+++ b/drivers/firmware/imx/ele_common.h
@@ -9,6 +9,7 @@
#include "se_fw.h"
+uint32_t plat_add_msg_crc(uint32_t *msg, uint32_t msg_len);
int imx_ele_msg_send_rcv(struct ele_mu_priv *priv);
#ifdef CONFIG_IMX_ELE_TRNG
int ele_trng_init(struct device *dev);
@@ -20,4 +21,11 @@ static inline int ele_trng_init(struct device *dev)
#endif
int ele_do_start_rng(struct device *dev);
+
+#ifdef CONFIG_PM_SLEEP
+int save_imem(struct device *dev);
+int restore_imem(struct device *dev,
+ uint8_t *pool_name);
#endif
+
+#endif /*__ELE_COMMON_H__ */
diff --git a/drivers/firmware/imx/se_fw.c b/drivers/firmware/imx/se_fw.c
index 6083c42dcda3..936fc0352054 100644
--- a/drivers/firmware/imx/se_fw.c
+++ b/drivers/firmware/imx/se_fw.c
@@ -46,6 +46,7 @@ struct imx_info {
/* platform specific flag to enable/disable the ELE True RNG */
bool start_rng;
bool enable_ele_trng;
+ bool imem_mgmt;
};
static LIST_HEAD(priv_data_list);
@@ -63,6 +64,7 @@ static const struct imx_info imx8ulp_info = {
.init_fw = false,
.start_rng = true,
.enable_ele_trng = false,
+ .imem_mgmt = true,
};
static const struct imx_info imx93_info = {
@@ -78,6 +80,7 @@ static const struct imx_info imx93_info = {
.init_fw = true,
.start_rng = true,
.enable_ele_trng = true,
+ .imem_mgmt = false,
};
static const struct of_device_id se_fw_match[] = {
@@ -160,7 +163,7 @@ static void ele_mu_rx_callback(struct mbox_client *c, void *msg)
}
-static phys_addr_t get_phy_buf_mem_pool(struct device *dev,
+phys_addr_t get_phy_buf_mem_pool(struct device *dev,
char *mem_pool_name,
u32 **buf,
uint32_t size)
@@ -182,7 +185,7 @@ static phys_addr_t get_phy_buf_mem_pool(struct device *dev,
return gen_pool_virt_to_phys(mem_pool, (ulong)*buf);
}
-static void free_phybuf_mem_pool(struct device *dev,
+void free_phybuf_mem_pool(struct device *dev,
char *mem_pool_name,
u32 *buf,
uint32_t size)
@@ -959,6 +962,17 @@ static int se_probe_cleanup(struct platform_device *pdev)
priv->flags &= (~RESERVED_DMA_POOL);
}
+ /* free the buffer in ele-mu remove, previously allocated
+ * in ele-mu probe to store encrypted IMEM
+ */
+ if (priv->imem.buf) {
+ dmam_free_coherent(&pdev->dev,
+ ELE_IMEM_SIZE,
+ priv->imem.buf,
+ priv->imem.phyaddr);
+ priv->imem.buf = NULL;
+ }
+
if (priv->ctxs) {
for (i = 0; i < priv->max_dev_ctx; i++) {
if (priv->ctxs[i])
@@ -1160,6 +1174,19 @@ static int se_fw_probe(struct platform_device *pdev)
dev_err(dev, "Failed to init ele-trng\n");
}
+ if (info->imem_mgmt) {
+ /* allocate buffer where ELE store encrypted IMEM */
+ priv->imem.buf = dmam_alloc_coherent(dev, ELE_IMEM_SIZE,
+ &priv->imem.phyaddr,
+ GFP_KERNEL);
+ if (!priv->imem.buf) {
+ dev_err(dev,
+ "dmam-alloc-failed: To store encr-IMEM.\n");
+ ret = -ENOMEM;
+ goto exit;
+ }
+ }
+
pr_info("i.MX secure-enclave: %s's mu#%d interface to firmware, configured.\n",
info->se_name,
priv->ele_mu_id);
@@ -1196,17 +1223,31 @@ static int se_fw_remove(struct platform_device *pdev)
#ifdef CONFIG_PM_SLEEP
static int se_fw_suspend(struct device *dev)
{
+ struct ele_mu_priv *priv = dev_get_drvdata(dev);
+ const struct of_device_id *of_id = of_match_device(se_fw_match, dev);
+ struct imx_info *info = (of_id != NULL) ? (struct imx_info *)of_id->data
+ : NULL;
+
+ if (info && info->imem_mgmt)
+ priv->imem.size = save_imem(dev);
+
return 0;
}
static int se_fw_resume(struct device *dev)
{
struct ele_mu_priv *priv = dev_get_drvdata(dev);
+ const struct of_device_id *of_id = of_match_device(se_fw_match, dev);
+ struct imx_info *info = (of_id != NULL) ? (struct imx_info *)of_id->data
+ : NULL;
int i;
for (i = 0; i < priv->max_dev_ctx; i++)
wake_up_interruptible(&priv->ctxs[i]->wq);
+ if (info && info->imem_mgmt)
+ restore_imem(dev, info->pool_name);
+
return 0;
}
#endif
diff --git a/drivers/firmware/imx/se_fw.h b/drivers/firmware/imx/se_fw.h
index b3502affbc85..acb967f2357c 100644
--- a/drivers/firmware/imx/se_fw.h
+++ b/drivers/firmware/imx/se_fw.h
@@ -165,4 +165,12 @@ struct ele_mu_priv {
struct ele_imem_buf imem;
};
+phys_addr_t get_phy_buf_mem_pool(struct device *dev,
+ char *mem_pool_name,
+ u32 **buf,
+ uint32_t size);
+void free_phybuf_mem_pool(struct device *dev,
+ char *mem_pool_name,
+ u32 *buf,
+ uint32_t size);
#endif
diff --git a/include/linux/firmware/imx/ele_base_msg.h b/include/linux/firmware/imx/ele_base_msg.h
index 8a5c385210fc..6fbea7a8d7c9 100644
--- a/include/linux/firmware/imx/ele_base_msg.h
+++ b/include/linux/firmware/imx/ele_base_msg.h
@@ -37,12 +37,23 @@
#define ELE_GET_TRNG_STATE_RETRY_COUNT 0x5
#define CSAL_TRNG_STATE_MASK 0x0000ffff
+#define ELE_SERVICE_SWAP_REQ 0xDF
+#define ELE_SERVICE_SWAP_REQ_MSG_SZ 0x03
+#define ELE_IMEM_SIZE 0x10000
+#define ELE_IMEM_STATE_OK 0xCA
+#define ELE_IMEM_STATE_BAD 0xFE
+#define ELE_IMEM_STATE_WORD 0x27
+#define ELE_IMEM_STATE_MASK 0x00ff0000
+#define ELE_IMEM_EXPORT 0x1
+#define ELE_IMEM_IMPORT 0x2
+
#define ELE_BASE_API_VERSION 0x6
-#define ELE_SUCCESS_IND 0xD6
-#define ELE_FAILURE_IND 0x29
int ele_get_info(struct device *dev, phys_addr_t addr, u32 data_size);
int ele_start_rng(struct device *dev);
int ele_get_trng_state(struct device *dev);
+int ele_service_swap(struct device *dev,
+ phys_addr_t addr,
+ u32 addr_size, u16 flag);
#endif
--
2.34.1
^ permalink raw reply related [flat|nested] 28+ messages in thread
* [PATCH v5 10/11] firmware: imx: enclave api to read-common-fuses
2023-08-23 7:33 [PATCH v5 00/11] firmware: imx: NXP Secure-Enclave FW Driver Pankaj Gupta
` (8 preceding siblings ...)
2023-08-23 7:33 ` [PATCH v5 09/11] firmware: imx: enclave-fw: add handling for save/restore IMEM region Pankaj Gupta
@ 2023-08-23 7:33 ` Pankaj Gupta
2023-08-24 18:38 ` Krzysztof Kozlowski
2023-08-23 7:33 ` [PATCH v5 11/11] MAINTAINERS: Added maintainer details Pankaj Gupta
10 siblings, 1 reply; 28+ messages in thread
From: Pankaj Gupta @ 2023-08-23 7:33 UTC (permalink / raw)
To: shawnguo, s.hauer, kernel, clin, conor+dt, pierre.gondois,
ping.bai, xiaoning.wang, wei.fang, peng.fan, haibo.chen, festevam,
linux-imx, davem, robh+dt, krzysztof.kozlowski+dt,
linux-arm-kernel, devicetree, linux-kernel, gaurav.jain,
alexander.stein, sahil.malhotra, aisheng.dong, V.Sethi
Cc: Pankaj Gupta
Added an API to read the common fuses only accessible to
enclave-firmware.
Signed-off-by: Pankaj Gupta <pankaj.gupta@nxp.com>
---
drivers/firmware/imx/ele_base_msg.c | 80 +++++++++++++++++++++++
include/linux/firmware/imx/ele_base_msg.h | 7 ++
2 files changed, 87 insertions(+)
diff --git a/drivers/firmware/imx/ele_base_msg.c b/drivers/firmware/imx/ele_base_msg.c
index b19ab8abeeb8..9785fcdcc29d 100644
--- a/drivers/firmware/imx/ele_base_msg.c
+++ b/drivers/firmware/imx/ele_base_msg.c
@@ -190,3 +190,83 @@ int ele_service_swap(struct device *dev,
return -EINVAL;
}
+
+static int read_otp_uniq_id(struct ele_mu_priv *priv, u32 *value)
+{
+ unsigned int tag, command, size, ver, status;
+
+ tag = MSG_TAG(priv->rx_msg.header);
+ command = MSG_COMMAND(priv->rx_msg.header);
+ size = MSG_SIZE(priv->rx_msg.header);
+ ver = MSG_VER(priv->rx_msg.header);
+ status = RES_STATUS(priv->rx_msg.data[0]);
+
+ if (tag == priv->rsp_tag &&
+ command == ELE_READ_FUSE_REQ &&
+ size == ELE_READ_FUSE_RSP_MSG_SZ &&
+ ver == ELE_BASE_API_VERSION &&
+ status == priv->success_tag) {
+ value[0] = priv->rx_msg.data[1];
+ value[1] = priv->rx_msg.data[2];
+ value[2] = priv->rx_msg.data[3];
+ value[3] = priv->rx_msg.data[4];
+ return 0;
+ }
+
+ return -EINVAL;
+}
+
+static int read_fuse_word(struct ele_mu_priv *priv, u32 *value)
+{
+ unsigned int tag, command, size, ver, status;
+
+ tag = MSG_TAG(priv->rx_msg.header);
+ command = MSG_COMMAND(priv->rx_msg.header);
+ size = MSG_SIZE(priv->rx_msg.header);
+ ver = MSG_VER(priv->rx_msg.header);
+ status = RES_STATUS(priv->rx_msg.data[0]);
+
+ if (tag == priv->rsp_tag &&
+ command == ELE_READ_FUSE_REQ &&
+ size == ELE_READ_FUSE_REQ_MSG_SZ &&
+ ver == ELE_BASE_API_VERSION &&
+ status == priv->success_tag) {
+ value[0] = priv->rx_msg.data[1];
+ return 0;
+ }
+
+ return -EINVAL;
+}
+
+int read_common_fuse(struct device *dev,
+ uint16_t fuse_id, u32 *value)
+{
+ struct ele_mu_priv *priv = dev_get_drvdata(dev);
+ int err;
+
+ err = plat_fill_cmd_msg_hdr(priv,
+ (struct mu_hdr *)&priv->tx_msg.header,
+ ELE_READ_FUSE_REQ, 8);
+ if (err) {
+ pr_err("Error: plat_fill_cmd_msg_hdr failed.\n");
+ return err;
+ }
+
+ priv->tx_msg.data[0] = fuse_id;
+ err = imx_ele_msg_send_rcv(priv);
+ if (err < 0)
+ return err;
+
+ switch (fuse_id) {
+ case OTP_UNIQ_ID:
+ err = read_otp_uniq_id(priv, value);
+ break;
+ default:
+ err = read_fuse_word(priv, value);
+ break;
+ }
+
+ return err;
+}
+EXPORT_SYMBOL_GPL(read_common_fuse);
+
diff --git a/include/linux/firmware/imx/ele_base_msg.h b/include/linux/firmware/imx/ele_base_msg.h
index 6fbea7a8d7c9..99a135c21f56 100644
--- a/include/linux/firmware/imx/ele_base_msg.h
+++ b/include/linux/firmware/imx/ele_base_msg.h
@@ -47,6 +47,13 @@
#define ELE_IMEM_EXPORT 0x1
#define ELE_IMEM_IMPORT 0x2
+#define ELE_READ_FUSE_REQ 0x97
+#define ELE_READ_FUSE_RSP_MSG_SZ 0x07
+#define ELE_READ_FUSE_REQ_MSG_SZ 0x03
+
+#define OTP_UNIQ_ID 0x01
+#define OTFAD_CONFIG 0x2
+
#define ELE_BASE_API_VERSION 0x6
int ele_get_info(struct device *dev, phys_addr_t addr, u32 data_size);
--
2.34.1
^ permalink raw reply related [flat|nested] 28+ messages in thread
* [PATCH v5 11/11] MAINTAINERS: Added maintainer details
2023-08-23 7:33 [PATCH v5 00/11] firmware: imx: NXP Secure-Enclave FW Driver Pankaj Gupta
` (9 preceding siblings ...)
2023-08-23 7:33 ` [PATCH v5 10/11] firmware: imx: enclave api to read-common-fuses Pankaj Gupta
@ 2023-08-23 7:33 ` Pankaj Gupta
10 siblings, 0 replies; 28+ messages in thread
From: Pankaj Gupta @ 2023-08-23 7:33 UTC (permalink / raw)
To: shawnguo, s.hauer, kernel, clin, conor+dt, pierre.gondois,
ping.bai, xiaoning.wang, wei.fang, peng.fan, haibo.chen, festevam,
linux-imx, davem, robh+dt, krzysztof.kozlowski+dt,
linux-arm-kernel, devicetree, linux-kernel, gaurav.jain,
alexander.stein, sahil.malhotra, aisheng.dong, V.Sethi
Cc: Pankaj Gupta
MAINTAINERS: Added maintainer details for se-fw driver.
Signed-off-by: Pankaj Gupta <pankaj.gupta@nxp.com>
---
MAINTAINERS | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/MAINTAINERS b/MAINTAINERS
index 3be1bdfe8ecc..654c1628417d 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -13620,6 +13620,16 @@ F: mm/
F: tools/mm/
F: tools/testing/selftests/mm/
+NXP EDGELOCK(SECURE) ENCLAVE FIRMWARE DRIVER
+M: Pankaj Gupta <pankaj.gupta@nxp.com>
+R: NXP Linux Team <linux-imx@nxp.com>
+L: linux-kernel@vger.kernel.org
+S: Maintained
+F: Documentation/devicetree/bindings/arm/freescale/fsl,se-fw.yaml
+F: drivers/firmware/imx/ele*.*
+F: drivers/firmware/imx/se*.*
+F: include/linux/firmware/imx/ele*.*
+
MEMORY TECHNOLOGY DEVICES (MTD)
M: Miquel Raynal <miquel.raynal@bootlin.com>
M: Richard Weinberger <richard@nod.at>
--
2.34.1
^ permalink raw reply related [flat|nested] 28+ messages in thread
* Re: [PATCH v5 01/11] dt-bindings: arm: fsl: add imx-se-fw binding doc
2023-08-23 7:33 ` [PATCH v5 01/11] dt-bindings: arm: fsl: add imx-se-fw binding doc Pankaj Gupta
@ 2023-08-23 8:28 ` Rob Herring
2023-08-23 10:42 ` [EXT] " Pankaj Gupta
2023-08-23 12:43 ` Rob Herring
1 sibling, 1 reply; 28+ messages in thread
From: Rob Herring @ 2023-08-23 8:28 UTC (permalink / raw)
To: Pankaj Gupta
Cc: linux-arm-kernel, haibo.chen, festevam, peng.fan, conor+dt,
V.Sethi, sahil.malhotra, shawnguo, s.hauer, clin, gaurav.jain,
linux-imx, robh+dt, ping.bai, krzysztof.kozlowski+dt,
aisheng.dong, xiaoning.wang, devicetree, davem, wei.fang,
alexander.stein, pierre.gondois, linux-kernel, kernel
On Wed, 23 Aug 2023 13:03:20 +0530, Pankaj Gupta wrote:
> The NXP's i.MX EdgeLock Enclave, a HW IP creating an embedded
> secure enclave within the SoC boundary to enable features like
> - HSM
> - SHE
> - V2X
>
> Communicates via message unit with linux kernel. This driver
> is enables communication ensuring well defined message sequence
> protocol between Application Core and enclave's firmware.
>
> Driver configures multiple misc-device on the MU, for multiple
> user-space applications can communicate on single MU.
>
> It exists on some i.MX processors. e.g. i.MX8ULP, i.MX93 etc.
>
> Signed-off-by: Pankaj Gupta <pankaj.gupta@nxp.com>
> ---
> .../bindings/firmware/fsl,imx-se-fw.yaml | 121 ++++++++++++++++++
> 1 file changed, 121 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/firmware/fsl,imx-se-fw.yaml
>
My bot found errors running 'make DT_CHECKER_FLAGS=-m dt_binding_check'
on your patch (DT_CHECKER_FLAGS is new in v5.13):
yamllint warnings/errors:
dtschema/dtc warnings/errors:
/builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/firmware/fsl,imx-se-fw.example.dtb: se-fw: 'mu-id' is a required property
from schema $id: http://devicetree.org/schemas/firmware/fsl,imx-se-fw.yaml#
/builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/firmware/fsl,imx-se-fw.example.dtb: se-fw: 'fsl,mu-id' does not match any of the regexes: 'pinctrl-[0-9]+'
from schema $id: http://devicetree.org/schemas/firmware/fsl,imx-se-fw.yaml#
doc reference errors (make refcheckdocs):
See https://patchwork.ozlabs.org/project/devicetree-bindings/patch/20230823073330.1712721-2-pankaj.gupta@nxp.com
The base for the series is generally the latest rc1. A different dependency
should be noted in *this* patch.
If you already ran 'make dt_binding_check' and didn't see the above
error(s), then make sure 'yamllint' is installed and dt-schema is up to
date:
pip3 install dtschema --upgrade
Please check and re-submit after running the above command yourself. Note
that DT_SCHEMA_FILES can be set to your schema file to speed up checking
your schema. However, it must be unset to test all examples with your schema.
^ permalink raw reply [flat|nested] 28+ messages in thread
* RE: [EXT] Re: [PATCH v5 01/11] dt-bindings: arm: fsl: add imx-se-fw binding doc
2023-08-23 8:28 ` Rob Herring
@ 2023-08-23 10:42 ` Pankaj Gupta
0 siblings, 0 replies; 28+ messages in thread
From: Pankaj Gupta @ 2023-08-23 10:42 UTC (permalink / raw)
To: Rob Herring
Cc: linux-arm-kernel@lists.infradead.org, Bough Chen,
festevam@gmail.com, Peng Fan, conor+dt@kernel.org, Varun Sethi,
Sahil Malhotra, shawnguo@kernel.org, s.hauer@pengutronix.de,
clin@suse.com, Gaurav Jain, dl-linux-imx, robh+dt@kernel.org,
Jacky Bai, krzysztof.kozlowski+dt@linaro.org, Aisheng Dong,
Clark Wang, devicetree@vger.kernel.org, davem@davemloft.net,
Wei Fang, alexander.stein@ew.tq-group.com, pierre.gondois@arm.com,
linux-kernel@vger.kernel.org, kernel@pengutronix.de
> -----Original Message-----
> From: Rob Herring <robh@kernel.org>
> Sent: Wednesday, August 23, 2023 1:59 PM
> To: Pankaj Gupta <pankaj.gupta@nxp.com>
> Cc: linux-arm-kernel@lists.infradead.org; Bough Chen
> <haibo.chen@nxp.com>; festevam@gmail.com; Peng Fan
> <peng.fan@nxp.com>; conor+dt@kernel.org; Varun Sethi
> <V.Sethi@nxp.com>; Sahil Malhotra <sahil.malhotra@nxp.com>;
> shawnguo@kernel.org; s.hauer@pengutronix.de; clin@suse.com; Gaurav Jain
> <gaurav.jain@nxp.com>; dl-linux-imx <linux-imx@nxp.com>;
> robh+dt@kernel.org; Jacky Bai <ping.bai@nxp.com>;
> krzysztof.kozlowski+dt@linaro.org; Aisheng Dong <aisheng.dong@nxp.com>;
> Clark Wang <xiaoning.wang@nxp.com>; devicetree@vger.kernel.org;
> davem@davemloft.net; Wei Fang <wei.fang@nxp.com>;
> alexander.stein@ew.tq-group.com; pierre.gondois@arm.com; linux-
> kernel@vger.kernel.org; kernel@pengutronix.de
> Subject: [EXT] Re: [PATCH v5 01/11] dt-bindings: arm: fsl: add imx-se-fw
> binding doc
>
> Caution: This is an external email. Please take care when clicking links or
> opening attachments. When in doubt, report the message using the 'Report
> this email' button
>
>
> On Wed, 23 Aug 2023 13:03:20 +0530, Pankaj Gupta wrote:
> > The NXP's i.MX EdgeLock Enclave, a HW IP creating an embedded secure
> > enclave within the SoC boundary to enable features like
> > - HSM
> > - SHE
> > - V2X
> >
> > Communicates via message unit with linux kernel. This driver is
> > enables communication ensuring well defined message sequence protocol
> > between Application Core and enclave's firmware.
> >
> > Driver configures multiple misc-device on the MU, for multiple
> > user-space applications can communicate on single MU.
> >
> > It exists on some i.MX processors. e.g. i.MX8ULP, i.MX93 etc.
> >
> > Signed-off-by: Pankaj Gupta <pankaj.gupta@nxp.com>
> > ---
> > .../bindings/firmware/fsl,imx-se-fw.yaml | 121 ++++++++++++++++++
> > 1 file changed, 121 insertions(+)
> > create mode 100644
> > Documentation/devicetree/bindings/firmware/fsl,imx-se-fw.yaml
> >
>
> My bot found errors running 'make DT_CHECKER_FLAGS=-m
> dt_binding_check'
> on your patch (DT_CHECKER_FLAGS is new in v5.13):
>
> yamllint warnings/errors:
>
> dtschema/dtc warnings/errors:
> /builds/robherring/dt-review-
> ci/linux/Documentation/devicetree/bindings/firmware/fsl,imx-se-
> fw.example.dtb: se-fw: 'mu-id' is a required property
> from schema $id:
> https://eur01.safelinks.protection.outlook.com/?url=http%3A%2F%2Fdevicetr
> ee.org%2Fschemas%2Ffirmware%2Ffsl%2Cimx-se-
> fw.yaml%23&data=05%7C01%7Cpankaj.gupta%40nxp.com%7C7e28c89d24c6
> 4b9c000108dba3b2f2d0%7C686ea1d3bc2b4c6fa92cd99c5c301635%7C0%7
> C0%7C638283761210875688%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4
> wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000%7C
> %7C%7C&sdata=SFldwBvByjOkEf%2FlzBmMJ3oZI9cBdWJe1ZmSh2AsflA%3D&r
> eserved=0
> /builds/robherring/dt-review-
> ci/linux/Documentation/devicetree/bindings/firmware/fsl,imx-se-
> fw.example.dtb: se-fw: 'fsl,mu-id' does not match any of the regexes: 'pinctrl-
> [0-9]+'
> from schema $id:
> https://eur01.safelinks.protection.outlook.com/?url=http%3A%2F%2Fdevicetr
> ee.org%2Fschemas%2Ffirmware%2Ffsl%2Cimx-se-
> fw.yaml%23&data=05%7C01%7Cpankaj.gupta%40nxp.com%7C7e28c89d24c6
> 4b9c000108dba3b2f2d0%7C686ea1d3bc2b4c6fa92cd99c5c301635%7C0%7
> C0%7C638283761210875688%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4
> wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000%7C
> %7C%7C&sdata=SFldwBvByjOkEf%2FlzBmMJ3oZI9cBdWJe1ZmSh2AsflA%3D&r
> eserved=0
>
> doc reference errors (make refcheckdocs):
>
> See
> https://eur01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fpatchw
> ork.ozlabs.org%2Fproject%2Fdevicetree-
> bindings%2Fpatch%2F20230823073330.1712721-2-
> pankaj.gupta%40nxp.com&data=05%7C01%7Cpankaj.gupta%40nxp.com%7C7
> e28c89d24c64b9c000108dba3b2f2d0%7C686ea1d3bc2b4c6fa92cd99c5c30
> 1635%7C0%7C0%7C638283761210875688%7CUnknown%7CTWFpbGZsb3d8
> eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D
> %7C3000%7C%7C%7C&sdata=afDClssaony%2B7aLwRX8VWJ1QyPrfZJJnEOcyU
> LYxR4g%3D&reserved=0
>
> The base for the series is generally the latest rc1. A different dependency
> should be noted in *this* patch.
>
> If you already ran 'make dt_binding_check' and didn't see the above error(s),
> then make sure 'yamllint' is installed and dt-schema is up to
> date:
>
> pip3 install dtschema --upgrade
>
> Please check and re-submit after running the above command yourself. Note
> that DT_SCHEMA_FILES can be set to your schema file to speed up checking
> your schema. However, it must be unset to test all examples with your schema.
Accepted.
Re-submitting the patch V6 by end of this, after fixing it.
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH v5 01/11] dt-bindings: arm: fsl: add imx-se-fw binding doc
2023-08-23 7:33 ` [PATCH v5 01/11] dt-bindings: arm: fsl: add imx-se-fw binding doc Pankaj Gupta
2023-08-23 8:28 ` Rob Herring
@ 2023-08-23 12:43 ` Rob Herring
2023-08-24 18:45 ` Krzysztof Kozlowski
1 sibling, 1 reply; 28+ messages in thread
From: Rob Herring @ 2023-08-23 12:43 UTC (permalink / raw)
To: Pankaj Gupta
Cc: shawnguo, s.hauer, kernel, clin, conor+dt, pierre.gondois,
ping.bai, xiaoning.wang, wei.fang, peng.fan, haibo.chen, festevam,
linux-imx, davem, krzysztof.kozlowski+dt, linux-arm-kernel,
devicetree, linux-kernel, gaurav.jain, alexander.stein,
sahil.malhotra, aisheng.dong, V.Sethi
On Wed, Aug 23, 2023 at 01:03:20PM +0530, Pankaj Gupta wrote:
> The NXP's i.MX EdgeLock Enclave, a HW IP creating an embedded
> secure enclave within the SoC boundary to enable features like
> - HSM
> - SHE
> - V2X
>
> Communicates via message unit with linux kernel. This driver
> is enables communication ensuring well defined message sequence
> protocol between Application Core and enclave's firmware.
>
> Driver configures multiple misc-device on the MU, for multiple
> user-space applications can communicate on single MU.
>
> It exists on some i.MX processors. e.g. i.MX8ULP, i.MX93 etc.
>
> Signed-off-by: Pankaj Gupta <pankaj.gupta@nxp.com>
> ---
v5? Where's the changelog for *this* patch?
> .../bindings/firmware/fsl,imx-se-fw.yaml | 121 ++++++++++++++++++
> 1 file changed, 121 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/firmware/fsl,imx-se-fw.yaml
>
> diff --git a/Documentation/devicetree/bindings/firmware/fsl,imx-se-fw.yaml b/Documentation/devicetree/bindings/firmware/fsl,imx-se-fw.yaml
> new file mode 100644
> index 000000000000..f7230f93e56d
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/firmware/fsl,imx-se-fw.yaml
> @@ -0,0 +1,121 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/firmware/fsl,imx-se-fw.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: NXP i.MX EdgeLock Enclave Firmware (ELEFW)
> +
> +maintainers:
> + - Pankaj Gupta <pankaj.gupta@nxp.com>
> +
> +description:
> + The NXP's i.MX EdgeLock Enclave, a HW IP creating an embedded
> + secure enclave within the SoC boundary to enable features like
> + - HSM
> + - SHE
> + - V2X
> +
> + It uses message unit to communicate and coordinate to pass messages
> + (e.g., data, status and control) through its interfaces.
> +
> + This driver configures multiple misc-devices on the MU, to exchange
> + messages from User-space application and NXP's Edgelocke Enclave firmware.
> + The driver ensures that the messages must follow the following protocol
> + defined.
> +
> + Non-Secure + Secure
> + |
> + |
> + +---------+ +-------------+ |
> + | ele_mu.c+<---->+imx-mailbox.c| |
> + | | | mailbox.c +<-->+------+ +------+
> + +---+-----+ +-------------+ | MU X +<-->+ ELE |
> + | +------+ +------+
> + +----------------+ |
> + | | |
> + v v |
> + logical logical |
> + receiver waiter |
> + + + |
> + | | |
> + | | |
> + | +----+------+ |
> + | | | |
> + | | | |
> + device_ctx device_ctx device_ctx |
> + |
> + User 0 User 1 User Y |
> + +------+ +------+ +------+ |
> + |misc.c| |misc.c| |misc.c| |
> + kernel space +------+ +------+ +------+ |
> + |
> + +------------------------------------------------------ |
> + | | | |
> + userspace /dev/ele_muXch0 | | |
> + /dev/ele_muXch1 | |
> + /dev/ele_muXchY |
> + |
> +
> + When a user sends a command to the firmware, it registers its device_ctx
> + as waiter of a response from firmware.
> +
> + A user can be registered as receiver of command from the ELE.
> + Create char devices in /dev as channels of the form /dev/ele_muXchY with X
> + the id of the driver and Y for each users. It allows to send and receive
> + messages to the NXP EdgeLock Enclave IP firmware on NXP SoC, where current
> + possible value, i.e., supported SoC(s) are imx8ulp, imx93.
Looks like a bunch of Linux details which don't belong in the binding.
Why do you need your own custom interface to userspace? No one else has
a similar feature in their platforms? Something like virtio or rpmsg
doesn't work?
> +
> +properties:
> + compatible:
> + enum:
> + - fsl,imx8ulp-se-fw
> + - fsl,imx93-se-fw
> +
> + mboxes:
> + description:
> + All MU channels must be within the same MU instance. Cross instances are
> + not allowed. Users need to ensure that used MU instance does not conflict
> + with other execution environments.
> + items:
> + - description: TX0 MU channel
> + - description: RX0 MU channel
> +
> + mbox-names:
> + items:
> + - const: tx
> + - const: rx
> +
> + fsl,mu-did:
> + $ref: /schemas/types.yaml#/definitions/uint32
> + description:
> + By design, Domain is a clean separated processing island with separate power,
> + clocking and peripheral; but with a tightly integrated bus fabric for efficient
> + communication. The Domain to which this message-unit is associated, is identified
> + via Domain ID or did.
> +
> + sram-pool:
I believe 'sram' is the somewhat standard property to refer to an SRAM
region.
> + items:
> + - description: SRAM memory instance.
Used for what?
> +
> + memory-region:
> + items:
> + - description: Reserved memory region that can be accessed by firmware. Used for
> + exchanging the buffers between driver and firmware.
> +
> +required:
> + - compatible
> + - mboxes
> + - mbox-names
> + - mu-id
> +
> +additionalProperties: false
> +
> +examples:
> + - |
> + ele_fw: se-fw {
> + compatible = "fsl,imx8ulp-se-fw";
> + mbox-names = "tx", "rx";
> + mboxes = <&s4muap 0 0>, <&s4muap 1 0>;
> + fsl,mu-id = <2>;
> + };
> --
> 2.34.1
>
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH v5 08/11] firmware: imx: enable trng
2023-08-23 7:33 ` [PATCH v5 08/11] firmware: imx: enable trng Pankaj Gupta
@ 2023-08-24 18:23 ` Krzysztof Kozlowski
0 siblings, 0 replies; 28+ messages in thread
From: Krzysztof Kozlowski @ 2023-08-24 18:23 UTC (permalink / raw)
To: Pankaj Gupta, shawnguo, s.hauer, kernel, clin, conor+dt,
pierre.gondois, ping.bai, xiaoning.wang, wei.fang, peng.fan,
haibo.chen, festevam, linux-imx, davem, robh+dt,
krzysztof.kozlowski+dt, linux-arm-kernel, devicetree,
linux-kernel, gaurav.jain, alexander.stein, sahil.malhotra,
aisheng.dong, V.Sethi
On 23/08/2023 09:33, Pankaj Gupta wrote:
> Enabled trng on imx93 platform through enclave fw.
>
> Signed-off-by: Gaurav Jain <gaurav.jain@nxp.com>
> Signed-off-by: Pankaj Gupta <pankaj.gupta@nxp.com>
> ---
> drivers/firmware/imx/Kconfig | 9 +++
> drivers/firmware/imx/Makefile | 3 +-
> drivers/firmware/imx/ele_base_msg.c | 88 +++++++++++++++++++++++
> drivers/firmware/imx/ele_common.c | 44 +++++++++++-
> drivers/firmware/imx/ele_common.h | 2 +
> drivers/firmware/imx/ele_fw_api.c | 54 ++++++++++++++
> drivers/firmware/imx/ele_trng.c | 48 +++++++++++++
> drivers/firmware/imx/se_fw.c | 23 +++++-
> include/linux/firmware/imx/ele_base_msg.h | 11 +++
> include/linux/firmware/imx/ele_fw_api.h | 5 ++
> 10 files changed, 283 insertions(+), 4 deletions(-)
> create mode 100644 drivers/firmware/imx/ele_trng.c
>
firmware is not a place for RNG driver. You did not even CC RNG folks...
> +
> +int ele_trng_init(struct device *dev)
> +{
> + struct ele_trng *trng;
> + int ret;
> +
> + trng = devm_kzalloc(dev, sizeof(*trng), GFP_KERNEL);
> + if (!trng)
> + return -ENOMEM;
> +
> + trng->dev = dev;
> + trng->rng.name = "ele-trng";
> + trng->rng.read = ele_get_hwrng;
> + trng->rng.priv = (unsigned long)trng;
> + trng->rng.quality = 1024;
> +
> + dev_dbg(dev, "registering ele-trng\n");
> +
> + ret = devm_hwrng_register(dev, &trng->rng);
> + if (ret)
> + return ret;
> +
> + dev_info(dev, "Successfully registered ele-trng\n");
Drop all simple trace replacements. Use tracing.
> + return 0;
> +}
> +
> +int ele_get_hwrng(struct hwrng *rng,
> + void *data, size_t len, bool wait)
> +{
> + struct ele_trng *trng = (struct ele_trng *)rng->priv;
> +
> + return ele_get_random(trng->dev, data, len);
> +}
> diff --git a/drivers/firmware/imx/se_fw.c b/drivers/firmware/imx/se_fw.c
> index 88300c41d62b..6083c42dcda3 100644
> --- a/drivers/firmware/imx/se_fw.c
> +++ b/drivers/firmware/imx/se_fw.c
> @@ -21,10 +21,10 @@
> #include <linux/of_reserved_mem.h>
> #include <linux/platform_device.h>
> #include <linux/slab.h>
> -#include <linux/delay.h>
> #include <linux/sys_soc.h>
>
> #include "se_fw.h"
> +#include "ele_common.h"
>
> #define SOC_ID_OF_IMX8ULP 0x084D
> #define SOC_ID_OF_IMX93 0x9300
> @@ -43,6 +43,9 @@ struct imx_info {
> uint8_t *pool_name;
> bool reserved_dma_ranges;
> bool init_fw;
> + /* platform specific flag to enable/disable the ELE True RNG */
> + bool start_rng;
> + bool enable_ele_trng;
> };
>
> static LIST_HEAD(priv_data_list);
> @@ -58,6 +61,8 @@ static const struct imx_info imx8ulp_info = {
> .pool_name = "sram-pool",
> .reserved_dma_ranges = true,
> .init_fw = false,
> + .start_rng = true,
> + .enable_ele_trng = false,
> };
>
> static const struct imx_info imx93_info = {
> @@ -71,6 +76,8 @@ static const struct imx_info imx93_info = {
> .pool_name = NULL,
> .reserved_dma_ranges = true,
> .init_fw = true,
> + .start_rng = true,
> + .enable_ele_trng = true,
> };
>
> static const struct of_device_id se_fw_match[] = {
> @@ -1140,9 +1147,23 @@ static int se_fw_probe(struct platform_device *pdev)
> }
> }
>
> + /* start ele rng */
> + if (info->start_rng) {
> + ret = ele_do_start_rng(dev);
> + if (ret)
> + dev_err(dev, "Failed to start ele rng\n");
> + }
> +
> + if (!ret && info->enable_ele_trng) {
> + ret = ele_trng_init(dev);
> + if (ret)
> + dev_err(dev, "Failed to init ele-trng\n");
> + }
> +
> pr_info("i.MX secure-enclave: %s's mu#%d interface to firmware, configured.\n",
dev_info
> info->se_name,
> priv->ele_mu_id);
> +
Not related.
> return devm_of_platform_populate(dev);
>
Best regards,
Krzysztof
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH v5 06/11] firmware: imx: add driver for NXP EdgeLock Enclave
2023-08-23 7:33 ` [PATCH v5 06/11] firmware: imx: add driver for NXP EdgeLock Enclave Pankaj Gupta
@ 2023-08-24 18:31 ` Krzysztof Kozlowski
2023-08-25 10:22 ` Stefan Wahren
1 sibling, 0 replies; 28+ messages in thread
From: Krzysztof Kozlowski @ 2023-08-24 18:31 UTC (permalink / raw)
To: Pankaj Gupta, shawnguo, s.hauer, kernel, clin, conor+dt,
pierre.gondois, ping.bai, xiaoning.wang, wei.fang, peng.fan,
haibo.chen, festevam, linux-imx, davem, robh+dt,
krzysztof.kozlowski+dt, linux-arm-kernel, devicetree,
linux-kernel, gaurav.jain, alexander.stein, sahil.malhotra,
aisheng.dong, V.Sethi
Cc: kernel test robot
On 23/08/2023 09:33, Pankaj Gupta wrote:
> The Edgelock Enclave , is the secure enclave embedded in the SoC
> to support the features like HSM, SHE & V2X, using message based
> communication channel.
>
> ELE FW communicates on a dedicated MU with application core where
> kernel is running. It exists on specific i.MX processors. e.g.
> i.MX8ULP, i.MX93.
>
> Reported-by: kernel test robot <lkp@intel.com>
Wrong tag. Bot did not report this driver.
> Closes:https://lore.kernel.org/oe-kbuild-all/202304120902.bP52A56z-lkp@intel.com
Drop.
> Signed-off-by: Pankaj Gupta <pankaj.gupta@nxp.com>
> ---
...
> +
> +static int se_fw_probe(struct platform_device *pdev)
> +{
> + struct ele_mu_device_ctx *dev_ctx;
> + struct device *dev = &pdev->dev;
> + struct ele_mu_priv *priv;
> + const struct of_device_id *of_id = of_match_device(se_fw_match, dev);
> + struct imx_info *info = NULL;
> + char *devname;
> + int ret;
> + int i;
> + struct device_node *np;
> +
> + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
> + if (!priv) {
> + ret = -ENOMEM;
> + dev_err(dev, "Fail allocate mem for private data\n");
> + return ret;
No, really, I asked to clean this driver from such crap. It is crap
because automated tools point it. It's a requirement to run them, which
you did not.
You must run coccicheck, smatch, sparse, W=1 builds and several build
tests. All of them must pass without single warning.
> + }
> + memset(priv, 0x0, sizeof(*priv));
> + priv->dev = dev;
> + dev_set_drvdata(dev, priv);
> +
> + /*
> + * Get the address of MU.
> + */
> + np = pdev->dev.of_node;
> + if (!np) {
> + dev_err(dev, "Cannot find MU User entry in device tree\n");
> + ret = -EOPNOTSUPP;
> + goto exit;
> + }
> +
> + /* Initialize the mutex. */
> + mutex_init(&priv->mu_cmd_lock);
> + mutex_init(&priv->mu_lock);
> +
> + priv->cmd_receiver_dev = NULL;
> + priv->waiting_rsp_dev = NULL;
> +
> + /* Mailbox client configuration */
> + priv->ele_mb_cl.dev = dev;
> + priv->ele_mb_cl.tx_block = false;
> + priv->ele_mb_cl.knows_txdone = true;
> + priv->ele_mb_cl.rx_callback = ele_mu_rx_callback;
> +
> + ret = ele_mu_request_channel(dev, &priv->tx_chan,
> + &priv->ele_mb_cl, "tx");
> + if (ret) {
> + if (ret != -EPROBE_DEFER)
> + dev_err(dev, "Failed to request tx channel\n");
> +
> + goto exit;
> + }
> +
> + ret = ele_mu_request_channel(dev, &priv->rx_chan,
> + &priv->ele_mb_cl, "rx");
> + if (ret) {
> + if (ret != -EPROBE_DEFER)
> + dev_err(dev, "Failed to request rx channel\n");
> +
> + goto exit;
> + }
> +
> + ret = of_property_read_u32(np, "fsl,mu-id", &priv->ele_mu_id);
> + if (ret) {
> + ret = -EINVAL;
> + dev_err(dev, "Not able to read mu-id.\n");
> + goto exit;
> + }
> +
> + info = (struct imx_info *)of_id->data;
> + priv->ele_mu_did = info->mu_did;
> + priv->max_dev_ctx = info->max_dev_ctx;
> + priv->cmd_tag = info->cmd_tag;
> + priv->rsp_tag = info->rsp_tag;
> + priv->success_tag = info->success_tag;
> +
> + priv->ctxs = devm_kzalloc(dev, sizeof(dev_ctx) * priv->max_dev_ctx,
> + GFP_KERNEL);
> +
> + if (!priv->ctxs) {
> + ret = -ENOMEM;
> + dev_err(dev, "Fail allocate mem for private dev-ctxs.\n");
> + goto exit;
> + }
> +
> + /* Create users */
> + for (i = 0; i < priv->max_dev_ctx; i++) {
> + dev_ctx = devm_kzalloc(dev, sizeof(*dev_ctx), GFP_KERNEL);
> + if (!dev_ctx) {
> + ret = -ENOMEM;
> + dev_err(dev,
> + "Fail to allocate memory for device context\n");
> + goto exit;
> + }
> +
> + dev_ctx->dev = dev;
> + dev_ctx->status = MU_FREE;
> + dev_ctx->priv = priv;
> +
> + priv->ctxs[i] = dev_ctx;
> +
> + /* Default value invalid for an header. */
> + init_waitqueue_head(&dev_ctx->wq);
> +
> + INIT_LIST_HEAD(&dev_ctx->pending_out);
> + INIT_LIST_HEAD(&dev_ctx->pending_in);
> + sema_init(&dev_ctx->fops_lock, 1);
> +
> + devname = devm_kasprintf(dev, GFP_KERNEL, "%s_mu%d_ch%d",
> + info->se_name,
> + priv->ele_mu_id, i);
> + if (!devname) {
> + ret = -ENOMEM;
> + dev_err(dev,
> + "Fail to allocate memory for misc dev name\n");
> + goto exit;
> + }
> +
> + dev_ctx->miscdev.name = devname;
> + dev_ctx->miscdev.minor = MISC_DYNAMIC_MINOR;
> + dev_ctx->miscdev.fops = &ele_mu_fops;
> + dev_ctx->miscdev.parent = dev;
> + ret = misc_register(&dev_ctx->miscdev);
> + if (ret) {
> + dev_err(dev, "failed to register misc device %d\n",
> + ret);
> + goto exit;
> + }
> +
> + ret = devm_add_action(dev, if_misc_deregister,
> + &dev_ctx->miscdev);
> + if (ret) {
> + dev_err(dev,
> + "failed[%d] to add action to the misc-dev\n",
> + ret);
> + goto exit;
> + }
> + }
> +
> + init_completion(&priv->done);
> + spin_lock_init(&priv->lock);
> +
> + list_add_tail(&priv->priv_data, &priv_data_list);
> + dev_set_drvdata(dev, priv);
> +
> + if (info->reserved_dma_ranges) {
> + ret = of_reserved_mem_device_init(dev);
> + if (ret) {
> + dev_err(dev,
> + "failed to init reserved memory region %d\n",
> + ret);
> + priv->flags &= (~RESERVED_DMA_POOL);
> + goto exit;
> + }
> + priv->flags |= RESERVED_DMA_POOL;
> + }
> +
> + if (info->socdev) {
> + ret = imx_soc_device_register(dev, info);
> + if (ret) {
> + dev_err(dev,
> + "failed[%d] to register SoC device\n", ret);
> + goto exit;
> + }
> + }
> +
> + pr_info("i.MX secure-enclave: %s's mu#%d interface to firmware, configured.\n",
dev_info
> + info->se_name,
> + priv->ele_mu_id);
> + return devm_of_platform_populate(dev);
> +
> +exit:
> + /* if execution control reaches here, ele-mu probe fail.
> + * hence doing the cleanup
> + */
> + return se_probe_cleanup(pdev);
> +}
> +
> +struct device *get_se_dev(uint32_t mu_id)
> +{
> + struct ele_mu_priv *priv;
> +
> + list_for_each_entry(priv, &priv_data_list, priv_data) {
> + if (priv->ele_mu_id == mu_id)
> + return priv->dev;
> + }
> +
> + return NULL;
> +}
> +EXPORT_SYMBOL(get_se_dev);
Uhu, that's GPL. Anyway, this needs to be documented.
> +
> +static int se_fw_remove(struct platform_device *pdev)
> +{
> + se_probe_cleanup(pdev);
> +
> + return 0;
> +}
> +
> +#ifdef CONFIG_PM_SLEEP
> +static int se_fw_suspend(struct device *dev)
> +{
> + return 0;
> +}
> +
> +static int se_fw_resume(struct device *dev)
> +{
> + struct ele_mu_priv *priv = dev_get_drvdata(dev);
> + int i;
> +
> + for (i = 0; i < priv->max_dev_ctx; i++)
> + wake_up_interruptible(&priv->ctxs[i]->wq);
> +
> + return 0;
> +}
> +#endif
> +
> +static const struct dev_pm_ops se_fw_pm = {
> + SET_SYSTEM_SLEEP_PM_OPS(se_fw_suspend, se_fw_resume)
> +};
> +
> +static struct platform_driver se_fw_driver = {
> + .driver = {
> + .name = "fsl-se-fw",
> + .of_match_table = se_fw_match,
> + .pm = &se_fw_pm,
> + },
> + .probe = se_fw_probe,
> + .remove = se_fw_remove,
> +};
> +MODULE_DEVICE_TABLE(of, se_fw_match);
> +
> +module_platform_driver(se_fw_driver);
> +
> +MODULE_AUTHOR("Pankaj Gupta <pankaj.gupta@nxp.com>");
> +MODULE_DESCRIPTION("iMX Secure Enclave FW Driver.");
> +MODULE_LICENSE("GPL v2");
> diff --git a/drivers/firmware/imx/se_fw.h b/drivers/firmware/imx/se_fw.h
> new file mode 100644
> index 000000000000..b3502affbc85
> --- /dev/null
> +++ b/drivers/firmware/imx/se_fw.h
> @@ -0,0 +1,168 @@
> +/* SPDX-License-Identifier: GPL-2.0+ */
> +/*
> + * Copyright 2021-2023 NXP
> + */
> +
> +#ifndef SE_MU_H
> +#define SE_MU_H
> +
> +#include <linux/miscdevice.h>
> +#include <linux/semaphore.h>
> +#include <linux/mailbox_client.h>
> +
> +/* macro to log operation of a misc device */
> +#define miscdev_dbg(p_miscdev, fmt, va_args...) \
No, drop. Don't create your own abstraction layers over common Linux code.
> + ({ \
> + struct miscdevice *_p_miscdev = p_miscdev; \
> + dev_dbg((_p_miscdev)->parent, "%s: " fmt, (_p_miscdev)->name, \
> + ##va_args); \
> + })
> +
> +#define miscdev_info(p_miscdev, fmt, va_args...) \
No, drop.
> + ({ \
> + struct miscdevice *_p_miscdev = p_miscdev; \
> + dev_info((_p_miscdev)->parent, "%s: " fmt, (_p_miscdev)->name, \
> + ##va_args); \
> + })
> +
> +#define miscdev_err(p_miscdev, fmt, va_args...) \
No, drop.
> + ({ \
> + struct miscdevice *_p_miscdev = p_miscdev; \
> + dev_err((_p_miscdev)->parent, "%s: " fmt, (_p_miscdev)->name, \
> + ##va_args); \
> + })
> +/* macro to log operation of a device context */
> +#define devctx_dbg(p_devctx, fmt, va_args...) \
> + miscdev_dbg(&((p_devctx)->miscdev), fmt, ##va_args)
> +#define devctx_info(p_devctx, fmt, va_args...) \
> + miscdev_info(&((p_devctx)->miscdev), fmt, ##va_args)
> +#define devctx_err(p_devctx, fmt, va_args...) \
> + miscdev_err((&(p_devctx)->miscdev), fmt, ##va_args)
No, drop all these.
> +
> +#define MAX_MESSAGE_SIZE 31
> +#define MAX_RECV_SIZE MAX_MESSAGE_SIZE
> +#define MAX_RECV_SIZE_BYTES (MAX_RECV_SIZE << 2)
> +#define MAX_MESSAGE_SIZE_BYTES (MAX_MESSAGE_SIZE << 2)
> +
> +#define ELE_MSG_DATA_NUM 10
> +
> +#define MSG_TAG(x) (((x) & 0xff000000) >> 24)
> +#define MSG_COMMAND(x) (((x) & 0x00ff0000) >> 16)
> +#define MSG_SIZE(x) (((x) & 0x0000ff00) >> 8)
> +#define MSG_VER(x) ((x) & 0x000000ff)
> +#define RES_STATUS(x) ((x) & 0x000000ff)
> +#define MAX_DATA_SIZE_PER_USER (65 * 1024)
> +#define S4_DEFAULT_MUAP_INDEX (2)
> +#define S4_MUAP_DEFAULT_MAX_USERS (4)
> +
> +#define DEFAULT_MESSAGING_TAG_COMMAND (0x17u)
> +#define DEFAULT_MESSAGING_TAG_RESPONSE (0xe1u)
> +
> +#define ELE_MU_IO_FLAGS_USE_SEC_MEM (0x02u)
> +#define ELE_MU_IO_FLAGS_USE_SHORT_ADDR (0x04u)
> +
> +struct ele_imem_buf {
> + u8 *buf;
> + phys_addr_t phyaddr;
> + u32 size;
> +};
> +
> +struct ele_buf_desc {
> + u8 *shared_buf_ptr;
> + u8 *usr_buf_ptr;
> + u32 size;
> + struct list_head link;
> +};
> +
> +/* Status of a char device */
> +enum mu_device_status_t {
> + MU_FREE,
> + MU_OPENED
> +};
> +
> +struct ele_shared_mem {
> + dma_addr_t dma_addr;
> + u32 size;
> + u32 pos;
> + u8 *ptr;
> +};
> +
> +/* Private struct for each char device instance. */
> +struct ele_mu_device_ctx {
> + struct device *dev;
> + struct ele_mu_priv *priv;
> + struct miscdevice miscdev;
> +
> + enum mu_device_status_t status;
> + wait_queue_head_t wq;
> + struct semaphore fops_lock;
> +
> + u32 pending_hdr;
> + struct list_head pending_in;
> + struct list_head pending_out;
> +
> + struct ele_shared_mem secure_mem;
> + struct ele_shared_mem non_secure_mem;
> +
> + u32 temp_cmd[MAX_MESSAGE_SIZE];
> + u32 temp_resp[MAX_RECV_SIZE];
> + u32 temp_resp_size;
> + struct notifier_block ele_notify;
> +};
> +
> +/* Header of the messages exchange with the EdgeLock Enclave */
> +struct mu_hdr {
> + u8 ver;
> + u8 size;
> + u8 command;
> + u8 tag;
> +} __packed;
> +
> +#define ELE_MU_HDR_SZ 4
> +#define TAG_OFFSET (ELE_MU_HDR_SZ - 1)
> +#define CMD_OFFSET (ELE_MU_HDR_SZ - 2)
> +#define SZ_OFFSET (ELE_MU_HDR_SZ - 3)
> +#define VER_OFFSET (ELE_MU_HDR_SZ - 4)
> +
> +struct ele_api_msg {
> + u32 header; /* u8 Tag; u8 Command; u8 Size; u8 Ver; */
> + u32 data[ELE_MSG_DATA_NUM];
> +};
> +
> +struct ele_mu_priv {
> + struct list_head priv_data;
> + struct ele_mu_device_ctx *cmd_receiver_dev;
> + struct ele_mu_device_ctx *waiting_rsp_dev;
> + /*
> + * prevent parallel access to the MU registers
> + * e.g. a user trying to send a command while the other one is
> + * sending a response.
> + */
> + struct mutex mu_lock;
> + /*
> + * prevent a command to be sent on the MU while another one is still
> + * processing. (response to a command is allowed)
> + */
> + struct mutex mu_cmd_lock;
> + struct device *dev;
> + u8 ele_mu_did;
> + u32 ele_mu_id;
> + u8 cmd_tag;
> + u8 rsp_tag;
> + u8 success_tag;
> +
> + struct mbox_client ele_mb_cl;
> + struct mbox_chan *tx_chan, *rx_chan;
> + struct ele_api_msg tx_msg, rx_msg;
> + struct completion done;
> + spinlock_t lock;
> + /* Flag to retain the state of initialization done at
> + * the time of ele-mu probe.
> + */
> + uint32_t flags;
> + u8 max_dev_ctx;
> + struct ele_mu_device_ctx **ctxs;
> + struct ele_imem_buf imem;
> +};
> +
> +#endif
> diff --git a/include/linux/firmware/imx/ele_base_msg.h b/include/linux/firmware/imx/ele_base_msg.h
> new file mode 100644
> index 000000000000..9c05936ba813
> --- /dev/null
> +++ b/include/linux/firmware/imx/ele_base_msg.h
> @@ -0,0 +1,37 @@
> +/* SPDX-License-Identifier: GPL-2.0+ */
> +/*
> + * Copyright 2021-2023 NXP
> + *
> + * Header file for the ELE Base API(s).
> + */
> +
> +#ifndef ELE_BASE_MSG_H
> +#define ELE_BASE_MSG_H
> +
> +#include <linux/types.h>
> +
> +#define WORD_SZ 4
> +#define MESSAGING_VERSION_7 0x7
> +#define ELE_NONE_VAL 0x0
> +
> +#define ELE_GET_INFO_BUFF_SZ 0x100
> +#define ELE_GET_INFO_READ_SZ 0xA0
> +#define DEVICE_GET_INFO_SZ 0x100
> +
> +#define GET_INFO_SOC_INFO_WORD_OFFSET 1
> +#define GET_INFO_UUID_WORD_OFFSET 3
> +#define GET_INFO_SL_NUM_MSB_WORD_OFF \
> + (GET_INFO_UUID_WORD_OFFSET + 3)
> +#define GET_INFO_SL_NUM_LSB_WORD_OFF \
> + (GET_INFO_UUID_WORD_OFFSET + 0)
> +
> +#define ELE_GET_INFO_REQ 0xDA
> +#define ELE_GET_INFO_REQ_MSG_SZ 0x02
> +
> +#define ELE_BASE_API_VERSION 0x6
> +#define ELE_SUCCESS_IND 0xD6
> +#define ELE_FAILURE_IND 0x29
> +
> +int ele_get_info(struct device *dev, phys_addr_t addr, u32 data_size);
> +
> +#endif
> diff --git a/include/linux/firmware/imx/ele_mu_ioctl.h b/include/linux/firmware/imx/ele_mu_ioctl.h
> new file mode 100644
> index 000000000000..b0f00acddecc
> --- /dev/null
> +++ b/include/linux/firmware/imx/ele_mu_ioctl.h
> @@ -0,0 +1,52 @@
> +/* SPDX-License-Identifier: (GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause*/
> +/*
> + * Copyright 2019-2023 NXP
> + */
> +
> +#ifndef ELE_MU_IOCTL_H
> +#define ELE_MU_IOCTL_H
> +
> +/* IOCTL definitions. */
> +
> +struct ele_mu_ioctl_setup_iobuf {
> + u8 *user_buf;
> + u32 length;
> + u32 flags;
> + u64 ele_addr;
> +};
> +
> +struct ele_mu_ioctl_shared_mem_cfg {
> + u32 base_offset;
> + u32 size;
> +};
> +
> +struct ele_mu_ioctl_get_mu_info {
> + u8 ele_mu_id;
> + u8 interrupt_idx;
> + u8 tz;
> + u8 did;
> +};
> +
> +struct ele_mu_ioctl_signed_message {
> + u8 *message;
> + u32 msg_size;
> + u32 error_code;
> +};
> +
> +#define ELE_MU_IO_FLAGS_IS_OUTPUT (0x00u)
> +#define ELE_MU_IO_FLAGS_IS_INPUT (0x01u)
> +#define ELE_MU_IO_FLAGS_USE_SEC_MEM (0x02u)
> +#define ELE_MU_IO_FLAGS_USE_SHORT_ADDR (0x04u)
> +#define ELE_MU_IO_FLAGS_IS_IN_OUT (0x08u)
> +
> +#define ELE_MU_IOCTL 0x0A /* like MISC_MAJOR. */
> +#define ELE_MU_IOCTL_ENABLE_CMD_RCV _IO(ELE_MU_IOCTL, 0x01)
> +#define ELE_MU_IOCTL_SHARED_BUF_CFG _IOW(ELE_MU_IOCTL, 0x02, \
> + struct ele_mu_ioctl_shared_mem_cfg)
> +#define ELE_MU_IOCTL_SETUP_IOBUF _IOWR(ELE_MU_IOCTL, 0x03, \
> + struct ele_mu_ioctl_setup_iobuf)
> +#define ELE_MU_IOCTL_GET_MU_INFO _IOR(ELE_MU_IOCTL, 0x04, \
> + struct ele_mu_ioctl_get_mu_info)
> +#define ELE_MU_IOCTL_SIGNED_MESSAGE _IOWR(ELE_MU_IOCTL, 0x05, \
No documentation.
Plus you just created some completely vendor-specific interface for the
firmware. I don't think this is suitable for upstream. Find respective
existing interface and use it.
Your Cc list is absolutely huge, but these are NXP people, not community
folks. Please reverse it and include instead other maintainers, not 10
NXP people.
I'll be NAKing for these reasons till you fix it.
Best regards,
Krzysztof
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH v5 07/11] firmware: imx: init-fw api exchange on imx93
2023-08-23 7:33 ` [PATCH v5 07/11] firmware: imx: init-fw api exchange on imx93 Pankaj Gupta
@ 2023-08-24 18:35 ` Krzysztof Kozlowski
0 siblings, 0 replies; 28+ messages in thread
From: Krzysztof Kozlowski @ 2023-08-24 18:35 UTC (permalink / raw)
To: Pankaj Gupta, shawnguo, s.hauer, kernel, clin, conor+dt,
pierre.gondois, ping.bai, xiaoning.wang, wei.fang, peng.fan,
haibo.chen, festevam, linux-imx, davem, robh+dt,
krzysztof.kozlowski+dt, linux-arm-kernel, devicetree,
linux-kernel, gaurav.jain, alexander.stein, sahil.malhotra,
aisheng.dong, V.Sethi
On 23/08/2023 09:33, Pankaj Gupta wrote:
> On imx93 platforms, exchange init-fw message with enclave's firmware
> is to be done.
>
> Signed-off-by: Pankaj Gupta <pankaj.gupta@nxp.com>
> ---
> drivers/firmware/imx/Makefile | 2 +-
> drivers/firmware/imx/ele_fw_api.c | 56 +++++++++++++++++++++++++
> drivers/firmware/imx/se_fw.c | 11 +++++
> include/linux/firmware/imx/ele_fw_api.h | 19 +++++++++
> 4 files changed, 87 insertions(+), 1 deletion(-)
> create mode 100644 drivers/firmware/imx/ele_fw_api.c
> create mode 100644 include/linux/firmware/imx/ele_fw_api.h
>
> diff --git a/drivers/firmware/imx/Makefile b/drivers/firmware/imx/Makefile
> index eab3f03e2e5e..bc6ed5514a19 100644
> --- a/drivers/firmware/imx/Makefile
> +++ b/drivers/firmware/imx/Makefile
> @@ -2,5 +2,5 @@
> obj-$(CONFIG_IMX_DSP) += imx-dsp.o
> obj-$(CONFIG_IMX_SCU) += imx-scu.o misc.o imx-scu-irq.o rm.o imx-scu-soc.o
> obj-$(CONFIG_IMX_SCU_PD) += scu-pd.o
> -sec_enclave-objs = se_fw.o ele_common.o ele_base_msg.o
> +sec_enclave-objs = se_fw.o ele_common.o ele_base_msg.o ele_fw_api.o
> obj-${CONFIG_IMX_SEC_ENCLAVE} += sec_enclave.o
> diff --git a/drivers/firmware/imx/ele_fw_api.c b/drivers/firmware/imx/ele_fw_api.c
> new file mode 100644
> index 000000000000..1df1fbcb6d9e
> --- /dev/null
> +++ b/drivers/firmware/imx/ele_fw_api.c
> @@ -0,0 +1,56 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later
> +/*
> + * Copyright 2023 NXP
> + */
> +
> +#include <linux/dma-mapping.h>
> +#include <linux/firmware/imx/ele_fw_api.h>
> +
> +#include "ele_common.h"
> +
> +/* Fill a command message header with a given command ID and length in bytes. */
> +static int plat_fill_cmd_msg_hdr(struct ele_mu_priv *priv,
> + struct mu_hdr *hdr,
> + uint8_t cmd, uint32_t len)
> +{
> + int err = 0;
> +
> + hdr->tag = priv->cmd_tag;
> + hdr->ver = MESSAGING_VERSION_7;
> + hdr->command = cmd;
> + hdr->size = (uint8_t)(len / sizeof(uint32_t));
> +
> + return err;
> +}
> +
> +int ele_init_fw(struct device *dev)
> +{
> + struct ele_mu_priv *priv = dev_get_drvdata(dev);
> + int ret;
> + unsigned int tag, command, size, ver, status;
> +
> + ret = plat_fill_cmd_msg_hdr(priv,
> + (struct mu_hdr *)&priv->tx_msg.header,
> + ELE_INIT_FW_REQ, 4);
This is some weird code. Why do you store TX and RX messages in state
container? This should be local to the function.
> + if (ret)
> + return ret;
> +
> + ret = imx_ele_msg_send_rcv(priv);
> + if (ret < 0)
> + return ret;
> +
> + tag = MSG_TAG(priv->rx_msg.header);
> + command = MSG_COMMAND(priv->rx_msg.header);
> + size = MSG_SIZE(priv->rx_msg.header);
> + ver = MSG_VER(priv->rx_msg.header);
> + status = RES_STATUS(priv->rx_msg.data[0]);
> +
> + if (tag == priv->rsp_tag
> + && command == ELE_INIT_FW_REQ
> + && size == ELE_INIT_FW_RSP_SZ
> + && ver == MESSAGING_VERSION_7
> + && status == priv->success_tag)
> + return 0;
Your coding style here and in all other places like this is unreadable.
Fix alignment.
> +
> + return -EINVAL;
> +}
> diff --git a/drivers/firmware/imx/se_fw.c b/drivers/firmware/imx/se_fw.c
> index 2c97b2adf18b..88300c41d62b 100644
> --- a/drivers/firmware/imx/se_fw.c
> +++ b/drivers/firmware/imx/se_fw.c
> @@ -8,6 +8,7 @@
> #include <linux/dev_printk.h>
> #include <linux/errno.h>
> #include <linux/export.h>
> +#include <linux/firmware/imx/ele_fw_api.h>
> #include <linux/firmware/imx/ele_base_msg.h>
> #include <linux/firmware/imx/ele_mu_ioctl.h>
> #include <linux/genalloc.h>
> @@ -41,6 +42,7 @@ struct imx_info {
> uint8_t *se_name;
> uint8_t *pool_name;
> bool reserved_dma_ranges;
> + bool init_fw;
> };
>
> static LIST_HEAD(priv_data_list);
> @@ -55,6 +57,7 @@ static const struct imx_info imx8ulp_info = {
> .se_name = "ele",
> .pool_name = "sram-pool",
> .reserved_dma_ranges = true,
> + .init_fw = false,
> };
>
> static const struct imx_info imx93_info = {
> @@ -67,6 +70,7 @@ static const struct imx_info imx93_info = {
> .se_name = "ele",
> .pool_name = NULL,
> .reserved_dma_ranges = true,
> + .init_fw = true,
> };
>
> static const struct of_device_id se_fw_match[] = {
> @@ -1120,6 +1124,13 @@ static int se_fw_probe(struct platform_device *pdev)
> priv->flags |= RESERVED_DMA_POOL;
> }
>
> + if (info->init_fw) {
> + /* start initializing ele fw */
> + ret = ele_init_fw(dev);
> + if (ret)
> + dev_err(dev, "Failed to initialize ele fw.\n");
> + }
> +
> if (info->socdev) {
> ret = imx_soc_device_register(dev, info);
> if (ret) {
> diff --git a/include/linux/firmware/imx/ele_fw_api.h b/include/linux/firmware/imx/ele_fw_api.h
> new file mode 100644
> index 000000000000..36c3f743cb38
> --- /dev/null
> +++ b/include/linux/firmware/imx/ele_fw_api.h
There is no need this to be Linux-wide. Keep it next to the driver.
Best regards,
Krzysztof
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH v5 09/11] firmware: imx: enclave-fw: add handling for save/restore IMEM region
2023-08-23 7:33 ` [PATCH v5 09/11] firmware: imx: enclave-fw: add handling for save/restore IMEM region Pankaj Gupta
@ 2023-08-24 18:37 ` Krzysztof Kozlowski
0 siblings, 0 replies; 28+ messages in thread
From: Krzysztof Kozlowski @ 2023-08-24 18:37 UTC (permalink / raw)
To: Pankaj Gupta, shawnguo, s.hauer, kernel, clin, conor+dt,
pierre.gondois, ping.bai, xiaoning.wang, wei.fang, peng.fan,
haibo.chen, festevam, linux-imx, davem, robh+dt,
krzysztof.kozlowski+dt, linux-arm-kernel, devicetree,
linux-kernel, gaurav.jain, alexander.stein, sahil.malhotra,
aisheng.dong, V.Sethi
On 23/08/2023 09:33, Pankaj Gupta wrote:
> Some IMEM region is lost during kernel power down. Due to this,
> firmware's functionaity cannot work correctly.
>
> Saving encrypted IMEM region in kernel memory during power down,
> and restore IMEM region on resume.
>
> Signed-off-by: Gaurav Jain <gaurav.jain@nxp.com>
> Signed-off-by: Pankaj Gupta <pankaj.gupta@nxp.com>
> @@ -959,6 +962,17 @@ static int se_probe_cleanup(struct platform_device *pdev)
> priv->flags &= (~RESERVED_DMA_POOL);
> }
>
> + /* free the buffer in ele-mu remove, previously allocated
> + * in ele-mu probe to store encrypted IMEM
> + */
Use Linux coding style comments.
> + if (priv->imem.buf) {
> + dmam_free_coherent(&pdev->dev,
> + ELE_IMEM_SIZE,
> + priv->imem.buf,
> + priv->imem.phyaddr);
> + priv->imem.buf = NULL;
> + }
> +
> if (priv->ctxs) {
> for (i = 0; i < priv->max_dev_ctx; i++) {
> if (priv->ctxs[i])
> @@ -1160,6 +1174,19 @@ static int se_fw_probe(struct platform_device *pdev)
> dev_err(dev, "Failed to init ele-trng\n");
> }
>
> + if (info->imem_mgmt) {
> + /* allocate buffer where ELE store encrypted IMEM */
> + priv->imem.buf = dmam_alloc_coherent(dev, ELE_IMEM_SIZE,
> + &priv->imem.phyaddr,
> + GFP_KERNEL);
> + if (!priv->imem.buf) {
> + dev_err(dev,
> + "dmam-alloc-failed: To store encr-IMEM.\n");
> + ret = -ENOMEM;
> + goto exit;
> + }
> + }
> +
> pr_info("i.MX secure-enclave: %s's mu#%d interface to firmware, configured.\n",
> info->se_name,
> priv->ele_mu_id);
> @@ -1196,17 +1223,31 @@ static int se_fw_remove(struct platform_device *pdev)
> #ifdef CONFIG_PM_SLEEP
> static int se_fw_suspend(struct device *dev)
> {
> + struct ele_mu_priv *priv = dev_get_drvdata(dev);
> + const struct of_device_id *of_id = of_match_device(se_fw_match, dev);
No.
> + struct imx_info *info = (of_id != NULL) ? (struct imx_info *)of_id->data
> + : NULL;
> +
> + if (info && info->imem_mgmt)
> + priv->imem.size = save_imem(dev);
> +
> return 0;
> }
>
> static int se_fw_resume(struct device *dev)
> {
> struct ele_mu_priv *priv = dev_get_drvdata(dev);
> + const struct of_device_id *of_id = of_match_device(se_fw_match, dev);
Why do you keep matching device every time? Don't.
> + struct imx_info *info = (of_id != NULL) ? (struct imx_info *)of_id->data
> + : NULL;
> int i;
>
> for (i = 0; i < priv->max_dev_ctx; i++)
> wake_up_interruptible(&priv->ctxs[i]->wq);
>
> + if (info && info->imem_mgmt)
> + restore_imem(dev, info->pool_name);
> +
> return 0;
> }
> #endif
> diff --git a/drivers/firmware/imx/se_fw.h b/drivers/firmware/imx/se_fw.h
> index b3502affbc85..acb967f2357c 100644
> --- a/drivers/firmware/imx/se_fw.h
> +++ b/drivers/firmware/imx/se_fw.h
> @@ -165,4 +165,12 @@ struct ele_mu_priv {
> struct ele_imem_buf imem;
> };
>
> +phys_addr_t get_phy_buf_mem_pool(struct device *dev,
> + char *mem_pool_name,
> + u32 **buf,
> + uint32_t size);
> +void free_phybuf_mem_pool(struct device *dev,
> + char *mem_pool_name,
> + u32 *buf,
> + uint32_t size);
> #endif
> diff --git a/include/linux/firmware/imx/ele_base_msg.h b/include/linux/firmware/imx/ele_base_msg.h
> index 8a5c385210fc..6fbea7a8d7c9 100644
> --- a/include/linux/firmware/imx/ele_base_msg.h
> +++ b/include/linux/firmware/imx/ele_base_msg.h
> @@ -37,12 +37,23 @@
> #define ELE_GET_TRNG_STATE_RETRY_COUNT 0x5
> #define CSAL_TRNG_STATE_MASK 0x0000ffff
>
> +#define ELE_SERVICE_SWAP_REQ 0xDF
> +#define ELE_SERVICE_SWAP_REQ_MSG_SZ 0x03
> +#define ELE_IMEM_SIZE 0x10000
> +#define ELE_IMEM_STATE_OK 0xCA
> +#define ELE_IMEM_STATE_BAD 0xFE
> +#define ELE_IMEM_STATE_WORD 0x27
> +#define ELE_IMEM_STATE_MASK 0x00ff0000
> +#define ELE_IMEM_EXPORT 0x1
> +#define ELE_IMEM_IMPORT 0x2
> +
> #define ELE_BASE_API_VERSION 0x6
> -#define ELE_SUCCESS_IND 0xD6
> -#define ELE_FAILURE_IND 0x29
No, you just added them. Don't add wrong code to remove it in next patch.
Best regards,
Krzysztof
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH v5 10/11] firmware: imx: enclave api to read-common-fuses
2023-08-23 7:33 ` [PATCH v5 10/11] firmware: imx: enclave api to read-common-fuses Pankaj Gupta
@ 2023-08-24 18:38 ` Krzysztof Kozlowski
0 siblings, 0 replies; 28+ messages in thread
From: Krzysztof Kozlowski @ 2023-08-24 18:38 UTC (permalink / raw)
To: Pankaj Gupta, shawnguo, s.hauer, kernel, clin, conor+dt,
pierre.gondois, ping.bai, xiaoning.wang, wei.fang, peng.fan,
haibo.chen, festevam, linux-imx, davem, robh+dt,
krzysztof.kozlowski+dt, linux-arm-kernel, devicetree,
linux-kernel, gaurav.jain, alexander.stein, sahil.malhotra,
aisheng.dong, V.Sethi
On 23/08/2023 09:33, Pankaj Gupta wrote:
> Added an API to read the common fuses only accessible to
> enclave-firmware.
>
> Signed-off-by: Pankaj Gupta <pankaj.gupta@nxp.com>
...
> +int read_common_fuse(struct device *dev,
> + uint16_t fuse_id, u32 *value)
> +{
> + struct ele_mu_priv *priv = dev_get_drvdata(dev);
> + int err;
> +
> + err = plat_fill_cmd_msg_hdr(priv,
> + (struct mu_hdr *)&priv->tx_msg.header,
> + ELE_READ_FUSE_REQ, 8);
> + if (err) {
> + pr_err("Error: plat_fill_cmd_msg_hdr failed.\n");
> + return err;
> + }
> +
> + priv->tx_msg.data[0] = fuse_id;
> + err = imx_ele_msg_send_rcv(priv);
> + if (err < 0)
> + return err;
> +
> + switch (fuse_id) {
> + case OTP_UNIQ_ID:
> + err = read_otp_uniq_id(priv, value);
> + break;
> + default:
> + err = read_fuse_word(priv, value);
> + break;
> + }
> +
> + return err;
> +}
> +EXPORT_SYMBOL_GPL(read_common_fuse);
Missing kerneldoc, missing user. Sorry, this cannot be accepted. Don't
add such dead code.
Best regards,
Krzysztof
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH v5 01/11] dt-bindings: arm: fsl: add imx-se-fw binding doc
2023-08-23 12:43 ` Rob Herring
@ 2023-08-24 18:45 ` Krzysztof Kozlowski
2023-08-24 19:23 ` Greg Kroah-Hartman
[not found] ` <DU2PR04MB86302A2639CA64D8DF08BF0495E3A@DU2PR04MB8630.eurprd04.prod.outlook.com>
0 siblings, 2 replies; 28+ messages in thread
From: Krzysztof Kozlowski @ 2023-08-24 18:45 UTC (permalink / raw)
To: Rob Herring, Pankaj Gupta
Cc: shawnguo, s.hauer, kernel, clin, conor+dt, pierre.gondois,
ping.bai, xiaoning.wang, wei.fang, peng.fan, haibo.chen, festevam,
linux-imx, davem, krzysztof.kozlowski+dt, linux-arm-kernel,
devicetree, linux-kernel, gaurav.jain, alexander.stein,
sahil.malhotra, aisheng.dong, V.Sethi, Greg Kroah-Hartman
On 23/08/2023 14:43, Rob Herring wrote:
>> + |
>> + +------------------------------------------------------ |
>> + | | | |
>> + userspace /dev/ele_muXch0 | | |
>> + /dev/ele_muXch1 | |
>> + /dev/ele_muXchY |
>> + |
>> +
>> + When a user sends a command to the firmware, it registers its device_ctx
>> + as waiter of a response from firmware.
>> +
>> + A user can be registered as receiver of command from the ELE.
>> + Create char devices in /dev as channels of the form /dev/ele_muXchY with X
>> + the id of the driver and Y for each users. It allows to send and receive
>> + messages to the NXP EdgeLock Enclave IP firmware on NXP SoC, where current
>> + possible value, i.e., supported SoC(s) are imx8ulp, imx93.
>
> Looks like a bunch of Linux details which don't belong in the binding.
>
> Why do you need your own custom interface to userspace? No one else has
> a similar feature in their platforms? Something like virtio or rpmsg
> doesn't work?
+Cc Greg,
I doubt they care. This is some stub-driver to pass messages from
user-space to the firmware. The interface is undocumented, without
examples and no user-space user.
Best regards,
Krzysztof
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH v5 01/11] dt-bindings: arm: fsl: add imx-se-fw binding doc
2023-08-24 18:45 ` Krzysztof Kozlowski
@ 2023-08-24 19:23 ` Greg Kroah-Hartman
2023-08-28 6:00 ` [EXT] " Varun Sethi
[not found] ` <DU2PR04MB86302A2639CA64D8DF08BF0495E3A@DU2PR04MB8630.eurprd04.prod.outlook.com>
1 sibling, 1 reply; 28+ messages in thread
From: Greg Kroah-Hartman @ 2023-08-24 19:23 UTC (permalink / raw)
To: Krzysztof Kozlowski
Cc: Rob Herring, Pankaj Gupta, shawnguo, s.hauer, kernel, clin,
conor+dt, pierre.gondois, ping.bai, xiaoning.wang, wei.fang,
peng.fan, haibo.chen, festevam, linux-imx, davem,
krzysztof.kozlowski+dt, linux-arm-kernel, devicetree,
linux-kernel, gaurav.jain, alexander.stein, sahil.malhotra,
aisheng.dong, V.Sethi
On Thu, Aug 24, 2023 at 08:45:41PM +0200, Krzysztof Kozlowski wrote:
> On 23/08/2023 14:43, Rob Herring wrote:
> >> + |
> >> + +------------------------------------------------------ |
> >> + | | | |
> >> + userspace /dev/ele_muXch0 | | |
> >> + /dev/ele_muXch1 | |
> >> + /dev/ele_muXchY |
> >> + |
> >> +
> >> + When a user sends a command to the firmware, it registers its device_ctx
> >> + as waiter of a response from firmware.
> >> +
> >> + A user can be registered as receiver of command from the ELE.
> >> + Create char devices in /dev as channels of the form /dev/ele_muXchY with X
> >> + the id of the driver and Y for each users. It allows to send and receive
> >> + messages to the NXP EdgeLock Enclave IP firmware on NXP SoC, where current
> >> + possible value, i.e., supported SoC(s) are imx8ulp, imx93.
> >
> > Looks like a bunch of Linux details which don't belong in the binding.
> >
> > Why do you need your own custom interface to userspace? No one else has
> > a similar feature in their platforms? Something like virtio or rpmsg
> > doesn't work?
>
> +Cc Greg,
>
> I doubt they care. This is some stub-driver to pass messages from
> user-space to the firmware. The interface is undocumented, without
> examples and no user-space user.
Great, no user? Let's delete the code then :)
thanks,
greg k-h
^ permalink raw reply [flat|nested] 28+ messages in thread
* RE: [EXT] Re: [PATCH v5 01/11] dt-bindings: arm: fsl: add imx-se-fw binding doc
[not found] ` <DU2PR04MB86302A2639CA64D8DF08BF0495E3A@DU2PR04MB8630.eurprd04.prod.outlook.com>
@ 2023-08-25 7:56 ` Varun Sethi
0 siblings, 0 replies; 28+ messages in thread
From: Varun Sethi @ 2023-08-25 7:56 UTC (permalink / raw)
To: krzk@kernel.org, Krzysztof Kozlowski, Pankaj Gupta,
shawnguo@kernel.org, s.hauer@pengutronix.de,
kernel@pengutronix.de, clin@suse.com, conor+dt@kernel.org,
pierre.gondois@arm.com, Jacky Bai, Clark Wang, Wei Fang, Peng Fan,
Bough Chen, festevam@gmail.com, dl-linux-imx, davem@davemloft.net,
krzysztof.kozlowski+dt@linaro.org,
linux-arm-kernel@lists.infradead.org, kernel@lists.infradead.org,
devicetree@vger.kernel.org, dl-linux-imx, kernel@vger.kernel.org,
Gaurav Jain, alexander.stein@ew.tq-group.com, Sahil Malhotra,
Aisheng Dong, gregkh@linuxfoundation.org, Rob Herring
[-- Attachment #1: Type: text/plain, Size: 3876 bytes --]
Please find comments inline.
Regards
Varun
> -----Original Message-----
> From: Pankaj Gupta <pankaj.gupta@nxp.com>
> Sent: Friday, August 25, 2023 12:56 PM
> To: Varun Sethi <V.Sethi@nxp.com>
> Subject: FW: [EXT] Re: [PATCH v5 01/11] dt-bindings: arm: fsl: add imx-se-fw
> binding doc
>
>
>
> -----Original Message-----
> From: Krzysztof Kozlowski <krzk@kernel.org>
> Sent: Friday, August 25, 2023 12:16 AM
> To: Rob Herring <robh@kernel.org>; Pankaj Gupta <pankaj.gupta@nxp.com>
> Cc: shawnguo@kernel.org; s.hauer@pengutronix.de;
> kernel@pengutronix.de; clin@suse.com; conor+dt@kernel.org;
> pierre.gondois@arm.com; Jacky Bai <ping.bai@nxp.com>; Clark Wang
> <xiaoning.wang@nxp.com>; Wei Fang <wei.fang@nxp.com>; Peng Fan
> <peng.fan@nxp.com>; Bough Chen <haibo.chen@nxp.com>;
> festevam@gmail.com; dl-linux-imx <linux-imx@nxp.com>;
> davem@davemloft.net; krzysztof.kozlowski+dt@linaro.org; linux-arm-
> kernel@lists.infradead.org; devicetree@vger.kernel.org; linux-
> kernel@vger.kernel.org; Gaurav Jain <gaurav.jain@nxp.com>;
> alexander.stein@ew.tq-group.com; Sahil Malhotra
> <sahil.malhotra@nxp.com>; Aisheng Dong <aisheng.dong@nxp.com>; Varun
> Sethi <V.Sethi@nxp.com>; Greg Kroah-Hartman
> <gregkh@linuxfoundation.org>
> Subject: [EXT] Re: [PATCH v5 01/11] dt-bindings: arm: fsl: add imx-se-fw
> binding doc
>
> Caution: This is an external email. Please take care when clicking links or
> opening attachments. When in doubt, report the message using the 'Report
> this email' button
>
>
> On 23/08/2023 14:43, Rob Herring wrote:
> >> + |
> >> + +------------------------------------------------------ |
> >> + | | | |
> >> + userspace /dev/ele_muXch0 | | |
> >> + /dev/ele_muXch1 | |
> >> + /dev/ele_muXchY |
> >> + |
> >> +
> >> + When a user sends a command to the firmware, it registers its
> >> + device_ctx as waiter of a response from firmware.
> >> +
> >> + A user can be registered as receiver of command from the ELE.
> >> + Create char devices in /dev as channels of the form
> >> + /dev/ele_muXchY with X the id of the driver and Y for each users.
> >> + It allows to send and receive messages to the NXP EdgeLock Enclave
> >> + IP firmware on NXP SoC, where current possible value, i.e., supported
> SoC(s) are imx8ulp, imx93.
> >
> > Looks like a bunch of Linux details which don't belong in the binding.
> >
> > Why do you need your own custom interface to userspace? No one else
> > has a similar feature in their platforms? Something like virtio or
> > rpmsg doesn't work?
>
> +Cc Greg,
>
> I doubt they care. This is some stub-driver to pass messages from user-space
> to the firmware. The interface is undocumented, without examples and no
> user-space user.
>
> Best regards,
> Krzysztof
[Varun] The goal of the driver is to pass messages between firmware and user
space/kernel consumers.
At the same time driver also enables firmware to use the storage via Linux
user space. We do have
middleware applications that utilize the driver. These applications leverage
cryptographic operations and trust
provisioning capabilities offered by the firmware. We can provide references
to the middleware applications in the next
version of the patch. We do plan to enable the kernel crypto API interface to
leverage operations provided by the firmware.
The operations that are exposed by the firmware are performance-sensitive and
session-based (thus serialized). So, the Virtio/rpmsg model
is not suited for our implementation. Also, the secure enclave IP, with which
the driver facilitates the communication is an opaque block
that doesn't fit the rpmsg model.
[-- Attachment #2: smime.p7s --]
[-- Type: application/pkcs7-signature, Size: 9707 bytes --]
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH v5 06/11] firmware: imx: add driver for NXP EdgeLock Enclave
2023-08-23 7:33 ` [PATCH v5 06/11] firmware: imx: add driver for NXP EdgeLock Enclave Pankaj Gupta
2023-08-24 18:31 ` Krzysztof Kozlowski
@ 2023-08-25 10:22 ` Stefan Wahren
2023-08-25 15:16 ` Conor Dooley
1 sibling, 1 reply; 28+ messages in thread
From: Stefan Wahren @ 2023-08-25 10:22 UTC (permalink / raw)
To: Pankaj Gupta, shawnguo, s.hauer, kernel, clin, conor+dt,
pierre.gondois, ping.bai, xiaoning.wang, wei.fang, peng.fan,
haibo.chen, festevam, linux-imx, davem, robh+dt,
krzysztof.kozlowski+dt, linux-arm-kernel, devicetree,
linux-kernel, gaurav.jain, alexander.stein, sahil.malhotra,
aisheng.dong, V.Sethi
Cc: kernel test robot
Hi Pankaj,
Am 23.08.23 um 09:33 schrieb Pankaj Gupta:
> The Edgelock Enclave , is the secure enclave embedded in the SoC
> to support the features like HSM, SHE & V2X, using message based
> communication channel.
>
> ELE FW communicates on a dedicated MU with application core where
> kernel is running. It exists on specific i.MX processors. e.g.
> i.MX8ULP, i.MX93.
>
> Reported-by: kernel test robot <lkp@intel.com>
> Closes:https://lore.kernel.org/oe-kbuild-all/202304120902.bP52A56z-lkp@intel.com
> Signed-off-by: Pankaj Gupta <pankaj.gupta@nxp.com>
> ---
> Documentation/ABI/testing/se-cdev | 29 +
> drivers/firmware/imx/Kconfig | 12 +
> drivers/firmware/imx/Makefile | 2 +
> drivers/firmware/imx/ele_base_msg.c | 62 ++
> drivers/firmware/imx/ele_common.c | 34 +
> drivers/firmware/imx/ele_common.h | 21 +
> drivers/firmware/imx/se_fw.c | 1201 +++++++++++++++++++++
> drivers/firmware/imx/se_fw.h | 168 +++
> include/linux/firmware/imx/ele_base_msg.h | 37 +
> include/linux/firmware/imx/ele_mu_ioctl.h | 52 +
> 10 files changed, 1618 insertions(+)
> create mode 100644 Documentation/ABI/testing/se-cdev
> create mode 100644 drivers/firmware/imx/ele_base_msg.c
> create mode 100644 drivers/firmware/imx/ele_common.c
> create mode 100644 drivers/firmware/imx/ele_common.h
> create mode 100644 drivers/firmware/imx/se_fw.c
> create mode 100644 drivers/firmware/imx/se_fw.h
> create mode 100644 include/linux/firmware/imx/ele_base_msg.h
> create mode 100644 include/linux/firmware/imx/ele_mu_ioctl.h
...
> +
> +int ele_get_info(struct device *dev, phys_addr_t addr, u32 data_size)
> +{
> + struct ele_mu_priv *priv = dev_get_drvdata(dev);
> + int ret;
> + unsigned int tag, command, size, ver, status;
> +
> + ret = plat_fill_cmd_msg_hdr(priv,
> + (struct mu_hdr *)&priv->tx_msg.header,
> + ELE_GET_INFO_REQ, 16);
> + if (ret)
> + return ret;
> +
> + priv->tx_msg.data[0] = upper_32_bits(addr);
> + priv->tx_msg.data[1] = lower_32_bits(addr);
> + priv->tx_msg.data[2] = data_size;
> + ret = imx_ele_msg_send_rcv(priv);
> + if (ret < 0)
> + return ret;
> +
> + tag = MSG_TAG(priv->rx_msg.header);
> + command = MSG_COMMAND(priv->rx_msg.header);
> + size = MSG_SIZE(priv->rx_msg.header);
> + ver = MSG_VER(priv->rx_msg.header);
> + status = RES_STATUS(priv->rx_msg.data[0]);
> + if (tag == priv->rsp_tag &&
> + command == ELE_GET_INFO_REQ &&
> + size == ELE_GET_INFO_REQ_MSG_SZ &&
> + ver == ELE_BASE_API_VERSION &&
> + status == priv->success_tag)
> + return 0;
except of the coding style, i won't recommend this error handling. In
case a user report a failure of ele_get_info(), we need to figure out
which of these conditions failed. Why not check the conditions step by
step and give a detailed error message.
The same applies to the rest of the series.
Best regards
> +
> + return -EINVAL;
> +}
>
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH v5 06/11] firmware: imx: add driver for NXP EdgeLock Enclave
2023-08-25 10:22 ` Stefan Wahren
@ 2023-08-25 15:16 ` Conor Dooley
0 siblings, 0 replies; 28+ messages in thread
From: Conor Dooley @ 2023-08-25 15:16 UTC (permalink / raw)
To: Stefan Wahren
Cc: Pankaj Gupta, shawnguo, s.hauer, kernel, clin, conor+dt,
pierre.gondois, ping.bai, xiaoning.wang, wei.fang, peng.fan,
haibo.chen, festevam, linux-imx, davem, robh+dt,
krzysztof.kozlowski+dt, linux-arm-kernel, devicetree,
linux-kernel, gaurav.jain, alexander.stein, sahil.malhotra,
aisheng.dong, V.Sethi, kernel test robot
[-- Attachment #1: Type: text/plain, Size: 706 bytes --]
> Am 23.08.23 um 09:33 schrieb Pankaj Gupta:
> > The Edgelock Enclave , is the secure enclave embedded in the SoC
> > to support the features like HSM, SHE & V2X, using message based
> > communication channel.
> >
> > ELE FW communicates on a dedicated MU with application core where
> > kernel is running. It exists on specific i.MX processors. e.g.
> > i.MX8ULP, i.MX93.
> >
> > Reported-by: kernel test robot <lkp@intel.com>
> > Closes:https://lore.kernel.org/oe-kbuild-all/202304120902.bP52A56z-lkp@intel.com
> > Signed-off-by: Pankaj Gupta <pankaj.gupta@nxp.com>
In passing, LKP did not report that support for your firmware was
missing, please remove the Reported-by & Closes tags.
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply [flat|nested] 28+ messages in thread
* RE: [EXT] Re: [PATCH v5 01/11] dt-bindings: arm: fsl: add imx-se-fw binding doc
2023-08-24 19:23 ` Greg Kroah-Hartman
@ 2023-08-28 6:00 ` Varun Sethi
2023-08-28 6:55 ` Krzysztof Kozlowski
0 siblings, 1 reply; 28+ messages in thread
From: Varun Sethi @ 2023-08-28 6:00 UTC (permalink / raw)
To: Greg Kroah-Hartman, Krzysztof Kozlowski
Cc: Rob Herring, Pankaj Gupta, shawnguo@kernel.org,
s.hauer@pengutronix.de, kernel@pengutronix.de, clin@suse.com,
conor+dt@kernel.org, pierre.gondois@arm.com, Jacky Bai,
Clark Wang, Wei Fang, Peng Fan, Bough Chen, festevam@gmail.com,
dl-linux-imx, davem@davemloft.net,
krzysztof.kozlowski+dt@linaro.org,
linux-arm-kernel@lists.infradead.org, devicetree@vger.kernel.org,
linux-kernel@vger.kernel.org, Gaurav Jain,
alexander.stein@ew.tq-group.com, Sahil Malhotra, Aisheng Dong
[-- Attachment #1: Type: text/plain, Size: 3169 bytes --]
Hi Greg,
> -----Original Message-----
> From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> Sent: Friday, August 25, 2023 12:54 AM
> To: Krzysztof Kozlowski <krzk@kernel.org>
> Cc: Rob Herring <robh@kernel.org>; Pankaj Gupta
> <pankaj.gupta@nxp.com>; shawnguo@kernel.org; s.hauer@pengutronix.de;
> kernel@pengutronix.de; clin@suse.com; conor+dt@kernel.org;
> pierre.gondois@arm.com; Jacky Bai <ping.bai@nxp.com>; Clark Wang
> <xiaoning.wang@nxp.com>; Wei Fang <wei.fang@nxp.com>; Peng Fan
> <peng.fan@nxp.com>; Bough Chen <haibo.chen@nxp.com>;
> festevam@gmail.com; dl-linux-imx <linux-imx@nxp.com>;
> davem@davemloft.net; krzysztof.kozlowski+dt@linaro.org; linux-arm-
> kernel@lists.infradead.org; devicetree@vger.kernel.org; linux-
> kernel@vger.kernel.org; Gaurav Jain <gaurav.jain@nxp.com>;
> alexander.stein@ew.tq-group.com; Sahil Malhotra
> <sahil.malhotra@nxp.com>; Aisheng Dong <aisheng.dong@nxp.com>; Varun
> Sethi <V.Sethi@nxp.com>
> Subject: [EXT] Re: [PATCH v5 01/11] dt-bindings: arm: fsl: add imx-se-fw
> binding doc
>
> Caution: This is an external email. Please take care when clicking links
or
> opening attachments. When in doubt, report the message using the 'Report
> this email' button
>
>
> On Thu, Aug 24, 2023 at 08:45:41PM +0200, Krzysztof Kozlowski wrote:
> > On 23/08/2023 14:43, Rob Herring wrote:
> > >> + |
> > >> + +------------------------------------------------------ |
> > >> + | | | |
> > >> + userspace /dev/ele_muXch0 | | |
> > >> + /dev/ele_muXch1 | |
> > >> + /dev/ele_muXchY |
> > >> + |
> > >> +
> > >> + When a user sends a command to the firmware, it registers its
> > >> + device_ctx as waiter of a response from firmware.
> > >> +
> > >> + A user can be registered as receiver of command from the ELE.
> > >> + Create char devices in /dev as channels of the form
> > >> + /dev/ele_muXchY with X the id of the driver and Y for each
> > >> + users. It allows to send and receive messages to the NXP
> > >> + EdgeLock Enclave IP firmware on NXP SoC, where current possible
> value, i.e., supported SoC(s) are imx8ulp, imx93.
> > >
> > > Looks like a bunch of Linux details which don't belong in the binding.
> > >
> > > Why do you need your own custom interface to userspace? No one else
> > > has a similar feature in their platforms? Something like virtio or
> > > rpmsg doesn't work?
> >
> > +Cc Greg,
> >
> > I doubt they care. This is some stub-driver to pass messages from
> > user-space to the firmware. The interface is undocumented, without
> > examples and no user-space user.
>
> Great, no user? Let's delete the code then :)
>
[Varun] We do have middleware applications that utilize the driver.
Following
are the links:
https://github.com/nxp-imx/imx-secure-enclave
https://github.com/nxp-imx/imx-smw
Also, we plan to enable the kernel crypto API interface to
leverage operations provided by the firmware.
Regards
Varun
[-- Attachment #2: smime.p7s --]
[-- Type: application/pkcs7-signature, Size: 9707 bytes --]
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [EXT] Re: [PATCH v5 01/11] dt-bindings: arm: fsl: add imx-se-fw binding doc
2023-08-28 6:00 ` [EXT] " Varun Sethi
@ 2023-08-28 6:55 ` Krzysztof Kozlowski
2023-08-28 9:14 ` Varun Sethi
0 siblings, 1 reply; 28+ messages in thread
From: Krzysztof Kozlowski @ 2023-08-28 6:55 UTC (permalink / raw)
To: Varun Sethi, Greg Kroah-Hartman, Krzysztof Kozlowski
Cc: Rob Herring, Pankaj Gupta, shawnguo@kernel.org,
s.hauer@pengutronix.de, kernel@pengutronix.de, clin@suse.com,
conor+dt@kernel.org, pierre.gondois@arm.com, Jacky Bai,
Clark Wang, Wei Fang, Peng Fan, Bough Chen, festevam@gmail.com,
dl-linux-imx, davem@davemloft.net,
krzysztof.kozlowski+dt@linaro.org,
linux-arm-kernel@lists.infradead.org, devicetree@vger.kernel.org,
linux-kernel@vger.kernel.org, Gaurav Jain,
alexander.stein@ew.tq-group.com, Sahil Malhotra, Aisheng Dong
On 28/08/2023 08:00, Varun Sethi wrote:
> Hi Greg,
>
>> -----Original Message-----
>> From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
>> Sent: Friday, August 25, 2023 12:54 AM
>> To: Krzysztof Kozlowski <krzk@kernel.org>
>> Cc: Rob Herring <robh@kernel.org>; Pankaj Gupta
>> <pankaj.gupta@nxp.com>; shawnguo@kernel.org; s.hauer@pengutronix.de;
>> kernel@pengutronix.de; clin@suse.com; conor+dt@kernel.org;
>> pierre.gondois@arm.com; Jacky Bai <ping.bai@nxp.com>; Clark Wang
>> <xiaoning.wang@nxp.com>; Wei Fang <wei.fang@nxp.com>; Peng Fan
>> <peng.fan@nxp.com>; Bough Chen <haibo.chen@nxp.com>;
>> festevam@gmail.com; dl-linux-imx <linux-imx@nxp.com>;
>> davem@davemloft.net; krzysztof.kozlowski+dt@linaro.org; linux-arm-
>> kernel@lists.infradead.org; devicetree@vger.kernel.org; linux-
>> kernel@vger.kernel.org; Gaurav Jain <gaurav.jain@nxp.com>;
>> alexander.stein@ew.tq-group.com; Sahil Malhotra
>> <sahil.malhotra@nxp.com>; Aisheng Dong <aisheng.dong@nxp.com>; Varun
>> Sethi <V.Sethi@nxp.com>
>> Subject: [EXT] Re: [PATCH v5 01/11] dt-bindings: arm: fsl: add imx-se-fw
>> binding doc
>>
>> Caution: This is an external email. Please take care when clicking links
> or
>> opening attachments. When in doubt, report the message using the 'Report
>> this email' button
>>
>>
>> On Thu, Aug 24, 2023 at 08:45:41PM +0200, Krzysztof Kozlowski wrote:
>>> On 23/08/2023 14:43, Rob Herring wrote:
>>>>> + |
>>>>> + +------------------------------------------------------ |
>>>>> + | | | |
>>>>> + userspace /dev/ele_muXch0 | | |
>>>>> + /dev/ele_muXch1 | |
>>>>> + /dev/ele_muXchY |
>>>>> + |
>>>>> +
>>>>> + When a user sends a command to the firmware, it registers its
>>>>> + device_ctx as waiter of a response from firmware.
>>>>> +
>>>>> + A user can be registered as receiver of command from the ELE.
>>>>> + Create char devices in /dev as channels of the form
>>>>> + /dev/ele_muXchY with X the id of the driver and Y for each
>>>>> + users. It allows to send and receive messages to the NXP
>>>>> + EdgeLock Enclave IP firmware on NXP SoC, where current possible
>> value, i.e., supported SoC(s) are imx8ulp, imx93.
>>>>
>>>> Looks like a bunch of Linux details which don't belong in the binding.
>>>>
>>>> Why do you need your own custom interface to userspace? No one else
>>>> has a similar feature in their platforms? Something like virtio or
>>>> rpmsg doesn't work?
>>>
>>> +Cc Greg,
>>>
>>> I doubt they care. This is some stub-driver to pass messages from
>>> user-space to the firmware. The interface is undocumented, without
>>> examples and no user-space user.
>>
>> Great, no user? Let's delete the code then :)
>>
> [Varun] We do have middleware applications that utilize the driver.
> Following
> are the links:
> https://github.com/nxp-imx/imx-secure-enclave
> https://github.com/nxp-imx/imx-smw
>
Why this is not explained in the cover letter and in the patch adding
the interfaces? You still need to document and explain the interface.
Best regards,
Krzysztof
^ permalink raw reply [flat|nested] 28+ messages in thread
* RE: [EXT] Re: [PATCH v5 01/11] dt-bindings: arm: fsl: add imx-se-fw binding doc
2023-08-28 6:55 ` Krzysztof Kozlowski
@ 2023-08-28 9:14 ` Varun Sethi
0 siblings, 0 replies; 28+ messages in thread
From: Varun Sethi @ 2023-08-28 9:14 UTC (permalink / raw)
To: Krzysztof Kozlowski, Greg Kroah-Hartman, Krzysztof Kozlowski
Cc: Rob Herring, Pankaj Gupta, shawnguo@kernel.org,
s.hauer@pengutronix.de, kernel@pengutronix.de, clin@suse.com,
conor+dt@kernel.org, pierre.gondois@arm.com, Jacky Bai,
Clark Wang, Wei Fang, Peng Fan, Bough Chen, festevam@gmail.com,
dl-linux-imx, davem@davemloft.net,
krzysztof.kozlowski+dt@linaro.org,
linux-arm-kernel@lists.infradead.org, devicetree@vger.kernel.org,
linux-kernel@vger.kernel.org, Gaurav Jain,
alexander.stein@ew.tq-group.com, Sahil Malhotra, Aisheng Dong
[-- Attachment #1: Type: text/plain, Size: 5846 bytes --]
Hi Krzysztof,
> -----Original Message-----
> From: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
> Sent: Monday, August 28, 2023 12:25 PM
> To: Varun Sethi <V.Sethi@nxp.com>; Greg Kroah-Hartman
> <gregkh@linuxfoundation.org>; Krzysztof Kozlowski <krzk@kernel.org>
> Cc: Rob Herring <robh@kernel.org>; Pankaj Gupta
> <pankaj.gupta@nxp.com>; shawnguo@kernel.org; s.hauer@pengutronix.de;
> kernel@pengutronix.de; clin@suse.com; conor+dt@kernel.org;
> pierre.gondois@arm.com; Jacky Bai <ping.bai@nxp.com>; Clark Wang
> <xiaoning.wang@nxp.com>; Wei Fang <wei.fang@nxp.com>; Peng Fan
> <peng.fan@nxp.com>; Bough Chen <haibo.chen@nxp.com>;
> festevam@gmail.com; dl-linux-imx <linux-imx@nxp.com>;
> davem@davemloft.net; krzysztof.kozlowski+dt@linaro.org; linux-arm-
> kernel@lists.infradead.org; devicetree@vger.kernel.org; linux-
> kernel@vger.kernel.org; Gaurav Jain <gaurav.jain@nxp.com>;
> alexander.stein@ew.tq-group.com; Sahil Malhotra
> <sahil.malhotra@nxp.com>; Aisheng Dong <aisheng.dong@nxp.com>
> Subject: Re: [EXT] Re: [PATCH v5 01/11] dt-bindings: arm: fsl: add
imx-se-fw
> binding doc
>
> Caution: This is an external email. Please take care when clicking links
or
> opening attachments. When in doubt, report the message using the 'Report
> this email' button
>
>
> On 28/08/2023 08:00, Varun Sethi wrote:
> > Hi Greg,
> >
> >> -----Original Message-----
> >> From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> >> Sent: Friday, August 25, 2023 12:54 AM
> >> To: Krzysztof Kozlowski <krzk@kernel.org>
> >> Cc: Rob Herring <robh@kernel.org>; Pankaj Gupta
> >> <pankaj.gupta@nxp.com>; shawnguo@kernel.org;
> s.hauer@pengutronix.de;
> >> kernel@pengutronix.de; clin@suse.com; conor+dt@kernel.org;
> >> pierre.gondois@arm.com; Jacky Bai <ping.bai@nxp.com>; Clark Wang
> >> <xiaoning.wang@nxp.com>; Wei Fang <wei.fang@nxp.com>; Peng Fan
> >> <peng.fan@nxp.com>; Bough Chen <haibo.chen@nxp.com>;
> >> festevam@gmail.com; dl-linux-imx <linux-imx@nxp.com>;
> >> davem@davemloft.net; krzysztof.kozlowski+dt@linaro.org; linux-arm-
> >> kernel@lists.infradead.org; devicetree@vger.kernel.org; linux-
> >> kernel@vger.kernel.org; Gaurav Jain <gaurav.jain@nxp.com>;
> >> alexander.stein@ew.tq-group.com; Sahil Malhotra
> >> <sahil.malhotra@nxp.com>; Aisheng Dong <aisheng.dong@nxp.com>;
> Varun
> >> Sethi <V.Sethi@nxp.com>
> >> Subject: [EXT] Re: [PATCH v5 01/11] dt-bindings: arm: fsl: add
> >> imx-se-fw binding doc
> >>
> >> Caution: This is an external email. Please take care when clicking
> >> links
> > or
> >> opening attachments. When in doubt, report the message using the
> >> 'Report this email' button
> >>
> >>
> >> On Thu, Aug 24, 2023 at 08:45:41PM +0200, Krzysztof Kozlowski wrote:
> >>> On 23/08/2023 14:43, Rob Herring wrote:
> >>>>> + |
> >>>>> + +------------------------------------------------------ |
> >>>>> + | | | |
> >>>>> + userspace /dev/ele_muXch0 | | |
> >>>>> + /dev/ele_muXch1 | |
> >>>>> + /dev/ele_muXchY |
> >>>>> + |
> >>>>> +
> >>>>> + When a user sends a command to the firmware, it registers its
> >>>>> + device_ctx as waiter of a response from firmware.
> >>>>> +
> >>>>> + A user can be registered as receiver of command from the ELE.
> >>>>> + Create char devices in /dev as channels of the form
> >>>>> + /dev/ele_muXchY with X the id of the driver and Y for each
> >>>>> + users. It allows to send and receive messages to the NXP
> >>>>> + EdgeLock Enclave IP firmware on NXP SoC, where current possible
> >> value, i.e., supported SoC(s) are imx8ulp, imx93.
> >>>>
> >>>> Looks like a bunch of Linux details which don't belong in the
binding.
> >>>>
> >>>> Why do you need your own custom interface to userspace? No one
> else
> >>>> has a similar feature in their platforms? Something like virtio or
> >>>> rpmsg doesn't work?
> >>>
> >>> +Cc Greg,
> >>>
> >>> I doubt they care. This is some stub-driver to pass messages from
> >>> user-space to the firmware. The interface is undocumented, without
> >>> examples and no user-space user.
> >>
> >> Great, no user? Let's delete the code then :)
> >>
> > [Varun] We do have middleware applications that utilize the driver.
> > Following
> > are the links:
> > https://eur01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgith
> > ub.com%2Fnxp-imx%2Fimx-secure-
> enclave&data=05%7C01%7CV.Sethi%40nxp.com
> > %7Ceda172f10a684cc926a908dba793b776%7C686ea1d3bc2b4c6fa92cd99c5c
> 301635
> > %7C0%7C0%7C638288025110398317%7CUnknown%7CTWFpbGZsb3d8eyJW
> IjoiMC4wLjAw
> >
> MDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000%7C%7C%
> 7C&sda
> >
> ta=jJ%2FZl1myldPaciswIps2dDuuzp%2BqXGZDnvh07yD%2BEFU%3D&reserve
> d=0
> > https://eur01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgith
> > ub.com%2Fnxp-imx%2Fimx-
> smw&data=05%7C01%7CV.Sethi%40nxp.com%7Ceda172f1
> >
> 0a684cc926a908dba793b776%7C686ea1d3bc2b4c6fa92cd99c5c301635%7C0%7
> C0%7C
> >
> 638288025110398317%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwM
> DAiLCJQIjo
> >
> iV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000%7C%7C%7C&sdata=U
> VjBwmzZ
> > myHu%2Fmy6WZiQcz2qksA67W1BtwFIJ8%2Ft7nQ%3D&reserved=0
> >
>
> Why this is not explained in the cover letter and in the patch adding the
> interfaces? You still need to document and explain the interface.
>
[Varun] Following information would be added in the next version of the
patchset:
1. Details of the users for this driver.
2. The ABI document would be enhanced to provide information about the
interfaces leveraged
by the user space middleware applications.
Please let me know if this would be sufficient.
Regards
Varun Sethi
[-- Attachment #2: smime.p7s --]
[-- Type: application/pkcs7-signature, Size: 9707 bytes --]
^ permalink raw reply [flat|nested] 28+ messages in thread
end of thread, other threads:[~2023-08-28 9:15 UTC | newest]
Thread overview: 28+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-08-23 7:33 [PATCH v5 00/11] firmware: imx: NXP Secure-Enclave FW Driver Pankaj Gupta
2023-08-23 7:33 ` [PATCH v5 01/11] dt-bindings: arm: fsl: add imx-se-fw binding doc Pankaj Gupta
2023-08-23 8:28 ` Rob Herring
2023-08-23 10:42 ` [EXT] " Pankaj Gupta
2023-08-23 12:43 ` Rob Herring
2023-08-24 18:45 ` Krzysztof Kozlowski
2023-08-24 19:23 ` Greg Kroah-Hartman
2023-08-28 6:00 ` [EXT] " Varun Sethi
2023-08-28 6:55 ` Krzysztof Kozlowski
2023-08-28 9:14 ` Varun Sethi
[not found] ` <DU2PR04MB86302A2639CA64D8DF08BF0495E3A@DU2PR04MB8630.eurprd04.prod.outlook.com>
2023-08-25 7:56 ` Varun Sethi
2023-08-23 7:33 ` [PATCH v5 02/11] arm64: dts: imx8ulp-evk: added nxp secure enclave firmware Pankaj Gupta
2023-08-23 7:33 ` [PATCH v5 03/11] arm64: dts: imx8ulp-evk: reserved mem-ranges to constrain ele_fw dma-range Pankaj Gupta
2023-08-23 7:33 ` [PATCH v5 04/11] arm64: dts: imx93-11x11-evk: added nxp secure enclave fw Pankaj Gupta
2023-08-23 7:33 ` [PATCH v5 05/11] arm64: dts: imx93-11x11-evk: reserved mem-ranges to constrain ele_fw dma-range Pankaj Gupta
2023-08-23 7:33 ` [PATCH v5 06/11] firmware: imx: add driver for NXP EdgeLock Enclave Pankaj Gupta
2023-08-24 18:31 ` Krzysztof Kozlowski
2023-08-25 10:22 ` Stefan Wahren
2023-08-25 15:16 ` Conor Dooley
2023-08-23 7:33 ` [PATCH v5 07/11] firmware: imx: init-fw api exchange on imx93 Pankaj Gupta
2023-08-24 18:35 ` Krzysztof Kozlowski
2023-08-23 7:33 ` [PATCH v5 08/11] firmware: imx: enable trng Pankaj Gupta
2023-08-24 18:23 ` Krzysztof Kozlowski
2023-08-23 7:33 ` [PATCH v5 09/11] firmware: imx: enclave-fw: add handling for save/restore IMEM region Pankaj Gupta
2023-08-24 18:37 ` Krzysztof Kozlowski
2023-08-23 7:33 ` [PATCH v5 10/11] firmware: imx: enclave api to read-common-fuses Pankaj Gupta
2023-08-24 18:38 ` Krzysztof Kozlowski
2023-08-23 7:33 ` [PATCH v5 11/11] MAINTAINERS: Added maintainer details Pankaj Gupta
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).