1 /*
2 * Copyright (c) 2020 HiSilicon (Shanghai) Technologies CO., LIMITED.
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 * Description: hard riscv interface
15 */
16 #include "platform_core.h"
17 #include "exception.h"
18 #include "chip_io.h"
19 #include "preserve.h"
20 #include "debug_print.h"
21 #include "securec.h"
22 #include "non_os_reboot.h"
23 #include "reboot_porting.h"
24 #include "watchdog_porting.h"
25 #ifdef SUPPORT_CPU_TRACE
26 #include "cpu_trace.h"
27 #include "memory_config_common.h"
28 #endif
29 #ifdef SUPPORT_WATCHDOG
30 #include "watchdog.h"
31 #endif
32
33 #if (CORE == MASTER_BY_ALL)
34 #include "cpu_utils.h"
35 #endif
36 #if SLAVE_BY_WS53_ONLY
37 #include "nonos_trace.h"
38 #endif
39
40 #include "non_os.h"
41
42 #include "oam_trace.h"
43 #include "debug_print.h"
44 #ifndef USE_CMSIS_OS
45 #include "arch_encoding.h"
46 #include "vectors.h"
47 #include "interrupt_handler.h"
48 #endif
49 #include "tcxo.h"
50 #if defined(__LITEOS__)
51 #include "los_sched_pri.h"
52 #include "los_task_pri.h"
53 #include "los_sem_pri.h"
54 #endif
55 #include "fcntl.h"
56 #include "unistd.h"
57 #if defined SAVE_EXC_INFO
58 #include "dfx_adapt_layer.h"
59 #if CONFIG_DFX_SUPPORT_FILE_SYSTEM == DFX_YES
60 #include "dfx_file_operation.h"
61 #include "sys/stat.h"
62 #if defined CFG_DRIVERS_NANDFLASH
63 #include "nandflash_config.h"
64 #endif
65 #if defined CFG_DRIVERS_MMC
66 #include "block.h"
67 #endif
68 #endif
69 #endif
70 #if defined(__FREERTOS__)
71 #include "FreeRTOS.h"
72 #include "encoding.h"
73 #endif
74
75 #ifdef CONFIG_SUPPORT_CRASHINFO_SAVE_TO_FLASH
76 #include "sfc.h"
77 #include "exception.h"
78 #include "board_ws63.h"
79 #include "partition_resource_id.h"
80 #include "partition.h"
81 #include "oam_trace.h"
82 #endif
83
84 #define EXCEPT_REBOOT_DELAY_MS 3000
85 #define IPC_NOTIFY_APPS_TIMEOUT_MS 16000
86 #define SW_PRINT_DELAY 200ULL
87 #define USER_STACK_PUSH_LENGTH 160
88 #define USER_STACK_OFFSET_PER 4
89 #define USER_STACK_PRINT_DEPTH 30
90 #define MAX_CALL_STACK 20
91 #define CALLSTACK_RA_POS 4
92 #define CALLSTACK_FP_POS 8
93 #define EXC_STACK_INFO_SIZE 8
94 #if defined(SAVE_EXC_INFO) && defined(CFG_DRIVERS_MMC)
95 #define ONE_SECTOR_SIZE 512
96 #define START_SECTOR_NUM 4445186
97 #endif
98 #ifdef __FREERTOS__
99 #define STACK_BOTTROM_INIT_VAL 0xa5a5a5a5
100 #else
101 #define STACK_BOTTROM_INIT_VAL 0xf0f0f0f
102 #endif
103 #if (ARCH == RISCV70)
104 #define MCAUSE_MASK 0x80000FFF
105 #define NMI_INTERRUPT 0x00000FFF
106 #else
107 #define NMI_INTERRUPT 0x8000000C
108 #endif
109 #if defined(__FREERTOS__)
110 #define SP_OFFSET (30 * 4)
111 #else
112 #define SP_OFFSET 0x10
113 #endif
114 #define CONTEXT_OFFSET (4 * 4 + 33 * 4 + 4)
115
116 #ifdef CONFIG_SUPPORT_CRASHINFO_SAVE_TO_FLASH
117 #define STACK_DEPTH 128
118 #define STACK_SAVE_DEPTH 10
119 #define STACK_SAVE_SIZE (STACK_SAVE_DEPTH * 8 + 4) /* |4B:count|4B:sp 4B:sp_content|4B:sp 4B:sp_content|...| */
120 #define BASE_ADDR 0x200000
121 #define CRASHINFO_GROUP_CNT 10
122 #define INVALID_SEM_ID 0xFFFFFFFF
123 #define TASK_NAME_MAX 23
124
125 static uint32_t g_crashinfo_flag = 0xdeadbeef;
126 #endif
127
128 #if defined(USE_CMSIS_OS) && defined(__LITEOS__)
129 extern VOID OsExcInfoDisplay(uint32_t excType, const ExcContext *excBufAddr);
130 extern ExcInfo g_excInfo;
131 #endif
132 static void deal_with_exception(exc_context_t *exc_buf_addr, uint32_t exc_type, reboot_cause_t reset_cause);
133
134 static hal_exception_dump_callback g_exception_dump_callback = NULL;
135
136 nmi_proc_func g_nmi_hook = do_hard_fault_handler;
137
138 exc_info_t g_exc_info;
139
140 #if defined SAVE_EXC_INFO
141 /* ifdef LOSCFG_EXC_SIMPLE_INFO g_xregs_map start from X4(instead of X0) to X31 */
142 static const uint8_t g_xregs_map[] = {
143 /* tp t0 t1 t2 s0 s1 a0 */
144 2, 30, 29, 28, 15, 14, 27,
145 /* a1 a2 a3 a4 a5 a6 a7 */
146 26, 25, 24, 23, 22, 21, 20,
147 /* s2 s3 s4 s5 s6 s7 s8 */
148 13, 12, 11, 10, 9, 8, 7,
149 /* s9 s10 s11 t3 t4 t5 t6 */
150 6, 5, 4, 19, 18, 17, 16
151 };
152 #if CONFIG_DFX_SUPPORT_FILE_SYSTEM == DFX_YES
153 static const char *g_exc_info_path = "/user/exc/exc_info.bin";
154 #endif
155 #endif
156
157 #if (SLAVE_BY_BS25_ONLY || SLAVE_BY_WS53_ONLY) && (!defined(NO_TIMEOUT))
158 static volatile uint32_t g_bt_nmi_reboot = 0;
159 static volatile uint32_t g_bt_nmi_mask = 0;
160 #endif
161 #if ((defined(BUILD_APPLICATION_STANDARD)) && (IS_MAIN_CORE == NO))
162
163 #include "ipc.h"
164 #include "ipc_actions.h"
165
wait_apps_refresh_flash(void)166 static void wait_apps_refresh_flash(void)
167 {
168 #if SYS_DEBUG_MODE_ENABLE == YES
169 for (uint32_t i = 0; i < WAIT_APPS_DUMP_DELAY_TIMES; i++) {
170 #if CORE == MASTER_BY_ALL
171 uapi_watchdog_kick();
172 #endif
173 uapi_tcxo_delay_ms((uint64_t)WAIT_APPS_DUMP_DELAY_MS_EACH_TIME);
174 }
175 #else /* SYS_DEBUG_MODE_ENABLE == NO */
176 uapi_tcxo_delay_ms((uint64_t)WAIT_APPS_REFRESH_FLASH_MS);
177 #endif /* SYS_DEBUG_MODE_ENABLE == YES */
178 }
179
notify_apps_coredump_and_wait(void)180 static void notify_apps_coredump_and_wait(void)
181 {
182 ipc_status_t ipc_returned_value;
183 ipc_returned_value = ipc_spin_send_message_timeout(CORES_APPS_CORE,
184 IPC_ACTION_SYS_REBOOT_REQ,
185 NULL,
186 sizeof(ipc_payload),
187 IPC_PRIORITY_HIGHEST, false, IPC_NOTIFY_APPS_TIMEOUT_MS);
188 if (ipc_returned_value != IPC_STATUS_OK) {
189 UNUSED(ipc_returned_value);
190 }
191 }
192 #endif
193
194 #ifndef USE_CMSIS_OS
do_process_exception(exc_context_t * exc_buff_addr)195 static void do_process_exception(exc_context_t *exc_buff_addr)
196 {
197 g_exc_info.type = (uint16_t)(exc_buff_addr->mcause);
198 g_exc_info.context = exc_buff_addr;
199 exc_info_display(&g_exc_info);
200 }
201
do_trap_unknown(exc_context_t * exc_buff_addr)202 void do_trap_unknown(exc_context_t *exc_buff_addr)
203 {
204 PRINT("Oops - unknown exception\r\n");
205 do_process_exception(exc_buff_addr);
206 }
207
do_trap_insn_misaligned(exc_context_t * exc_buff_addr)208 void do_trap_insn_misaligned(exc_context_t *exc_buff_addr)
209 {
210 PRINT("Oops - instruction address misaligned\r\n");
211 do_process_exception(exc_buff_addr);
212 }
213
do_trap_insn_fault(exc_context_t * exc_buff_addr)214 void do_trap_insn_fault(exc_context_t *exc_buff_addr)
215 {
216 PRINT("Oops - instruction access fault\r\n");
217 do_process_exception(exc_buff_addr);
218 }
219
do_trap_insn_illegal(exc_context_t * exc_buff_addr)220 void do_trap_insn_illegal(exc_context_t *exc_buff_addr)
221 {
222 PRINT("Oops - illegal instruction\r\n");
223 do_process_exception(exc_buff_addr);
224 }
225
do_trap_load_misaligned(exc_context_t * exc_buff_addr)226 void do_trap_load_misaligned(exc_context_t *exc_buff_addr)
227 {
228 PRINT("Oops - load address misaligned\r\n");
229 do_process_exception(exc_buff_addr);
230 }
231
do_trap_load_fault(exc_context_t * exc_buff_addr)232 void do_trap_load_fault(exc_context_t *exc_buff_addr)
233 {
234 PRINT("Oops - load access fault\r\n");
235 do_process_exception(exc_buff_addr);
236 }
237
do_trap_store_misaligned(exc_context_t * exc_buff_addr)238 void do_trap_store_misaligned(exc_context_t *exc_buff_addr)
239 {
240 PRINT("Oops - store (or AMO) address misaligned\r\n");
241 do_process_exception(exc_buff_addr);
242 }
243
do_trap_store_fault(exc_context_t * exc_buff_addr)244 void do_trap_store_fault(exc_context_t *exc_buff_addr)
245 {
246 PRINT("Oops - store (or AMO) access fault\r\n");
247 do_process_exception(exc_buff_addr);
248 }
249
do_trap_ecall_u(exc_context_t * exc_buff_addr)250 void do_trap_ecall_u(exc_context_t *exc_buff_addr)
251 {
252 PRINT("Oops - environment call from U-mode\r\n");
253 do_process_exception(exc_buff_addr);
254 }
255
do_trap_ecall_s(exc_context_t * exc_buff_addr)256 void do_trap_ecall_s(exc_context_t *exc_buff_addr)
257 {
258 PRINT("Oops - environment call from S-mode\r\n");
259 do_process_exception(exc_buff_addr);
260 }
261
do_trap_ecall_m(exc_context_t * exc_buff_addr)262 void do_trap_ecall_m(exc_context_t *exc_buff_addr)
263 {
264 PRINT("Oops - environment call from M-mode\r\n");
265 do_process_exception(exc_buff_addr);
266 }
267
do_trap_break(exc_context_t * exc_buff_addr)268 void do_trap_break(exc_context_t *exc_buff_addr)
269 {
270 PRINT("Oops - ebreak\r\n");
271 do_process_exception(exc_buff_addr);
272 }
273
do_insn_page_fault(exc_context_t * exc_buff_addr)274 void do_insn_page_fault(exc_context_t *exc_buff_addr)
275 {
276 PRINT("Oops - insn page fault\r\n");
277 do_process_exception(exc_buff_addr);
278 }
279
do_load_page_fault(exc_context_t * exc_buff_addr)280 void do_load_page_fault(exc_context_t *exc_buff_addr)
281 {
282 PRINT("Oops - load page fault\r\n");
283 do_process_exception(exc_buff_addr);
284 }
285
do_store_page_fault(exc_context_t * exc_buff_addr)286 void do_store_page_fault(exc_context_t *exc_buff_addr)
287 {
288 PRINT("Oops - store page fault\r\n");
289 do_process_exception(exc_buff_addr);
290 }
291
do_hard_fault(exc_context_t * exc_buff_addr)292 void do_hard_fault(exc_context_t *exc_buff_addr)
293 {
294 PRINT("Oops - hard fault\r\n");
295 do_process_exception(exc_buff_addr);
296 }
297
do_lockup(exc_context_t * exc_buff_addr)298 void do_lockup(exc_context_t *exc_buff_addr)
299 {
300 PRINT("Oops - lock up\r\n");
301 do_process_exception(exc_buff_addr);
302 }
303
default_handler(void)304 void default_handler(void)
305 {
306 uint32_t hwi_index = interrupt_number_get();
307 PRINT("default_handler : interrupt idx[%d]\n", hwi_index);
308 while (true) { }
309 UNUSED(hwi_index);
310 }
311
nmi_handler(void)312 void nmi_handler(void)
313 {
314 uint32_t hwi_index = interrupt_number_get();
315 PRINT("nmi_handler : interrupt idx[%d]\n", hwi_index);
316 while (true) { }
317 UNUSED(hwi_index);
318 }
319 #endif
320
321 #ifdef SUPPORT_CALLSTACK
dump_call_stack(uint32_t fp)322 static void dump_call_stack(uint32_t fp)
323 {
324 uint32_t back_fp = fp;
325 uint32_t tmp_fp;
326 uint32_t back_ra;
327 uint32_t count = 0;
328
329 PRINT("*******dump call stack begin*******\n");
330
331 while ((back_fp != 0) && (back_fp != STACK_BOTTROM_INIT_VAL)) {
332 tmp_fp = back_fp;
333 back_ra = *((uint32_t *)(tmp_fp - CALLSTACK_RA_POS));
334 back_fp = *((uint32_t *)(tmp_fp - CALLSTACK_FP_POS));
335 PRINT("call stack %d -- ra = 0x%x fp = 0x%x\n", count, back_ra, back_fp);
336
337 count++;
338 if ((count == MAX_CALL_STACK) || (back_fp == tmp_fp)) {
339 break;
340 }
341 }
342
343 PRINT("*******dump call stack end*******\n");
344 }
345 #else
back_trace(uint32_t fp)346 void back_trace(uint32_t fp)
347 {
348 uint32_t back_fp = fp + USER_STACK_PUSH_LENGTH;
349 uint32_t temp_fp;
350 uint32_t back_sp;
351 uint32_t count = 0;
352
353 PRINT("*******backtrace begin*******\n");
354
355 while (back_fp != 0) {
356 temp_fp = back_fp;
357 back_sp = readl(temp_fp);
358 PRINT("traceback %d -- sp addr= 0x%x sp content= 0x%x\n", count, temp_fp, back_sp);
359 back_fp = back_fp + USER_STACK_OFFSET_PER;
360
361 count++;
362 if (count == USER_STACK_PRINT_DEPTH) {
363 break;
364 }
365 }
366 PRINT("*******backtrace end*******\n");
367 UNUSED(back_sp);
368 }
369 #endif
370
exc_info_display(const exc_info_t * exc)371 void exc_info_display(const exc_info_t *exc)
372 {
373 if (exc == NULL) {
374 return;
375 }
376 PRINT("**************Exception Information************** \n");
377 PRINT("uwExcType = 0x%x\n", exc->type);
378
379 PRINT("mepc = 0x%x\n", exc->context->task_context.mepc);
380 PRINT("mstatus = 0x%x\n", exc->context->task_context.mstatus);
381 PRINT("mtval = 0x%x\n", exc->context->mtval);
382 PRINT("mcause = 0x%x\n", exc->context->mcause);
383 PRINT("ccause = 0x%x\n", exc->context->ccause);
384 #if CORE == WIFI
385 PRINT("cxcptsc = 0x%x\n", read_custom_csr(CXCPTSC));
386 #endif
387 PRINT("ra = 0x%x\n", exc->context->task_context.ra);
388 PRINT("sp = 0x%x\n", exc->context->task_context.sp);
389 PRINT("gp = 0x%x\n", exc->context->gp);
390 PRINT("tp = 0x%x\n", exc->context->task_context.tp);
391 PRINT("t0 = 0x%x\n", exc->context->task_context.t0);
392 PRINT("t1 = 0x%x\n", exc->context->task_context.t1);
393 PRINT("t2 = 0x%x\n", exc->context->task_context.t2);
394 PRINT("s0 = 0x%x\n", exc->context->task_context.s0);
395 PRINT("s1 = 0x%x\n", exc->context->task_context.s1);
396 PRINT("a0 = 0x%x\n", exc->context->task_context.a0);
397 PRINT("a1 = 0x%x\n", exc->context->task_context.a1);
398 PRINT("a2 = 0x%x\n", exc->context->task_context.a2);
399 PRINT("a3 = 0x%x\n", exc->context->task_context.a3);
400 PRINT("a4 = 0x%x\n", exc->context->task_context.a4);
401 PRINT("a5 = 0x%x\n", exc->context->task_context.a5);
402 PRINT("a6 = 0x%x\n", exc->context->task_context.a6);
403 PRINT("a7 = 0x%x\n", exc->context->task_context.a7);
404 PRINT("s2 = 0x%x\n", exc->context->task_context.s2);
405 PRINT("s3 = 0x%x\n", exc->context->task_context.s3);
406 PRINT("s4 = 0x%x\n", exc->context->task_context.s4);
407 PRINT("s5 = 0x%x\n", exc->context->task_context.s5);
408 PRINT("s6 = 0x%x\n", exc->context->task_context.s6);
409 PRINT("s7 = 0x%x\n", exc->context->task_context.s7);
410 PRINT("s8 = 0x%x\n", exc->context->task_context.s8);
411 PRINT("s9 = 0x%x\n", exc->context->task_context.s9);
412 PRINT("s10 = 0x%x\n", exc->context->task_context.s10);
413 PRINT("s11 = 0x%x\n", exc->context->task_context.s11);
414 PRINT("t3 = 0x%x\n", exc->context->task_context.t3);
415 PRINT("t4 = 0x%x\n", exc->context->task_context.t4);
416 PRINT("t5 = 0x%x\n", exc->context->task_context.t5);
417 PRINT("t6 = 0x%x\n", exc->context->task_context.t6);
418
419 PRINT("**************Exception Information end************** \n");
420 return;
421 }
422
wait_apps_prepare_for_rebooting(void)423 void wait_apps_prepare_for_rebooting(void)
424 {
425 #if ((defined(BUILD_APPLICATION_STANDARD)) && (IS_MAIN_CORE == NO))
426 notify_apps_coredump_and_wait();
427 wait_apps_refresh_flash();
428 #endif
429 }
430
431 #if MCU_ONLY
hal_set_nmi_cause(uint16_t status)432 static reboot_cause_t hal_set_nmi_cause(uint16_t status)
433 {
434 reboot_cause_t reset_cause = REBOOT_CAUSE_APPLICATION_GLOBAL;
435 switch (status) {
436 case NON_OS_NMI_CWDT_INT_FLAG:
437 reset_cause = REBOOT_CAUSE_APPLICATION_CHIP_WDT;
438 break;
439 case NON_OS_NMI_XIP_CTRL_INT_FLAG:
440 reset_cause = REBOOT_CAUSE_APPLICATION_XIP_CTRL;
441 break;
442 case NON_OS_NMI_XIP_CACHE_INT_FLAG:
443 reset_cause = REBOOT_CAUSE_APPLICATION_XIP_CACHE;
444 break;
445 case NON_OS_NMI_MDMA_INT_FLAG:
446 reset_cause = REBOOT_CAUSE_APPLICATION_MDMA;
447 break;
448 case NON_OS_NMI_SMDMAINT_FLAG:
449 reset_cause = REBOOT_CAUSE_APPLICATION_SMDMA;
450 break;
451 default:
452 break;
453 }
454 return reset_cause;
455 }
456 #endif
457
458 #if (CORE == MASTER_BY_ALL)
hal_set_reset_cause(uint32_t id)459 static reboot_cause_t hal_set_reset_cause(uint32_t id)
460 {
461 #if CORE != WIFI
462 reboot_cause_t reset_cause = REBOOT_CAUSE_UNKNOWN;
463
464 if (id == NMI_INTERRUPT) {
465 reset_cause = hal_set_nmi_cause(NON_OS_NMI_CWDT_INT_FLAG);
466 } else {
467 reset_cause = REBOOT_CAUSE_APPLICATION_HARDFAULT;
468 }
469 return reset_cause;
470 #else
471 UNUSED(id);
472 return REBOOT_CAUSE_UNKNOWN;
473 #endif
474 }
475 #endif
476
hal_save_reg_info(exc_context_t * exc_buf_addr)477 static void hal_save_reg_info(exc_context_t *exc_buf_addr)
478 {
479 exc_buf_addr->task_context.sp += SP_OFFSET;
480 set_exception_info_riscv(exc_buf_addr);
481 }
482
483 #if defined SAVE_EXC_INFO
484 #ifdef SUPPORT_CALLSTACK
get_stack_size(uint32_t fp,uint16_t * stack_size)485 static void get_stack_size(uint32_t fp, uint16_t *stack_size)
486 {
487 uint32_t back_fp = fp;
488 uint32_t tmp_fp;
489 uint32_t back_ra;
490 while ((back_fp != 0) && (back_fp != STACK_BOTTROM_INIT_VAL)) {
491 tmp_fp = back_fp;
492 back_ra = *((uint32_t *)(uintptr_t)(tmp_fp - CALLSTACK_RA_POS));
493 back_fp = *((uint32_t *)(uintptr_t)(tmp_fp - CALLSTACK_FP_POS));
494 (*stack_size)++;
495 if ((*stack_size == MAX_CALL_STACK) || (back_fp == tmp_fp)) {
496 break;
497 }
498 }
499 }
500
set_exc_stack_info(exc_info_save_t ** exc_info_save,uint32_t fp)501 static void set_exc_stack_info(exc_info_save_t **exc_info_save, uint32_t fp)
502 {
503 exc_stack_info_t *stack = (*exc_info_save)->stack;
504 uint32_t back_fp = fp;
505 uint32_t tmp_fp;
506 uint32_t back_ra;
507 uint32_t stack_size = (*exc_info_save)->stack_size;
508 uint32_t i;
509 for (i = 0; i < stack_size; i++) {
510 tmp_fp = back_fp;
511 back_ra = *((uint32_t *)(uintptr_t)(tmp_fp - CALLSTACK_RA_POS));
512 back_fp = *((uint32_t *)(uintptr_t)(tmp_fp - CALLSTACK_FP_POS));
513 stack[i].ra = back_ra;
514 stack[i].fp = back_fp;
515 }
516 }
517 #else
get_stack_size(uint32_t sp,uint16_t * stack_size)518 static void get_stack_size(uint32_t sp, uint16_t *stack_size)
519 {
520 uint32_t back_sp = sp;
521 while (back_sp != 0) {
522 back_sp = back_sp + USER_STACK_OFFSET_PER;
523 (*stack_size)++;
524 if (*stack_size == USER_STACK_PRINT_DEPTH) {
525 break;
526 }
527 }
528 }
529
set_exc_stack_info(exc_info_save_t ** exc_info_save,uint32_t sp)530 static void set_exc_stack_info(exc_info_save_t **exc_info_save, uint32_t sp)
531 {
532 exc_stack_info_t *stack = (*exc_info_save)->backtrace;
533 uint32_t back_sp = sp;
534 uint32_t backtrace_size = (*exc_info_save)->backtrace_size;
535 uint32_t i;
536 for (i = 0; i < backtrace_size; i++) {
537 back_sp = back_sp + USER_STACK_OFFSET_PER;
538 stack[i].sp_addr = back_sp;
539 stack[i].sp_content = *((uint32_t *)(back_sp));
540 }
541 }
542 #endif
543
set_exc_context_info(const task_context_t * task_context,exc_info_save_t ** exc_info_save)544 static void set_exc_context_info(const task_context_t *task_context, exc_info_save_t **exc_info_save)
545 {
546 exc_info_save_t *exc_info = *exc_info_save;
547 exc_info->mstatus = task_context->mstatus;
548 exc_info->mepc = task_context->mepc;
549 exc_info->ra = task_context->ra;
550 exc_info->sp = task_context->sp;
551
552 uint32_t i;
553 const uint32_t *context_regs = (const uint32_t *)(uintptr_t)task_context;
554 uint32_t *context_exc_info = (uint32_t *)(uintptr_t)exc_info;
555
556 #ifndef LOSCFG_EXC_SIMPLE_INFO
557 for (i = 0; i < sizeof(g_xregs_map) / sizeof(g_xregs_map[0]); i++) {
558 context_exc_info[EXC_INFO_SAVE_TP_INDEX + i] = context_regs[g_xregs_map[i]];
559 }
560 #else
561 for (i = 0; i < sizeof(g_xregs_map) / sizeof(g_xregs_map[0]); i++) {
562 context_exc_info[EXC_INFO_SAVE_X4_INDEX + i] = context_regs[g_xregs_map[i]];
563 }
564 #endif
565 #ifdef SUPPORT_CALLSTACK
566 set_exc_stack_info(exc_info_save, task_context->s0);
567 #elif defined(__LITEOS__)
568 set_exc_stack_info(exc_info_save, task_context->sp);
569 #endif
570 }
571
set_exc_info(uint32_t exc_type,const exc_context_t * exc_buf_addr,exc_info_save_t ** exc_info_save)572 static errcode_t set_exc_info(uint32_t exc_type, const exc_context_t *exc_buf_addr, exc_info_save_t **exc_info_save)
573 {
574 unused(exc_type);
575 exc_info_save_t *exc_info = *exc_info_save;
576 #if defined(USE_CMSIS_OS) && defined(__LITEOS__)
577 uint32_t phase;
578 uint32_t thrd_pid;
579 if (g_excInfo.nestCnt > 1) { /* Exception nesting level is 1 */
580 phase = OS_EXC_STAGE_EXC;
581 thrd_pid = OS_EXC_STAGE_INIT_VALUE;
582 } else if (!OS_SCHEDULER_ACTIVE) {
583 phase = OS_EXC_STAGE_INIT;
584 thrd_pid = OS_EXC_STAGE_INIT_VALUE;
585 } else if (OS_INT_ACTIVE != 0) {
586 phase = OS_EXC_STAGE_IRQ;
587 thrd_pid = OS_EXC_STAGE_INIT_VALUE;
588 } else {
589 phase = OS_EXC_STAGE_TASK;
590 thrd_pid = LOS_CurTaskIDGet();
591 }
592 char *task_name = OsCurTaskNameGet();
593 if (strcpy_s(exc_info->task_name, sizeof(exc_info->task_name), task_name) != EOK) {
594 return ERRCODE_FAIL;
595 }
596 exc_info->thrd_pid = thrd_pid;
597 exc_info->type = (uint16_t)exc_type;
598 exc_info->nest_cnt = g_excInfo.nestCnt;
599 #ifndef LOSCFG_EXC_SIMPLE_INFO
600 if (strcpy_s(exc_info->phase, sizeof(exc_info->phase), g_excOccurStage[phase])) {
601 return ERRCODE_FAIL;
602 }
603 #else
604 exc_info->phase = (uint16_t)phase;
605 #endif
606
607 exc_info->ccause = exc_buf_addr->ccause;
608 #elif defined(__FREERTOS__)
609 exc_info->uw_exc_type = (uint16_t)exc_buf_addr->mcause;
610 #if CORE == WIFI
611 exc_info->cxcptsc = read_custom_csr(CXCPTSC);
612 #endif
613 #endif
614 exc_info->mcause = exc_buf_addr->mcause;
615 exc_info->mtval = exc_buf_addr->mtval;
616 exc_info->gp = exc_buf_addr->gp;
617 set_exc_context_info((const task_context_t *)&exc_buf_addr->task_context, exc_info_save);
618 return ERRCODE_SUCC;
619 }
620
621 #ifdef CFG_DRIVERS_MMC
emmc_exc_info_write(void)622 errcode_t emmc_exc_info_write(void)
623 {
624 char *exc_info_buffer = (char *)dfx_malloc(0, ONE_SECTOR_SIZE);
625 uint32_t sector_num = mmc_direct_read(0, exc_info_buffer, START_SECTOR_NUM, 1);
626 if (sector_num == 0) {
627 return ERRCODE_FAIL;
628 }
629 if (strlen(exc_info_buffer) == 0) {
630 return ERRCODE_SUCC;
631 }
632 int32_t ret = crash_data_write(g_exc_info_path, 0, (const uint8_t *)exc_info_buffer, ONE_SECTOR_SIZE);
633 if (ret < 0) {
634 return ERRCODE_FAIL;
635 }
636 return ERRCODE_SUCC;
637 }
638 #endif
exc_info_save(uint32_t exc_type,const exc_context_t * exc_buf_addr)639 static errcode_t exc_info_save(uint32_t exc_type, const exc_context_t *exc_buf_addr)
640 {
641 uint16_t stack_size = 0;
642 #ifdef SUPPORT_CALLSTACK
643 get_stack_size(exc_buf_addr->task_context.s0, &stack_size);
644 #elif defined(__LITEOS__)
645 get_stack_size(exc_buf_addr->task_context.sp, &stack_size);
646 #endif
647 uint32_t exc_size = (uint32_t)EXC_INFO_SAVE_SIZE + (stack_size * EXC_STACK_INFO_SIZE);
648 exc_info_save_t *exc_info_save = (exc_info_save_t *)dfx_malloc(0, exc_size);
649 if (exc_info_save == NULL) {
650 return ERRCODE_FAIL;
651 }
652 memset_s(exc_info_save, exc_size, 0, exc_size);
653 #ifdef SUPPORT_CALLSTACK
654 exc_info_save->stack_size = stack_size;
655 #elif defined(__LITEOS__)
656 exc_info_save->backtrace_size = stack_size;
657 #endif
658 if (set_exc_info(exc_type, (const exc_context_t *)exc_buf_addr, &exc_info_save) != ERRCODE_SUCC) {
659 dfx_free(0, exc_info_save);
660 return ERRCODE_FAIL;
661 }
662 int32_t ret;
663 #if CONFIG_DFX_SUPPORT_FILE_SYSTEM == DFX_YES
664 #ifdef CFG_DRIVERS_NANDFLASH
665 nand_driver_init(SPEED_SLOW);
666 set_trans_type(TRANS_BY_CPU_SINGLE_LINE);
667 ret = exc_info_write(g_exc_info_path, 0, (const uint8_t *)exc_info_save, exc_size);
668 #endif
669 #ifdef CFG_DRIVERS_MMC
670 char *exc_info_buffer = (char *)dfx_malloc(0, ONE_SECTOR_SIZE);
671 memset_s(exc_info_buffer, ONE_SECTOR_SIZE, 0, ONE_SECTOR_SIZE);
672 memcpy_s(exc_info_buffer, ONE_SECTOR_SIZE, exc_info_save, exc_size);
673 ret = (int32_t)mmc_write_in_exception(0, exc_info_buffer, START_SECTOR_NUM, 1);
674 dfx_free(0, exc_info_buffer);
675 #endif
676 #else
677 if (dfx_flash_erase(FLASH_OP_TYPE_DUMP_INFO, 0, exc_size) != ERRCODE_SUCC) {
678 dfx_free(0, exc_info_save);
679 return ERRCODE_FAIL;
680 }
681 ret = dfx_flash_write(FLASH_OP_TYPE_DUMP_INFO, 0, (uint8_t *)exc_info_save, exc_size, 0);
682 #endif
683 dfx_free(0, exc_info_save);
684 if (ret <= 0) {
685 return ERRCODE_FAIL;
686 }
687 return ERRCODE_SUCC;
688 }
689 #endif
690
exc_fault_info_display(uint32_t exc_type,const exc_context_t * exc_buf_addr)691 static void exc_fault_info_display(uint32_t exc_type, const exc_context_t *exc_buf_addr)
692 {
693 #if defined(USE_CMSIS_OS) && defined(__LITEOS__)
694 OsExcInfoDisplay(exc_type, (const ExcContext *)(uintptr_t)exc_buf_addr);
695 #if !(MASTER_BY_BRANDY_ONLY)
696 exec_fault_handler(exc_type, (const ExcContext *)(uintptr_t)exc_buf_addr);
697 #endif
698 #endif
699
700 #if defined SAVE_EXC_INFO
701 exc_info_save(exc_type, (const exc_context_t *)exc_buf_addr);
702 #endif
703 #if SLAVE_BY_WS53_ONLY
704 syserr_backtrace_print(exc_buf_addr);
705 #endif
706 UNUSED(exc_type);
707 UNUSED(exc_buf_addr);
708 }
709
710 #ifdef CONFIG_SUPPORT_CRASHINFO_SAVE_TO_FLASH
711 static const char *g_exc_occur_stage[] = {
712 "Init",
713 "Task",
714 "Irq",
715 "Exc"
716 };
717
read_from_flash(uint32_t flash_addr,uint8_t * read_buffer,uint32_t read_size)718 uint32_t read_from_flash(uint32_t flash_addr, uint8_t *read_buffer, uint32_t read_size)
719 {
720 return uapi_sfc_reg_read(flash_addr, read_buffer, read_size);
721 }
722
crashinfo_flash_addr_get(uint32_t * flash_save_addr,uint32_t * flash_save_size)723 static inline bool crashinfo_flash_addr_get(uint32_t *flash_save_addr, uint32_t *flash_save_size)
724 {
725 partition_information_t info = {0};
726
727 if (uapi_partition_get_info(PARTITION_CRASH_INFO, &info) != ERRCODE_SUCC) {
728 return false;
729 }
730 *flash_save_addr = info.part_info.addr_info.addr;
731 *flash_save_size = info.part_info.addr_info.size;
732 return true;
733 }
734
crashinfo_back_trace_save(uint32_t addr,uint32_t sp)735 static void crashinfo_back_trace_save(uint32_t addr, uint32_t sp)
736 {
737 uint32_t back_sp = sp;
738 uint32_t stack_depth = 0;
739 uint32_t count = 0;
740 uint32_t ptr = addr;
741
742 while (back_sp != 0) {
743 if (is_valid_txt_addr(*((uint32_t *)(back_sp)))) {
744 ptr += sizeof(uint32_t);
745 uapi_sfc_reg_write(ptr, (uint8_t *)(uintptr_t)&back_sp, sizeof(uint32_t));
746 ptr += sizeof(uint32_t);
747 uapi_sfc_reg_write(ptr, (uint8_t *)(uintptr_t)back_sp, sizeof(uint32_t));
748 if (++count == STACK_SAVE_DEPTH) {
749 break;
750 }
751 }
752 back_sp = back_sp + USER_STACK_OFFSET_PER;
753 if (++stack_depth == STACK_DEPTH) {
754 break;
755 }
756 }
757 uapi_sfc_reg_write(addr, (uint8_t *)(uintptr_t)&count, sizeof(uint32_t));
758 }
759
crashinfo_back_trace_print(uint32_t addr)760 static void crashinfo_back_trace_print(uint32_t addr)
761 {
762 uint32_t count = 0;
763 uint32_t max_trace_count = 0;
764 uint32_t ptr = addr;
765 uint32_t back_sp = 0;
766 uint32_t sp_content = 0;
767 uapi_sfc_reg_read(ptr, (uint8_t *)(uintptr_t)&count, sizeof(uint32_t));
768 while (count-- > 0) {
769 ptr += sizeof(uint32_t);
770 uapi_sfc_reg_read(ptr, (uint8_t *)(uintptr_t)&back_sp, sizeof(uint32_t));
771 ptr += sizeof(uint32_t);
772 uapi_sfc_reg_read(ptr, (uint8_t *)(uintptr_t)&sp_content, sizeof(uint32_t));
773 PRINT("sp addr= 0x%x sp content= 0x%x\r\n", back_sp, sp_content);
774 if (++max_trace_count == STACK_SAVE_DEPTH) {
775 break;
776 }
777 }
778 }
779
crashinfo_taskinfo_get_size(const LosTaskCB * all_task_array)780 static uint32_t crashinfo_taskinfo_get_size(const LosTaskCB *all_task_array)
781 {
782 const LosTaskCB *task_cb = NULL;
783 uint32_t loop;
784 uint32_t save_size = sizeof(uint32_t);
785 for (loop = 0; loop < g_taskMaxNum; ++loop) {
786 task_cb = all_task_array + loop;
787 if ((task_cb->taskStatus & OS_TASK_STATUS_UNUSED) != 0) {
788 continue;
789 }
790 save_size += sizeof(uint32_t);
791 save_size += sizeof(uint32_t);
792 save_size += strlen(task_cb->taskName) + 1;
793 }
794 return save_size;
795 }
796
crashinfo_taskinfo_get_size_from_flash(uint32_t flash_save_offset)797 static uint32_t crashinfo_taskinfo_get_size_from_flash(uint32_t flash_save_offset)
798 {
799 uint32_t loop;
800 uint32_t task_name_len = 0;
801 uint32_t save_size = sizeof(uint32_t);
802 uint32_t cnt = 0;
803 uapi_sfc_reg_read(flash_save_offset, (uint8_t *)(uintptr_t)&cnt, sizeof(uint32_t));
804 for (loop = 0; loop < cnt; ++loop) {
805 save_size += sizeof(uint32_t);
806 uapi_sfc_reg_read(flash_save_offset + save_size, (uint8_t *)(uintptr_t)&task_name_len, sizeof(uint32_t));
807 save_size += sizeof(uint32_t);
808 save_size += task_name_len + 1;
809 }
810 return save_size;
811 }
812
crashinfo_taskinfo_save(uint32_t flash_save_offset,const LosTaskCB * all_task_array)813 static void crashinfo_taskinfo_save(uint32_t flash_save_offset, const LosTaskCB *all_task_array)
814 {
815 const LosTaskCB *task_cb = NULL;
816 uint32_t loop;
817 uint32_t semid = 0;
818 uint32_t save_offset = flash_save_offset + sizeof(uint32_t);
819 uint32_t task_name_size[g_taskMaxNum];
820 uint32_t cnt = 0;
821 memset_s(task_name_size, sizeof(uint32_t) * g_taskMaxNum, 0, sizeof(uint32_t) * g_taskMaxNum);
822 for (loop = 0; loop < g_taskMaxNum; ++loop) {
823 task_cb = all_task_array + loop;
824 if ((task_cb->taskStatus & OS_TASK_STATUS_UNUSED) != 0) {
825 continue;
826 }
827 semid = (task_cb->taskSem != NULL) ? ((LosSemCB *)task_cb->taskSem)->semId : INVALID_SEM_ID;
828 uapi_sfc_reg_write(save_offset, (uint8_t *)(uintptr_t)&semid, sizeof(uint32_t));
829 save_offset += sizeof(uint32_t);
830 task_name_size[task_cb->taskId] = strlen(task_cb->taskName);
831 uapi_sfc_reg_write(save_offset, (uint8_t *)(uintptr_t)&(task_name_size[task_cb->taskId]), sizeof(uint32_t));
832 save_offset += sizeof(uint32_t);
833 uapi_sfc_reg_write(save_offset, (uint8_t *)(uintptr_t)(task_cb->taskName), strlen(task_cb->taskName) + 1);
834 save_offset += strlen(task_cb->taskName) + 1;
835 cnt++;
836 }
837 uapi_sfc_reg_write(flash_save_offset, (uint8_t *)(uintptr_t)&cnt, sizeof(uint32_t));
838 }
839
crashinfo_size_check(uint32_t flash_save_size,uint32_t * crashinfo_group_size,uint32_t * left_size)840 static errcode_t crashinfo_size_check(uint32_t flash_save_size, uint32_t *crashinfo_group_size, uint32_t *left_size)
841 {
842 uint32_t waterline_addr = 0;
843 uint32_t waterline_len = 0;
844 uint32_t cbarray_addr = 0;
845 uint32_t cbarray_len = 0;
846 char *task_name = OsCurTaskNameGetExt();
847 OsTaskWaterLineArrayGet(&waterline_addr, &waterline_len);
848 OsTaskCBArrayGet(&cbarray_addr, &cbarray_len);
849 uint32_t task_info_size = crashinfo_taskinfo_get_size((LosTaskCB *)cbarray_addr);
850 uint32_t need_space = sizeof(uint32_t) + sizeof(uint32_t) + sizeof(uint32_t) * CRASHINFO_GROUP_CNT +
851 sizeof(uint32_t) + strlen(task_name) + 1 + sizeof(g_excInfo) + sizeof(exc_context_t) + STACK_SAVE_SIZE +
852 waterline_len + task_info_size + sizeof(uint32_t) + cbarray_len;
853 *left_size = flash_save_size - (sizeof(uint32_t) + sizeof(uint32_t) + sizeof(uint32_t) * CRASHINFO_GROUP_CNT +
854 sizeof(uint32_t) + strlen(task_name) + 1 + sizeof(g_excInfo) + sizeof(exc_context_t) + STACK_SAVE_SIZE +
855 waterline_len + task_info_size + sizeof(uint32_t));
856 if (need_space > flash_save_size) {
857 PRINT("No Space to Save the whole Crash Info\r\n");
858 return ERRCODE_FAIL;
859 }
860 uint32_t crashinfo_group_index = 0;
861 crashinfo_group_size[crashinfo_group_index++] = strlen(task_name) + 1;
862 crashinfo_group_size[crashinfo_group_index++] = sizeof(g_excInfo);
863 crashinfo_group_size[crashinfo_group_index++] = sizeof(exc_context_t);
864 crashinfo_group_size[crashinfo_group_index++] = STACK_SAVE_SIZE;
865 crashinfo_group_size[crashinfo_group_index++] = waterline_len;
866 crashinfo_group_size[crashinfo_group_index++] = task_info_size;
867 crashinfo_group_size[crashinfo_group_index++] = cbarray_len;
868 crashinfo_group_size[crashinfo_group_index++] = sizeof(LosTaskCB);
869 return ERRCODE_SUCC;
870 }
871
crashinfo_save(exc_context_t * exc_buf_addr)872 void crashinfo_save(exc_context_t *exc_buf_addr)
873 {
874 uint32_t flash_save_addr = 0, flash_save_size = 0, flash_save_offset = 0, left_size = 0;
875 uint32_t crashinfo_group_size[CRASHINFO_GROUP_CNT] = {0};
876 uint32_t crashinfo_group_cnt = CRASHINFO_GROUP_CNT;
877 bool ret = crashinfo_flash_addr_get(&flash_save_addr, &flash_save_size);
878 if (!ret) {
879 PRINT("No Space to Save Crash Info\r\n");
880 return;
881 }
882 char *task_name = OsCurTaskNameGetExt();
883 uint32_t waterline_addr = 0, waterline_len = 0, cbarray_addr = 0, cbarray_len = 0;
884 uint32_t task_name_len = strlen(task_name);
885
886 OsTaskWaterLineArrayGet(&waterline_addr, &waterline_len);
887 OsTaskCBArrayGet(&cbarray_addr, &cbarray_len);
888 if (crashinfo_size_check(flash_save_size, crashinfo_group_size, &left_size) != ERRCODE_SUCC) {
889 cbarray_len = left_size / sizeof(LosTaskCB) * sizeof(LosTaskCB);
890 }
891 uint32_t task_num = cbarray_len / sizeof(LosTaskCB);
892 uint32_t task_info_size = crashinfo_taskinfo_get_size((LosTaskCB *)cbarray_addr);
893
894 flash_save_offset = flash_save_addr;
895 if (uapi_sfc_reg_erase(flash_save_offset, flash_save_size) != ERRCODE_SUCC) {
896 PRINT("Erase Flash Failed\r\n");
897 return;
898 }
899 flash_save_offset += sizeof(uint32_t);
900 uapi_sfc_reg_write(flash_save_offset, (uint8_t *)(uintptr_t)&crashinfo_group_cnt, sizeof(uint32_t));
901 flash_save_offset += sizeof(uint32_t);
902 uapi_sfc_reg_write(flash_save_offset, (uint8_t *)(uintptr_t)&crashinfo_group_size, sizeof(uint32_t) *
903 CRASHINFO_GROUP_CNT);
904 flash_save_offset += sizeof(uint32_t) * CRASHINFO_GROUP_CNT;
905 uapi_sfc_reg_write(flash_save_offset, (uint8_t *)(uintptr_t)&task_name_len, sizeof(uint32_t));
906 flash_save_offset += sizeof(uint32_t);
907 uapi_sfc_reg_write(flash_save_offset, (uint8_t *)(uintptr_t)task_name, task_name_len + 1);
908 flash_save_offset += task_name_len + 1;
909 uapi_sfc_reg_write(flash_save_offset, (uint8_t *)(uintptr_t)&g_excInfo, sizeof(g_excInfo));
910 flash_save_offset += sizeof(g_excInfo);
911
912 uapi_sfc_reg_write(flash_save_offset, (uint8_t *)(uintptr_t)exc_buf_addr, sizeof(exc_context_t));
913 flash_save_offset += sizeof(exc_context_t);
914 uint32_t backtrace_sp = ((ExcContext *)exc_buf_addr)->taskContext.sp;
915 crashinfo_back_trace_save(flash_save_offset, backtrace_sp);
916 flash_save_offset += STACK_SAVE_SIZE;
917 uapi_sfc_reg_write(flash_save_offset, (uint8_t *)(uintptr_t)&task_num, sizeof(uint32_t));
918 flash_save_offset += sizeof(uint32_t);
919 uapi_sfc_reg_write(flash_save_offset, (uint8_t *)(uintptr_t)waterline_addr, waterline_len);
920 flash_save_offset += waterline_len;
921 crashinfo_taskinfo_save(flash_save_offset, (const LosTaskCB *)cbarray_addr);
922 flash_save_offset += task_info_size;
923 uapi_sfc_reg_write(flash_save_offset, (uint8_t *)(uintptr_t)cbarray_addr, cbarray_len);
924 uapi_sfc_reg_write(flash_save_addr, (uint8_t *)(uintptr_t)&g_crashinfo_flag, sizeof(uint32_t));
925 }
926
crashinfo_status_get(void)927 bool crashinfo_status_get(void)
928 {
929 uint32_t flash_save_addr = 0;
930 uint32_t flash_save_size = 0;
931 bool ret = crashinfo_flash_addr_get(&flash_save_addr, &flash_save_size);
932 if (!ret) {
933 PRINT("No Space to Save Crash Info\r\n");
934 return false;
935 }
936 uint32_t save_flag = 0;
937 uapi_sfc_reg_read(flash_save_addr, (uint8_t *)(uintptr_t)&save_flag, sizeof(uint32_t));
938 if (save_flag == g_crashinfo_flag) {
939 return true;
940 }
941 return false;
942 }
943
crashinfo_clr(void)944 void crashinfo_clr(void)
945 {
946 uint32_t flash_save_addr = 0, flash_save_size = 0;
947 bool ret = crashinfo_flash_addr_get(&flash_save_addr, &flash_save_size);
948 if (!ret) {
949 PRINT("No Space to Save Crash Info\r\n");
950 return;
951 }
952 uint32_t save_flag = 0;
953 uapi_sfc_reg_write(flash_save_addr, (uint8_t *)(uintptr_t)&save_flag, sizeof(uint32_t));
954 }
955
crashinfo_dump(void)956 void crashinfo_dump(void)
957 {
958 uint32_t flash_save_addr = 0, flash_save_size = 0;
959 bool ret = crashinfo_flash_addr_get(&flash_save_addr, &flash_save_size);
960 if (!ret) {
961 PRINT("No Space to Save Crash Info\r\n");
962 return;
963 }
964 uint32_t save_flag = 0;
965 uint32_t flash_save_offset = flash_save_addr;
966 uapi_sfc_reg_read(flash_save_offset, (uint8_t *)(uintptr_t)&save_flag, sizeof(uint32_t));
967 if (save_flag != g_crashinfo_flag) {
968 PRINT("Crash info nil\r\n");
969 return;
970 }
971
972 uint32_t waterline_addr = 0, waterline_len = 0, cbarray_addr = 0, cbarray_len = 0, task_name_len = 0;
973 char task_name[TASK_NAME_MAX] = {0};
974
975 OsTaskWaterLineArrayGet(&waterline_addr, &waterline_len);
976 OsTaskCBArrayGet(&cbarray_addr, &cbarray_len);
977 PRINT("--------------Last Crash info dump--------------\r\n");
978 flash_save_offset += sizeof(uint32_t);
979 flash_save_offset += sizeof(uint32_t);
980 flash_save_offset += sizeof(uint32_t) * CRASHINFO_GROUP_CNT;
981
982 uapi_sfc_reg_read(flash_save_offset, (uint8_t *)(uintptr_t)&task_name_len, sizeof(uint32_t));
983 flash_save_offset += sizeof(uint32_t);
984 uapi_sfc_reg_read(flash_save_offset, (uint8_t *)(uintptr_t)task_name, task_name_len + 1);
985 flash_save_offset += task_name_len + 1;
986
987 ExcInfo exc_info = {0};
988 uapi_sfc_reg_read(flash_save_offset, (uint8_t *)(uintptr_t)&exc_info, sizeof(ExcInfo));
989 PRINT("task:%s\n""thrdPid:0x%x\n""type:0x%x\n""nestCnt:%u\n""phase:%s\n",
990 task_name, exc_info.thrdPid, exc_info.type, exc_info.nestCnt, g_exc_occur_stage[exc_info.phase]);
991 flash_save_offset += sizeof(ExcInfo);
992
993 exc_context_t exc_context_buffer = {0};
994 uapi_sfc_reg_read(flash_save_offset, (uint8_t *)(uintptr_t)&exc_context_buffer, sizeof(exc_context_t));
995 exc_info.context = (ExcContext *)(&exc_context_buffer);
996 OsExcInfoDisplayContextExt(&exc_info);
997 flash_save_offset += sizeof(exc_context_t);
998 crashinfo_back_trace_print(flash_save_offset);
999
1000 flash_save_offset += STACK_SAVE_SIZE;
1001 uint32_t task_num = 0;
1002 uapi_sfc_reg_read(flash_save_offset, (uint8_t *)(uintptr_t)&task_num, sizeof(uint32_t));
1003 flash_save_offset += sizeof(uint32_t);
1004 waterline_addr = flash_save_offset + BASE_ADDR;
1005 uint32_t taskinfo_size = crashinfo_taskinfo_get_size_from_flash(flash_save_offset + waterline_len);
1006 cbarray_addr = waterline_addr + waterline_len + taskinfo_size;
1007 crashinfo_taskinfo_title_print();
1008 crashinfo_taskinfo_print((LosTaskCB *)cbarray_addr, (UINT32 *)waterline_addr, flash_save_offset + waterline_len,
1009 task_num);
1010 PRINT("--------------Last Crash info dump end--------------\r\n");
1011 }
1012 #endif
1013
do_hard_fault_handler(exc_context_t * exc_buf_addr)1014 void do_hard_fault_handler(exc_context_t *exc_buf_addr)
1015 {
1016 if (exc_buf_addr == NULL) { return; }
1017 #ifdef SUPPORT_CPU_TRACE
1018 cpu_trace_disable();
1019 #endif
1020 uint32_t exc_type = exc_buf_addr->mcause;
1021 PRINT("exception:%x\r\n", exc_type);
1022 if (exc_type == NMI_INTERRUPT) {
1023 PRINT("Oops:NMI\n");
1024 #ifdef WDT_INVOKE_USER_CALLBACK
1025 if (watchdog_port_check_nmi_intr(non_os_get_nmi_raw_status()) == ERRCODE_SUCC) {
1026 irq_wdt_handler();
1027 }
1028 #endif
1029 }
1030 reboot_cause_t reset_cause = 0;
1031 reset_cause = hal_set_reset_cause(exc_type);
1032 /* must set magic before memory dump */
1033 cpu_utils_set_system_status_by_cause(reset_cause);
1034 hal_save_reg_info(exc_buf_addr);
1035 deal_with_exception(exc_buf_addr, exc_type, reset_cause);
1036 }
1037
deal_with_exception(exc_context_t * exc_buf_addr,uint32_t exc_type,reboot_cause_t reset_cause)1038 static void deal_with_exception(exc_context_t *exc_buf_addr, uint32_t exc_type, reboot_cause_t reset_cause)
1039 {
1040 UNUSED(reset_cause);
1041
1042 #if defined(BUILD_APPLICATION_STANDARD) && (CORE == MASTER_BY_ALL)
1043 set_exception_time_stamp();
1044 // Record the reason before wait, so apps can get the reason.
1045 set_cpu_utils_reset_cause(reset_cause);
1046 #endif
1047 exc_fault_info_display(exc_type, exc_buf_addr);
1048 if (g_exception_dump_callback != NULL) {
1049 g_exception_dump_callback(exc_type, exc_buf_addr);
1050 }
1051 #ifdef CONFIG_SUPPORT_CRASHINFO_SAVE_TO_FLASH
1052 crashinfo_save(exc_buf_addr);
1053 #endif
1054
1055 #ifdef CONFIG_MIDDLEWARE_SUPPORT_EXCEPT_REBOOT
1056 cpu_utils_reset_chip_with_log((cores_t)MASTER_BY_ALL, reset_cause);
1057 #elif defined CONFIG_MEMORY_CUSTOMIZE_RSV
1058 reboot_mem_save_to_flash();
1059 #endif
1060 #ifdef CONFIG_MIDDLEWARE_SUPPORT_EXCEPT_DISABLE_WDT
1061 uapi_watchdog_disable();
1062 #else
1063 uapi_watchdog_enable(WDT_MODE_RESET);
1064 #endif
1065 #ifdef CONFIG_MIDDLEWARE_SUPPORT_EXCEPT_WAITFOREVER
1066 while (1) {}
1067 #endif
1068 }
1069
1070 #if defined(__FREERTOS__)
1071 typedef struct {
1072 uint32_t ra; /* X1 */
1073
1074 uint32_t t0; /* X5 */
1075 uint32_t t1; /* X6 */
1076 uint32_t t2; /* X7 */
1077 uint32_t s0; /* X8 */
1078 uint32_t s1; /* X9 */
1079 uint32_t a0; /* X10 */
1080 uint32_t a1; /* X11 */
1081 uint32_t a2; /* X12 */
1082 uint32_t a3; /* X13 */
1083 uint32_t a4; /* X14 */
1084 uint32_t a5; /* X15 */
1085 uint32_t a6; /* X16 */
1086 uint32_t a7; /* X17 */
1087 uint32_t s2; /* X18 */
1088 uint32_t s3; /* X19 */
1089 uint32_t s4; /* X20 */
1090 uint32_t s5; /* X21 */
1091 uint32_t s6; /* X22 */
1092 uint32_t s7; /* X23 */
1093 uint32_t s8; /* X24 */
1094 uint32_t s9; /* X25 */
1095 uint32_t s10; /* X26 */
1096 uint32_t s11; /* X27 */
1097 uint32_t t3; /* X28 */
1098 uint32_t t4; /* X29 */
1099 uint32_t t5; /* X30 */
1100 uint32_t t6; /* X31 */
1101 uint32_t mstatus; /* mstatus */
1102 } exc_context_freertos_t;
1103
exception_get_exc_reg(exc_context_t * exc_buff_addr,exc_context_freertos_t * exc_reg)1104 static void exception_get_exc_reg(exc_context_t *exc_buff_addr, exc_context_freertos_t *exc_reg)
1105 {
1106 exc_buff_addr->task_context.ra = exc_reg->ra;
1107 exc_buff_addr->task_context.t0 = exc_reg->t0;
1108 exc_buff_addr->task_context.t1 = exc_reg->t1;
1109 exc_buff_addr->task_context.t2 = exc_reg->t2;
1110 exc_buff_addr->task_context.s0 = exc_reg->s0;
1111 exc_buff_addr->task_context.s1 = exc_reg->s1;
1112 exc_buff_addr->task_context.a0 = exc_reg->a0;
1113 exc_buff_addr->task_context.a1 = exc_reg->a1;
1114 exc_buff_addr->task_context.a2 = exc_reg->a2;
1115 exc_buff_addr->task_context.a3 = exc_reg->a3;
1116 exc_buff_addr->task_context.a4 = exc_reg->a4;
1117 exc_buff_addr->task_context.a5 = exc_reg->a5;
1118 exc_buff_addr->task_context.a6 = exc_reg->a6;
1119 exc_buff_addr->task_context.a7 = exc_reg->a7;
1120 exc_buff_addr->task_context.s2 = exc_reg->s2;
1121 exc_buff_addr->task_context.s3 = exc_reg->s3;
1122 exc_buff_addr->task_context.s4 = exc_reg->s4;
1123 exc_buff_addr->task_context.s5 = exc_reg->s5;
1124 exc_buff_addr->task_context.s6 = exc_reg->s6;
1125 exc_buff_addr->task_context.s7 = exc_reg->s7;
1126 exc_buff_addr->task_context.s8 = exc_reg->s8;
1127 exc_buff_addr->task_context.s9 = exc_reg->s9;
1128 exc_buff_addr->task_context.s10 = exc_reg->s10;
1129 exc_buff_addr->task_context.s11 = exc_reg->s11;
1130 exc_buff_addr->task_context.t3 = exc_reg->t3;
1131 exc_buff_addr->task_context.t4 = exc_reg->t4;
1132 exc_buff_addr->task_context.t5 = exc_reg->t5;
1133 exc_buff_addr->task_context.t6 = exc_reg->t6;
1134 exc_buff_addr->task_context.mstatus = exc_reg->mstatus;
1135 exc_buff_addr->task_context.sp = (uint32_t)exc_reg;
1136 }
1137
1138 static exc_context_t g_exc_buff_addr;
do_fault_handler_freertos(void)1139 void do_fault_handler_freertos(void)
1140 {
1141 exc_context_freertos_t *exc_reg = (exc_context_freertos_t *)(read_csr(mscratch) + CONTEXT_OFFSET);
1142 exception_get_exc_reg(&g_exc_buff_addr, exc_reg);
1143 g_exc_buff_addr.ccause = (uint8_t)read_csr(0xFC2);
1144 g_exc_buff_addr.mcause = read_csr(mcause);
1145 g_exc_buff_addr.mtval = read_csr(mtval);
1146 g_exc_buff_addr.task_context.mepc = read_csr(mepc);
1147 do_hard_fault_handler(&g_exc_buff_addr);
1148 }
1149 #endif
1150
1151 #if defined(__LITEOS__)
do_fault_handler(uint32_t exc_type,exc_context_t * exc_buff_addr)1152 void do_fault_handler(uint32_t exc_type, exc_context_t *exc_buff_addr)
1153 {
1154 UNUSED(exc_type);
1155 do_hard_fault_handler(exc_buff_addr);
1156 }
1157 #endif
1158
hal_register_exception_dump_callback(hal_exception_dump_callback callback)1159 void hal_register_exception_dump_callback(hal_exception_dump_callback callback)
1160 {
1161 if (callback != NULL) {
1162 g_exception_dump_callback = callback;
1163 }
1164 }
1165