• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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