[U-Boot] [PATCH 2/5] fsl_sec_mon: Add driver for Security Monitor block of Freescale

Gaurav Rana gaurav.rana at freescale.com
Tue Feb 24 08:37:54 CET 2015


sec_mon is responsible for monitoring system states and
can be transitioned on any security failures.

Signed-off-by: Ruchika Gupta <ruchika.gupta at freescale.com>
Signed-off-by: Gaurav Rana <gaurav.rana at freescale.com>
---
 drivers/misc/Kconfig       |   8 +++
 drivers/misc/Makefile      |   1 +
 drivers/misc/fsl_sec_mon.c | 146 +++++++++++++++++++++++++++++++++++++++++++++
 include/fsl_sec_mon.h      |  58 ++++++++++++++++++
 4 files changed, 213 insertions(+)
 create mode 100644 drivers/misc/fsl_sec_mon.c
 create mode 100644 include/fsl_sec_mon.h

diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index 0df25c3..36a8f0d 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -53,3 +53,11 @@ config DM_CROS_EC
 	  but otherwise makes few changes. Since cros_ec also supports
 	  LPC (which doesn't support driver model yet), a full
 	  conversion is not yet possible.
+
+config CONFIG_FSL_SEC_MON
+	bool "Enable FSL SEC_MON Driver"
+	help
+	  Freescale Security Monitor block is responsible for monitoring
+	  system states.
+	  Security Monitor can be transitioned on any security failures,
+	  like software violations or hardware security violations.
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index a34972d..6028cd4 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -28,3 +28,4 @@ obj-$(CONFIG_SMSC_LPC47M) += smsc_lpc47m.o
 obj-$(CONFIG_STATUS_LED) += status_led.o
 obj-$(CONFIG_TWL4030_LED) += twl4030_led.o
 obj-$(CONFIG_FSL_IFC) += fsl_ifc.o
+obj-$(CONFIG_FSL_SEC_MON) += fsl_sec_mon.o
diff --git a/drivers/misc/fsl_sec_mon.c b/drivers/misc/fsl_sec_mon.c
new file mode 100644
index 0000000..c47e369
--- /dev/null
+++ b/drivers/misc/fsl_sec_mon.c
@@ -0,0 +1,146 @@
+/*
+ * Copyright 2010-2012 Freescale Semiconductor, Inc.
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <fsl_sec_mon.h>
+
+int change_sec_mon_state(u32 initial_state, u32 final_state)
+{
+	struct ccsr_sec_mon_regs *sec_mon_regs = (void *)
+						(CONFIG_SYS_SEC_MON_ADDR);
+	u32 sts = sec_mon_in32(&sec_mon_regs->hp_stat);
+	int timeout = 10;
+
+	if ((sts & HPSR_SSM_ST_MASK) != initial_state)
+		return -1;
+
+	if (initial_state == HPSR_SSM_ST_TRUST) {
+		switch (final_state) {
+		case HPSR_SSM_ST_NON_SECURE:
+			printf("SEC_MON state transitioning to Soft Fail.\n");
+			sec_mon_setbits32(&sec_mon_regs->hp_com, HPCOMR_SW_SV);
+
+			/*
+			 * poll till SEC_MON is in
+			 * Soft Fail state
+			 */
+			while (((sts & HPSR_SSM_ST_MASK) !=
+				HPSR_SSM_ST_SOFT_FAIL)) {
+				while (timeout) {
+					sts = sec_mon_in32
+						(&sec_mon_regs->hp_stat);
+
+					if ((sts & HPSR_SSM_ST_MASK) ==
+						HPSR_SSM_ST_SOFT_FAIL)
+						break;
+
+					udelay(10);
+					timeout--;
+				}
+			}
+
+			if (timeout == 0) {
+				printf("SEC_MON state transition timeout.\n");
+				return -1;
+			}
+
+			timeout = 10;
+
+			printf("SEC_MON state transitioning to Non Secure.\n");
+			sec_mon_setbits32(&sec_mon_regs->hp_com, HPCOMR_SSM_ST);
+
+			/*
+			 * poll till SEC_MON is in
+			 * Non Secure state
+			 */
+			while (((sts & HPSR_SSM_ST_MASK) !=
+				HPSR_SSM_ST_NON_SECURE)) {
+				while (timeout) {
+					sts = sec_mon_in32
+						(&sec_mon_regs->hp_stat);
+
+					if ((sts & HPSR_SSM_ST_MASK) ==
+						HPSR_SSM_ST_NON_SECURE)
+						break;
+
+					udelay(10);
+					timeout--;
+				}
+			}
+
+			if (timeout == 0) {
+				printf("SEC_MON state transition timeout.\n");
+				return -1;
+			}
+			break;
+		case HPSR_SSM_ST_SOFT_FAIL:
+			printf("SEC_MON state transitioning to Soft Fail.\n");
+			sec_mon_setbits32(&sec_mon_regs->hp_com, HPCOMR_SW_FSV);
+
+			/*
+			 * polling loop till SEC_MON is in
+			 * Soft Fail state
+			 */
+			while (((sts & HPSR_SSM_ST_MASK) !=
+				HPSR_SSM_ST_SOFT_FAIL)) {
+				while (timeout) {
+					sts = sec_mon_in32
+						(&sec_mon_regs->hp_stat);
+
+					if ((sts & HPSR_SSM_ST_MASK) ==
+						HPSR_SSM_ST_SOFT_FAIL)
+						break;
+
+					udelay(10);
+					timeout--;
+				}
+			}
+
+			if (timeout == 0) {
+				printf("SEC_MON state transition timeout.\n");
+				return -1;
+			}
+			break;
+		default:
+			return -1;
+		}
+	} else if (initial_state == HPSR_SSM_ST_NON_SECURE) {
+		switch (final_state) {
+		case HPSR_SSM_ST_SOFT_FAIL:
+			printf("SEC_MON state transitioning to Soft Fail.\n");
+			sec_mon_setbits32(&sec_mon_regs->hp_com, HPCOMR_SW_FSV);
+
+			/*
+			 * polling loop till SEC_MON is in
+			 * Soft Fail state
+			 */
+			while (((sts & HPSR_SSM_ST_MASK) !=
+				HPSR_SSM_ST_SOFT_FAIL)) {
+				while (timeout) {
+					sts = sec_mon_in32
+						(&sec_mon_regs->hp_stat);
+
+					if ((sts & HPSR_SSM_ST_MASK) ==
+						HPSR_SSM_ST_SOFT_FAIL)
+						break;
+
+					udelay(10);
+					timeout--;
+				}
+			}
+
+			if (timeout == 0) {
+				printf("SEC_MON state transition timeout.\n");
+				return -1;
+			}
+			break;
+		default:
+			return -1;
+		}
+	}
+
+	return 0;
+}
diff --git a/include/fsl_sec_mon.h b/include/fsl_sec_mon.h
new file mode 100644
index 0000000..cf3f5d1
--- /dev/null
+++ b/include/fsl_sec_mon.h
@@ -0,0 +1,58 @@
+/*
+ * Common internal memory map for some Freescale SoCs
+ *
+ * Copyright 2014 Freescale Semiconductor, Inc.
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#ifndef __FSL_SEC_MON_H
+#define __FSL_SEC_MON_H
+
+#include <common.h>
+#include <asm/io.h>
+
+#ifdef CONFIG_SYS_FSL_SEC_MON_LE
+#define sec_mon_in32(a)       in_le32(a)
+#define sec_mon_out32(a, v)   out_le32(a, v)
+#define sec_mon_in16(a)       in_le16(a)
+#define sec_mon_clrbits32     clrbits_le32
+#define sec_mon_setbits32     setbits_le32
+#elif defined(CONFIG_SYS_FSL_SEC_MON_BE)
+#define sec_mon_in32(a)       in_be32(a)
+#define sec_mon_out32(a, v)   out_be32(a, v)
+#define sec_mon_in16(a)       in_be16(a)
+#define sec_mon_clrbits32     clrbits_be32
+#define sec_mon_setbits32     setbits_be32
+#else
+#error Neither CONFIG_SYS_FSL_SEC_MON_LE nor CONFIG_SYS_FSL_SEC_MON_BE defined
+#endif
+
+struct ccsr_sec_mon_regs {
+	u8 reserved0[0x04];
+	u32 hp_com;	/* 0x04 SEC_MON_HP Command Register */
+	u8 reserved2[0x0c];
+	u32 hp_stat;	/* 0x08 SEC_MON_HP Status Register */
+};
+
+#define HPCOMR_SW_SV 0x100		/* Security Violation bit */
+#define HPCOMR_SW_FSV 0x200		/* Fatal Security Violation bit */
+#define HPCOMR_SSM_ST 0x1		/* SSM_ST field in SEC_MON command */
+#define HPSR_SSM_ST_CHECK	0x900	/* SEC_MON is in check state */
+#define HPSR_SSM_ST_NON_SECURE	0xb00	/* SEC_MON is in non secure state */
+#define HPSR_SSM_ST_TRUST	0xd00	/* SEC_MON is in trusted state */
+#define HPSR_SSM_ST_SOFT_FAIL	0x300	/* SEC_MON is in soft fail state */
+#define HPSR_SSM_ST_MASK	0xf00	/* Mask for SSM_ST field */
+
+/*
+ * SEC_MON read. This specifies the possible reads
+ * from the SEC_MON
+ */
+enum {
+	SEC_MON_SSM_ST,
+	SEC_MON_SW_FSV,
+	SEC_MON_SW_SV,
+};
+
+int change_sec_mon_state(uint32_t initial_state, uint32_t final_state);
+
+#endif /* __FSL_SEC_MON_H */
-- 
1.8.1.4



More information about the U-Boot mailing list