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
16
17 #include <stdint.h>
18 #include "boot.h"
19 #include "sdkconfig.h"
20 #include "reset_reason.h"
21 #include <os/os.h>
22 #include "bk_arch.h"
23 #include "stack_base.h"
24 #include "bk_uart.h"
25 #include "bk_rtos_debug.h"
26 #include <os/os.h>
27 #include <stdio.h>
28 #include "platform.h"
29 #include <components/system.h>
30 #include <os/mem.h>
31 #include <components/log.h>
32 #include <common/bk_assert.h>
33 #include <driver/wdt.h>
34 #include <bk_wdt.h>
35
36 #if (CONFIG_CACHE_ENABLE)
37 #define SRAM_BLOCK_COUNT 4
38 extern unsigned int g_sram_addr_map[SRAM_BLOCK_COUNT];
39 #else
40 #if (CONFIG_SLAVE_CORE)
41 #define RAM_BASE_ADDR 0x30060000
42 #else
43 #define RAM_BASE_ADDR 0x30000000
44 #endif
45 #endif
46
47 #define SYS_DELAY_TIME_5S (85000000UL)
48
49 #if CONFIG_LITEOS_M_V3 || CONFIG_LITEOS_M_MST
50 typedef struct {
51 union {
52 struct {
53 long x2; //sp
54 long x4; //tp
55 long x31; //t6
56 long x30; //t5
57 long x29; //t4
58 long x28; //t3
59 long x7; //t2
60 long x6; //t1
61 long x5; //t0
62 long x27; //s11
63 long x26; //s10
64 long x25; //s9
65 long x24; //s8
66 long x23; //s7
67 long x22; //s6
68 long x21; //s5
69 long mstatus;
70 long mepc;
71 long x17; //a7
72 long x16; //a6
73 long x15; //a5
74 long x14; //a4
75 long x13; //a3
76 long x12; //a2
77 long x11; //a1
78 long x10; //a0
79 long x20; //s4
80 long x19; //s3
81 long x18; //s2
82 long x9; //s1
83 long x8; //s0
84 long x1; //ra
85 };
86 long riscv_regs[32];
87 };
88 } SAVED_CONTEXT;
89
90 #else // CONFIG_FREERTOS
91
92 typedef struct {
93 union {
94 struct {
95 long mepc;
96 long x1;
97 long x5;
98 long x6;
99 long x7;
100 long x8;
101 long x9;
102 long x10;
103 long x11;
104 long x12;
105 long x13;
106 long x14;
107 long x15;
108 long x16;
109 long x17;
110 long x18;
111 long x19;
112 long x20;
113 long x21;
114 long x22;
115 long x23;
116 long x24;
117 long x25;
118 long x26;
119 long x27;
120 long x28;
121 long x29;
122 long x30;
123 long x31;
124 long mstatus;
125 };
126 long riscv_regs[30];
127 };
128 } SAVED_CONTEXT;
129 #endif
130
131 typedef void (*hook_func)(void);
132
133 extern char _dtcm_ema_start, _dtcm_bss_end;
134 extern char _end; //BSS end in SRAM2
135
136 extern void mtime_handler(void);
137 extern void mswi_handler(void);
138 extern void mext_interrupt(void);
139 extern void stack_mem_dump(uint32_t stack_top, uint32_t stack_bottom);
140 extern void user_except_handler (unsigned long mcause, SAVED_CONTEXT *context);
141 extern void close_wdt(void);
142
143 static hook_func s_wifi_dump_func = NULL;
144 static hook_func s_ble_dump_func = NULL;
145
146 volatile unsigned int g_enter_exception = 0;
147
arch_is_enter_exception(void)148 unsigned int arch_is_enter_exception(void) {
149 return g_enter_exception;
150 }
151
rtos_regist_wifi_dump_hook(hook_func wifi_func)152 void rtos_regist_wifi_dump_hook(hook_func wifi_func)
153 {
154 s_wifi_dump_func = wifi_func;
155 }
156
rtos_regist_ble_dump_hook(hook_func ble_func)157 void rtos_regist_ble_dump_hook(hook_func ble_func)
158 {
159 s_ble_dump_func = ble_func;
160 }
161
trap_handler(unsigned long mcause,SAVED_CONTEXT * context)162 void trap_handler(unsigned long mcause, SAVED_CONTEXT *context)
163 {
164 if (0 == g_enter_exception) {
165 // Make sure the interrupt is disable
166 uint32_t int_level = rtos_disable_int();
167 uint32_t mie_status = rtos_disable_mie_int();
168
169 #if CONFIG_INT_WDT
170 close_wdt();
171 bk_task_wdt_stop();
172 #endif
173 /* Handled Trap */
174 g_enter_exception = 1;
175 BK_LOG_FLUSH();
176 bk_set_printf_sync(true);
177
178 user_except_handler(mcause, context);
179 BK_DUMP_OUT("Unhandled Trap : mcause = 0x%x, mepc = 0x%x\r\n", mcause, context->mepc);
180 while(g_enter_exception);
181
182 rtos_enable_mie_int(mie_status);
183 rtos_enable_int(int_level);
184 }
185
186 }
187
188
189 /**
190 * this function will show registers of CPU
191 *
192 * @param mcause
193 * @param context
194 */
arch_dump_cpu_registers(unsigned long mcause,SAVED_CONTEXT * context)195 void arch_dump_cpu_registers (unsigned long mcause, SAVED_CONTEXT *context)
196 {
197
198 BK_DUMP_OUT("Current regs:\r\n");
199
200 BK_DUMP_OUT("1 ra x 0x%lx\r\n", context->x1);
201 BK_DUMP_OUT("2 sp x 0x%lx\r\n", context + 1);
202 BK_DUMP_OUT("5 t0 x 0x%lx\r\n", context->x5);
203 BK_DUMP_OUT("6 t1 x 0x%lx\r\n", context->x6);
204 BK_DUMP_OUT("7 t2 x 0x%lx\r\n", context->x7);
205 BK_DUMP_OUT("8 fp x 0x%lx\r\n", context->x8);
206 BK_DUMP_OUT("9 s1 x 0x%lx\r\n", context->x9);
207 BK_DUMP_OUT("10 a0 x 0x%lx\r\n", context->x10);
208 BK_DUMP_OUT("11 a1 x 0x%lx\r\n", context->x11);
209 BK_DUMP_OUT("12 a2 x 0x%lx\r\n", context->x12);
210 BK_DUMP_OUT("13 a3 x 0x%lx\r\n", context->x13);
211 BK_DUMP_OUT("14 a4 x 0x%lx\r\n", context->x14);
212 BK_DUMP_OUT("15 a5 x 0x%lx\r\n", context->x15);
213 BK_DUMP_OUT("16 a6 x 0x%lx\r\n", context->x16);
214 BK_DUMP_OUT("17 a7 x 0x%lx\r\n", context->x17);
215 BK_DUMP_OUT("18 s2 x 0x%lx\r\n", context->x18);
216 BK_DUMP_OUT("19 s3 x 0x%lx\r\n", context->x19);
217 BK_DUMP_OUT("20 s4 x 0x%lx\r\n", context->x20);
218 BK_DUMP_OUT("21 s5 x 0x%lx\r\n", context->x21);
219 BK_DUMP_OUT("22 s6 x 0x%lx\r\n", context->x22);
220 BK_DUMP_OUT("23 s7 x 0x%lx\r\n", context->x23);
221 BK_DUMP_OUT("24 s8 x 0x%lx\r\n", context->x24);
222 BK_DUMP_OUT("25 s9 x 0x%lx\r\n", context->x25);
223 BK_DUMP_OUT("26 s10 x 0x%lx\r\n", context->x26);
224 BK_DUMP_OUT("27 s11 x 0x%lx\r\n", context->x27);
225 BK_DUMP_OUT("28 t3 x 0x%lx\r\n", context->x28);
226 BK_DUMP_OUT("29 t4 x 0x%lx\r\n", context->x29);
227 BK_DUMP_OUT("30 t5 x 0x%lx\r\n", context->x30);
228 BK_DUMP_OUT("31 t6 x 0x%lx\r\n", context->x31);
229
230 if (mcause == TRAP_M_USER_ASSERT) {
231 BK_DUMP_OUT("32 pc x 0x%lx\r\n", context->x1 - 4);
232 } else {
233 BK_DUMP_OUT("32 pc x 0x%lx\r\n", context->mepc - 4);
234 }
235
236 BK_DUMP_OUT("833 mstatus x 0x%lx\r\n", context->mstatus);
237
238 BK_DUMP_OUT("838 mtvec x 0x%lx\r\n", read_csr(NDS_MTVEC));
239 BK_DUMP_OUT("897 mscratch x 0x%lx\r\n", read_csr(NDS_MSCRATCH));
240 BK_DUMP_OUT("898 mepc x 0x%lx\r\n", context->mepc);
241 BK_DUMP_OUT("899 mcause x 0x%lx\r\n", mcause);
242 BK_DUMP_OUT("900 mtval x 0x%lx\r\n", read_csr(NDS_MTVAL));
243 BK_DUMP_OUT("2058 mdcause x 0x%lx\r\n", read_csr(NDS_MDCAUSE));
244
245 BK_DUMP_OUT("\r\n");
246
247 if (mcause == 0x2) {
248 stack_mem_dump((uint32_t)(context->mepc - 32), (uint32_t)(context->mepc + 32));
249 }
250 }
251
sys_delay_sync(uint32_t time_count)252 void sys_delay_sync(uint32_t time_count )
253 {
254 volatile UINT32 i = 0;
255
256 for (i = 0; i < time_count; i ++)
257 ;
258 }
259
user_except_handler(unsigned long mcause,SAVED_CONTEXT * context)260 void user_except_handler (unsigned long mcause, SAVED_CONTEXT *context) {
261 BK_DUMP_OUT("***********************************************************************************************\r\n");
262 BK_DUMP_OUT("***********************************user except handler begin***********************************\r\n");
263 BK_DUMP_OUT("***********************************************************************************************\r\n");
264
265 arch_dump_cpu_registers(mcause, context);
266
267 if(NULL != s_wifi_dump_func) {
268 s_wifi_dump_func();
269 }
270
271 if(NULL != s_ble_dump_func) {
272 s_ble_dump_func();
273 }
274
275 BK_DUMP_OUT("System will dump memory in 5s, please ready to save whole log.........\r\n");
276
277 sys_delay_sync(SYS_DELAY_TIME_5S);
278
279 #if CONFIG_MEMDUMP_ALL
280 stack_mem_dump((uint32_t)&_dtcm_ema_start, (uint32_t)&_dtcm_bss_end);
281 #if CONFIG_CACHE_ENABLE && (!CONFIG_SLAVE_CORE)
282 for (int i = 0; i < SRAM_BLOCK_COUNT; i++) {
283 stack_mem_dump(g_sram_addr_map[i], g_sram_addr_map[i] + 0x20000);
284 }
285 #else
286 stack_mem_dump(RAM_BASE_ADDR, (uint32_t)&_end);
287 #endif
288 #endif
289
290 rtos_dump_backtrace();
291 rtos_dump_task_list();
292 #if CONFIG_FREERTOS
293 rtos_dump_task_runtime_stats();
294 #endif
295
296 #if CONFIG_FREERTOS && CONFIG_MEM_DEBUG
297 os_dump_memory_stats(0, 0, NULL);
298 #endif
299
300 arch_dump_cpu_registers(mcause, context);
301
302
303 BK_DUMP_OUT("***********************************************************************************************\r\n");
304 BK_DUMP_OUT("************************************user except handler end************************************\r\n");
305 BK_DUMP_OUT("***********************************************************************************************\r\n");
306
307 bk_reboot();
308
309 }
310
set_reboot_tag(uint32_t tag)311 void set_reboot_tag(uint32_t tag) {
312 uint32_t p_tag = REBOOT_TAG_ADDR;
313 *((uint32_t *)p_tag) = tag;
314 }
315
get_reboot_tag(void)316 inline uint32_t get_reboot_tag(void) {
317 return *((uint32_t *)REBOOT_TAG_ADDR);
318 }
319
320
user_nmi_handler(unsigned long mcause,unsigned long ra)321 void user_nmi_handler(unsigned long mcause, unsigned long ra) {
322 if(mcause == MCAUSE_CAUSE_WATCHDOG) {
323 if( REBOOT_TAG_REQ == get_reboot_tag() ) {
324 BK_DUMP_OUT("Wait reboot.\r\n");
325 while(1);
326 }
327 }
328
329 #if CONFIG_INT_WDT
330 close_wdt();
331 bk_task_wdt_stop();
332 #endif
333
334 BK_DUMP_OUT("========Call NULL func pointer/WDT, please check the code near ra reg.========\r\n");
335 BK_DUMP_OUT("1 ra x 0x%lx\r\n", ra);
336 BK_DUMP_OUT("========Call NULL func pointer/WDT, please check the code near ra reg.========\r\n");
337 }
338
339 #if CONFIG_SAVE_BOOT_TIME_POINT
340
341 static uint64_t s_saved_boot_info[2*CPU_SAVED_TIME_MAX];
342
343 extern uint64_t riscv_get_mtimer(void);
344 extern uint64_t riscv_get_instruct_cnt(void);
345
get_saved_time_info_addr(uint32_t time_point)346 static uint32_t get_saved_time_info_addr(uint32_t time_point) {
347 uint32_t addr = 0;
348
349 if (CPU_BOOT_TIME == time_point) {
350 //The BSS section not ready at cpu boot time point
351 addr = CPU_BOOT_TIME_ADDR;
352 } else if (time_point < CPU_SAVED_TIME_MAX){
353 addr = (uint32_t)&s_saved_boot_info[2*time_point];
354 }
355
356 return addr;
357 }
358
save_mtime_point(uint32_t time_point)359 void save_mtime_point(uint32_t time_point) {
360 uint32_t addr = get_saved_time_info_addr(time_point);
361
362 if (0 != addr) {
363 *((uint64_t *)addr) = riscv_get_mtimer();
364 *((uint64_t *)addr + 1) = riscv_get_instruct_cnt();
365 }
366 }
367
show_saved_mtime_point(uint32_t time_point)368 void show_saved_mtime_point(uint32_t time_point) {
369 uint32_t addr = get_saved_time_info_addr(time_point);
370
371 if (0 != addr) {
372 uint64_t saved_time = *((uint64_t *)addr);
373 uint64_t saved_inst_cnt = *((uint64_t *)addr + 1);
374 uint32_t saved_time_ms = (u32)(saved_time & 0xFFFFFFFF) / 26000;
375 BK_DUMP_OUT("saved time: 0x%x:0x%08x\r\n", (u32)(saved_time >> 32), (u32)(saved_time & 0xFFFFFFFF));
376 BK_DUMP_OUT("saved time: %ldms\r\n", saved_time_ms);
377 BK_DUMP_OUT("saved inst_cnt: 0x%x:0x%08x\r\n", (u32)(saved_inst_cnt >> 32), (u32)(saved_inst_cnt & 0xFFFFFFFF));
378 }
379 }
380
show_saved_mtime_info(void)381 void show_saved_mtime_info(void)
382 {
383 BK_DUMP_OUT("==============Show Boot Time===================\r\n");
384 show_saved_mtime_point(CPU_BOOT_TIME);
385
386 BK_DUMP_OUT("==============Show Init Mem Time===================\r\n");
387 show_saved_mtime_point(CPU_INIT_MEM_TIME);
388
389 BK_DUMP_OUT("==============Show MAIN Emtry Time===================\r\n");
390 show_saved_mtime_point(CPU_MAIN_ENTRY_TIME);
391
392 BK_DUMP_OUT("==============Show INIT Driver Time===================\r\n");
393 show_saved_mtime_point(CPU_INIT_DRIVER_TIME);
394
395 BK_DUMP_OUT("==============Show App Entry Time===================\r\n");
396 show_saved_mtime_point(CPU_APP_ENTRY_TIME);
397
398 BK_DUMP_OUT("==============Show Start Sche Time===================\r\n");
399 show_saved_mtime_point(CPU_START_SCHE_TIME);
400
401 BK_DUMP_OUT("==============Show Start Wifi init Time===================\r\n");
402 show_saved_mtime_point(CPU_START_WIFI_INIT_TIME);
403
404 BK_DUMP_OUT("==============Show Finish Wifi init Time===================\r\n");
405 show_saved_mtime_point(CPU_FINISH_WIFI_INIT_TIME);
406
407 BK_DUMP_OUT("==============Show App Finish Time===================\r\n");
408 show_saved_mtime_point(CPU_APP_FINISH_TIME);
409
410 BK_DUMP_OUT("==============Show Main Finish Time===================\r\n");
411 show_saved_mtime_point(CPU_MIAN_FINISH_TIME);
412
413 BK_DUMP_OUT("==============Show Start Connect Time===================\r\n");
414 show_saved_mtime_point(CPU_START_CONNECT_TIME);
415
416 BK_DUMP_OUT("==============Show Wifi Connected Time===================\r\n");
417 show_saved_mtime_point(CPU_CONNECTED_TIME);
418 }
419
420
show_current_time_point(const char * info)421 void show_current_time_point(const char *info) {
422 uint64_t current_time = riscv_get_mtimer();;
423 uint32_t current_time_ms = (u32) (current_time/26000);
424 BK_DUMP_OUT("%s: current time: %ldms\r\n", info, current_time_ms);
425 }
426
427 #endif
428