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:HAL UTILS INTERFACE 15 */ 16 17 #ifndef EXCEPTION_H 18 #define EXCEPTION_H 19 20 #include <stdint.h> 21 #include "platform.h" 22 #include "errcode.h" 23 24 #if (ARCH == RISCV31) || (ARCH == RISCV70) 25 #include "vectors.h" 26 #endif 27 28 /** @defgroup connectivity_drivers_hal_hal HAL 29 * @ingroup connectivity_drivers_hal 30 * @{ 31 */ 32 #define WAIT_APPS_DUMP_DELAY_MS_EACH_TIME 16000U 33 #define WAIT_APPS_DUMP_DELAY_TIMES 2 34 #define WAIT_APPS_REFRESH_FLASH_MS 2000 35 36 #define EXCEP_INFO_FOR_R4_TO_R11 8 37 #ifndef LOSCFG_EXC_SIMPLE_INFO 38 #if defined(__LITEOS__) 39 #define EXC_INFO_SAVE_TP_INDEX 16 40 #endif 41 #if defined(__FREERTOS__) 42 #if CORE == WIFI 43 #define EXC_INFO_SAVE_TP_INDEX 9 44 #else 45 #define EXC_INFO_SAVE_TP_INDEX 8 46 #endif 47 #endif 48 #else 49 #define EXC_INFO_SAVE_X4_INDEX 15 50 #endif 51 52 enum INT_ID_FAULT_TYPE_ENUM { 53 INT_ID_NMI_FAULT = 2, 54 INT_ID_HARD_FAULT = 3, 55 INT_ID_MEM_FAULT = 4, 56 INT_ID_BUS_FAULT = 5, 57 INT_ID_USAGE_FAULT = 6, 58 INT_ID_CHIP_WATCHDOG_FAULT = 59, 59 INT_ID_WATCHDOG_FAULT = 47, 60 61 INT_ID_INDEX_BUTT 62 }; 63 64 /** 65 * riscv fault type 66 */ 67 enum IRQ_ID_FAULT_TYPE_ENMU { 68 IRQ_ID_INSTRUCTION_ADDRESS_MISALIGNED = 0, 69 IRQ_ID_INSTRUCTION_ACCESS_FAULT = 1, 70 IRQ_ID_ILLEGAL_INSTRUCTION = 2, 71 IRQ_ID_BREAKPOINT = 3, 72 IRQ_ID_LOAD_ADDERSS_MISALIGNED = 4, 73 IRQ_ID_LOAD_ACCESS_FAULT = 5, 74 IRQ_ID_STORE_OR_AMO_ADDRESS_MISALIGNED = 6, 75 IRQ_ID_STORE_OR_AMO_ACCESS_FALUT = 7, 76 IRQ_ID_ENVIRONMENT_CALL_FROM_UMODE = 8, 77 IRQ_ID_ENVIRONMENT_CALL_FROM_SMODE = 9, 78 IRQ_ID_RESERVED_0 = 10, 79 IRQ_ID_ENVIRONMENT_CALL_FROM_MMODE = 11, 80 IRQ_ID_INSTRUCTION_PAGE_FAULT = 12, 81 IRQ_ID_LOAD_PAGE_FAULT = 13, 82 IRQ_ID_RESERVED_1 = 14, 83 IRQ_ID_STORE_OR_AMO_PAGE_FAULT = 15, 84 85 #if (ARCH == RISCV70) 86 IRQ_ID_ASYNCHRONOUS_EXCEPTION = 24, 87 IRQ_ID_NMI_INTERRUPT = 0x00000FFF 88 #else 89 IRQ_ID_HARD_FAULT = 16, 90 IRQ_ID_LOCK_UP = 17, 91 IRQ_ID_NMI_INTERRUPT = 0x8000000C 92 #endif 93 }; 94 95 /** 96 * @brief Structure which is pushed onto the stack by the Cortex-M0 during 97 * exception processing - stack frame. 98 */ 99 typedef struct stack_frame_t { 100 unsigned long stacked_r0; 101 unsigned long stacked_r1; 102 unsigned long stacked_r2; 103 unsigned long stacked_r3; 104 unsigned long stacked_r12; 105 unsigned long stacked_lr; 106 unsigned long stacked_pc; 107 unsigned long stacked_psr; 108 } exception_stack_frame_t; 109 110 typedef struct excep_info_t { 111 #if (ARCH == CM3) || (ARCH == CM7) 112 unsigned long regs[EXCEP_INFO_FOR_R4_TO_R11]; // r4-r11 113 #endif 114 unsigned long sp; 115 unsigned long sp_bottom; 116 unsigned long exp_task_id; 117 unsigned long task_array; 118 unsigned long task_max_num; 119 } exception_info_t; 120 121 #if (ARCH == CM7) 122 typedef struct { 123 #ifdef LOSCFG_ARCH_FPU_ENABLE 124 uint32_t s16; 125 uint32_t s17; 126 uint32_t s18; 127 uint32_t s19; 128 uint32_t s20; 129 uint32_t s21; 130 uint32_t s22; 131 uint32_t s23; 132 uint32_t s24; 133 uint32_t s25; 134 uint32_t s26; 135 uint32_t s27; 136 uint32_t s28; 137 uint32_t s29; 138 uint32_t s30; 139 uint32_t s31; 140 #endif 141 uint32_t r4; 142 uint32_t r5; 143 uint32_t r6; 144 uint32_t r7; 145 uint32_t r8; 146 uint32_t r9; 147 uint32_t r10; 148 uint32_t r11; 149 uint32_t primask; 150 uint32_t sp; 151 uint32_t r0; 152 uint32_t r1; 153 uint32_t r2; 154 uint32_t r3; 155 uint32_t r12; 156 uint32_t lr; 157 uint32_t pc; 158 uint32_t xpsr; 159 #ifdef LOSCFG_ARCH_FPU_ENABLE 160 uint32_t s0; 161 uint32_t s1; 162 uint32_t s2; 163 uint32_t s3; 164 uint32_t s4; 165 uint32_t s5; 166 uint32_t s6; 167 uint32_t s7; 168 uint32_t s8; 169 uint32_t s9; 170 uint32_t s10; 171 uint32_t s11; 172 uint32_t s12; 173 uint32_t s13; 174 uint32_t s14; 175 uint32_t s15; 176 uint32_t fpscr; 177 uint32_t no_name; 178 #endif 179 } exc_content_t; 180 181 typedef struct { 182 uint16_t phase; 183 uint16_t type; 184 uint32_t fault_addr; 185 uint32_t intnum_or_taskid; 186 uint16_t nest_cnt; 187 uint16_t reserved; 188 exc_content_t *context; 189 } exc_info_t; 190 191 #endif 192 #if (ARCH == RISCV31) || (ARCH == RISCV70) 193 #ifdef SUPPORT_CALLSTACK 194 typedef struct { 195 uint32_t ra; 196 uint32_t fp; 197 } exc_stack_info_t; 198 #else 199 typedef struct { 200 uint32_t sp_addr; 201 uint32_t sp_content; 202 } exc_backtrace_info_t; 203 #endif 204 205 #if defined(__LITEOS__) 206 typedef struct { 207 char task_name[16]; 208 uint32_t thrd_pid; 209 uint16_t type; 210 uint16_t nest_cnt; 211 #ifndef LOSCFG_EXC_SIMPLE_INFO 212 char phase[8]; 213 #else 214 uint16_t phase; 215 uint16_t ret; 216 #endif 217 uint32_t ccause; 218 uint32_t mcause; 219 uint32_t mtval; 220 uint32_t gp; 221 uint32_t mstatus; 222 uint32_t mepc; 223 uint32_t ra; 224 uint32_t sp; 225 #ifndef LOSCFG_EXC_SIMPLE_INFO 226 uint32_t tp; 227 uint32_t t0; 228 uint32_t t1; 229 uint32_t t2; 230 uint32_t s0; 231 uint32_t s1; 232 uint32_t a0; 233 uint32_t a1; 234 uint32_t a2; 235 uint32_t a3; 236 uint32_t a4; 237 uint32_t a5; 238 uint32_t a6; 239 uint32_t a7; 240 uint32_t s2; 241 uint32_t s3; 242 uint32_t s4; 243 uint32_t s5; 244 uint32_t s6; 245 uint32_t s7; 246 uint32_t s8; 247 uint32_t s9; 248 uint32_t s10; 249 uint32_t s11; 250 uint32_t t3; 251 uint32_t t4; 252 uint32_t t5; 253 uint32_t t6; 254 #else 255 uint32_t x4; 256 uint32_t x5; 257 uint32_t x6; 258 uint32_t x7; 259 uint32_t x8; 260 uint32_t x9; 261 uint32_t x10; 262 uint32_t x11; 263 uint32_t x12; 264 uint32_t x13; 265 uint32_t x14; 266 uint32_t x15; 267 uint32_t x16; 268 uint32_t x17; 269 uint32_t x18; 270 uint32_t x19; 271 uint32_t x20; 272 uint32_t x21; 273 uint32_t x22; 274 uint32_t x23; 275 uint32_t x24; 276 uint32_t x25; 277 uint32_t x26; 278 uint32_t x27; 279 uint32_t x28; 280 uint32_t x29; 281 uint32_t x30; 282 uint32_t x31; 283 #endif 284 #ifdef SUPPORT_CALLSTACK 285 uint32_t stack_size; 286 exc_stack_info_t stack[0]; 287 #else 288 uint32_t backtrace_size; 289 exc_backtrace_info_t backtrace[0]; 290 #endif 291 } exc_info_save_t; 292 #define EXC_INFO_SAVE_SIZE sizeof(exc_info_save_t) 293 #endif 294 295 #if defined(__FREERTOS__) 296 typedef struct { 297 uint16_t uw_exc_type; 298 uint16_t ret; 299 uint32_t mepc; 300 uint32_t mstatus; 301 uint32_t mtval; 302 uint32_t mcause; 303 #if CORE == WIFI 304 uint32_t cxcptsc; 305 #endif 306 uint32_t ra; 307 uint32_t sp; 308 uint32_t gp; 309 uint32_t tp; 310 uint32_t t0; 311 uint32_t t1; 312 uint32_t t2; 313 uint32_t s0; 314 uint32_t s1; 315 uint32_t a0; 316 uint32_t a1; 317 uint32_t a2; 318 uint32_t a3; 319 uint32_t a4; 320 uint32_t a5; 321 uint32_t a6; 322 uint32_t a7; 323 uint32_t s2; 324 uint32_t s3; 325 uint32_t s4; 326 uint32_t s5; 327 uint32_t s6; 328 uint32_t s7; 329 uint32_t s8; 330 uint32_t s9; 331 uint32_t s10; 332 uint32_t s11; 333 uint32_t t3; 334 uint32_t t4; 335 uint32_t t5; 336 uint32_t t6; 337 #ifdef SUPPORT_CALLSTACK 338 uint32_t stack_size; 339 exc_stack_info_t stack[0]; 340 #endif 341 } exc_info_save_t; 342 #define EXC_INFO_SAVE_SIZE sizeof(exc_info_save_t) 343 #endif 344 #endif 345 #if (ARCH == CM3) || (ARCH == CM7) 346 typedef struct { 347 uint32_t lr; 348 uint32_t fp; 349 } exc_stack_info_t; 350 typedef struct { 351 char task_name[16]; 352 uint32_t task_id; 353 uint32_t task_stack_size; 354 uint32_t system_mem_addr; 355 char phase[22]; 356 uint16_t type; 357 uint32_t fault_addr; 358 uint32_t int_num_or_task_id; 359 uint32_t r0; 360 uint32_t r1; 361 uint32_t r2; 362 uint32_t r3; 363 uint32_t r4; 364 uint32_t r5; 365 uint32_t r6; 366 uint32_t r7; 367 uint32_t r8; 368 uint32_t r9; 369 uint32_t r10; 370 uint32_t r11; 371 uint32_t r12; 372 uint32_t pri_mask; 373 uint32_t sp; 374 uint32_t lr; 375 uint32_t pc; 376 uint32_t xpsr; 377 uint32_t psp; 378 uint32_t pri_mask_scb; 379 uint32_t fault_mask; 380 uint32_t base_pri; 381 uint32_t control; 382 uint32_t scb_icsr; 383 uint32_t scb_scr; 384 uint32_t scb_shcsr; 385 uint32_t scb_cfsr; 386 uint32_t scb_hfsr; 387 uint32_t scb_dfsr; 388 uint32_t scb_mmfar; 389 uint32_t scb_bfsr; 390 uint32_t scb_afsr; 391 #ifdef LOSCFG_BACKTRACE 392 uint32_t stack_size; 393 exc_stack_info_t stack[0]; 394 #endif 395 } exc_info_save_t; 396 #define EXC_INFO_SAVE_SIZE sizeof(exc_info_save_t) 397 #endif 398 /** 399 * @brief Callback to output the exception information. 400 */ 401 #if (ARCH == RISCV31) || (ARCH == RISCV70) 402 typedef void (*nmi_proc_func)(exc_context_t *); 403 typedef void (*hal_exception_dump_callback)(uint32_t irq_id, exc_context_t *exc_buf_addr); 404 #else 405 typedef void (*hal_exception_dump_callback)(uint32_t id, uint32_t reason, uint32_t addr, exc_info_t *exc_info); 406 #endif 407 408 /** 409 * @brief Prototype for the assembly language hard-fault handler. This will setup the stack and attempt to 410 * generate a stack trace to aid debug. 411 * @param exc_buf_addr Fault param1. 412 */ 413 #if (ARCH == RISCV31) || (ARCH == RISCV70) 414 void do_hard_fault_handler(exc_context_t *exc_buf_addr); 415 #if defined(__LITEOS__) 416 void do_fault_handler(uint32_t exc_type, exc_context_t *exc_buff_addr); 417 #endif 418 #if defined(__FREERTOS__) 419 void do_fault_handler_freertos(void); 420 #endif 421 #elif (ARCH == CM7) 422 /** 423 * @brief Prototype for the assembly language hard-fault handler. This will setup the stack and attempt to 424 * generate a stack trace to aid debug. 425 * @param exc_info exception information. 426 * @param context register information. 427 */ 428 void do_hard_fault_handler(uint32_t exc_info, exc_content_t *context); 429 #endif 430 431 /** 432 * @brief Register the exception dump callback 433 * @param callback The dump callback func 434 */ 435 void hal_register_exception_dump_callback(hal_exception_dump_callback callback); 436 437 /** 438 * @brief Wait for the apps to finish the preparing for rebooting. 439 * eg. notify the apps and finish coredump if the debug is enable; 440 * Wait for the apps refresh the flash. 441 * @return 442 */ 443 void wait_apps_prepare_for_rebooting(void); 444 445 /** 446 * @brief Save the exception reset information for debug after the restart. 447 * @return 448 */ 449 void hal_save_exception_reset_info(void); 450 451 #ifdef CONFIG_SUPPORT_CRASHINFO_SAVE_TO_FLASH 452 void crashinfo_save(exc_context_t *exc_buf_addr); 453 bool crashinfo_status_get(void); 454 void crashinfo_dump(void); 455 void crashinfo_clr(void); 456 #endif 457 458 #if (ARCH == RISCV31) || (ARCH == RISCV70) 459 #ifndef SUPPORT_CALLSTACK 460 void back_trace(uint32_t fp); 461 #endif 462 #ifndef USE_CMSIS_OS 463 void do_trap_unknown(exc_context_t *exc_buff_addr); 464 void do_trap_insn_misaligned(exc_context_t *exc_buff_addr); 465 void do_trap_insn_fault(exc_context_t *exc_buff_addr); 466 void do_trap_insn_illegal(exc_context_t *exc_buff_addr); 467 void do_trap_load_misaligned(exc_context_t *exc_buff_addr); 468 void do_trap_load_fault(exc_context_t *exc_buff_addr); 469 void do_trap_store_misaligned(exc_context_t *exc_buff_addr); 470 void do_trap_store_fault(exc_context_t *exc_buff_addr); 471 void do_trap_ecall_u(exc_context_t *exc_buff_addr); 472 void do_trap_ecall_s(exc_context_t *exc_buff_addr); 473 void do_trap_ecall_m(exc_context_t *exc_buff_addr); 474 void do_trap_break(exc_context_t *exc_buff_addr); 475 void do_insn_page_fault(exc_context_t *exc_buff_addr); 476 void do_load_page_fault(exc_context_t *exc_buff_addr); 477 void do_store_page_fault(exc_context_t *exc_buff_addr); 478 void do_hard_fault(exc_context_t *exc_buff_addr); 479 void do_lockup(exc_context_t *exc_buff_addr); 480 void default_handler(void); 481 void nmi_handler(void); 482 #endif 483 484 #ifdef SAVE_EXC_INFO 485 #if CONFIG_DFX_SUPPORT_FILE_SYSTEM == DFX_YES 486 /** 487 * @brief Write exc info to the file system. 488 * @return The length of file written if success or -1 if failed. 489 */ 490 int32_t exc_info_write(const char *path, uint32_t offset, const uint8_t *buf, uint32_t size); 491 #endif 492 #ifdef CFG_DRIVERS_MMC 493 /** 494 * @brief Emmc write exc info to the file system from sector after reboot system. 495 * @return Success or fail. 496 */ 497 errcode_t emmc_exc_info_write(void); 498 #endif 499 #endif 500 #endif 501 502 /** 503 * @} 504 */ 505 #endif 506