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