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