The tampers are security feature available on i.MX products and
managed by SNVS block.The tamper goal is to detect the variation
of hardware or physical parameters, which can indicate an attack.
The SNVS, which provides secure non-volatile storage, allows to
detect some hardware attacks against the SoC.They are connected
to the security-violation ports, which send an alert when an
out-of-range value is detected.
This detection is done by:
-Analog tampers: measure analogic values
- External clock frequency.
- Temperature.
- Voltage.
- Digital tampers:
- External tamper
- Other detectors:
- Secure real-time counter rollover tamper.
- Monotonic counter rollover tamper.
- Power supply glitch tamper.
The on-chip sensors for voltage, temperature, and clock frequency
indicate if tamper scenarios may be present. These sensors generate an
out-of-range signal that causes a security violation to clear the
authentication and storage keys and to block access to sensitive
information.
Add linux module secvio driver to handle security violation interrupt.
The "imx-secvio-sc" module is designed to report security violations
and tamper triggering to the user.
The functionalities of the module are accessible via the "debugfs"
kernel.The folder containing the interface files for the module is
"<kernel_debugfs>/secvio/".
Get status
Reading from the "info" file will return the status of security:
- Fuse related to security tampers.
- SNVS readable registers.
- DGO registers.
Signed-off-by: Vabhav Sharma <[email protected]>
---
Vabhav Sharma (4):
dt-bindings: firmware: secvio: Add device tree bindings
firmware: imx: Add SC APIs required for secvio module
soc: imx: secvio: Add support for SNVS secvio and tamper via SCFW
arm64: dts: imx8q: Add node for Security Violation
.../bindings/arm/freescale/fsl,scu-secvio.yaml | 35 ++
.../devicetree/bindings/firmware/fsl,scu.yaml | 10 +
arch/arm64/boot/dts/freescale/imx8qxp.dtsi | 5 +
drivers/firmware/imx/Makefile | 2 +-
drivers/firmware/imx/imx-scu.c | 4 +-
drivers/firmware/imx/seco.c | 216 ++++++++
drivers/soc/imx/Kconfig | 11 +
drivers/soc/imx/Makefile | 1 +
drivers/soc/imx/secvio/Makefile | 2 +
drivers/soc/imx/secvio/imx-secvio-debugfs.c | 274 ++++++++++
drivers/soc/imx/secvio/imx-secvio-sc.c | 595 +++++++++++++++++++++
include/linux/firmware/imx/ipc.h | 1 +
include/linux/firmware/imx/sci.h | 4 +
include/linux/firmware/imx/svc/seco.h | 69 +++
include/soc/imx/imx-secvio-sc.h | 216 ++++++++
15 files changed, 1443 insertions(+), 2 deletions(-)
---
base-commit: 93a39e4766083050ca0ecd6a3548093a3b9eb60c
change-id: 20240508-secvio-8acfa2838385
Best regards,
--
Vabhav Sharma <[email protected]>
Document the secvio device tree bindings.
The tampers are security feature available on i.MX products and
managed by SNVS block.The tamper goal is to detect the variation
of hardware or physical parameters, which can indicate an attack.
The SNVS, which provides secure non-volatile storage, allows to
detect some hardware attacks against the SoC.They are connected
to the security-violation ports, which send an alert when an
out-of-range value is detected.
The "imx-secvio-sc" module is designed to report security violations
and tamper triggering via SCU firmware to the user.
Add the imx-scu secvio sub node and secvio sub node description.
Signed-off-by: Franck LENORMAND <[email protected]>
Signed-off-by: Vabhav Sharma <[email protected]>
---
.../bindings/arm/freescale/fsl,scu-secvio.yaml | 35 ++++++++++++++++++++++
.../devicetree/bindings/firmware/fsl,scu.yaml | 10 +++++++
2 files changed, 45 insertions(+)
diff --git a/Documentation/devicetree/bindings/arm/freescale/fsl,scu-secvio.yaml b/Documentation/devicetree/bindings/arm/freescale/fsl,scu-secvio.yaml
new file mode 100644
index 000000000000..30dc1e21f903
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/freescale/fsl,scu-secvio.yaml
@@ -0,0 +1,35 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/arm/freescale/fsl,scu-secvio.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: NXP i.MX Security Violation driver
+
+maintainers:
+ - Franck LENORMAND <[email protected]>
+
+description: |
+ Receive security violation from the SNVS via the SCU firmware. Allow to
+ register notifier for additional processing
+
+properties:
+ compatible:
+ enum:
+ - fsl,imx-sc-secvio
+
+ nvmem:
+ maxItems: 1
+
+required:
+ - compatible
+ - nvmem
+
+additionalProperties: false
+
+examples:
+ - |
+ secvio {
+ compatible = "fsl,imx-sc-secvio";
+ nvmem = <&ocotp>;
+ };
diff --git a/Documentation/devicetree/bindings/firmware/fsl,scu.yaml b/Documentation/devicetree/bindings/firmware/fsl,scu.yaml
index 557e524786c2..b40e127fdc88 100644
--- a/Documentation/devicetree/bindings/firmware/fsl,scu.yaml
+++ b/Documentation/devicetree/bindings/firmware/fsl,scu.yaml
@@ -129,6 +129,11 @@ properties:
RTC controller provided by the SCU
$ref: /schemas/rtc/fsl,scu-rtc.yaml
+ secvio:
+ description:
+ Receive security violation from the SNVS via the SCU firmware
+ $ref: /schemas/arm/freescale/fsl,scu-secvio.yaml
+
thermal-sensor:
description:
Thermal sensor provided by the SCU
@@ -197,6 +202,11 @@ examples:
compatible = "fsl,imx8qxp-sc-rtc";
};
+ secvio {
+ compatible = "fsl,imx-sc-secvio";
+ nvmem = <&ocotp>;
+ };
+
keys {
compatible = "fsl,imx8qxp-sc-key", "fsl,imx-sc-key";
linux,keycodes = <KEY_POWER>;
--
2.25.1
The Security Violation module requires below System Controller
Security controller API to interact with SNVS block via SCFW
- imx_sc_seco_build_info
- imx_sc_seco_secvio_enable
- imx_sc_seco_secvio_config
- imx_sc_seco_secvio_dgo_config
Signed-off-by: Franck LENORMAND <[email protected]>
Reviewed-by: Iuliana Prodan <[email protected]>
Reviewed-by: Horia Geanta<[email protected]>
Signed-off-by: Dong Aisheng <[email protected]>
Signed-off-by: Vabhav Sharma <[email protected]>
---
drivers/firmware/imx/Makefile | 2 +-
drivers/firmware/imx/imx-scu.c | 4 +-
drivers/firmware/imx/seco.c | 216 ++++++++++++++++++++++++++++++++++
include/linux/firmware/imx/ipc.h | 1 +
include/linux/firmware/imx/sci.h | 4 +
include/linux/firmware/imx/svc/seco.h | 69 +++++++++++
6 files changed, 294 insertions(+), 2 deletions(-)
diff --git a/drivers/firmware/imx/Makefile b/drivers/firmware/imx/Makefile
index 8f9f04a513a8..b53d2dee8ff3 100644
--- a/drivers/firmware/imx/Makefile
+++ b/drivers/firmware/imx/Makefile
@@ -1,3 +1,3 @@
# SPDX-License-Identifier: GPL-2.0
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) += imx-scu.o misc.o imx-scu-irq.o rm.o imx-scu-soc.o seco.o
diff --git a/drivers/firmware/imx/imx-scu.c b/drivers/firmware/imx/imx-scu.c
index 1dd4362ef9a3..c96dc73689a8 100644
--- a/drivers/firmware/imx/imx-scu.c
+++ b/drivers/firmware/imx/imx-scu.c
@@ -242,9 +242,11 @@ int imx_scu_call_rpc(struct imx_sc_ipc *sc_ipc, void *msg, bool have_resp)
* APIs are defined as void function in SCU firmware, so they
* should be treated as return success always.
*/
- if ((saved_svc == IMX_SC_RPC_SVC_MISC) &&
+ if (((saved_svc == IMX_SC_RPC_SVC_MISC) &&
(saved_func == IMX_SC_MISC_FUNC_UNIQUE_ID ||
saved_func == IMX_SC_MISC_FUNC_GET_BUTTON_STATUS))
+ || (saved_svc == IMX_SC_RPC_SVC_SECO &&
+ saved_func == IMX_SC_SECO_FUNC_BUILD_INFO))
ret = 0;
}
diff --git a/drivers/firmware/imx/seco.c b/drivers/firmware/imx/seco.c
new file mode 100644
index 000000000000..2d6bf301ac87
--- /dev/null
+++ b/drivers/firmware/imx/seco.c
@@ -0,0 +1,216 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2020, 2024 NXP
+ *
+ * File containing client-side RPC functions for the SECO service. These
+ * function are ported to clients that communicate to the SC.
+ */
+
+#include <linux/firmware/imx/sci.h>
+
+struct imx_sc_msg_seco_get_build_id {
+ struct imx_sc_rpc_msg hdr;
+ u32 version;
+ u32 commit;
+} __packed __aligned(4);
+
+int imx_sc_seco_build_info(struct imx_sc_ipc *ipc, uint32_t *version,
+ uint32_t *commit)
+{
+ struct imx_sc_msg_seco_get_build_id msg;
+ struct imx_sc_rpc_msg *hdr = &msg.hdr;
+ int ret;
+
+ hdr->ver = IMX_SC_RPC_VERSION;
+ hdr->svc = IMX_SC_RPC_SVC_SECO;
+ hdr->func = IMX_SC_SECO_FUNC_BUILD_INFO;
+ hdr->size = 1;
+
+ ret = imx_scu_call_rpc(ipc, &msg, true);
+ if (ret)
+ return ret;
+
+ if (version)
+ *version = msg.version;
+ if (commit)
+ *commit = msg.commit;
+
+ return 0;
+}
+EXPORT_SYMBOL(imx_sc_seco_build_info);
+
+int imx_sc_seco_secvio_enable(struct imx_sc_ipc *ipc)
+{
+ struct imx_sc_rpc_msg msg;
+ struct imx_sc_rpc_msg *hdr = &msg;
+
+ hdr->ver = IMX_SC_RPC_VERSION;
+ hdr->svc = IMX_SC_RPC_SVC_SECO;
+ hdr->func = IMX_SC_SECO_FUNC_SECVIO_ENABLE;
+ hdr->size = 1;
+
+ return imx_scu_call_rpc(ipc, &msg, true);
+}
+EXPORT_SYMBOL(imx_sc_seco_secvio_enable);
+
+struct imx_sc_msg_req_seco_config {
+ struct imx_sc_rpc_msg hdr;
+ u32 data0;
+ u32 data1;
+ u32 data2;
+ u32 data3;
+ u32 data4;
+ u8 id;
+ u8 access;
+ u8 size;
+} __packed __aligned(4);
+
+struct imx_sc_msg_resp_seco_config {
+ struct imx_sc_rpc_msg hdr;
+ u32 data0;
+ u32 data1;
+ u32 data2;
+ u32 data3;
+ u32 data4;
+} __packed __aligned(4);
+
+int imx_sc_seco_secvio_config(struct imx_sc_ipc *ipc, u8 id, u8 access,
+ u32 *data0, u32 *data1, u32 *data2, u32 *data3,
+ u32 *data4, u8 size)
+{
+ struct imx_sc_msg_req_seco_config msg;
+ struct imx_sc_msg_resp_seco_config *resp;
+ struct imx_sc_rpc_msg *hdr = &msg.hdr;
+ int ret;
+
+ hdr->ver = IMX_SC_RPC_VERSION;
+ hdr->svc = IMX_SC_RPC_SVC_SECO;
+ hdr->func = IMX_SC_SECO_FUNC_SECVIO_CONFIG;
+ hdr->size = 7;
+
+ /* Check the pointers on data are valid and set it if doing a write */
+ switch (size) {
+ case 5:
+ if (data4) {
+ if (access)
+ msg.data4 = *data4;
+ } else {
+ return -EINVAL;
+ }
+ fallthrough;
+ case 4:
+ if (data3) {
+ if (access)
+ msg.data3 = *data3;
+ } else {
+ return -EINVAL;
+ }
+ fallthrough;
+ case 3:
+ if (data2) {
+ if (access)
+ msg.data2 = *data2;
+ } else {
+ return -EINVAL;
+ }
+ fallthrough;
+ case 2:
+ if (data1) {
+ if (access)
+ msg.data1 = *data1;
+ } else {
+ return -EINVAL;
+ }
+ fallthrough;
+ case 1:
+ if (data0) {
+ if (access)
+ msg.data0 = *data0;
+ } else {
+ return -EINVAL;
+ }
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ msg.id = id;
+ msg.access = access;
+ msg.size = size;
+
+ ret = imx_scu_call_rpc(ipc, &msg, true);
+ if (ret)
+ return ret;
+
+ resp = (struct imx_sc_msg_resp_seco_config *)&msg;
+
+ /* Pointers already checked so we just copy the data if reading */
+ if (!access)
+ switch (size) {
+ case 5:
+ *data4 = resp->data4;
+ fallthrough;
+ case 4:
+ *data3 = resp->data3;
+ fallthrough;
+ case 3:
+ *data2 = resp->data2;
+ fallthrough;
+ case 2:
+ *data1 = resp->data1;
+ fallthrough;
+ case 1:
+ *data0 = resp->data0;
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL(imx_sc_seco_secvio_config);
+
+struct imx_sc_msg_req_seco_dgo_config {
+ struct imx_sc_rpc_msg hdr;
+ u32 data;
+ u8 id;
+ u8 access;
+} __packed __aligned(4);
+
+struct imx_sc_msg_resp_seco_dgo_config {
+ struct imx_sc_rpc_msg hdr;
+ u32 data;
+} __packed __aligned(4);
+
+int imx_sc_seco_secvio_dgo_config(struct imx_sc_ipc *ipc, u8 id, u8 access,
+ u32 *data)
+{
+ struct imx_sc_msg_req_seco_dgo_config msg;
+ struct imx_sc_msg_resp_seco_dgo_config *resp;
+ struct imx_sc_rpc_msg *hdr = &msg.hdr;
+ int ret;
+
+ hdr->ver = IMX_SC_RPC_VERSION;
+ hdr->svc = IMX_SC_RPC_SVC_SECO;
+ hdr->func = IMX_SC_SECO_FUNC_SECVIO_DGO_CONFIG;
+ hdr->size = 3;
+
+ if (access) {
+ if (data)
+ msg.data = *data;
+ else
+ return -EINVAL;
+ }
+
+ msg.access = access;
+ msg.id = id;
+
+ ret = imx_scu_call_rpc(ipc, &msg, true);
+ if (ret)
+ return ret;
+
+ resp = (struct imx_sc_msg_resp_seco_dgo_config *)&msg;
+
+ if (!access && data)
+ *data = resp->data;
+
+ return 0;
+}
+EXPORT_SYMBOL(imx_sc_seco_secvio_dgo_config);
diff --git a/include/linux/firmware/imx/ipc.h b/include/linux/firmware/imx/ipc.h
index 0b4643571625..df38ab8e7e2e 100644
--- a/include/linux/firmware/imx/ipc.h
+++ b/include/linux/firmware/imx/ipc.h
@@ -25,6 +25,7 @@ enum imx_sc_rpc_svc {
IMX_SC_RPC_SVC_PAD = 6,
IMX_SC_RPC_SVC_MISC = 7,
IMX_SC_RPC_SVC_IRQ = 8,
+ IMX_SC_RPC_SVC_SECO = 9,
};
struct imx_sc_rpc_msg {
diff --git a/include/linux/firmware/imx/sci.h b/include/linux/firmware/imx/sci.h
index df17196df5ff..947e49d8bebc 100644
--- a/include/linux/firmware/imx/sci.h
+++ b/include/linux/firmware/imx/sci.h
@@ -15,6 +15,10 @@
#include <linux/firmware/imx/svc/misc.h>
#include <linux/firmware/imx/svc/pm.h>
#include <linux/firmware/imx/svc/rm.h>
+#include <linux/firmware/imx/svc/seco.h>
+
+#define IMX_SC_IRQ_SECVIO BIT(6) /* Security violation */
+#define IMX_SC_IRQ_GROUP_WAKE 3 /* Wakeup interrupts */
#if IS_ENABLED(CONFIG_IMX_SCU)
int imx_scu_enable_general_irq_channel(struct device *dev);
diff --git a/include/linux/firmware/imx/svc/seco.h b/include/linux/firmware/imx/svc/seco.h
new file mode 100644
index 000000000000..508444c02d39
--- /dev/null
+++ b/include/linux/firmware/imx/svc/seco.h
@@ -0,0 +1,69 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright 2020, 2024 NXP
+ *
+ * Header file containing the public API for the System Controller (SC)
+ * Security Controller (SECO) function.
+ *
+ * SECO_SVC (SVC) Security Controller Service
+ *
+ * Module for the Security Controller (SECO) service.
+ */
+
+#ifndef _SC_SECO_API_H
+#define _SC_SECO_API_H
+
+#include <linux/errno.h>
+#include <linux/firmware/imx/sci.h>
+
+/*
+ * This type is used to indicate RPCs/RM/SECO function calls.
+ */
+enum imx_sc_seco_func {
+ IMX_SC_SECO_FUNC_UNKNOWN = 0,
+ IMX_SC_SECO_FUNC_BUILD_INFO = 16,
+ IMX_SC_SECO_FUNC_SECVIO_ENABLE = 25,
+ IMX_SC_SECO_FUNC_SECVIO_CONFIG = 26,
+ IMX_SC_SECO_FUNC_SECVIO_DGO_CONFIG = 27,
+};
+
+#if IS_ENABLED(CONFIG_IMX_SCU)
+int imx_sc_seco_build_info(struct imx_sc_ipc *ipc, uint32_t *version,
+ uint32_t *commit);
+int imx_sc_seco_secvio_enable(struct imx_sc_ipc *ipc);
+int imx_sc_seco_secvio_config(struct imx_sc_ipc *ipc, u8 id, u8 access,
+ u32 *data0, u32 *data1, u32 *data2, u32 *data3,
+ u32 *data4, u8 size);
+int imx_sc_seco_secvio_dgo_config(struct imx_sc_ipc *ipc, u8 id, u8 access,
+ u32 *data);
+#else /* IS_ENABLED(CONFIG_IMX_SCU) */
+static inline
+int imx_sc_seco_build_info(struct imx_sc_ipc *ipc, uint32_t *version,
+ uint32_t *commit)
+{
+ return -EOPNOTSUPP;
+}
+
+static inline
+int imx_sc_seco_secvio_enable(struct imx_sc_ipc *ipc)
+{
+ return -EOPNOTSUPP;
+}
+
+static inline
+int imx_sc_seco_secvio_config(struct imx_sc_ipc *ipc, u8 id, u8 access,
+ u32 *data0, u32 *data1, u32 *data2, u32 *data3,
+ u32 *data4, u8 size)
+{
+ return -EOPNOTSUPP;
+}
+
+static inline
+int imx_sc_seco_secvio_dgo_config(struct imx_sc_ipc *ipc, u8 id, u8 access,
+ u32 *data)
+{
+ return -EOPNOTSUPP;
+}
+#endif /* IS_ENABLED(CONFIG_IMX_SCU) */
+
+#endif /* _SC_SECO_API_H */
--
2.25.1
Add secvio node definition for imx8qxp.
Signed-off-by: Franck LENORMAND <[email protected]>
Signed-off-by: Vabhav Sharma <[email protected]>
---
arch/arm64/boot/dts/freescale/imx8qxp.dtsi | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/arch/arm64/boot/dts/freescale/imx8qxp.dtsi b/arch/arm64/boot/dts/freescale/imx8qxp.dtsi
index 0313f295de2e..09d3e11eef3f 100644
--- a/arch/arm64/boot/dts/freescale/imx8qxp.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8qxp.dtsi
@@ -241,6 +241,11 @@ rtc: rtc {
compatible = "fsl,imx8qxp-sc-rtc";
};
+ secvio: secvio {
+ compatible = "fsl,imx-sc-secvio";
+ nvmem = <&ocotp>;
+ };
+
watchdog {
compatible = "fsl,imx8qxp-sc-wdt", "fsl,imx-sc-wdt";
timeout-sec = <60>;
--
2.25.1
The i.MX8QXP SoC contains the Secure Non-Volatile Storage (SNVS)
block. This block can detect specific hardware attacks.This block
can only be accessible using the SCFW API.
This module interact with the SCU which relay request to/from the
SNVS block to detect if security violation occurred.
The driver register an IRQ handle to SCU for security violation
interrupt.
When an interruption is fired, the driver inform the user.
Signed-off-by: Franck LENORMAND <[email protected]>
Signed-off-by: Vabhav Sharma <[email protected]>
---
drivers/soc/imx/Kconfig | 11 +
drivers/soc/imx/Makefile | 1 +
drivers/soc/imx/secvio/Makefile | 2 +
drivers/soc/imx/secvio/imx-secvio-debugfs.c | 274 +++++++++++++
drivers/soc/imx/secvio/imx-secvio-sc.c | 595 ++++++++++++++++++++++++++++
include/soc/imx/imx-secvio-sc.h | 216 ++++++++++
6 files changed, 1099 insertions(+)
diff --git a/drivers/soc/imx/Kconfig b/drivers/soc/imx/Kconfig
index 2a90ddd20104..3d2715a8b798 100644
--- a/drivers/soc/imx/Kconfig
+++ b/drivers/soc/imx/Kconfig
@@ -20,4 +20,15 @@ config SOC_IMX9
help
If you say yes here, you get support for the NXP i.MX9 family
+config SECVIO_SC
+ tristate "NXP SC secvio support"
+ depends on IMX_SCU
+ default y
+ help
+ If you say yes here you get support for the NXP SNVS security
+ violation module. It includes the possibility to read information
+ related to security violations and tampers. It also gives the
+ possibility to register user callbacks when a security violation
+ occurs.
+
endmenu
diff --git a/drivers/soc/imx/Makefile b/drivers/soc/imx/Makefile
index 3ad321ca608a..bda0259077be 100644
--- a/drivers/soc/imx/Makefile
+++ b/drivers/soc/imx/Makefile
@@ -4,3 +4,4 @@ obj-$(CONFIG_ARCH_MXC) += soc-imx.o
endif
obj-$(CONFIG_SOC_IMX8M) += soc-imx8m.o
obj-$(CONFIG_SOC_IMX9) += imx93-src.o
+obj-${CONFIG_SECVIO_SC} += secvio/
diff --git a/drivers/soc/imx/secvio/Makefile b/drivers/soc/imx/secvio/Makefile
new file mode 100644
index 000000000000..55ef1c044009
--- /dev/null
+++ b/drivers/soc/imx/secvio/Makefile
@@ -0,0 +1,2 @@
+obj-y += imx-secvio-sc.o
+obj-$(CONFIG_DEBUG_FS) += imx-secvio-debugfs.o
diff --git a/drivers/soc/imx/secvio/imx-secvio-debugfs.c b/drivers/soc/imx/secvio/imx-secvio-debugfs.c
new file mode 100644
index 000000000000..8dd0cd4361b9
--- /dev/null
+++ b/drivers/soc/imx/secvio/imx-secvio-debugfs.c
@@ -0,0 +1,274 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright 2019, 2024 NXP
+ */
+
+/*
+ * The module exposes below files in debugfs:
+ * - secvio/info:
+ * * Read: It returns the value of the fuses and SNVS registers which are
+ * readable and related to secvio and tampers.
+ */
+
+#include <linux/kernel.h>
+#include <linux/device.h>
+#include <linux/debugfs.h>
+#include <linux/uaccess.h>
+#include <linux/nvmem-consumer.h>
+
+#include <linux/firmware/imx/svc/misc.h>
+#include <linux/firmware/imx/svc/seco.h>
+
+#include <soc/imx/imx-secvio-sc.h>
+
+static int fuse_reader(struct device *dev, u32 id, u32 *value, u8 mul)
+{
+ struct imx_secvio_sc_data *data = dev_get_drvdata(dev);
+ u32 size_to_read = mul * sizeof(u32);
+ int ret;
+
+ ret = nvmem_device_read(data->nvmem, id, size_to_read, value);
+ if (ret < 0) {
+ dev_err(data->dev, "Failed to read fuse %d: %d\n", id, ret);
+ return ret;
+ }
+
+ if (ret != size_to_read) {
+ dev_err(data->dev, "Read only %d instead of %d\n", ret,
+ size_to_read);
+ return -ENOMEM;
+ }
+
+ return 0;
+}
+
+static int snvs_reader(struct device *dev, u32 id, u32 *value, u8 mul)
+{
+ int ret;
+ u32 *v1, *v2, *v3, *v4, *v5;
+ struct imx_secvio_sc_data *data;
+
+ data = dev_get_drvdata(dev);
+ v1 = NULL;
+ v2 = NULL;
+ v3 = NULL;
+ v4 = NULL;
+ v5 = NULL;
+
+ switch (mul) {
+ case 5:
+ v5 = &value[4];
+ fallthrough;
+ case 4:
+ v4 = &value[3];
+ fallthrough;
+ case 3:
+ v3 = &value[2];
+ fallthrough;
+ case 2:
+ v2 = &value[1];
+ fallthrough;
+ case 1:
+ v1 = &value[0];
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ ret = imx_sc_seco_secvio_config(data->ipc_handle, id, SECVIO_CONFIG_READ,
+ v1, v2, v3, v4, v5, mul);
+ if (ret < 0)
+ dev_err(dev, "Failed to read snvs reg %d: %d\n", id, ret);
+
+ return ret;
+}
+
+static int snvs_dgo_reader(struct device *dev, u32 id, u32 *value, u8 mul)
+{
+ struct imx_secvio_sc_data *data = dev_get_drvdata(dev);
+ int ret;
+
+ if (mul != 1)
+ return -EINVAL;
+
+ ret = imx_sc_seco_secvio_dgo_config(data->ipc_handle, id,
+ SECVIO_CONFIG_READ, value);
+ if (ret)
+ dev_err(dev, "Failed to read snvs dgo reg %d: %d\n", id, ret);
+
+ return ret;
+}
+
+static const struct imx_secvio_info_entry {
+ int (*reader)(struct device *dev, u32 id, u32 *value, u8 mul);
+ const char *type;
+ const char *name;
+ u32 id;
+ u8 mul;
+} gs_imx_secvio_info_list[] = {
+ {fuse_reader, "fuse", "trim", 30, 1},
+ {fuse_reader, "fuse", "trim2", 31, 1},
+ {fuse_reader, "fuse", "ctrim1", 260, 1},
+ {fuse_reader, "fuse", "ctrim2", 261, 1},
+ {fuse_reader, "fuse", "ctrim3", 262, 1},
+ {fuse_reader, "fuse", "ctrim4", 263, 1},
+ {fuse_reader, "fuse", "OSC_CAP", 768, 1},
+
+ {snvs_reader, "snvs", "HPLR", 0x0, 1},
+ {snvs_reader, "snvs", "LPLR", 0x34, 1},
+ {snvs_reader, "snvs", "HPSICR", 0xc, 1},
+ {snvs_reader, "snvs", "HPSVCR", 0x10, 1},
+ {snvs_reader, "snvs", "HPSVS", 0x18, 1},
+ {snvs_reader, "snvs", "LPSVC", 0x40, 1},
+ {snvs_reader, "snvs", "LPTDC", 0x48, 2},
+ {snvs_reader, "snvs", "LPSR", 0x4c, 1},
+ {snvs_reader, "snvs", "LPTDS", 0xa4, 1},
+ {snvs_reader, "snvs", "LPTGFC", 0x44, 3},
+ {snvs_reader, "snvs", "LPATCTL", 0xe0, 1},
+ {snvs_reader, "snvs", "LPATCLK", 0xe4, 1},
+ {snvs_reader, "snvs", "LPATRC1", 0xe8, 2},
+ {snvs_reader, "snvs", "LPMKC", 0x3c, 1},
+ {snvs_reader, "snvs", "LPSMC", 0x5c, 2},
+ {snvs_reader, "snvs", "LPPGD", 0x64, 1},
+ {snvs_reader, "snvs", "HPVID", 0xf8, 2},
+
+ {snvs_dgo_reader, "dgo", "Offset", 0x0, 1},
+ {snvs_dgo_reader, "dgo", "PUP/PD", 0x10, 1},
+ {snvs_dgo_reader, "dgo", "Anatest", 0x20, 1},
+ {snvs_dgo_reader, "dgo", "T trim", 0x30, 1},
+ {snvs_dgo_reader, "dgo", "Misc", 0x40, 1},
+ {snvs_dgo_reader, "dgo", "Vmon", 0x50, 1},
+};
+
+struct imx_secvio_sc_info_seq_data {
+ struct device *dev;
+ const struct imx_secvio_info_entry *list;
+ int size;
+};
+
+static void *imx_secvio_sc_info_seq_start(struct seq_file *m, loff_t *pos)
+{
+ struct imx_secvio_sc_info_seq_data *data = m->private;
+
+ /* Check we are not out of bound */
+ if (*pos >= data->size)
+ return NULL;
+
+ return (void *)pos;
+}
+
+static void *imx_secvio_sc_info_seq_next(struct seq_file *m, void *v, loff_t *pos)
+{
+ /* Increment the counter */
+ ++*pos;
+
+ /* call the start function which will check the index */
+ return imx_secvio_sc_info_seq_start(m, pos);
+}
+
+static void imx_secvio_sc_info_seq_stop(struct seq_file *m, void *v)
+{
+}
+
+static int imx_secvio_sc_info_seq_show(struct seq_file *m, void *v)
+{
+ struct imx_secvio_sc_info_seq_data *data = m->private;
+ const struct imx_secvio_info_entry *e;
+ int ret;
+ u32 vals[5];
+ int idx;
+
+ idx = *(loff_t *)v;
+ e = &data->list[idx];
+
+ /* Read the values */
+ ret = e->reader(data->dev, e->id, (u32 *)&vals, e->mul);
+ if (ret) {
+ dev_err(data->dev, "Fail to read %s %s (idx %d)\n", e->type,
+ e->name, e->id);
+ return 0;
+ }
+
+ seq_printf(m, "%5s/%-10s(%.3d):", e->type, e->name, e->id);
+
+ /* Loop over the values */
+ for (idx = 0; idx < e->mul; idx++)
+ seq_printf(m, " %.8x", vals[idx]);
+
+ seq_puts(m, "\n");
+
+ return 0;
+}
+
+static const struct seq_operations imx_secvio_sc_info_seq_ops = {
+ .start = imx_secvio_sc_info_seq_start,
+ .next = imx_secvio_sc_info_seq_next,
+ .stop = imx_secvio_sc_info_seq_stop,
+ .show = imx_secvio_sc_info_seq_show,
+};
+
+static int imx_secvio_sc_info_open(struct inode *inode, struct file *file)
+{
+ struct imx_secvio_sc_info_seq_data *data;
+
+ data = __seq_open_private(file, &imx_secvio_sc_info_seq_ops, sizeof(*data));
+ if (!data)
+ return -ENOMEM;
+
+ data->dev = inode->i_private;
+ data->list = gs_imx_secvio_info_list;
+ data->size = ARRAY_SIZE(gs_imx_secvio_info_list);
+
+ return 0;
+}
+
+static const struct file_operations imx_secvio_sc_info_ops = {
+ .owner = THIS_MODULE,
+ .open = imx_secvio_sc_info_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = seq_release_private,
+};
+
+static void if_debugfs_remove_recursive(void *dentry)
+{
+ debugfs_remove_recursive(dentry);
+}
+
+int imx_secvio_sc_debugfs(struct device *dev)
+{
+ struct imx_secvio_sc_data *data = dev_get_drvdata(dev);
+ struct dentry *dir;
+ int ret = 0;
+
+ /* Create a folder */
+ dir = debugfs_create_dir(dev_name(dev), NULL);
+ if (IS_ERR(dir)) {
+ dev_err(dev, "Failed to create dfs dir\n");
+ ret = PTR_ERR(dir);
+ goto exit;
+ }
+ data->dfs = dir;
+
+ ret = devm_add_action(dev, if_debugfs_remove_recursive, data->dfs);
+ if (ret) {
+ dev_err(dev, "Failed to add managed action to disable IRQ\n");
+ goto remove_fs;
+ }
+
+ /* Create the file to read info and write to reg */
+ dir = debugfs_create_file("info", 0x666, data->dfs, dev,
+ &imx_secvio_sc_info_ops);
+ if (IS_ERR(dir)) {
+ dev_err(dev, "Failed to add info to debugfs\n");
+ ret = PTR_ERR(dir);
+ goto exit;
+ }
+
+exit:
+ return ret;
+
+remove_fs:
+ debugfs_remove_recursive(data->dfs);
+ goto exit;
+}
diff --git a/drivers/soc/imx/secvio/imx-secvio-sc.c b/drivers/soc/imx/secvio/imx-secvio-sc.c
new file mode 100644
index 000000000000..a4e96c730a23
--- /dev/null
+++ b/drivers/soc/imx/secvio/imx-secvio-sc.c
@@ -0,0 +1,595 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright 2019, 2024 NXP
+ *
+ */
+
+/*
+ * The i.MX8QXP SoC contains the Secure Non-Volatile Storage (SNVS) block. This
+ * block can detect specific hardware attacks.This block can only be accessible
+ * using the SCFW API.
+ *
+ * This module interact with the SCU which relay request to/from the SNVS block
+ * to detect if security violation occurred.
+ *
+ * The module exports an API to add processing when a SV is detected:
+ * - register_imx_secvio_sc_notifier
+ * - unregister_imx_secvio_sc_notifier
+ * - imx_secvio_sc_check_state
+ * - imx_secvio_sc_clear_state
+ * - imx_secvio_sc_enable_irq
+ * - imx_secvio_sc_disable_irq
+ */
+
+#include <dt-bindings/firmware/imx/rsrc.h>
+#include <linux/device.h>
+#include <linux/fs.h>
+#include <linux/kernel.h>
+#include <linux/miscdevice.h>
+#include <linux/mod_devicetable.h>
+#include <linux/module.h>
+#include <linux/notifier.h>
+#include <linux/nvmem-consumer.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/uaccess.h>
+
+#include <linux/firmware/imx/ipc.h>
+#include <linux/firmware/imx/sci.h>
+#include <linux/firmware/imx/svc/seco.h>
+#include <linux/firmware/imx/svc/rm.h>
+#include <soc/imx/imx-secvio-sc.h>
+
+/* Reference on the driver_device */
+static struct device *imx_secvio_sc_dev;
+
+/* Register IDs for sc_seco_secvio_config API */
+#define HPSVS_ID 0x18
+#define LPS_ID 0x4c
+#define LPTDS_ID 0xa4
+#define HPVIDR_ID 0xf8
+
+#define SECO_MINOR_VERSION_SUPPORT_SECVIO_TAMPER 0x53
+#define SECO_VERSION_MINOR_MASK GENMASK(15, 0)
+
+/* Notifier list for new CB */
+static BLOCKING_NOTIFIER_HEAD(imx_secvio_sc_notifier_chain);
+
+int register_imx_secvio_sc_notifier(struct notifier_block *nb)
+{
+ return blocking_notifier_chain_register(&imx_secvio_sc_notifier_chain,
+ nb);
+}
+EXPORT_SYMBOL(register_imx_secvio_sc_notifier);
+
+int unregister_imx_secvio_sc_notifier(struct notifier_block *nb)
+{
+ return blocking_notifier_chain_unregister(&imx_secvio_sc_notifier_chain,
+ nb);
+}
+EXPORT_SYMBOL(unregister_imx_secvio_sc_notifier);
+
+static void if_imx_scu_irq_register_notifier(void *nb)
+{
+ imx_scu_irq_register_notifier(nb);
+}
+
+static void if_unregister_imx_secvio_sc_notifier(void *nb)
+{
+ unregister_imx_secvio_sc_notifier(nb);
+}
+
+static
+int imx_secvio_sc_notifier_call_chain(struct secvio_sc_notifier_info *info)
+{
+ return blocking_notifier_call_chain(&imx_secvio_sc_notifier_chain, 0,
+ (void *)info);
+}
+
+int imx_secvio_sc_get_state(struct device *dev,
+ struct secvio_sc_notifier_info *info)
+{
+ int ret, err = 0;
+ struct imx_secvio_sc_data *data;
+
+ dev = imx_secvio_sc_dev;
+ if (!dev)
+ return -EINVAL;
+
+ data = dev_get_drvdata(dev);
+
+ /* Read secvio status */
+ ret = imx_sc_seco_secvio_config(data->ipc_handle, HPSVS_ID, SECVIO_CONFIG_READ,
+ &info->hpsvs, NULL, NULL, NULL, NULL, 1);
+ if (ret) {
+ err = ret;
+ dev_err(dev, "Fail read secvio config status %d\n", ret);
+ }
+ info->hpsvs &= HPSVS_ALL_SV_MASK;
+
+ /* Read tampers status */
+ ret = imx_sc_seco_secvio_config(data->ipc_handle, LPS_ID, SECVIO_CONFIG_READ,
+ &info->lps, NULL, NULL, NULL, NULL, 1);
+ if (ret) {
+ err = ret;
+ dev_err(dev, "Fail read tamper 1 status: %d\n", ret);
+ }
+ info->lps &= LPS_ALL_TP_MASK;
+
+ ret = imx_sc_seco_secvio_config(data->ipc_handle, LPTDS_ID, SECVIO_CONFIG_READ,
+ &info->lptds, NULL, NULL, NULL, NULL, 1);
+ if (ret) {
+ err = ret;
+ dev_err(dev, "Fail read tamper 2 status: %d\n", ret);
+ }
+ info->lptds &= LPTDS_ALL_TP_MASK;
+
+ dev_dbg(dev, "Status: %.8x, %.8x, %.8x\n", info->hpsvs,
+ info->lps, info->lptds);
+
+ return err;
+}
+EXPORT_SYMBOL(imx_secvio_sc_get_state);
+
+int imx_secvio_sc_check_state(struct device *dev)
+{
+ struct secvio_sc_notifier_info info;
+ int ret;
+
+ dev = imx_secvio_sc_dev;
+
+ ret = imx_secvio_sc_get_state(dev, &info);
+ if (ret) {
+ dev_err(dev, "Failed to get secvio state\n");
+ return ret;
+ }
+
+ /* Call chain of CB registered to this module if status detected */
+ if (info.hpsvs || info.lps || info.lptds)
+ if (imx_secvio_sc_notifier_call_chain(&info))
+ dev_warn(dev,
+ "Issues when calling the notifier chain\n");
+
+ return ret;
+}
+EXPORT_SYMBOL(imx_secvio_sc_check_state);
+
+static int imx_secvio_sc_disable_irq(struct device *dev)
+{
+ int ret;
+
+ if (!dev)
+ return -EINVAL;
+
+ /* Disable the IRQ */
+ ret = imx_scu_irq_group_enable(IMX_SC_IRQ_GROUP_WAKE, IMX_SC_IRQ_SECVIO,
+ false);
+ if (ret) {
+ dev_err(dev, "Cannot disable SCU IRQ: %d\n", ret);
+ return ret;
+ }
+
+ return ret;
+}
+
+static int imx_secvio_sc_enable_irq(struct device *dev)
+{
+ int ret = 0, err;
+ u32 irq_status;
+ struct imx_secvio_sc_data *data;
+
+ if (!dev)
+ return -EINVAL;
+
+ data = dev_get_drvdata(dev);
+
+ /* Enable the IRQ */
+ ret = imx_scu_irq_group_enable(IMX_SC_IRQ_GROUP_WAKE, IMX_SC_IRQ_SECVIO,
+ true);
+ if (ret) {
+ dev_err(dev, "Cannot enable SCU IRQ: %d\n", ret);
+ goto exit;
+ }
+
+ /* Enable interrupt */
+ ret = imx_sc_seco_secvio_enable(data->ipc_handle);
+ if (ret) {
+ dev_err(dev, "Cannot enable SNVS irq: %d\n", ret);
+ goto exit;
+ }
+
+ /* Unmask interrupt */
+ ret = imx_scu_irq_get_status(IMX_SC_IRQ_GROUP_WAKE, &irq_status);
+ if (ret) {
+ dev_err(dev, "Cannot unmask irq: %d\n", ret);
+ goto exit;
+ }
+
+exit:
+ if (ret) {
+ err = imx_secvio_sc_disable_irq(dev);
+ if (err)
+ dev_warn(dev, "Failed to disable the IRQ\n");
+ }
+
+ return ret;
+}
+
+static int imx_secvio_sc_notify(struct notifier_block *nb,
+ unsigned long event, void *group)
+{
+ struct imx_secvio_sc_data *data =
+ container_of(nb, struct imx_secvio_sc_data,
+ irq_nb);
+ struct device *dev = data->dev;
+ int ret;
+
+ /* Filter event for us */
+ if (!((event & IMX_SC_IRQ_SECVIO) &&
+ (*(u8 *)group == IMX_SC_IRQ_GROUP_WAKE)))
+ return 0;
+
+ dev_warn(dev, "secvio security violation detected\n");
+
+ ret = imx_secvio_sc_check_state(dev);
+
+ /* Re-enable interrupt */
+ ret = imx_secvio_sc_enable_irq(dev);
+ if (ret)
+ dev_err(dev, "Failed to enable IRQ\n");
+
+ return ret;
+}
+
+int imx_secvio_sc_clear_state(struct device *dev, u32 hpsvs, u32 lps, u32 lptds)
+{
+ int ret;
+ struct imx_secvio_sc_data *data;
+
+ dev = imx_secvio_sc_dev;
+ if (!dev)
+ return -EINVAL;
+
+ data = dev_get_drvdata(dev);
+
+ ret = imx_sc_seco_secvio_config(data->ipc_handle, HPSVS_ID, SECVIO_CONFIG_WRITE,
+ &hpsvs, NULL, NULL, NULL, NULL, 1);
+ if (ret) {
+ dev_err(dev, "Fail to clear secvio status: %d\n", ret);
+ return ret;
+ }
+
+ ret = imx_sc_seco_secvio_config(data->ipc_handle, LPS_ID, SECVIO_CONFIG_WRITE,
+ &lps, NULL, NULL, NULL, NULL, 1);
+ if (ret) {
+ dev_err(dev, "Fail to clear tamper 1 status: %d\n", ret);
+ return ret;
+ }
+
+ ret = imx_sc_seco_secvio_config(data->ipc_handle, LPTDS_ID, SECVIO_CONFIG_WRITE,
+ &lptds, NULL, NULL, NULL, NULL, 1);
+ if (ret) {
+ dev_err(dev, "Fail to clear tamper 2 status: %d\n", ret);
+ return ret;
+ }
+
+ return ret;
+}
+EXPORT_SYMBOL(imx_secvio_sc_clear_state);
+
+static int report_to_user_notify(struct notifier_block *nb,
+ unsigned long status, void *notif_info)
+{
+ struct secvio_sc_notifier_info *info = notif_info;
+ struct imx_secvio_sc_data *data =
+ container_of(nb, struct imx_secvio_sc_data,
+ report_nb);
+ struct device *dev = data->dev;
+
+ /* Information about the security violation */
+ if (info->hpsvs & HPSVS_LP_SEC_VIO_MASK)
+ dev_info(dev, "SNVS secvio: LPSV\n");
+ if (info->hpsvs & HPSVS_SW_LPSV_MASK)
+ dev_info(dev, "SNVS secvio: SW LPSV\n");
+ if (info->hpsvs & HPSVS_SW_FSV_MASK)
+ dev_info(dev, "SNVS secvio: SW FSV\n");
+ if (info->hpsvs & HPSVS_SW_SV_MASK)
+ dev_info(dev, "SNVS secvio: SW SV\n");
+ if (info->hpsvs & HPSVS_SV5_MASK)
+ dev_info(dev, "SNVS secvio: SV 5\n");
+ if (info->hpsvs & HPSVS_SV4_MASK)
+ dev_info(dev, "SNVS secvio: SV 4\n");
+ if (info->hpsvs & HPSVS_SV3_MASK)
+ dev_info(dev, "SNVS secvio: SV 3\n");
+ if (info->hpsvs & HPSVS_SV2_MASK)
+ dev_info(dev, "SNVS secvio: SV 2\n");
+ if (info->hpsvs & HPSVS_SV1_MASK)
+ dev_info(dev, "SNVS secvio: SV 1\n");
+ if (info->hpsvs & HPSVS_SV0_MASK)
+ dev_info(dev, "SNVS secvio: SV 0\n");
+
+ /* Information about the tampers */
+ if (info->lps & LPS_ESVD_MASK)
+ dev_info(dev, "SNVS tamper: External SV\n");
+ if (info->lps & LPS_ET2D_MASK)
+ dev_info(dev, "SNVS tamper: Tamper 2\n");
+ if (info->lps & LPS_ET1D_MASK)
+ dev_info(dev, "SNVS tamper: Tamper 1\n");
+ if (info->lps & LPS_WMT2D_MASK)
+ dev_info(dev, "SNVS tamper: Wire Mesh 2\n");
+ if (info->lps & LPS_WMT1D_MASK)
+ dev_info(dev, "SNVS tamper: Wire Mesh 1\n");
+ if (info->lps & LPS_VTD_MASK)
+ dev_info(dev, "SNVS tamper: Voltage\n");
+ if (info->lps & LPS_TTD_MASK)
+ dev_info(dev, "SNVS tamper: Temperature\n");
+ if (info->lps & LPS_CTD_MASK)
+ dev_info(dev, "SNVS tamper: Clock\n");
+ if (info->lps & LPS_PGD_MASK)
+ dev_info(dev, "SNVS tamper: Power Glitch\n");
+ if (info->lps & LPS_MCR_MASK)
+ dev_info(dev, "SNVS tamper: Monotonic Counter rollover\n");
+ if (info->lps & LPS_SRTCR_MASK)
+ dev_info(dev, "SNVS tamper: Secure RTC rollover\n");
+ if (info->lps & LPS_LPTA_MASK)
+ dev_info(dev, "SNVS tamper: Time alarm\n");
+
+ if (info->lptds & LPTDS_ET10D_MASK)
+ dev_info(dev, "SNVS tamper: Tamper 10\n");
+ if (info->lptds & LPTDS_ET9D_MASK)
+ dev_info(dev, "SNVS tamper: Tamper 9\n");
+ if (info->lptds & LPTDS_ET8D_MASK)
+ dev_info(dev, "SNVS tamper: Tamper 8\n");
+ if (info->lptds & LPTDS_ET7D_MASK)
+ dev_info(dev, "SNVS tamper: Tamper 7\n");
+ if (info->lptds & LPTDS_ET6D_MASK)
+ dev_info(dev, "SNVS tamper: Tamper 6\n");
+ if (info->lptds & LPTDS_ET5D_MASK)
+ dev_info(dev, "SNVS tamper: Tamper 5\n");
+ if (info->lptds & LPTDS_ET4D_MASK)
+ dev_info(dev, "SNVS tamper: Tamper 4\n");
+ if (info->lptds & LPTDS_ET3D_MASK)
+ dev_info(dev, "SNVS tamper: Tamper 3\n");
+
+ return 0;
+}
+
+static void if_imx_secvio_sc_disable_irq(void *dev)
+{
+ imx_secvio_sc_disable_irq(dev);
+}
+
+static int imx_secvio_sc_open(struct inode *node, struct file *filp)
+{
+ filp->private_data = node->i_private;
+
+ return 0;
+}
+
+static long imx_secvio_sc_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+{
+ struct device *dev = file->private_data;
+ struct secvio_sc_notifier_info info;
+ int ret;
+
+ switch (cmd) {
+ case IMX_SECVIO_SC_GET_STATE:
+ ret = imx_secvio_sc_get_state(dev, &info);
+ if (ret)
+ return ret;
+
+ ret = copy_to_user((void *)arg, &info, sizeof(info));
+ if (ret) {
+ dev_err(dev, "Fail to copy info to user\n");
+ return -EFAULT;
+ }
+ break;
+ case IMX_SECVIO_SC_CHECK_STATE:
+ ret = imx_secvio_sc_check_state(dev);
+ if (ret)
+ return ret;
+ break;
+ case IMX_SECVIO_SC_CLEAR_STATE:
+ ret = copy_from_user(&info, (void *)arg, sizeof(info));
+ if (ret) {
+ dev_err(dev, "Fail to copy info from user\n");
+ return -EFAULT;
+ }
+
+ ret = imx_secvio_sc_clear_state(dev, info.hpsvs, info.lps,
+ info.lptds);
+ if (ret)
+ return ret;
+ break;
+ default:
+ ret = -ENOIOCTLCMD;
+ }
+
+ return ret;
+}
+
+static const struct file_operations imx_secvio_sc_fops = {
+ .owner = THIS_MODULE,
+ .open = imx_secvio_sc_open,
+ .unlocked_ioctl = imx_secvio_sc_ioctl,
+};
+
+static void if_misc_deregister(void *miscdevice)
+{
+ misc_deregister(miscdevice);
+}
+
+static int imx_secvio_sc_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct imx_secvio_sc_data *data;
+ u32 seco_version = 0;
+ bool own_secvio;
+ u32 irq_status;
+ int ret;
+
+ /* Allocate private data */
+ data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
+ if (!data)
+ return -ENOMEM;
+
+ if (!devres_open_group(dev, NULL, GFP_KERNEL))
+ return -ENOMEM;
+
+ data->dev = dev;
+
+ dev_set_drvdata(dev, data);
+
+ data->nvmem = devm_nvmem_device_get(dev, NULL);
+ if (IS_ERR(data->nvmem)) {
+ ret = PTR_ERR(data->nvmem);
+
+ if (ret != -EPROBE_DEFER)
+ dev_err_probe(dev, ret, "Failed to retrieve nvmem\n");
+
+ goto clean;
+ }
+
+ /* Get a handle */
+ ret = imx_scu_get_handle(&data->ipc_handle);
+ if (ret) {
+ dev_err(dev, "cannot get handle to scu: %d\n", ret);
+ goto clean;
+ }
+
+ /* Check the version of the SECO */
+ ret = imx_sc_seco_build_info(data->ipc_handle, &seco_version, NULL);
+ if (ret) {
+ dev_err(dev, "Failed to get seco version\n");
+ goto clean;
+ }
+
+ if ((seco_version & SECO_VERSION_MINOR_MASK) <
+ SECO_MINOR_VERSION_SUPPORT_SECVIO_TAMPER) {
+ dev_err(dev, "SECO version %.8x doesn't support all secvio\n",
+ seco_version);
+ ret = -EOPNOTSUPP;
+ goto clean;
+ }
+
+ /* Init debug FS */
+ ret = imx_secvio_sc_debugfs(dev);
+ if (ret) {
+ dev_err(dev, "Failed to set debugfs\n");
+ goto clean;
+ }
+
+ /* Check we own the SECVIO */
+ ret = imx_sc_rm_is_resource_owned(data->ipc_handle, IMX_SC_R_SECVIO);
+ if (ret < 0) {
+ dev_err(dev, "Failed to retrieve secvio ownership\n");
+ goto clean;
+ }
+
+ own_secvio = ret > 0;
+ if (!own_secvio) {
+ dev_err(dev, "Secvio resource is not owned\n");
+ ret = -EPERM;
+ goto clean;
+ }
+
+ /* Check IRQ exists and enable it */
+ ret = imx_scu_irq_get_status(IMX_SC_IRQ_GROUP_WAKE, &irq_status);
+ if (ret) {
+ dev_err(dev, "Cannot get IRQ state: %d\n", ret);
+ goto clean;
+ }
+
+ ret = imx_secvio_sc_enable_irq(dev);
+ if (ret) {
+ dev_err(dev, "Failed to enable IRQ\n");
+ goto clean;
+ }
+
+ ret = devm_add_action_or_reset(dev, if_imx_secvio_sc_disable_irq, dev);
+ if (ret) {
+ dev_err(dev, "Failed to add managed action to disable IRQ\n");
+ goto clean;
+ }
+
+ /* Register the notifier for IRQ from SNVS */
+ data->irq_nb.notifier_call = imx_secvio_sc_notify;
+ ret = imx_scu_irq_register_notifier(&data->irq_nb);
+ if (ret) {
+ dev_err(dev, "Failed to register IRQ notification handler\n");
+ goto clean;
+ }
+
+ ret = devm_add_action_or_reset(dev, if_imx_scu_irq_register_notifier,
+ &data->irq_nb);
+ if (ret) {
+ dev_err(dev, "Failed to add action to remove irq notif\n");
+ goto clean;
+ }
+
+ /* Register the notification for reporting to user */
+ data->report_nb.notifier_call = report_to_user_notify;
+ ret = register_imx_secvio_sc_notifier(&data->report_nb);
+ if (ret) {
+ dev_err(dev, "Failed to register report notif handler\n");
+ goto clean;
+ }
+
+ ret = devm_add_action_or_reset(dev, if_unregister_imx_secvio_sc_notifier,
+ &data->report_nb);
+ if (ret) {
+ dev_err(dev, "Failed to add action to remove report notif\n");
+ goto clean;
+ }
+
+ /* Register misc device for IOCTL */
+ data->miscdev.name = devm_kstrdup(dev, "secvio-sc", GFP_KERNEL);
+ data->miscdev.minor = MISC_DYNAMIC_MINOR;
+ data->miscdev.fops = &imx_secvio_sc_fops;
+ data->miscdev.parent = dev;
+ ret = misc_register(&data->miscdev);
+ if (ret) {
+ dev_err(dev, "failed to register misc device\n");
+ return ret;
+ }
+
+ ret = devm_add_action_or_reset(dev, if_misc_deregister, &data->miscdev);
+ if (ret) {
+ dev_err(dev, "Failed to add action to unregister miscdev\n");
+ goto clean;
+ }
+
+ imx_secvio_sc_dev = dev;
+
+ /* Process current state of the secvio and tampers */
+ imx_secvio_sc_check_state(dev);
+
+ devres_remove_group(dev, NULL);
+
+ return ret;
+
+clean:
+ devres_release_group(dev, NULL);
+
+ return ret;
+}
+
+static const struct of_device_id imx_secvio_sc_dt_ids[] = {
+ { .compatible = "fsl,imx-sc-secvio", },
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, imx_secvio_sc_dt_ids);
+
+static struct platform_driver imx_secvio_sc_driver = {
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = "imx-secvio-sc",
+ .of_match_table = imx_secvio_sc_dt_ids,
+ },
+ .probe = imx_secvio_sc_probe,
+};
+module_platform_driver(imx_secvio_sc_driver);
+
+MODULE_AUTHOR("Franck LENORMAND <[email protected]>");
+MODULE_DESCRIPTION("NXP i.MX driver to handle SNVS secvio irq sent by SCFW");
+MODULE_LICENSE("GPL");
diff --git a/include/soc/imx/imx-secvio-sc.h b/include/soc/imx/imx-secvio-sc.h
new file mode 100644
index 000000000000..d8c9208217fe
--- /dev/null
+++ b/include/soc/imx/imx-secvio-sc.h
@@ -0,0 +1,216 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright 2019, 2024 NXP
+ */
+
+#ifndef _MISC_IMX_SECVIO_SC_H_
+#define _MISC_IMX_SECVIO_SC_H_
+
+#include <linux/kernel.h>
+#include <linux/miscdevice.h>
+#include <linux/notifier.h>
+
+/* Bitmask of the security violation status bit in the HPSVS register */
+#define HPSVS_LP_SEC_VIO_MASK BIT(31)
+#define HPSVS_SW_LPSV_MASK BIT(15)
+#define HPSVS_SW_FSV_MASK BIT(14)
+#define HPSVS_SW_SV_MASK BIT(13)
+#define HPSVS_SV5_MASK BIT(5)
+#define HPSVS_SV4_MASK BIT(4)
+#define HPSVS_SV3_MASK BIT(3)
+#define HPSVS_SV2_MASK BIT(2)
+#define HPSVS_SV1_MASK BIT(1)
+#define HPSVS_SV0_MASK BIT(0)
+
+/* Bitmask of all security violation status bit in the HPSVS register */
+#define HPSVS_ALL_SV_MASK (HPSVS_LP_SEC_VIO_MASK | \
+ HPSVS_SW_LPSV_MASK | \
+ HPSVS_SW_FSV_MASK | \
+ HPSVS_SW_SV_MASK | \
+ HPSVS_SV5_MASK | \
+ HPSVS_SV4_MASK | \
+ HPSVS_SV3_MASK | \
+ HPSVS_SV2_MASK | \
+ HPSVS_SV1_MASK | \
+ HPSVS_SV0_MASK)
+
+/*
+ * Bitmask of the security violation and tampers status bit in the LPS register
+ */
+#define LPS_ESVD_MASK BIT(16)
+#define LPS_ET2D_MASK BIT(10)
+#define LPS_ET1D_MASK BIT(9)
+#define LPS_WMT2D_MASK BIT(8)
+#define LPS_WMT1D_MASK BIT(7)
+#define LPS_VTD_MASK BIT(6)
+#define LPS_TTD_MASK BIT(5)
+#define LPS_CTD_MASK BIT(4)
+#define LPS_PGD_MASK BIT(3)
+#define LPS_MCR_MASK BIT(2)
+#define LPS_SRTCR_MASK BIT(1)
+#define LPS_LPTA_MASK BIT(0)
+
+/*
+ * Bitmask of all security violation and tampers status bit in the LPS register
+ */
+#define LPS_ALL_TP_MASK (LPS_ESVD_MASK | \
+ LPS_ET2D_MASK | \
+ LPS_ET1D_MASK | \
+ LPS_WMT2D_MASK | \
+ LPS_WMT1D_MASK | \
+ LPS_VTD_MASK | \
+ LPS_TTD_MASK | \
+ LPS_CTD_MASK | \
+ LPS_PGD_MASK | \
+ LPS_MCR_MASK | \
+ LPS_SRTCR_MASK | \
+ LPS_LPTA_MASK)
+
+/*
+ * Bitmask of the security violation and tampers status bit in the LPTDS
+ * register
+ */
+#define LPTDS_ET10D_MASK BIT(7)
+#define LPTDS_ET9D_MASK BIT(6)
+#define LPTDS_ET8D_MASK BIT(5)
+#define LPTDS_ET7D_MASK BIT(4)
+#define LPTDS_ET6D_MASK BIT(3)
+#define LPTDS_ET5D_MASK BIT(2)
+#define LPTDS_ET4D_MASK BIT(1)
+#define LPTDS_ET3D_MASK BIT(0)
+
+/*
+ * Bitmask of all security violation and tampers status bit in the LPTDS
+ * register
+ */
+#define LPTDS_ALL_TP_MASK (LPTDS_ET10D_MASK | \
+ LPTDS_ET9D_MASK | \
+ LPTDS_ET8D_MASK | \
+ LPTDS_ET7D_MASK | \
+ LPTDS_ET6D_MASK | \
+ LPTDS_ET5D_MASK | \
+ LPTDS_ET4D_MASK | \
+ LPTDS_ET3D_MASK)
+
+/* Access for sc_seco_secvio_config API */
+#define SECVIO_CONFIG_READ 0
+#define SECVIO_CONFIG_WRITE 1
+
+/* Internal Structure */
+struct imx_secvio_sc_data {
+ struct device *dev;
+
+ struct imx_sc_ipc *ipc_handle;
+
+ struct notifier_block irq_nb;
+ struct notifier_block report_nb;
+
+ struct nvmem_device *nvmem;
+
+ struct miscdevice miscdev;
+
+#ifdef CONFIG_DEBUG_FS
+ struct dentry *dfs;
+#endif
+
+ u32 version;
+};
+
+/* Struct for notification */
+/**
+ * struct secvio_sc_notifier_info - Information about the status of the SNVS
+ * @hpsvs: status from register HPSVS
+ * @lps: status from register LPS
+ * @lptds: status from register LPTDS
+ */
+struct secvio_sc_notifier_info {
+ u32 hpsvs;
+ u32 lps;
+ u32 lptds;
+};
+
+/**
+ * register_imx_secvio_sc_notifier() - Register a notifier
+ *
+ * @nb: The notifier block structure
+ *
+ * Register a function to notify to the imx-secvio-sc module. The function
+ * will be notified when a check of the state of the SNVS happens: called by
+ * a user or triggered by an interruption form the SNVS.
+ *
+ * The struct secvio_sc_notifier_info is passed as data to the notifier.
+ *
+ * Return: 0 in case of success
+ */
+int register_imx_secvio_sc_notifier(struct notifier_block *nb);
+
+/**
+ * unregister_imx_secvio_sc_notifier() - Unregister a notifier
+ *
+ * @nb: The notifier block structure
+ *
+ * Return: 0 in case of success
+ */
+int unregister_imx_secvio_sc_notifier(struct notifier_block *nb);
+
+/**
+ * imx_secvio_sc_get_state() - Get the state of the SNVS
+ *
+ * @dev: Pointer to the struct device of secvio
+ * @info: The structure containing the state of the SNVS
+ *
+ * Return: 0 in case of success
+ */
+int imx_secvio_sc_get_state(struct device *dev, struct secvio_sc_notifier_info *info);
+
+/**
+ * imx_secvio_sc_check_state() - Check the state of the SNVS
+ *
+ * If a security violation or a tamper is detected, the list of notifier
+ * (registered using register_imx_secvio_sc_notifier() ) will be called
+ *
+ * @dev: Pointer to the struct device of secvio
+ *
+ * Return: 0 in case of success
+ */
+int imx_secvio_sc_check_state(struct device *dev);
+
+/**
+ * imx_secvio_sc_clear_state() - Clear the state of the SNVS
+ *
+ * @dev: Pointer to the struct device of secvio
+ * @hpsvs: Value to write to HPSVS register
+ * @lps: Value to write to LPS register
+ * @lptds: Value to write to LPTDSregister
+ *
+ * The function will write the value provided to the corresponding register
+ * which will clear the status of the bits set.
+ *
+ * Return: 0 in case of success
+ */
+int imx_secvio_sc_clear_state(struct device *dev, u32 hpsvs, u32 lps, u32 lptds);
+
+/* Commands of the ioctl interface */
+enum ioctl_cmd_t {
+ GET_STATE,
+ CHECK_STATE,
+ CLEAR_STATE,
+};
+
+/* Definition for the ioctl interface */
+#define IMX_SECVIO_SC_GET_STATE _IOR('S', GET_STATE, \
+ struct secvio_sc_notifier_info)
+#define IMX_SECVIO_SC_CHECK_STATE _IO('S', CHECK_STATE)
+#define IMX_SECVIO_SC_CLEAR_STATE _IOW('S', CLEAR_STATE, \
+ struct secvio_sc_notifier_info)
+
+#ifdef CONFIG_DEBUG_FS
+int imx_secvio_sc_debugfs(struct device *dev);
+#else
+static inline
+int imx_secvio_sc_debugfs(struct device *dev)
+{
+ return 0;
+}
+#endif /* CONFIG_DEBUG_FS */
+#endif /* _MISC_IMX_SECVIO_SC_H_ */
--
2.25.1
On Thu, May 09, 2024 at 02:45:32AM +0200, Vabhav Sharma wrote:
> Document the secvio device tree bindings.
reduntant sentence.
>
> The tampers are security feature available on i.MX products and
> managed by SNVS block.The tamper goal is to detect the variation
^^ space here
> of hardware or physical parameters, which can indicate an attack.
>
> The SNVS, which provides secure non-volatile storage, allows to
> detect some hardware attacks against the SoC.They are connected
^^ space here
> to the security-violation ports, which send an alert when an
> out-of-range value is detected.
>
> The "imx-secvio-sc" module is designed to report security violations
> and tamper triggering via SCU firmware to the user.
>
> Add the imx-scu secvio sub node and secvio sub node description.
>
> Signed-off-by: Franck LENORMAND <[email protected]>
> Signed-off-by: Vabhav Sharma <[email protected]>
> ---
> .../bindings/arm/freescale/fsl,scu-secvio.yaml | 35 ++++++++++++++++++++++
> .../devicetree/bindings/firmware/fsl,scu.yaml | 10 +++++++
> 2 files changed, 45 insertions(+)
>
> diff --git a/Documentation/devicetree/bindings/arm/freescale/fsl,scu-secvio.yaml b/Documentation/devicetree/bindings/arm/freescale/fsl,scu-secvio.yaml
> new file mode 100644
> index 000000000000..30dc1e21f903
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/arm/freescale/fsl,scu-secvio.yaml
> @@ -0,0 +1,35 @@
> +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/arm/freescale/fsl,scu-secvio.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: NXP i.MX Security Violation driver
Violation detect driver
> +
> +maintainers:
> + - Franck LENORMAND <[email protected]>
> +
> +description: |
Needn't "|"
> + Receive security violation from the SNVS via the SCU firmware. Allow to
> + register notifier for additional processing
> +
> +properties:
> + compatible:
> + enum:
> + - fsl,imx-sc-secvio
> +
> + nvmem:
> + maxItems: 1
> +
any interrupt defined? how do you notify such violation event?
> +required:
> + - compatible
> + - nvmem
> +
> +additionalProperties: false
> +
> +examples:
> + - |
> + secvio {
> + compatible = "fsl,imx-sc-secvio";
> + nvmem = <&ocotp>;
> + };
> diff --git a/Documentation/devicetree/bindings/firmware/fsl,scu.yaml b/Documentation/devicetree/bindings/firmware/fsl,scu.yaml
> index 557e524786c2..b40e127fdc88 100644
> --- a/Documentation/devicetree/bindings/firmware/fsl,scu.yaml
> +++ b/Documentation/devicetree/bindings/firmware/fsl,scu.yaml
> @@ -129,6 +129,11 @@ properties:
> RTC controller provided by the SCU
> $ref: /schemas/rtc/fsl,scu-rtc.yaml
>
> + secvio:
> + description:
> + Receive security violation from the SNVS via the SCU firmware
> + $ref: /schemas/arm/freescale/fsl,scu-secvio.yaml
> +
> thermal-sensor:
> description:
> Thermal sensor provided by the SCU
> @@ -197,6 +202,11 @@ examples:
> compatible = "fsl,imx8qxp-sc-rtc";
> };
>
> + secvio {
> + compatible = "fsl,imx-sc-secvio";
> + nvmem = <&ocotp>;
> + };
> +
> keys {
> compatible = "fsl,imx8qxp-sc-key", "fsl,imx-sc-key";
> linux,keycodes = <KEY_POWER>;
>
> --
> 2.25.1
>
On 09/05/2024 02:45, Vabhav Sharma wrote:
> Document the secvio device tree bindings.
>
> The tampers are security feature available on i.MX products and
> managed by SNVS block.The tamper goal is to detect the variation
> of hardware or physical parameters, which can indicate an attack.
>
> The SNVS, which provides secure non-volatile storage, allows to
> detect some hardware attacks against the SoC.They are connected
> to the security-violation ports, which send an alert when an
> out-of-range value is detected.
>
> The "imx-secvio-sc" module is designed to report security violations
> and tamper triggering via SCU firmware to the user.
>
> Add the imx-scu secvio sub node and secvio sub node description.
>
> Signed-off-by: Franck LENORMAND <[email protected]>
> Signed-off-by: Vabhav Sharma <[email protected]>
> ---
That's not v1, right? What changed? Why do we have to guess this?
This is thoroughly documented in kernel process so read the
documentation before posting.
> .../bindings/arm/freescale/fsl,scu-secvio.yaml | 35 ++++++++++++++++++++++
> .../devicetree/bindings/firmware/fsl,scu.yaml | 10 +++++++
> 2 files changed, 45 insertions(+)
>
> diff --git a/Documentation/devicetree/bindings/arm/freescale/fsl,scu-secvio.yaml b/Documentation/devicetree/bindings/arm/freescale/fsl,scu-secvio.yaml
> new file mode 100644
> index 000000000000..30dc1e21f903
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/arm/freescale/fsl,scu-secvio.yaml
> @@ -0,0 +1,35 @@
> +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/arm/freescale/fsl,scu-secvio.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: NXP i.MX Security Violation driver
Bindings are for hardware, not drivers. Describe hardware.
> +
> +maintainers:
> + - Franck LENORMAND <[email protected]>
> +
> +description: |
Do not need '|' unless you need to preserve formatting.
> + Receive security violation from the SNVS via the SCU firmware. Allow to
> + register notifier for additional processing
Notifier? That's a Linux thing, how does it relate to the hardware?
> +
> +properties:
> + compatible:
> + enum:
> + - fsl,imx-sc-secvio
Missing SoC compatibles.
So no, that's just abuse of DT to instantiate driver.
NAK. Drop the binding.
Best regards,
Krzysztof
On 09/05/2024 05:06, Frank Li wrote:
> On Thu, May 09, 2024 at 02:45:32AM +0200, Vabhav Sharma wrote:
>> Document the secvio device tree bindings.
>
> reduntant sentence.
>>
>> The tampers are security feature available on i.MX products and
>> managed by SNVS block.The tamper goal is to detect the variation
> ^^ space here
>
>> of hardware or physical parameters, which can indicate an attack.
>>
>> The SNVS, which provides secure non-volatile storage, allows to
>> detect some hardware attacks against the SoC.They are connected
> ^^ space here
>> to the security-violation ports, which send an alert when an
>> out-of-range value is detected.
>>
>> The "imx-secvio-sc" module is designed to report security violations
>> and tamper triggering via SCU firmware to the user.
>>
>> Add the imx-scu secvio sub node and secvio sub node description.
>>
>> Signed-off-by: Franck LENORMAND <[email protected]>
>> Signed-off-by: Vabhav Sharma <[email protected]>
>> ---
>> .../bindings/arm/freescale/fsl,scu-secvio.yaml | 35 ++++++++++++++++++++++
>> .../devicetree/bindings/firmware/fsl,scu.yaml | 10 +++++++
>> 2 files changed, 45 insertions(+)
>>
>> diff --git a/Documentation/devicetree/bindings/arm/freescale/fsl,scu-secvio.yaml b/Documentation/devicetree/bindings/arm/freescale/fsl,scu-secvio.yaml
>> new file mode 100644
>> index 000000000000..30dc1e21f903
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/arm/freescale/fsl,scu-secvio.yaml
>> @@ -0,0 +1,35 @@
>> +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
>> +%YAML 1.2
>> +---
>> +$id: http://devicetree.org/schemas/arm/freescale/fsl,scu-secvio.yaml#
>> +$schema: http://devicetree.org/meta-schemas/core.yaml#
>> +
>> +title: NXP i.MX Security Violation driver
>
> Violation detect driver
Bindings are not for drivers.
Best regards,
Krzysztof
On 09/05/2024 02:45, Vabhav Sharma wrote:
> The tampers are security feature available on i.MX products and
> managed by SNVS block.The tamper goal is to detect the variation
> of hardware or physical parameters, which can indicate an attack.
>
> The SNVS, which provides secure non-volatile storage, allows to
> detect some hardware attacks against the SoC.They are connected
> to the security-violation ports, which send an alert when an
> out-of-range value is detected.
>
> This detection is done by:
> -Analog tampers: measure analogic values
> - External clock frequency.
> - Temperature.
> - Voltage.
>
> - Digital tampers:
> - External tamper
> - Other detectors:
> - Secure real-time counter rollover tamper.
> - Monotonic counter rollover tamper.
> - Power supply glitch tamper.
>
> The on-chip sensors for voltage, temperature, and clock frequency
> indicate if tamper scenarios may be present. These sensors generate an
> out-of-range signal that causes a security violation to clear the
> authentication and storage keys and to block access to sensitive
> information.
>
> Add linux module secvio driver to handle security violation interrupt.
>
> The "imx-secvio-sc" module is designed to report security violations
> and tamper triggering to the user.
>
> The functionalities of the module are accessible via the "debugfs"
> kernel.The folder containing the interface files for the module is
> "<kernel_debugfs>/secvio/".
>
> Get status
> Reading from the "info" file will return the status of security:
> - Fuse related to security tampers.
> - SNVS readable registers.
> - DGO registers.
>
> Signed-off-by: Vabhav Sharma <[email protected]>
> ---
> Vabhav Sharma (4):
> dt-bindings: firmware: secvio: Add device tree bindings
> firmware: imx: Add SC APIs required for secvio module
> soc: imx: secvio: Add support for SNVS secvio and tamper via SCFW
> arm64: dts: imx8q: Add node for Security Violation
Please version your patches correctly and provide changelog.
I wrote about b4 already, which solves this as well.
What changed here?
Best regards,
Krzysztof
> -----Original Message-----
> From: Krzysztof Kozlowski <[email protected]>
> Sent: Thursday, May 9, 2024 11:21 AM
> To: Vabhav Sharma <[email protected]>; Rob Herring
> <[email protected]>; Krzysztof Kozlowski <[email protected]>; Conor Dooley
> <[email protected]>; Franck Lenormand <[email protected]>;
> Aisheng Dong <[email protected]>; Shawn Guo
> <[email protected]>; Sascha Hauer <[email protected]>;
> Pengutronix Kernel Team <[email protected]>; Fabio Estevam
> <[email protected]>; Peng Fan <[email protected]>
> Cc: [email protected]; [email protected];
> [email protected]; [email protected]; Varun Sethi
> <[email protected]>; Silvano Di Ninno <[email protected]>; Pankaj
> Gupta <[email protected]>; Frank Li <[email protected]>; Daniel Baluta
> <[email protected]>; Iuliana Prodan <[email protected]>; Horia
> Geanta <[email protected]>
> Subject: [EXT] Re: [PATCH 0/4] soc: imx: secvio: Add secvio support
>
> 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 09/05/2024 02:45, Vabhav Sharma wrote:
> > The tampers are security feature available on i.MX products and
> > managed by SNVS block.The tamper goal is to detect the variation of
> > hardware or physical parameters, which can indicate an attack.
> >
> > The SNVS, which provides secure non-volatile storage, allows to detect
> > some hardware attacks against the SoC.They are connected to the
> > security-violation ports, which send an alert when an out-of-range
> > value is detected.
> >
> > This detection is done by:
> > -Analog tampers: measure analogic values
> > - External clock frequency.
> > - Temperature.
> > - Voltage.
> >
> > - Digital tampers:
> > - External tamper
> > - Other detectors:
> > - Secure real-time counter rollover tamper.
> > - Monotonic counter rollover tamper.
> > - Power supply glitch tamper.
> >
> > The on-chip sensors for voltage, temperature, and clock frequency
> > indicate if tamper scenarios may be present. These sensors generate an
> > out-of-range signal that causes a security violation to clear the
> > authentication and storage keys and to block access to sensitive
> > information.
> >
> > Add linux module secvio driver to handle security violation interrupt.
> >
> > The "imx-secvio-sc" module is designed to report security violations
> > and tamper triggering to the user.
> >
> > The functionalities of the module are accessible via the "debugfs"
> > kernel.The folder containing the interface files for the module is
> > "<kernel_debugfs>/secvio/".
> >
> > Get status
> > Reading from the "info" file will return the status of security:
> > - Fuse related to security tampers.
> > - SNVS readable registers.
> > - DGO registers.
> >
> > Signed-off-by: Vabhav Sharma <[email protected]>
> > ---
> > Vabhav Sharma (4):
> > dt-bindings: firmware: secvio: Add device tree bindings
> > firmware: imx: Add SC APIs required for secvio module
> > soc: imx: secvio: Add support for SNVS secvio and tamper via SCFW
> > arm64: dts: imx8q: Add node for Security Violation
>
> Please version your patches correctly and provide changelog.
Sure, I will update the changelog for v1 and v2.
>
> I wrote about b4 already, which solves this as well.
Ok, I used it, will provide details for changelog in next version
>
> What changed here?
As highlighted by you, Used b4 script to auto add all maintainer/reviewer.
>
> Best regards,
> Krzysztof
> -----Original Message-----
> From: Krzysztof Kozlowski <[email protected]>
> Sent: Thursday, May 9, 2024 11:24 AM
> To: Vabhav Sharma <[email protected]>; Rob Herring
> <[email protected]>; Krzysztof Kozlowski <[email protected]>; Conor Dooley
> <[email protected]>; Franck Lenormand <[email protected]>;
> Aisheng Dong <[email protected]>; Shawn Guo
> <[email protected]>; Sascha Hauer <[email protected]>;
> Pengutronix Kernel Team <[email protected]>; Fabio Estevam
> <[email protected]>; Peng Fan <[email protected]>
> Cc: [email protected]; [email protected];
> [email protected]; [email protected]; Varun Sethi
> <[email protected]>; Silvano Di Ninno <[email protected]>; Pankaj
> Gupta <[email protected]>; Frank Li <[email protected]>; Daniel Baluta
> <[email protected]>
> Subject: [EXT] Re: [PATCH 1/4] dt-bindings: firmware: secvio: Add device tree
> bindings
>
> 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 09/05/2024 02:45, Vabhav Sharma wrote:
> > Document the secvio device tree bindings.
> >
> > The tampers are security feature available on i.MX products and
> > managed by SNVS block.The tamper goal is to detect the variation of
> > hardware or physical parameters, which can indicate an attack.
> >
> > The SNVS, which provides secure non-volatile storage, allows to detect
> > some hardware attacks against the SoC.They are connected to the
> > security-violation ports, which send an alert when an out-of-range
> > value is detected.
> >
> > The "imx-secvio-sc" module is designed to report security violations
> > and tamper triggering via SCU firmware to the user.
> >
> > Add the imx-scu secvio sub node and secvio sub node description.
> >
> > Signed-off-by: Franck LENORMAND <[email protected]>
> > Signed-off-by: Vabhav Sharma <[email protected]>
> > ---
>
> That's not v1, right? What changed? Why do we have to guess this?
Yes, correct this is v2, I will provide changelog details in v3 for v2 and v1
>
> This is thoroughly documented in kernel process so read the documentation
> before posting.
>
>
> > .../bindings/arm/freescale/fsl,scu-secvio.yaml | 35
> ++++++++++++++++++++++
> > .../devicetree/bindings/firmware/fsl,scu.yaml | 10 +++++++
> > 2 files changed, 45 insertions(+)
> >
> > diff --git
> > a/Documentation/devicetree/bindings/arm/freescale/fsl,scu-secvio.yaml
> > b/Documentation/devicetree/bindings/arm/freescale/fsl,scu-secvio.yaml
> > new file mode 100644
> > index 000000000000..30dc1e21f903
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/arm/freescale/fsl,scu-secvio.y
> > +++ aml
> > @@ -0,0 +1,35 @@
> > +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) %YAML 1.2
> > +---
> > +$id:
> > +https://eur01.safelinks.protection.outlook.com/?url=http%3A%2F%2Fdevi
> > +cetree.org%2Fschemas%2Farm%2Ffreescale%2Ffsl%2Cscu-
> secvio.yaml%23&dat
> >
> +a=05%7C02%7Cvabhav.sharma%40nxp.com%7Cdea3ecc999444d8c3f7108dc
> 6fec67e
> >
> +b%7C686ea1d3bc2b4c6fa92cd99c5c301635%7C0%7C0%7C63850830837113
> 8503%7CU
> >
> +nknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTi
> I6Ik1h
> >
> +aWwiLCJXVCI6Mn0%3D%7C0%7C%7C%7C&sdata=Nl9F3A9%2BTraZboxg3KXT
> 35pIPAyYZ
> > +51URq1wff7XCmo%3D&reserved=0
> > +$schema:
> > +https://eur01.safelinks.protection.outlook.com/?url=http%3A%2F%2Fdevi
> > +cetree.org%2Fmeta-
> schemas%2Fcore.yaml%23&data=05%7C02%7Cvabhav.sharma
> >
> +%40nxp.com%7Cdea3ecc999444d8c3f7108dc6fec67eb%7C686ea1d3bc2b4c
> 6fa92cd
> >
> +99c5c301635%7C0%7C0%7C638508308371152796%7CUnknown%7CTWFpb
> GZsb3d8eyJW
> >
> +IjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C
> 0%7C
> >
> +%7C%7C&sdata=dwOG7uVGtO8rccW7vcRwvc2%2B9gyDroIsWnFlXyFxbOM%
> 3D&reserve
> > +d=0
> > +
> > +title: NXP i.MX Security Violation driver
>
> Bindings are for hardware, not drivers. Describe hardware.
Yes, I will use "security violation detection hardware exported through SCU firmware"
>
> > +
> > +maintainers:
> > + - Franck LENORMAND <[email protected]>
> > +
> > +description: |
>
> Do not need '|' unless you need to preserve formatting.
Ok
>
> > + Receive security violation from the SNVS via the SCU firmware.
> > + Allow to register notifier for additional processing
>
> Notifier? That's a Linux thing, how does it relate to the hardware?
Violation detected by HW will call driver API to signify the violation.
>
> > +
> > +properties:
> > + compatible:
> > + enum:
> > + - fsl,imx-sc-secvio
>
> Missing SoC compatibles.
Ok, I will use fsl,imx8dxl-sc-secvio
>
> So no, that's just abuse of DT to instantiate driver.
>
> NAK. Drop the binding.
I will detail the dt binding to describe the real hardware
>
> Best regards,
> Krzysztof
> -----Original Message-----
> From: Krzysztof Kozlowski <[email protected]>
> Sent: Thursday, May 9, 2024 11:24 AM
> To: Frank Li <[email protected]>; Vabhav Sharma <[email protected]>
> Cc: Rob Herring <[email protected]>; Krzysztof Kozlowski
> <[email protected]>; Conor Dooley <[email protected]>; Franck
> Lenormand <[email protected]>; Aisheng Dong
> <[email protected]>; Shawn Guo <[email protected]>; Sascha
> Hauer <[email protected]>; Pengutronix Kernel Team
> <[email protected]>; Fabio Estevam <[email protected]>; Peng Fan
> <[email protected]>; [email protected]; linux-
> [email protected]; [email protected]; linux-arm-
> [email protected]; Varun Sethi <[email protected]>; Silvano Di Ninno
> <[email protected]>; Pankaj Gupta <[email protected]>; Daniel
> Baluta <[email protected]>
> Subject: [EXT] Re: [PATCH 1/4] dt-bindings: firmware: secvio: Add device tree
> bindings
>
> 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 09/05/2024 05:06, Frank Li wrote:
> > On Thu, May 09, 2024 at 02:45:32AM +0200, Vabhav Sharma wrote:
> >> Document the secvio device tree bindings.
> >
> > reduntant sentence.
> >>
> >> The tampers are security feature available on i.MX products and
> >> managed by SNVS block.The tamper goal is to detect the variation
> > ^^ space here
> >
> >> of hardware or physical parameters, which can indicate an attack.
> >>
> >> The SNVS, which provides secure non-volatile storage, allows to
> >> detect some hardware attacks against the SoC.They are connected
> > ^^ space here
> >> to the security-violation ports, which send an alert when an
> >> out-of-range value is detected.
> >>
> >> The "imx-secvio-sc" module is designed to report security violations
> >> and tamper triggering via SCU firmware to the user.
> >>
> >> Add the imx-scu secvio sub node and secvio sub node description.
> >>
> >> Signed-off-by: Franck LENORMAND <[email protected]>
> >> Signed-off-by: Vabhav Sharma <[email protected]>
> >> ---
> >> .../bindings/arm/freescale/fsl,scu-secvio.yaml | 35
> ++++++++++++++++++++++
> >> .../devicetree/bindings/firmware/fsl,scu.yaml | 10 +++++++
> >> 2 files changed, 45 insertions(+)
> >>
> >> diff --git
> >> a/Documentation/devicetree/bindings/arm/freescale/fsl,scu-secvio.yaml
> >> b/Documentation/devicetree/bindings/arm/freescale/fsl,scu-secvio.yaml
> >> new file mode 100644
> >> index 000000000000..30dc1e21f903
> >> --- /dev/null
> >> +++ b/Documentation/devicetree/bindings/arm/freescale/fsl,scu-secvio.
> >> +++ yaml
> >> @@ -0,0 +1,35 @@
> >> +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) %YAML 1.2
> >> +---
> >> +$id:
> >> +https://eur01.safelinks.protection.outlook.com/?url=http%3A%2F%2Fdev
> >> +icetree.org%2Fschemas%2Farm%2Ffreescale%2Ffsl%2Cscu-
> secvio.yaml%23&d
> >>
> +ata=05%7C02%7Cvabhav.sharma%40nxp.com%7C16a07379ee384ddc18f908
> dc6fec
> >>
> +75e7%7C686ea1d3bc2b4c6fa92cd99c5c301635%7C0%7C0%7C63850830857
> 3434788
> >>
> +%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIi
> LCJBTiI
> >>
> +6Ik1haWwiLCJXVCI6Mn0%3D%7C0%7C%7C%7C&sdata=MBhqXwhXIQjDb3A
> RdYJ4U5EXM
> >> +ryEy%2F9m5X6jGuNhHxo%3D&reserved=0
> >> +$schema:
> >> +https://eur01.safelinks.protection.outlook.com/?url=http%3A%2F%2Fdev
> >> +icetree.org%2Fmeta-
> schemas%2Fcore.yaml%23&data=05%7C02%7Cvabhav.shar
> >>
> +ma%40nxp.com%7C16a07379ee384ddc18f908dc6fec75e7%7C686ea1d3bc2
> b4c6fa9
> >>
> +2cd99c5c301635%7C0%7C0%7C638508308573446476%7CUnknown%7CTWF
> pbGZsb3d8
> >>
> +eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3
> D%7
> >>
> +C0%7C%7C%7C&sdata=m0RzUoVfr%2F2HkLlSOjhTq%2FQX3EM6ZAW7h5hQ
> Eidnc1g%3D
> >> +&reserved=0
> >> +
> >> +title: NXP i.MX Security Violation driver
> >
> > Violation detect driver
>
> Bindings are not for drivers.
This is security violation detection hardware exported through SCU firmware. I will detail the HW in the binding
>
> Best regards,
> Krzysztof
> -----Original Message-----
> From: Frank Li <[email protected]>
> Sent: Thursday, May 9, 2024 8:37 AM
> To: Vabhav Sharma <[email protected]>
> Cc: Rob Herring <[email protected]>; Krzysztof Kozlowski
> <[email protected]>; Conor Dooley <[email protected]>; Franck
> Lenormand <[email protected]>; Aisheng Dong
> <[email protected]>; Shawn Guo <[email protected]>; Sascha
> Hauer <[email protected]>; Pengutronix Kernel Team
> <[email protected]>; Fabio Estevam <[email protected]>; Peng Fan
> <[email protected]>; [email protected]; linux-
> [email protected]; [email protected]; linux-arm-
> [email protected]; Varun Sethi <[email protected]>; Silvano Di Ninno
> <[email protected]>; Pankaj Gupta <[email protected]>; Daniel
> Baluta <[email protected]>
> Subject: Re: [PATCH 1/4] dt-bindings: firmware: secvio: Add device tree
> bindings
>
> On Thu, May 09, 2024 at 02:45:32AM +0200, Vabhav Sharma wrote:
> > Document the secvio device tree bindings.
>
> reduntant sentence.
Ok, I am removing in v3.
> >
> > The tampers are security feature available on i.MX products and
> > managed by SNVS block.The tamper goal is to detect the variation
> ^^ space here
>
> > of hardware or physical parameters, which can indicate an attack.
> >
> > The SNVS, which provides secure non-volatile storage, allows to detect
> > some hardware attacks against the SoC.They are connected
> ^^ space here
> > to the security-violation ports, which send an alert when an
> > out-of-range value is detected.
> >
> > The "imx-secvio-sc" module is designed to report security violations
> > and tamper triggering via SCU firmware to the user.
> >
> > Add the imx-scu secvio sub node and secvio sub node description.
> >
> > Signed-off-by: Franck LENORMAND <[email protected]>
> > Signed-off-by: Vabhav Sharma <[email protected]>
> > ---
> > .../bindings/arm/freescale/fsl,scu-secvio.yaml | 35
> ++++++++++++++++++++++
> > .../devicetree/bindings/firmware/fsl,scu.yaml | 10 +++++++
> > 2 files changed, 45 insertions(+)
> >
> > diff --git
> > a/Documentation/devicetree/bindings/arm/freescale/fsl,scu-secvio.yaml
> > b/Documentation/devicetree/bindings/arm/freescale/fsl,scu-secvio.yaml
> > new file mode 100644
> > index 000000000000..30dc1e21f903
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/arm/freescale/fsl,scu-secvio.y
> > +++ aml
> > @@ -0,0 +1,35 @@
> > +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) %YAML 1.2
> > +---
> > +$id: http://devicetree.org/schemas/arm/freescale/fsl,scu-secvio.yaml#
> > +$schema: http://devicetree.org/meta-schemas/core.yaml#
> > +
> > +title: NXP i.MX Security Violation driver
>
> Violation detect driver
Ok
>
> > +
> > +maintainers:
> > + - Franck LENORMAND <[email protected]>
> > +
> > +description: |
>
> Needn't "|"
Ok
>
> > + Receive security violation from the SNVS via the SCU firmware.
> > + Allow to register notifier for additional processing
> > +
> > +properties:
> > + compatible:
> > + enum:
> > + - fsl,imx-sc-secvio
> > +
> > + nvmem:
> > + maxItems: 1
> > +
>
> any interrupt defined? how do you notify such violation event?
Yes, there is security violation interrupt bit in register map of SECVIO HW block with uses RPC call to notify/enable/disable this bit using RPC API exported through SCU firmware
>
> > +required:
> > + - compatible
> > + - nvmem
> > +
> > +additionalProperties: false
> > +
> > +examples:
> > + - |
> > + secvio {
> > + compatible = "fsl,imx-sc-secvio";
> > + nvmem = <&ocotp>;
> > + };
> > diff --git a/Documentation/devicetree/bindings/firmware/fsl,scu.yaml
> > b/Documentation/devicetree/bindings/firmware/fsl,scu.yaml
> > index 557e524786c2..b40e127fdc88 100644
> > --- a/Documentation/devicetree/bindings/firmware/fsl,scu.yaml
> > +++ b/Documentation/devicetree/bindings/firmware/fsl,scu.yaml
> > @@ -129,6 +129,11 @@ properties:
> > RTC controller provided by the SCU
> > $ref: /schemas/rtc/fsl,scu-rtc.yaml
> >
> > + secvio:
> > + description:
> > + Receive security violation from the SNVS via the SCU firmware
> > + $ref: /schemas/arm/freescale/fsl,scu-secvio.yaml
> > +
> > thermal-sensor:
> > description:
> > Thermal sensor provided by the SCU @@ -197,6 +202,11 @@
> > examples:
> > compatible = "fsl,imx8qxp-sc-rtc";
> > };
> >
> > + secvio {
> > + compatible = "fsl,imx-sc-secvio";
> > + nvmem = <&ocotp>;
> > + };
> > +
> > keys {
> > compatible = "fsl,imx8qxp-sc-key", "fsl,imx-sc-key";
> > linux,keycodes = <KEY_POWER>;
> >
> > --
> > 2.25.1
> >
On 07/06/2024 06:58, Vabhav Sharma wrote:
>>
>> Missing SoC compatibles.
> Ok, I will use fsl,imx8dxl-sc-secvio
>>
>> So no, that's just abuse of DT to instantiate driver.
>>
>> NAK. Drop the binding.
> I will detail the dt binding to describe the real hardware
Still looks like way just to instantiate driver. Why it cannot be part
of existing firmware SCU node?
Best regards,
Krzysztof
Hi Krzysztof
> From: Krzysztof Kozlowski <[email protected]>
> Sent: 2024年6月7日 15:08
>
> On 07/06/2024 06:58, Vabhav Sharma wrote:
> >>
> >> Missing SoC compatibles.
> > Ok, I will use fsl,imx8dxl-sc-secvio
> >>
> >> So no, that's just abuse of DT to instantiate driver.
> >>
> >> NAK. Drop the binding.
> > I will detail the dt binding to describe the real hardware
>
> Still looks like way just to instantiate driver. Why it cannot be part of existing
> firmware SCU node?
>
Technically yes. But SCU case is a little bit complicated as there're many
functions and all of them are already added as sub nodes in SCU node
for consistency and handling platform difference.
I guess some of them, e.g. rtc, could be part of SCU node (reuse) while
some couldn't. e.g. pinctrl
Do you want us to only make secvio reuse existing SCU node?
This might look a bit strange to the existing sub nodes.
BTW, even we can reuse SCU node for secvio function, we still need update
binding doc to add extra property 'nvmem' for secvio.
Please share your suggestions considering above information.
e.g.
https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git/tree/Documentation/devicetree/bindings/firmware/fsl,scu.yaml
firmware {
system-controller {
compatible = "fsl,imx-scu";
....
rtc {
compatible = "fsl,imx8qxp-sc-rtc";
};
keys {
compatible = "fsl,imx8qxp-sc-key", "fsl,imx-sc-key";
linux,keycodes = <KEY_POWER>;
};
watchdog {
compatible = "fsl,imx8qxp-sc-wdt", "fsl,imx-sc-wdt";
timeout-sec = <60>;
};
thermal-sensor {
compatible = "fsl,imx8qxp-sc-thermal", "fsl,imx-sc-thermal";
#thermal-sensor-cells = <1>;
};
.....
};
Regards
Aisheng
> Best regards,
> Krzysztof
On 12/06/2024 09:20, Aisheng Dong wrote:
> Hi Krzysztof
>
>> From: Krzysztof Kozlowski <[email protected]>
>> Sent: 2024年6月7日 15:08
>>
>> On 07/06/2024 06:58, Vabhav Sharma wrote:
>>>>
>>>> Missing SoC compatibles.
>>> Ok, I will use fsl,imx8dxl-sc-secvio
>>>>
>>>> So no, that's just abuse of DT to instantiate driver.
>>>>
>>>> NAK. Drop the binding.
>>> I will detail the dt binding to describe the real hardware
>>
>> Still looks like way just to instantiate driver. Why it cannot be part of existing
>> firmware SCU node?
>>
>
> Technically yes. But SCU case is a little bit complicated as there're many
> functions and all of them are already added as sub nodes in SCU node
> for consistency and handling platform difference.
>
> I guess some of them, e.g. rtc, could be part of SCU node (reuse) while
> some couldn't. e.g. pinctrl
> Do you want us to only make secvio reuse existing SCU node?
Yes
> This might look a bit strange to the existing sub nodes.
Nothing strange/unusual to me.
>
> BTW, even we can reuse SCU node for secvio function, we still need update
> binding doc to add extra property 'nvmem' for secvio.
Sure.
Best regards,
Krzysztof
Hi Krzysztof,
> From: Krzysztof Kozlowski <[email protected]>
> Sent: 2024年6月13日 14:14
>
> On 12/06/2024 09:20, Aisheng Dong wrote:
> > Hi Krzysztof
> >
> >> From: Krzysztof Kozlowski <[email protected]>
> >> Sent: 2024年6月7日 15:08
> >>
> >> On 07/06/2024 06:58, Vabhav Sharma wrote:
> >>>>
> >>>> Missing SoC compatibles.
> >>> Ok, I will use fsl,imx8dxl-sc-secvio
> >>>>
> >>>> So no, that's just abuse of DT to instantiate driver.
> >>>>
> >>>> NAK. Drop the binding.
> >>> I will detail the dt binding to describe the real hardware
> >>
> >> Still looks like way just to instantiate driver. Why it cannot be
> >> part of existing firmware SCU node?
> >>
> >
> > Technically yes. But SCU case is a little bit complicated as there're
> > many functions and all of them are already added as sub nodes in SCU
> > node for consistency and handling platform difference.
> >
> > I guess some of them, e.g. rtc, could be part of SCU node (reuse)
> > while some couldn't. e.g. pinctrl Do you want us to only make secvio
> > reuse existing SCU node?
>
> Yes
>
Digging a bit more on the implementation. It seems there will be a
'parent depends on child' issue when reusing the parent SCU node for secvio.
Considering the defer probe support and ocotop could be modules, I'm still thinking
If any solution. Do you have a good suggestion?
e.g.
system-controller {
compatible = "fsl,imx-scu";
nvmem = <&ocotp>;
...
ocotp: ocotp {
compatible = "fsl,imx8qxp-scu-ocotp";
#address-cells = <1>;
#size-cells = <1>;
read-only;
};
...
}
static int imx_scu_probe(struct platform_device *pdev)
{
...
ret = imx_secvio_sc_setup(dev);
if (ret)
dev_warn(dev, "failed to initialize secvio: %d\n", ret);
...
return devm_of_platform_populate(dev);
}
Regards
Aisheng
> > This might look a bit strange to the existing sub nodes.
>
> Nothing strange/unusual to me.
>
> >
> > BTW, even we can reuse SCU node for secvio function, we still need
> > update binding doc to add extra property 'nvmem' for secvio.
>
> Sure.
>
>
>
> Best regards,
> Krzysztof
On 13/06/2024 10:48, Aisheng Dong wrote:
> Hi Krzysztof,
>
>> From: Krzysztof Kozlowski <[email protected]>
>> Sent: 2024年6月13日 14:14
>>
>> On 12/06/2024 09:20, Aisheng Dong wrote:
>>> Hi Krzysztof
>>>
>>>> From: Krzysztof Kozlowski <[email protected]>
>>>> Sent: 2024年6月7日 15:08
>>>>
>>>> On 07/06/2024 06:58, Vabhav Sharma wrote:
>>>>>>
>>>>>> Missing SoC compatibles.
>>>>> Ok, I will use fsl,imx8dxl-sc-secvio
>>>>>>
>>>>>> So no, that's just abuse of DT to instantiate driver.
>>>>>>
>>>>>> NAK. Drop the binding.
>>>>> I will detail the dt binding to describe the real hardware
>>>>
>>>> Still looks like way just to instantiate driver. Why it cannot be
>>>> part of existing firmware SCU node?
>>>>
>>>
>>> Technically yes. But SCU case is a little bit complicated as there're
>>> many functions and all of them are already added as sub nodes in SCU
>>> node for consistency and handling platform difference.
>>>
>>> I guess some of them, e.g. rtc, could be part of SCU node (reuse)
>>> while some couldn't. e.g. pinctrl Do you want us to only make secvio
>>> reuse existing SCU node?
>>
>> Yes
>>
>
> Digging a bit more on the implementation. It seems there will be a
> 'parent depends on child' issue when reusing the parent SCU node for secvio.
> Considering the defer probe support and ocotop could be modules, I'm still thinking
> If any solution. Do you have a good suggestion?
I don't see any problem there. You will have even worse if making it
children and using populate - unpredictable order.
Best regards,
Krzysztof