diff options
Diffstat (limited to 'roms/u-boot/drivers/misc/fsl_sec_mon.c')
-rw-r--r-- | roms/u-boot/drivers/misc/fsl_sec_mon.c | 164 |
1 files changed, 164 insertions, 0 deletions
diff --git a/roms/u-boot/drivers/misc/fsl_sec_mon.c b/roms/u-boot/drivers/misc/fsl_sec_mon.c new file mode 100644 index 000000000..321bd27fd --- /dev/null +++ b/roms/u-boot/drivers/misc/fsl_sec_mon.c @@ -0,0 +1,164 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright 2015 Freescale Semiconductor, Inc. + */ + +#include <common.h> +#include <fsl_sec_mon.h> +#include <linux/delay.h> + +static u32 get_sec_mon_state(void) +{ + struct ccsr_sec_mon_regs *sec_mon_regs = (void *) + (CONFIG_SYS_SEC_MON_ADDR); + return sec_mon_in32(&sec_mon_regs->hp_stat) & HPSR_SSM_ST_MASK; +} + +static int set_sec_mon_state_non_sec(void) +{ + u32 sts; + int timeout = 10; + struct ccsr_sec_mon_regs *sec_mon_regs = (void *) + (CONFIG_SYS_SEC_MON_ADDR); + + sts = get_sec_mon_state(); + + switch (sts) { + /* + * If initial state is check or Non-Secure, then set the Software + * Security Violation Bit and transition to Non-Secure State. + */ + case HPSR_SSM_ST_CHECK: + printf("SEC_MON state transitioning to Non Secure.\n"); + sec_mon_setbits32(&sec_mon_regs->hp_com, HPCOMR_SW_SV); + + /* polling loop till SEC_MON is in Non Secure state */ + while (timeout) { + sts = get_sec_mon_state(); + + 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; + + /* + * If initial state is Trusted, Secure or Soft-Fail, then first set + * the Software Security Violation Bit and transition to Soft-Fail + * State. + */ + case HPSR_SSM_ST_TRUST: + case HPSR_SSM_ST_SECURE: + 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_SV); + + /* polling loop till SEC_MON is in Soft-Fail state */ + while (timeout) { + sts = get_sec_mon_state(); + + 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; + + /* + * If SSM Soft Fail to Non-Secure State Transition + * disable is not set, then set SSM_ST bit and + * transition to Non-Secure State. + */ + if ((sec_mon_in32(&sec_mon_regs->hp_com) & + HPCOMR_SSM_SFNS_DIS) == 0) { + printf("SEC_MON state transitioning to Non Secure.\n"); + sec_mon_setbits32(&sec_mon_regs->hp_com, HPCOMR_SSM_ST); + + /* polling loop till SEC_MON is in Non Secure*/ + while (timeout) { + sts = get_sec_mon_state(); + + 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; + default: + printf("SEC_MON already in Non Secure state.\n"); + return 0; + } + return 0; +} + +static int set_sec_mon_state_soft_fail(void) +{ + u32 sts; + int timeout = 10; + struct ccsr_sec_mon_regs *sec_mon_regs = (void *) + (CONFIG_SYS_SEC_MON_ADDR); + + 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 (timeout) { + sts = get_sec_mon_state(); + + 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; + } + return 0; +} + +int set_sec_mon_state(u32 state) +{ + int ret = -1; + + switch (state) { + case HPSR_SSM_ST_NON_SECURE: + ret = set_sec_mon_state_non_sec(); + break; + case HPSR_SSM_ST_SOFT_FAIL: + ret = set_sec_mon_state_soft_fail(); + break; + default: + printf("SEC_MON state transition not supported.\n"); + return 0; + } + + return ret; +} |