540 lines
12 KiB
C
540 lines
12 KiB
C
/*
|
|
* Copyright (c) @CompanyNameMagicTag 2018-2020. All rights reserved.
|
|
* Description: HAL UTILS INTERFACE
|
|
* Author: @CompanyNameTag
|
|
* Create: 2018-10-15
|
|
*/
|
|
|
|
#ifndef EXCEPTION_H
|
|
#define EXCEPTION_H
|
|
|
|
#include <stdint.h>
|
|
#include "platform.h"
|
|
#include "errcode.h"
|
|
|
|
#if (ARCH == RISCV31) || (ARCH == RISCV70)
|
|
#include "vectors.h"
|
|
#endif
|
|
|
|
#ifdef __cplusplus
|
|
#if __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
#endif
|
|
|
|
/** @defgroup connectivity_drivers_hal_hal HAL
|
|
* @ingroup connectivity_drivers_hal
|
|
* @{
|
|
*/
|
|
#define WAIT_APPS_DUMP_DELAY_MS_EACH_TIME 16000U
|
|
#define WAIT_APPS_DUMP_DELAY_TIMES 2
|
|
#define WAIT_APPS_REFRESH_FLASH_MS 2000
|
|
#define TASK_NAME_MAX_LEN 16
|
|
#define M_CTL_NMI_INT_RAW_STS 0x52000704
|
|
#define XIP_CACHE_CTL_INTR_STS 0xa3006120
|
|
#define XIP_CTL_INTR_STS 0xa3006500
|
|
|
|
#define FS_MAX_FILE_HANDLES 1024
|
|
|
|
#define EXCEP_INFO_FOR_R4_TO_R11 8
|
|
#ifndef LOSCFG_EXC_SIMPLE_INFO
|
|
|
|
#if defined(__LITEOS__)
|
|
#define EXC_INFO_SAVE_TP_INDEX 16
|
|
#endif
|
|
#if defined(__FREERTOS__)
|
|
#if CORE == WIFI
|
|
#define EXC_INFO_SAVE_TP_INDEX 13
|
|
#else
|
|
#define EXC_INFO_SAVE_TP_INDEX 12
|
|
#endif
|
|
#endif
|
|
#else
|
|
#if defined(__LITEOS__)
|
|
#define EXC_INFO_SAVE_X4_INDEX 15
|
|
#endif
|
|
#if defined(__FREERTOS__)
|
|
#if CORE == WIFI
|
|
#define EXC_INFO_SAVE_X4_INDEX 13
|
|
#else
|
|
#define EXC_INFO_SAVE_X4_INDEX 12
|
|
#endif
|
|
#endif
|
|
#endif
|
|
|
|
enum INT_ID_FAULT_TYPE_ENUM {
|
|
INT_ID_NMI_FAULT = 2,
|
|
INT_ID_HARD_FAULT = 3,
|
|
INT_ID_MEM_FAULT = 4,
|
|
INT_ID_BUS_FAULT = 5,
|
|
INT_ID_USAGE_FAULT = 6,
|
|
INT_ID_CHIP_WATCHDOG_FAULT = 59,
|
|
INT_ID_WATCHDOG_FAULT = 47,
|
|
|
|
INT_ID_INDEX_BUTT
|
|
};
|
|
|
|
/**
|
|
* riscv fault type
|
|
*/
|
|
enum IRQ_ID_FAULT_TYPE_ENMU {
|
|
IRQ_ID_INSTRUCTION_ADDRESS_MISALIGNED = 0,
|
|
IRQ_ID_INSTRUCTION_ACCESS_FAULT = 1,
|
|
IRQ_ID_ILLEGAL_INSTRUCTION = 2,
|
|
IRQ_ID_BREAKPOINT = 3,
|
|
IRQ_ID_LOAD_ADDERSS_MISALIGNED = 4,
|
|
IRQ_ID_LOAD_ACCESS_FAULT = 5,
|
|
IRQ_ID_STORE_OR_AMO_ADDRESS_MISALIGNED = 6,
|
|
IRQ_ID_STORE_OR_AMO_ACCESS_FALUT = 7,
|
|
IRQ_ID_ENVIRONMENT_CALL_FROM_UMODE = 8,
|
|
IRQ_ID_ENVIRONMENT_CALL_FROM_SMODE = 9,
|
|
IRQ_ID_RESERVED_0 = 10,
|
|
IRQ_ID_ENVIRONMENT_CALL_FROM_MMODE = 11,
|
|
IRQ_ID_INSTRUCTION_PAGE_FAULT = 12,
|
|
IRQ_ID_LOAD_PAGE_FAULT = 13,
|
|
IRQ_ID_RESERVED_1 = 14,
|
|
IRQ_ID_STORE_OR_AMO_PAGE_FAULT = 15,
|
|
|
|
#if (ARCH == RISCV70)
|
|
IRQ_ID_ASYNCHRONOUS_EXCEPTION = 24,
|
|
IRQ_ID_NMI_INTERRUPT = 0x00000FFF
|
|
#else
|
|
IRQ_ID_HARD_FAULT = 16,
|
|
IRQ_ID_LOCK_UP = 17,
|
|
IRQ_ID_NMI_INTERRUPT = 0x8000000C
|
|
#endif
|
|
};
|
|
|
|
/**
|
|
* @brief Structure which is pushed onto the stack by the Cortex-M0 during
|
|
* exception processing - stack frame.
|
|
*/
|
|
typedef struct stack_frame_t {
|
|
unsigned long stacked_r0;
|
|
unsigned long stacked_r1;
|
|
unsigned long stacked_r2;
|
|
unsigned long stacked_r3;
|
|
unsigned long stacked_r12;
|
|
unsigned long stacked_lr;
|
|
unsigned long stacked_pc;
|
|
unsigned long stacked_psr;
|
|
} exception_stack_frame_t;
|
|
|
|
typedef struct {
|
|
uint16_t nmi_int_raw_sts;
|
|
uint16_t xip_cache_int_sts;
|
|
uint16_t xip_int_sts;
|
|
uint16_t reserved;
|
|
} exc_nmi_stat_t;
|
|
|
|
typedef struct excep_info_t {
|
|
#if (ARCH == CM3) || (ARCH == CM7)
|
|
unsigned long regs[EXCEP_INFO_FOR_R4_TO_R11]; // r4-r11
|
|
#endif
|
|
unsigned long sp;
|
|
unsigned long sp_bottom;
|
|
unsigned long exp_task_id;
|
|
unsigned long task_array;
|
|
unsigned long task_max_num;
|
|
} exception_info_t;
|
|
|
|
#if (ARCH == CM7)
|
|
typedef struct {
|
|
#ifdef LOSCFG_ARCH_FPU_ENABLE
|
|
uint32_t s16;
|
|
uint32_t s17;
|
|
uint32_t s18;
|
|
uint32_t s19;
|
|
uint32_t s20;
|
|
uint32_t s21;
|
|
uint32_t s22;
|
|
uint32_t s23;
|
|
uint32_t s24;
|
|
uint32_t s25;
|
|
uint32_t s26;
|
|
uint32_t s27;
|
|
uint32_t s28;
|
|
uint32_t s29;
|
|
uint32_t s30;
|
|
uint32_t s31;
|
|
#endif
|
|
uint32_t r4;
|
|
uint32_t r5;
|
|
uint32_t r6;
|
|
uint32_t r7;
|
|
uint32_t r8;
|
|
uint32_t r9;
|
|
uint32_t r10;
|
|
uint32_t r11;
|
|
uint32_t primask;
|
|
uint32_t sp;
|
|
uint32_t r0;
|
|
uint32_t r1;
|
|
uint32_t r2;
|
|
uint32_t r3;
|
|
uint32_t r12;
|
|
uint32_t lr;
|
|
uint32_t pc;
|
|
uint32_t xpsr;
|
|
#ifdef LOSCFG_ARCH_FPU_ENABLE
|
|
uint32_t s0;
|
|
uint32_t s1;
|
|
uint32_t s2;
|
|
uint32_t s3;
|
|
uint32_t s4;
|
|
uint32_t s5;
|
|
uint32_t s6;
|
|
uint32_t s7;
|
|
uint32_t s8;
|
|
uint32_t s9;
|
|
uint32_t s10;
|
|
uint32_t s11;
|
|
uint32_t s12;
|
|
uint32_t s13;
|
|
uint32_t s14;
|
|
uint32_t s15;
|
|
uint32_t fpscr;
|
|
uint32_t no_name;
|
|
#endif
|
|
} exc_content_t;
|
|
|
|
typedef struct {
|
|
uint16_t phase;
|
|
uint16_t type;
|
|
uint32_t fault_addr;
|
|
uint32_t intnum_or_taskid;
|
|
uint16_t nest_cnt;
|
|
uint16_t reserved;
|
|
exc_content_t *context;
|
|
} exc_info_t;
|
|
|
|
#endif
|
|
#if (ARCH == RISCV31) || (ARCH == RISCV70)
|
|
#ifdef SUPPORT_CALLSTACK
|
|
typedef struct {
|
|
uint32_t ra;
|
|
uint32_t fp;
|
|
} exc_stack_info_t;
|
|
#else
|
|
typedef struct {
|
|
uint32_t sp_addr;
|
|
uint32_t sp_content;
|
|
} exc_backtrace_info_t;
|
|
#endif
|
|
|
|
#if defined(__LITEOS__)
|
|
typedef struct {
|
|
char task_name[TASK_NAME_MAX_LEN];
|
|
uint32_t thrd_pid;
|
|
uint16_t type;
|
|
uint16_t nest_cnt;
|
|
#ifndef LOSCFG_EXC_SIMPLE_INFO
|
|
char phase[8];
|
|
#else
|
|
uint16_t phase;
|
|
uint16_t ret;
|
|
#endif
|
|
uint32_t ccause;
|
|
uint32_t mcause;
|
|
uint32_t mtval;
|
|
uint32_t gp;
|
|
uint32_t mstatus;
|
|
uint32_t mepc;
|
|
uint32_t ra;
|
|
uint32_t sp;
|
|
#ifndef LOSCFG_EXC_SIMPLE_INFO
|
|
uint32_t tp;
|
|
uint32_t t0;
|
|
uint32_t t1;
|
|
uint32_t t2;
|
|
uint32_t s0;
|
|
uint32_t s1;
|
|
uint32_t a0;
|
|
uint32_t a1;
|
|
uint32_t a2;
|
|
uint32_t a3;
|
|
uint32_t a4;
|
|
uint32_t a5;
|
|
uint32_t a6;
|
|
uint32_t a7;
|
|
uint32_t s2;
|
|
uint32_t s3;
|
|
uint32_t s4;
|
|
uint32_t s5;
|
|
uint32_t s6;
|
|
uint32_t s7;
|
|
uint32_t s8;
|
|
uint32_t s9;
|
|
uint32_t s10;
|
|
uint32_t s11;
|
|
uint32_t t3;
|
|
uint32_t t4;
|
|
uint32_t t5;
|
|
uint32_t t6;
|
|
#else
|
|
uint32_t x4;
|
|
uint32_t x5;
|
|
uint32_t x6;
|
|
uint32_t x7;
|
|
uint32_t x8;
|
|
uint32_t x9;
|
|
uint32_t x10;
|
|
uint32_t x11;
|
|
uint32_t x12;
|
|
uint32_t x13;
|
|
uint32_t x14;
|
|
uint32_t x15;
|
|
uint32_t x16;
|
|
uint32_t x17;
|
|
uint32_t x18;
|
|
uint32_t x19;
|
|
uint32_t x20;
|
|
uint32_t x21;
|
|
uint32_t x22;
|
|
uint32_t x23;
|
|
uint32_t x24;
|
|
uint32_t x25;
|
|
uint32_t x26;
|
|
uint32_t x27;
|
|
uint32_t x28;
|
|
uint32_t x29;
|
|
uint32_t x30;
|
|
uint32_t x31;
|
|
#endif
|
|
uint32_t reg0;
|
|
uint32_t reg1;
|
|
uint32_t reg2;
|
|
uint32_t reg3;
|
|
#ifdef SUPPORT_CALLSTACK
|
|
uint32_t stack_size;
|
|
exc_stack_info_t stack[0];
|
|
#else
|
|
uint32_t backtrace_size;
|
|
exc_backtrace_info_t backtrace[0];
|
|
#endif
|
|
} exc_info_save_t;
|
|
#define EXC_INFO_SAVE_SIZE sizeof(exc_info_save_t)
|
|
#endif
|
|
|
|
#if defined(__FREERTOS__)
|
|
typedef struct {
|
|
char task_name[TASK_NAME_MAX_LEN];
|
|
uint16_t uw_exc_type;
|
|
uint16_t ret;
|
|
uint32_t mepc;
|
|
uint32_t mstatus;
|
|
uint32_t mtval;
|
|
uint32_t mcause;
|
|
#if CORE == WIFI
|
|
uint32_t cxcptsc;
|
|
#endif
|
|
uint32_t ra;
|
|
uint32_t sp;
|
|
uint32_t gp;
|
|
uint32_t tp;
|
|
uint32_t t0;
|
|
uint32_t t1;
|
|
uint32_t t2;
|
|
uint32_t s0;
|
|
uint32_t s1;
|
|
uint32_t a0;
|
|
uint32_t a1;
|
|
uint32_t a2;
|
|
uint32_t a3;
|
|
uint32_t a4;
|
|
uint32_t a5;
|
|
uint32_t a6;
|
|
uint32_t a7;
|
|
uint32_t s2;
|
|
uint32_t s3;
|
|
uint32_t s4;
|
|
uint32_t s5;
|
|
uint32_t s6;
|
|
uint32_t s7;
|
|
uint32_t s8;
|
|
uint32_t s9;
|
|
uint32_t s10;
|
|
uint32_t s11;
|
|
uint32_t t3;
|
|
uint32_t t4;
|
|
uint32_t t5;
|
|
uint32_t t6;
|
|
uint32_t reg0;
|
|
uint32_t reg1;
|
|
uint32_t reg2;
|
|
uint32_t reg3;
|
|
#ifdef SUPPORT_CALLSTACK
|
|
uint32_t stack_size;
|
|
exc_stack_info_t stack[0];
|
|
#endif
|
|
} exc_info_save_t;
|
|
#define EXC_INFO_SAVE_SIZE sizeof(exc_info_save_t)
|
|
#endif
|
|
#endif
|
|
#if (ARCH == CM3) || (ARCH == CM7)
|
|
typedef struct {
|
|
uint32_t lr;
|
|
uint32_t fp;
|
|
} exc_stack_info_t;
|
|
typedef struct {
|
|
char task_name[TASK_NAME_MAX_LEN];
|
|
uint32_t task_id;
|
|
uint32_t task_stack_size;
|
|
uint32_t system_mem_addr;
|
|
char phase[22];
|
|
uint16_t type;
|
|
uint32_t fault_addr;
|
|
uint32_t int_num_or_task_id;
|
|
uint32_t r0;
|
|
uint32_t r1;
|
|
uint32_t r2;
|
|
uint32_t r3;
|
|
uint32_t r4;
|
|
uint32_t r5;
|
|
uint32_t r6;
|
|
uint32_t r7;
|
|
uint32_t r8;
|
|
uint32_t r9;
|
|
uint32_t r10;
|
|
uint32_t r11;
|
|
uint32_t r12;
|
|
uint32_t pri_mask;
|
|
uint32_t sp;
|
|
uint32_t lr;
|
|
uint32_t pc;
|
|
uint32_t xpsr;
|
|
uint32_t psp;
|
|
uint32_t pri_mask_scb;
|
|
uint32_t fault_mask;
|
|
uint32_t base_pri;
|
|
uint32_t control;
|
|
uint32_t scb_icsr;
|
|
uint32_t scb_scr;
|
|
uint32_t scb_shcsr;
|
|
uint32_t scb_cfsr;
|
|
uint32_t scb_hfsr;
|
|
uint32_t scb_dfsr;
|
|
uint32_t scb_mmfar;
|
|
uint32_t scb_bfsr;
|
|
uint32_t scb_afsr;
|
|
uint32_t reg0;
|
|
uint32_t reg1;
|
|
uint32_t reg2;
|
|
uint32_t reg3;
|
|
#ifdef LOSCFG_BACKTRACE
|
|
uint32_t stack_size;
|
|
exc_stack_info_t stack[0];
|
|
#endif
|
|
} exc_info_save_t;
|
|
#define EXC_INFO_SAVE_SIZE sizeof(exc_info_save_t)
|
|
#endif
|
|
/**
|
|
* @brief Callback to output the exception information.
|
|
*/
|
|
#if (ARCH == RISCV31) || (ARCH == RISCV70)
|
|
typedef void (*nmi_proc_func)(exc_context_t *);
|
|
typedef void (*hal_exception_dump_callback)(uint32_t irq_id, exc_context_t *exc_buf_addr);
|
|
#else
|
|
typedef void (*hal_exception_dump_callback)(uint32_t id, uint32_t reason, uint32_t addr, exc_info_t *exc_info);
|
|
#endif
|
|
|
|
/**
|
|
* @brief Prototype for the assembly language hard-fault handler. This will setup the stack and attempt to
|
|
* generate a stack trace to aid debug.
|
|
* @param exc_buf_addr Fault param1.
|
|
*/
|
|
#if (ARCH == RISCV31) || (ARCH == RISCV70)
|
|
void do_hard_fault_handler(exc_context_t *exc_buf_addr);
|
|
#if defined(__LITEOS__)
|
|
void do_fault_handler(uint32_t exc_type, exc_context_t *exc_buff_addr);
|
|
void nmi_fault_handler(uint32_t exc_type, exc_context_t *exc_buff_addr);
|
|
#endif
|
|
#if defined(__FREERTOS__)
|
|
void do_fault_handler_freertos(void);
|
|
#endif
|
|
#elif (ARCH == CM7)
|
|
/**
|
|
* @brief Prototype for the assembly language hard-fault handler. This will setup the stack and attempt to
|
|
* generate a stack trace to aid debug.
|
|
* @param exc_info exception information.
|
|
* @param context register information.
|
|
*/
|
|
void do_hard_fault_handler(uint32_t exc_info, exc_content_t *context);
|
|
#endif
|
|
|
|
/**
|
|
* @brief Register the exception dump callback
|
|
* @param callback The dump callback func
|
|
*/
|
|
void hal_register_exception_dump_callback(hal_exception_dump_callback callback);
|
|
|
|
/**
|
|
* @brief Wait for the apps to finish the preparing for rebooting.
|
|
* eg. notify the apps and finish coredump if the debug is enable;
|
|
* Wait for the apps refresh the flash.
|
|
* @return
|
|
*/
|
|
void wait_apps_prepare_for_rebooting(void);
|
|
|
|
/**
|
|
* @brief Save the exception reset information for debug after the restart.
|
|
* @return
|
|
*/
|
|
void hal_save_exception_reset_info(void);
|
|
|
|
#if (ARCH == RISCV31) || (ARCH == RISCV70)
|
|
#ifndef SUPPORT_CALLSTACK
|
|
void back_trace(uint32_t fp);
|
|
#endif
|
|
#ifndef USE_CMSIS_OS
|
|
void do_trap_unknown(exc_context_t *exc_buff_addr);
|
|
void do_trap_insn_misaligned(exc_context_t *exc_buff_addr);
|
|
void do_trap_insn_fault(exc_context_t *exc_buff_addr);
|
|
void do_trap_insn_illegal(exc_context_t *exc_buff_addr);
|
|
void do_trap_load_misaligned(exc_context_t *exc_buff_addr);
|
|
void do_trap_load_fault(exc_context_t *exc_buff_addr);
|
|
void do_trap_store_misaligned(exc_context_t *exc_buff_addr);
|
|
void do_trap_store_fault(exc_context_t *exc_buff_addr);
|
|
void do_trap_ecall_u(exc_context_t *exc_buff_addr);
|
|
void do_trap_ecall_s(exc_context_t *exc_buff_addr);
|
|
void do_trap_ecall_m(exc_context_t *exc_buff_addr);
|
|
void do_trap_break(exc_context_t *exc_buff_addr);
|
|
void do_insn_page_fault(exc_context_t *exc_buff_addr);
|
|
void do_load_page_fault(exc_context_t *exc_buff_addr);
|
|
void do_store_page_fault(exc_context_t *exc_buff_addr);
|
|
void do_hard_fault(exc_context_t *exc_buff_addr);
|
|
void do_lockup(exc_context_t *exc_buff_addr);
|
|
void default_handler(void);
|
|
void nmi_handler(void);
|
|
#endif
|
|
|
|
#ifdef SAVE_EXC_INFO
|
|
#if CONFIG_DFX_SUPPORT_FILE_SYSTEM == DFX_YES
|
|
/**
|
|
* @brief Write exc info to the file system.
|
|
* @return The length of file written if success or -1 if failed.
|
|
*/
|
|
int32_t exc_info_write(const char *path, uint32_t offset, const uint8_t *buf, uint32_t size);
|
|
#endif
|
|
#ifdef CFG_DRIVERS_MMC
|
|
/**
|
|
* @brief Emmc write exc info to the file system from sector after reboot system.
|
|
* @return Success or fail.
|
|
*/
|
|
errcode_t emmc_exc_info_write(void);
|
|
#endif
|
|
#endif
|
|
#endif
|
|
void reset_deal_with_fs(void);
|
|
bool get_exception_status(void);
|
|
/**
|
|
* @}
|
|
*/
|
|
#ifdef __cplusplus
|
|
#if __cplusplus
|
|
}
|
|
#endif
|
|
#endif
|
|
|
|
#endif
|