1 /*
2 // Copyright (C) 2022 Beken Corporation
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15 #include <common/bk_include.h>
16 #include "bk_fake_clock.h"
17 #include "bk_icu.h"
18 #include "bk_drv_model.h"
19 #include "bk_uart.h"
20
21 #include "sys_rtos.h"
22 #include "bk_arm_arch.h"
23 #include "sys_ctrl.h"
24 #include "bk_sys_ctrl.h"
25
26 #include "reset_reason.h"
27 #include <components/log.h>
28
29 #define TAG "init"
30 #define DISPLAY_START_TYPE_STR 1
31
32 /* 1. For bk7231n/7236, persist memory lost after power on
33 * 2. For other platform, persist memory lost after interrupt watchdog or power on
34 * */
35 #define PERSIST_MEMORY_ADDR (0x0040001c)
36
37 static RESET_SOURCE_STATUS s_start_type;
38 static uint32_t s_misc_value_save;
39 static uint32_t s_mem_value_save;
40
bk_misc_get_start_type(void)41 RESET_SOURCE_STATUS bk_misc_get_start_type(void)
42 {
43 return s_start_type;
44 }
45
persist_memory_init(void)46 void persist_memory_init(void)
47 {
48 *((volatile uint32_t *)(PERSIST_MEMORY_ADDR)) = (uint32_t)CRASH_ILLEGAL_JUMP_VALUE;
49 }
50
persist_memory_get(void)51 uint32_t persist_memory_get(void)
52 {
53 return (*((volatile uint32_t *)(PERSIST_MEMORY_ADDR)));
54 }
55
persist_memory_is_lost(void)56 bool persist_memory_is_lost(void)
57 {
58 if ((uint32_t)CRASH_ILLEGAL_JUMP_VALUE == persist_memory_get())
59 return false;
60 else
61 return true;
62 }
63
misc_get_start_type_str(uint32_t start_type)64 static char *misc_get_start_type_str(uint32_t start_type)
65 {
66 #if DISPLAY_START_TYPE_STR
67 switch (start_type) {
68 case RESET_SOURCE_POWERON:
69 return "power on";
70
71 case RESET_SOURCE_REBOOT:
72 return "software reboot";
73
74 case RESET_SOURCE_WATCHDOG:
75 return "interrupt watchdog";
76
77 case RESET_SOURCE_DEEPPS_GPIO:
78 return "deep sleep gpio";
79
80 case RESET_SOURCE_DEEPPS_RTC:
81 return "deep sleep rtc";
82
83 case RESET_SOURCE_CRASH_ILLEGAL_JUMP:
84 return "illegal jump";
85
86 case RESET_SOURCE_CRASH_UNDEFINED:
87 return "undefined";
88
89 case RESET_SOURCE_CRASH_PREFETCH_ABORT:
90 return "prefetch abort";
91
92 case RESET_SOURCE_CRASH_DATA_ABORT:
93 return "data abort";
94
95 case RESET_SOURCE_CRASH_UNUSED:
96 return "unused";
97
98 case RESET_SOURCE_DEEPPS_USB:
99 return "deep sleep usb";
100
101 case RESET_SOURCE_UNKNOWN:
102 default:
103 return "unknow";
104 }
105 #else
106 return "";
107 #endif
108 }
109
show_reset_reason(void)110 void show_reset_reason(void)
111 {
112 BK_LOGI(TAG, "reason - %s\r\n", misc_get_start_type_str(s_start_type));
113 #if CONFIG_DEEP_PS
114 if(RESET_SOURCE_DEEPPS_GPIO == s_start_type)
115 {
116 BK_LOGI(TAG, "by gpio - %d\r\n", bk_misc_wakeup_get_gpio_num());
117 }
118 #endif
119 BK_LOGI(TAG, "regs - %x, %x, %x\r\n", s_start_type, s_misc_value_save, s_mem_value_save);
120 }
121
122 #if (CONFIG_SOC_BK7231N) || (CONFIG_SOC_BK7236A)
123 //only can be do once
reset_reason_init(void)124 RESET_SOURCE_STATUS reset_reason_init(void)
125 {
126 uint32_t misc_value;
127 sctrl_ctrl(CMD_GET_SCTRL_RETETION, &misc_value);
128
129 if ((s_start_type = sctrl_get_deep_sleep_wake_soure()) == 0) {
130 if (0 == (misc_value & SW_RETENTION_WDT_FLAG)) {
131 if (persist_memory_is_lost())
132 s_start_type = RESET_SOURCE_POWERON;
133 else
134 s_start_type = RESET_SOURCE_CRASH_ILLEGAL_JUMP;
135 } else {
136 switch (misc_value & SW_RETENTION_VAL_MASK) {
137 case (RESET_SOURCE_REBOOT & SW_RETENTION_VAL_MASK):
138 s_start_type = RESET_SOURCE_REBOOT;
139 break;
140 case (CRASH_UNDEFINED_VALUE & SW_RETENTION_VAL_MASK):
141 s_start_type = RESET_SOURCE_CRASH_UNDEFINED;
142 break;
143 case (CRASH_PREFETCH_ABORT_VALUE & SW_RETENTION_VAL_MASK):
144 s_start_type = RESET_SOURCE_CRASH_PREFETCH_ABORT;
145 break;
146 case (CRASH_DATA_ABORT_VALUE & SW_RETENTION_VAL_MASK):
147 s_start_type = RESET_SOURCE_CRASH_DATA_ABORT;
148 break;
149 case (CRASH_UNUSED_VALUE & SW_RETENTION_VAL_MASK):
150 s_start_type = RESET_SOURCE_CRASH_UNUSED;
151 break;
152 case (RESET_SOURCE_WATCHDOG & SW_RETENTION_VAL_MASK):
153 s_start_type = RESET_SOURCE_WATCHDOG;
154 break;
155 default:
156 s_start_type = RESET_SOURCE_UNKNOWN;
157 break;
158 }
159 }
160 }
161
162 s_misc_value_save = misc_value;
163 s_mem_value_save = persist_memory_get();
164 persist_memory_init();
165
166 //clear
167 sctrl_ctrl(CMD_SET_SCTRL_RETETION, &misc_value);
168
169 return s_start_type;
170 }
171
bk_misc_update_set_type(uint32_t type)172 void bk_misc_update_set_type(uint32_t type)
173 {
174 uint32_t misc_value = type & SW_RETENTION_VAL_MASK;
175 sctrl_ctrl(CMD_SET_SCTRL_RETETION, &misc_value);
176 }
177 #elif (CONFIG_SOC_BK7256XX)
reset_reason_init(void)178 RESET_SOURCE_STATUS reset_reason_init(void)
179 {
180 return RESET_SOURCE_UNKNOWN;
181 }
182
bk_misc_update_set_type(uint32_t type)183 void bk_misc_update_set_type(uint32_t type)
184 {
185
186 }
187 #else
188 //only can be do once
reset_reason_init(void)189 RESET_SOURCE_STATUS reset_reason_init(void)
190 {
191 uint32_t misc_value = *((volatile uint32_t *)(START_TYPE_ADDR));
192
193 #if (!CONFIG_SOC_BK7271)
194 if ((s_start_type = sctrl_get_deep_sleep_wake_soure()) == 0)
195 #else
196 BK_LOGI(TAG, "reset_reason_init TODO\r\n");
197 #endif
198 {
199 switch (misc_value) {
200 case RESET_SOURCE_REBOOT:
201 s_start_type = misc_value;
202 break;
203 case CRASH_UNDEFINED_VALUE:
204 s_start_type = RESET_SOURCE_CRASH_UNDEFINED;
205 break;
206 case CRASH_PREFETCH_ABORT_VALUE:
207 s_start_type = RESET_SOURCE_CRASH_PREFETCH_ABORT;
208 break;
209 case CRASH_DATA_ABORT_VALUE:
210 s_start_type = RESET_SOURCE_CRASH_DATA_ABORT;
211 break;
212 case CRASH_UNUSED_VALUE:
213 s_start_type = RESET_SOURCE_CRASH_UNUSED;
214 break;
215 case CRASH_ILLEGAL_JUMP_VALUE:
216 s_start_type = RESET_SOURCE_CRASH_ILLEGAL_JUMP;
217 break;
218 case RESET_SOURCE_WATCHDOG:
219 if (persist_memory_is_lost())
220 s_start_type = RESET_SOURCE_WATCHDOG;
221 else
222 s_start_type = RESET_SOURCE_CRASH_ILLEGAL_JUMP;
223 break;
224
225 default:
226 if (persist_memory_is_lost())
227 s_start_type = RESET_SOURCE_POWERON;
228 else
229 s_start_type = RESET_SOURCE_CRASH_ILLEGAL_JUMP;
230 break;
231 }
232 }
233
234 s_misc_value_save = misc_value;
235 s_mem_value_save = persist_memory_get();
236 persist_memory_init();
237
238 return s_start_type;
239 }
240
bk_misc_update_set_type(uint32_t type)241 void bk_misc_update_set_type(uint32_t type)
242 {
243 *((volatile uint32_t *)(START_TYPE_ADDR)) = (uint32_t)type;
244 }
245 #endif
246