diff options
Diffstat (limited to 'drivers/misc')
-rw-r--r-- | drivers/misc/Kconfig | 8 | ||||
-rw-r--r-- | drivers/misc/Makefile | 1 | ||||
-rw-r--r-- | drivers/misc/fsl_sec_mon.c | 146 |
3 files changed, 155 insertions, 0 deletions
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..d482a7d --- /dev/null +++ b/drivers/misc/fsl_sec_mon.c @@ -0,0 +1,146 @@ +/* + * Copyright 2015 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; +} |