/** * * @brief Fault handler * * This routine is called when fatal error conditions are detected by hardware * and is responsible only for reporting the error. Once reported, it then * invokes the user provided routine _SysFatalErrorHandler() which is * responsible for implementing the error handling policy. * * Since the ESF can be either on the MSP or PSP depending if an exception or * interrupt was already being handled, it is passed a pointer to both and has * to find out on which the ESP is present. * * @param esf ESF on the stack, either MSP or PSP depending at what processor * state the exception was taken. * * @return This function does not return. */ void _Fault(const NANO_ESF *esf) { int fault = _ScbActiveVectorGet(); FAULT_DUMP(esf, fault); _SysFatalErrorHandler(_NANO_ERR_HW_EXCEPTION, esf); }
/** * * @brief Nanokernel fatal error handler * * This routine is called when a fatal error condition is detected by either * hardware or software. * * The caller is expected to always provide a usable ESF. In the event that the * fatal error does not have a hardware generated ESF, the caller should either * create its own or use a pointer to the global default ESF <_default_esf>. * * @param reason the reason that the handler was called * @param pEsf pointer to the exception stack frame * * @return This function does not return. */ FUNC_NORETURN void _NanoFatalErrorHandler(unsigned int reason, const NANO_ESF *pEsf) { _debug_fatal_hook(pEsf); #ifdef CONFIG_PRINTK /* Display diagnostic information about the error */ switch (reason) { case _NANO_ERR_CPU_EXCEPTION: break; case _NANO_ERR_SPURIOUS_INT: printk("***** Unhandled interrupt vector %d occurred! " "*****\n", _loapic_isr_vector_get()); break; case _NANO_ERR_INVALID_TASK_EXIT: printk("***** Invalid Exit Software Error! *****\n"); break; #if defined(CONFIG_STACK_CANARIES) case _NANO_ERR_STACK_CHK_FAIL: printk("***** Stack Check Fail! *****\n"); break; #endif /* CONFIG_STACK_CANARIES */ case _NANO_ERR_ALLOCATION_FAIL: printk("**** Kernel Allocation Failure! ****\n"); break; default: printk("**** Unknown Fatal Error %d! ****\n", reason); break; } printk("Current thread ID = 0x%x\n" "Faulting segment:address = 0x%x:0x%x\n" "eax: 0x%x, ebx: 0x%x, ecx: 0x%x, edx: 0x%x\n" "esi: 0x%x, edi: 0x%x, ebp: 0%x, esp: 0x%x\n" "eflags: 0x%x\n", sys_thread_self_get(), pEsf->cs & 0xFFFF, pEsf->eip, pEsf->eax, pEsf->ebx, pEsf->ecx, pEsf->edx, pEsf->esi, pEsf->edi, pEsf->ebp, pEsf->esp, pEsf->eflags); #endif /* CONFIG_PRINTK */ /* * Error was fatal to a kernel task or a fiber; invoke the system * fatal error handling policy defined for the platform. */ _SysFatalErrorHandler(reason, pEsf); }
/** * * @brief Kernel fatal error handler * * This routine is called when fatal error conditions are detected by software * and is responsible only for reporting the error. Once reported, it then * invokes the user provided routine _SysFatalErrorHandler() which is * responsible for implementing the error handling policy. * * The caller is expected to always provide a usable ESF. In the event that the * fatal error does not have a hardware generated ESF, the caller should either * create its own or use a pointer to the global default ESF <_default_esf>. * * @return This function does not return. */ FUNC_NORETURN void _NanoFatalErrorHandler(unsigned int reason, const NANO_ESF *pEsf) { switch (reason) { case _NANO_ERR_HW_EXCEPTION: break; #if defined(CONFIG_STACK_CANARIES) || defined(CONFIG_ARC_STACK_CHECKING) case _NANO_ERR_STACK_CHK_FAIL: printk("***** Stack Check Fail! *****\n"); break; #endif case _NANO_ERR_ALLOCATION_FAIL: printk("**** Kernel Allocation Failure! ****\n"); break; case _NANO_ERR_KERNEL_OOPS: printk("***** Kernel OOPS! *****\n"); break; case _NANO_ERR_KERNEL_PANIC: printk("***** Kernel Panic! *****\n"); break; default: printk("**** Unknown Fatal Error %d! ****\n", reason); break; } printk("Current thread ID = %p\n" "Faulting instruction address = 0x%lx\n", k_current_get(), _arc_v2_aux_reg_read(_ARC_V2_ERET)); /* * Now that the error has been reported, call the user implemented * policy * to respond to the error. The decisions as to what responses are * appropriate to the various errors are something the customer must * decide. */ _SysFatalErrorHandler(reason, pEsf); for (;;) ; }
/** * * @brief Kernel fatal error handler * * This routine is called when fatal error conditions are detected by software * and is responsible only for reporting the error. Once reported, it then * invokes the user provided routine _SysFatalErrorHandler() which is * responsible for implementing the error handling policy. * * The caller is expected to always provide a usable ESF. In the event that the * fatal error does not have a hardware generated ESF, the caller should either * create its own or use a pointer to the global default ESF <_default_esf>. * * Unlike other arches, this function may return if _SysFatalErrorHandler * determines that only the current thread should be aborted and the CPU * was in handler mode. PendSV will be asserted in this case and the current * thread taken off the run queue. Leaving the exception will immediately * trigger a context switch. * * @param reason the reason that the handler was called * @param pEsf pointer to the exception stack frame */ void _NanoFatalErrorHandler(unsigned int reason, const NANO_ESF *pEsf) { switch (reason) { case _NANO_ERR_INVALID_TASK_EXIT: printk("***** Invalid Exit Software Error! *****\n"); break; #if defined(CONFIG_STACK_CANARIES) || defined(CONFIG_STACK_SENTINEL) case _NANO_ERR_STACK_CHK_FAIL: printk("***** Stack Check Fail! *****\n"); break; #endif /* CONFIG_STACK_CANARIES */ case _NANO_ERR_ALLOCATION_FAIL: printk("**** Kernel Allocation Failure! ****\n"); break; case _NANO_ERR_KERNEL_OOPS: printk("***** Kernel OOPS! *****\n"); break; case _NANO_ERR_KERNEL_PANIC: printk("***** Kernel Panic! *****\n"); break; default: printk("**** Unknown Fatal Error %d! ****\n", reason); break; } printk("Current thread ID = %p\n" "Faulting instruction address = 0x%x\n", k_current_get(), pEsf->pc); /* * Now that the error has been reported, call the user implemented * policy * to respond to the error. The decisions as to what responses are * appropriate to the various errors are something the customer must * decide. */ _SysFatalErrorHandler(reason, pEsf); }
/** * * @brief Kernel fatal error handler * * This routine is called when a fatal error condition is detected by either * hardware or software. * * The caller is expected to always provide a usable ESF. In the event that the * fatal error does not have a hardware generated ESF, the caller should either * create its own or use a pointer to the global default ESF <_default_esf>. * * @param reason the reason that the handler was called * @param pEsf pointer to the exception stack frame * * @return This function does not return. */ FUNC_NORETURN void _NanoFatalErrorHandler(unsigned int reason, const NANO_ESF *pEsf) { _debug_fatal_hook(pEsf); #ifdef CONFIG_PRINTK /* Display diagnostic information about the error */ switch (reason) { case _NANO_ERR_CPU_EXCEPTION: break; case _NANO_ERR_SPURIOUS_INT: { int vector = _irq_controller_isr_vector_get(); printk("***** Unhandled interrupt vector "); if (vector >= 0) { printk("%d ", vector); } printk("*****\n"); break; } #if defined(CONFIG_STACK_CANARIES) || defined(CONFIG_STACK_SENTINEL) || \ defined(CONFIG_HW_STACK_PROTECTION) || \ defined(CONFIG_USERSPACE) case _NANO_ERR_STACK_CHK_FAIL: printk("***** Stack Check Fail! *****\n"); break; #endif /* CONFIG_STACK_CANARIES */ case _NANO_ERR_KERNEL_OOPS: printk("***** Kernel OOPS! *****\n"); break; case _NANO_ERR_KERNEL_PANIC: printk("***** Kernel Panic! *****\n"); break; case _NANO_ERR_ALLOCATION_FAIL: printk("**** Kernel Allocation Failure! ****\n"); break; default: printk("**** Unknown Fatal Error %d! ****\n", reason); break; } printk("Current thread ID = %p\n" "Faulting segment:address = 0x%04x:0x%08x\n" "eax: 0x%08x, ebx: 0x%08x, ecx: 0x%08x, edx: 0x%08x\n" "esi: 0x%08x, edi: 0x%08x, ebp: 0x%08x, esp: 0x%08x\n" "eflags: 0x%x\n", k_current_get(), pEsf->cs & 0xFFFF, pEsf->eip, pEsf->eax, pEsf->ebx, pEsf->ecx, pEsf->edx, pEsf->esi, pEsf->edi, pEsf->ebp, pEsf->esp, pEsf->eflags); #endif /* CONFIG_PRINTK */ /* * Error was fatal to a kernel task or a thread; invoke the system * fatal error handling policy defined for the platform. */ _SysFatalErrorHandler(reason, pEsf); }
FUNC_NORETURN void _arch_syscall_oops(void *ssf_ptr) { _SysFatalErrorHandler(_NANO_ERR_KERNEL_OOPS, ssf_ptr); CODE_UNREACHABLE; }