1*d8e97999SPankaj Gupta /* 2*d8e97999SPankaj Gupta * Copyright 2021 NXP 3*d8e97999SPankaj Gupta * 4*d8e97999SPankaj Gupta * SPDX-License-Identifier: BSD-3-Clause 5*d8e97999SPankaj Gupta * 6*d8e97999SPankaj Gupta */ 7*d8e97999SPankaj Gupta 8*d8e97999SPankaj Gupta #include <stdint.h> 9*d8e97999SPankaj Gupta #include <stdio.h> 10*d8e97999SPankaj Gupta #include <stdlib.h> 11*d8e97999SPankaj Gupta 12*d8e97999SPankaj Gupta #include <snvs.h> 13*d8e97999SPankaj Gupta 14*d8e97999SPankaj Gupta static uintptr_t g_nxp_snvs_addr; 15*d8e97999SPankaj Gupta 16*d8e97999SPankaj Gupta void snvs_init(uintptr_t nxp_snvs_addr) 17*d8e97999SPankaj Gupta { 18*d8e97999SPankaj Gupta g_nxp_snvs_addr = nxp_snvs_addr; 19*d8e97999SPankaj Gupta } 20*d8e97999SPankaj Gupta 21*d8e97999SPankaj Gupta uint32_t get_snvs_state(void) 22*d8e97999SPankaj Gupta { 23*d8e97999SPankaj Gupta struct snvs_regs *snvs = (struct snvs_regs *) (g_nxp_snvs_addr); 24*d8e97999SPankaj Gupta 25*d8e97999SPankaj Gupta return (snvs_read32(&snvs->hp_stat) & HPSTS_MASK_SSM_ST); 26*d8e97999SPankaj Gupta } 27*d8e97999SPankaj Gupta 28*d8e97999SPankaj Gupta static uint32_t do_snvs_state_transition(uint32_t state_transtion_bit, 29*d8e97999SPankaj Gupta uint32_t target_state) 30*d8e97999SPankaj Gupta { 31*d8e97999SPankaj Gupta struct snvs_regs *snvs = (struct snvs_regs *) (g_nxp_snvs_addr); 32*d8e97999SPankaj Gupta uint32_t sts = get_snvs_state(); 33*d8e97999SPankaj Gupta uint32_t fetch_cnt = 16U; 34*d8e97999SPankaj Gupta uint32_t val = snvs_read32(&snvs->hp_com) | state_transtion_bit; 35*d8e97999SPankaj Gupta 36*d8e97999SPankaj Gupta snvs_write32(&snvs->hp_com, val); 37*d8e97999SPankaj Gupta 38*d8e97999SPankaj Gupta /* polling loop till SNVS is in target state */ 39*d8e97999SPankaj Gupta do { 40*d8e97999SPankaj Gupta sts = get_snvs_state(); 41*d8e97999SPankaj Gupta } while ((sts != target_state) && ((--fetch_cnt) != 0)); 42*d8e97999SPankaj Gupta 43*d8e97999SPankaj Gupta return sts; 44*d8e97999SPankaj Gupta } 45*d8e97999SPankaj Gupta void transition_snvs_non_secure(void) 46*d8e97999SPankaj Gupta { 47*d8e97999SPankaj Gupta struct snvs_regs *snvs = (struct snvs_regs *) (g_nxp_snvs_addr); 48*d8e97999SPankaj Gupta uint32_t sts = get_snvs_state(); 49*d8e97999SPankaj Gupta 50*d8e97999SPankaj Gupta switch (sts) { 51*d8e97999SPankaj Gupta /* If initial state is check or Non-Secure, then 52*d8e97999SPankaj Gupta * set the Software Security Violation Bit and 53*d8e97999SPankaj Gupta * transition to Non-Secure State. 54*d8e97999SPankaj Gupta */ 55*d8e97999SPankaj Gupta case HPSTS_CHECK_SSM_ST: 56*d8e97999SPankaj Gupta sts = do_snvs_state_transition(HPCOM_SW_SV, HPSTS_NON_SECURE_SSM_ST); 57*d8e97999SPankaj Gupta break; 58*d8e97999SPankaj Gupta 59*d8e97999SPankaj Gupta /* If initial state is Trusted, Secure or Soft-Fail, then 60*d8e97999SPankaj Gupta * first set the Software Security Violation Bit and 61*d8e97999SPankaj Gupta * transition to Soft-Fail State. 62*d8e97999SPankaj Gupta */ 63*d8e97999SPankaj Gupta case HPSTS_TRUST_SSM_ST: 64*d8e97999SPankaj Gupta case HPSTS_SECURE_SSM_ST: 65*d8e97999SPankaj Gupta case HPSTS_SOFT_FAIL_SSM_ST: 66*d8e97999SPankaj Gupta sts = do_snvs_state_transition(HPCOM_SW_SV, HPSTS_NON_SECURE_SSM_ST); 67*d8e97999SPankaj Gupta 68*d8e97999SPankaj Gupta /* If SSM Soft Fail to Non-Secure State Transition 69*d8e97999SPankaj Gupta * Disable is not set, then set SSM_ST bit and 70*d8e97999SPankaj Gupta * transition to Non-Secure State. 71*d8e97999SPankaj Gupta */ 72*d8e97999SPankaj Gupta if ((snvs_read32(&snvs->hp_com) & HPCOM_SSM_SFNS_DIS) == 0) { 73*d8e97999SPankaj Gupta sts = do_snvs_state_transition(HPCOM_SSM_ST, HPSTS_NON_SECURE_SSM_ST); 74*d8e97999SPankaj Gupta } 75*d8e97999SPankaj Gupta break; 76*d8e97999SPankaj Gupta default: 77*d8e97999SPankaj Gupta break; 78*d8e97999SPankaj Gupta } 79*d8e97999SPankaj Gupta } 80*d8e97999SPankaj Gupta 81*d8e97999SPankaj Gupta void transition_snvs_soft_fail(void) 82*d8e97999SPankaj Gupta { 83*d8e97999SPankaj Gupta do_snvs_state_transition(HPCOM_SW_FSV, HPSTS_SOFT_FAIL_SSM_ST); 84*d8e97999SPankaj Gupta } 85*d8e97999SPankaj Gupta 86*d8e97999SPankaj Gupta uint32_t transition_snvs_trusted(void) 87*d8e97999SPankaj Gupta { 88*d8e97999SPankaj Gupta struct snvs_regs *snvs = (struct snvs_regs *) (g_nxp_snvs_addr); 89*d8e97999SPankaj Gupta uint32_t sts = get_snvs_state(); 90*d8e97999SPankaj Gupta 91*d8e97999SPankaj Gupta switch (sts) { 92*d8e97999SPankaj Gupta /* If initial state is check, set the SSM_ST bit to 93*d8e97999SPankaj Gupta * change the state to trusted. 94*d8e97999SPankaj Gupta */ 95*d8e97999SPankaj Gupta case HPSTS_CHECK_SSM_ST: 96*d8e97999SPankaj Gupta sts = do_snvs_state_transition(HPCOM_SSM_ST, HPSTS_TRUST_SSM_ST); 97*d8e97999SPankaj Gupta break; 98*d8e97999SPankaj Gupta /* If SSM Secure to Trusted State Transition Disable 99*d8e97999SPankaj Gupta * is not set, then set SSM_ST bit and 100*d8e97999SPankaj Gupta * transition to Trusted State. 101*d8e97999SPankaj Gupta */ 102*d8e97999SPankaj Gupta case HPSTS_SECURE_SSM_ST: 103*d8e97999SPankaj Gupta if ((snvs_read32(&snvs->hp_com) & HPCOM_SSM_ST_DIS) == 0) { 104*d8e97999SPankaj Gupta sts = do_snvs_state_transition(HPCOM_SSM_ST, HPSTS_TRUST_SSM_ST); 105*d8e97999SPankaj Gupta } 106*d8e97999SPankaj Gupta break; 107*d8e97999SPankaj Gupta /* If initial state is Soft-Fail or Non-Secure, then 108*d8e97999SPankaj Gupta * transition to Trusted is not Possible. 109*d8e97999SPankaj Gupta */ 110*d8e97999SPankaj Gupta default: 111*d8e97999SPankaj Gupta break; 112*d8e97999SPankaj Gupta } 113*d8e97999SPankaj Gupta 114*d8e97999SPankaj Gupta return sts; 115*d8e97999SPankaj Gupta } 116*d8e97999SPankaj Gupta 117*d8e97999SPankaj Gupta uint32_t transition_snvs_secure(void) 118*d8e97999SPankaj Gupta { 119*d8e97999SPankaj Gupta uint32_t sts = get_snvs_state(); 120*d8e97999SPankaj Gupta 121*d8e97999SPankaj Gupta if (sts == HPSTS_SECURE_SSM_ST) { 122*d8e97999SPankaj Gupta return sts; 123*d8e97999SPankaj Gupta } 124*d8e97999SPankaj Gupta 125*d8e97999SPankaj Gupta if (sts != HPSTS_TRUST_SSM_ST) { 126*d8e97999SPankaj Gupta sts = transition_snvs_trusted(); 127*d8e97999SPankaj Gupta if (sts != HPSTS_TRUST_SSM_ST) { 128*d8e97999SPankaj Gupta return sts; 129*d8e97999SPankaj Gupta } 130*d8e97999SPankaj Gupta } 131*d8e97999SPankaj Gupta 132*d8e97999SPankaj Gupta sts = do_snvs_state_transition(HPCOM_SSM_ST, HPSTS_TRUST_SSM_ST); 133*d8e97999SPankaj Gupta 134*d8e97999SPankaj Gupta return sts; 135*d8e97999SPankaj Gupta } 136*d8e97999SPankaj Gupta 137*d8e97999SPankaj Gupta void snvs_write_lp_gpr_bit(uint32_t offset, uint32_t bit_pos, bool flag_val) 138*d8e97999SPankaj Gupta { 139*d8e97999SPankaj Gupta if (flag_val) { 140*d8e97999SPankaj Gupta snvs_write32(g_nxp_snvs_addr + offset, 141*d8e97999SPankaj Gupta (snvs_read32(g_nxp_snvs_addr + offset)) 142*d8e97999SPankaj Gupta | (1 << bit_pos)); 143*d8e97999SPankaj Gupta } else { 144*d8e97999SPankaj Gupta snvs_write32(g_nxp_snvs_addr + offset, 145*d8e97999SPankaj Gupta (snvs_read32(g_nxp_snvs_addr + offset)) 146*d8e97999SPankaj Gupta & ~(1 << bit_pos)); 147*d8e97999SPankaj Gupta } 148*d8e97999SPankaj Gupta } 149*d8e97999SPankaj Gupta 150*d8e97999SPankaj Gupta uint32_t snvs_read_lp_gpr_bit(uint32_t offset, uint32_t bit_pos) 151*d8e97999SPankaj Gupta { 152*d8e97999SPankaj Gupta return (snvs_read32(g_nxp_snvs_addr + offset) & (1 << bit_pos)); 153*d8e97999SPankaj Gupta } 154*d8e97999SPankaj Gupta 155*d8e97999SPankaj Gupta void snvs_disable_zeroize_lp_gpr(void) 156*d8e97999SPankaj Gupta { 157*d8e97999SPankaj Gupta snvs_write_lp_gpr_bit(NXP_LPCR_OFFSET, 158*d8e97999SPankaj Gupta NXP_GPR_Z_DIS_BIT, 159*d8e97999SPankaj Gupta true); 160*d8e97999SPankaj Gupta } 161*d8e97999SPankaj Gupta 162*d8e97999SPankaj Gupta #if defined(NXP_NV_SW_MAINT_LAST_EXEC_DATA) && defined(NXP_COINED_BB) 163*d8e97999SPankaj Gupta void snvs_write_app_data_bit(uint32_t bit_pos) 164*d8e97999SPankaj Gupta { 165*d8e97999SPankaj Gupta snvs_write_lp_gpr_bit(NXP_APP_DATA_LP_GPR_OFFSET, 166*d8e97999SPankaj Gupta bit_pos, 167*d8e97999SPankaj Gupta true); 168*d8e97999SPankaj Gupta } 169*d8e97999SPankaj Gupta 170*d8e97999SPankaj Gupta uint32_t snvs_read_app_data(void) 171*d8e97999SPankaj Gupta { 172*d8e97999SPankaj Gupta return snvs_read32(g_nxp_snvs_addr + NXP_APP_DATA_LP_GPR_OFFSET); 173*d8e97999SPankaj Gupta } 174*d8e97999SPankaj Gupta 175*d8e97999SPankaj Gupta uint32_t snvs_read_app_data_bit(uint32_t bit_pos) 176*d8e97999SPankaj Gupta { 177*d8e97999SPankaj Gupta uint8_t ret = snvs_read_lp_gpr_bit(NXP_APP_DATA_LP_GPR_OFFSET, bit_pos); 178*d8e97999SPankaj Gupta 179*d8e97999SPankaj Gupta return ((ret != 0U) ? 1U : 0U); 180*d8e97999SPankaj Gupta } 181*d8e97999SPankaj Gupta 182*d8e97999SPankaj Gupta void snvs_clear_app_data(void) 183*d8e97999SPankaj Gupta { 184*d8e97999SPankaj Gupta snvs_write32(g_nxp_snvs_addr + NXP_APP_DATA_LP_GPR_OFFSET, 0x0); 185*d8e97999SPankaj Gupta } 186*d8e97999SPankaj Gupta #endif 187