xref: /rk3399_ARM-atf/drivers/nxp/sec_mon/snvs.c (revision 9719e19a977df3e8bf7567b3c0e1d6b2ebc5b46f)
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 
snvs_init(uintptr_t nxp_snvs_addr)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 
get_snvs_state(void)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 
do_snvs_state_transition(uint32_t state_transtion_bit,uint32_t target_state)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 }
transition_snvs_non_secure(void)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 
transition_snvs_soft_fail(void)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 
transition_snvs_trusted(void)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 
transition_snvs_secure(void)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 
snvs_write_lp_gpr_bit(uint32_t offset,uint32_t bit_pos,bool flag_val)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 
snvs_read_lp_gpr_bit(uint32_t offset,uint32_t bit_pos)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 
snvs_disable_zeroize_lp_gpr(void)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)
snvs_write_app_data_bit(uint32_t bit_pos)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 
snvs_read_app_data(void)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 
snvs_read_app_data_bit(uint32_t bit_pos)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 
snvs_clear_app_data(void)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