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