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