1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * Copyright 2015 Freescale Semiconductor, Inc. 4 */ 5 6 #include <common.h> 7 #include <fsl_sec_mon.h> 8 9 static u32 get_sec_mon_state(void) 10 { 11 struct ccsr_sec_mon_regs *sec_mon_regs = (void *) 12 (CONFIG_SYS_SEC_MON_ADDR); 13 return sec_mon_in32(&sec_mon_regs->hp_stat) & HPSR_SSM_ST_MASK; 14 } 15 16 static int set_sec_mon_state_non_sec(void) 17 { 18 u32 sts; 19 int timeout = 10; 20 struct ccsr_sec_mon_regs *sec_mon_regs = (void *) 21 (CONFIG_SYS_SEC_MON_ADDR); 22 23 sts = get_sec_mon_state(); 24 25 switch (sts) { 26 /* 27 * If initial state is check or Non-Secure, then set the Software 28 * Security Violation Bit and transition to Non-Secure State. 29 */ 30 case HPSR_SSM_ST_CHECK: 31 printf("SEC_MON state transitioning to Non Secure.\n"); 32 sec_mon_setbits32(&sec_mon_regs->hp_com, HPCOMR_SW_SV); 33 34 /* polling loop till SEC_MON is in Non Secure state */ 35 while (timeout) { 36 sts = get_sec_mon_state(); 37 38 if ((sts & HPSR_SSM_ST_MASK) == 39 HPSR_SSM_ST_NON_SECURE) 40 break; 41 42 udelay(10); 43 timeout--; 44 } 45 46 if (timeout == 0) { 47 printf("SEC_MON state transition timeout.\n"); 48 return -1; 49 } 50 break; 51 52 /* 53 * If initial state is Trusted, Secure or Soft-Fail, then first set 54 * the Software Security Violation Bit and transition to Soft-Fail 55 * State. 56 */ 57 case HPSR_SSM_ST_TRUST: 58 case HPSR_SSM_ST_SECURE: 59 case HPSR_SSM_ST_SOFT_FAIL: 60 printf("SEC_MON state transitioning to Soft Fail.\n"); 61 sec_mon_setbits32(&sec_mon_regs->hp_com, HPCOMR_SW_SV); 62 63 /* polling loop till SEC_MON is in Soft-Fail state */ 64 while (timeout) { 65 sts = get_sec_mon_state(); 66 67 if ((sts & HPSR_SSM_ST_MASK) == 68 HPSR_SSM_ST_SOFT_FAIL) 69 break; 70 71 udelay(10); 72 timeout--; 73 } 74 75 if (timeout == 0) { 76 printf("SEC_MON state transition timeout.\n"); 77 return -1; 78 } 79 80 timeout = 10; 81 82 /* 83 * If SSM Soft Fail to Non-Secure State Transition 84 * disable is not set, then set SSM_ST bit and 85 * transition to Non-Secure State. 86 */ 87 if ((sec_mon_in32(&sec_mon_regs->hp_com) & 88 HPCOMR_SSM_SFNS_DIS) == 0) { 89 printf("SEC_MON state transitioning to Non Secure.\n"); 90 sec_mon_setbits32(&sec_mon_regs->hp_com, HPCOMR_SSM_ST); 91 92 /* polling loop till SEC_MON is in Non Secure*/ 93 while (timeout) { 94 sts = get_sec_mon_state(); 95 96 if ((sts & HPSR_SSM_ST_MASK) == 97 HPSR_SSM_ST_NON_SECURE) 98 break; 99 100 udelay(10); 101 timeout--; 102 } 103 104 if (timeout == 0) { 105 printf("SEC_MON state transition timeout.\n"); 106 return -1; 107 } 108 } 109 break; 110 default: 111 printf("SEC_MON already in Non Secure state.\n"); 112 return 0; 113 } 114 return 0; 115 } 116 117 static int set_sec_mon_state_soft_fail(void) 118 { 119 u32 sts; 120 int timeout = 10; 121 struct ccsr_sec_mon_regs *sec_mon_regs = (void *) 122 (CONFIG_SYS_SEC_MON_ADDR); 123 124 printf("SEC_MON state transitioning to Soft Fail.\n"); 125 sec_mon_setbits32(&sec_mon_regs->hp_com, HPCOMR_SW_FSV); 126 127 /* polling loop till SEC_MON is in Soft-Fail state */ 128 while (timeout) { 129 sts = get_sec_mon_state(); 130 131 if ((sts & HPSR_SSM_ST_MASK) == 132 HPSR_SSM_ST_SOFT_FAIL) 133 break; 134 135 udelay(10); 136 timeout--; 137 } 138 139 if (timeout == 0) { 140 printf("SEC_MON state transition timeout.\n"); 141 return -1; 142 } 143 return 0; 144 } 145 146 int set_sec_mon_state(u32 state) 147 { 148 int ret = -1; 149 150 switch (state) { 151 case HPSR_SSM_ST_NON_SECURE: 152 ret = set_sec_mon_state_non_sec(); 153 break; 154 case HPSR_SSM_ST_SOFT_FAIL: 155 ret = set_sec_mon_state_soft_fail(); 156 break; 157 default: 158 printf("SEC_MON state transition not supported.\n"); 159 return 0; 160 } 161 162 return ret; 163 } 164