diff --git a/arch/x86/core/Kconfig b/arch/x86/core/Kconfig index 7433fd53cce..cde2113fcdc 100644 --- a/arch/x86/core/Kconfig +++ b/arch/x86/core/Kconfig @@ -34,6 +34,16 @@ config NO_NESTED_INTERRUPTS help disable nest interrupts. +config EXCEPTION_DEBUG + bool + prompt "Unhandled exception debugging" + default y + depends on PRINTK + help + Install handlers for various CPU exception/trap vectors to + make debugging them easier, at a small expense in code size. + This prints out the specific exception vector and any associated + error codes. menu "Memory Layout Options" diff --git a/arch/x86/core/excstub.S b/arch/x86/core/excstub.S index b24cd5415ea..a5ec21f193d 100644 --- a/arch/x86/core/excstub.S +++ b/arch/x86/core/excstub.S @@ -288,3 +288,27 @@ BRANCH_LABEL(nestedException) SYS_NANO_CPU_EXC_CONNECT(_FpNotAvailableExcHandler,IV_DEVICE_NOT_AVAILABLE) #endif /* CONFIG_FP_SHARING */ +#if CONFIG_EXCEPTION_DEBUG + +#define EXC_HANDLER(vec) NANO_CPU_EXC_CONNECT_NO_ERR(handle_exc_##vec, vec, 0) +#define EXC_HANDLER_CODE(vec) NANO_CPU_EXC_CONNECT(handle_exc_##vec, vec, 0) + +EXC_HANDLER(IV_DIVIDE_ERROR) +EXC_HANDLER(IV_NON_MASKABLE_INTERRUPT) +EXC_HANDLER(IV_OVERFLOW) +EXC_HANDLER(IV_BOUND_RANGE) +EXC_HANDLER(IV_INVALID_OPCODE) +#ifndef CONFIG_FP_SHARING +EXC_HANDLER(IV_DEVICE_NOT_AVAILABLE) +#endif +EXC_HANDLER_CODE(IV_DOUBLE_FAULT) +EXC_HANDLER_CODE(IV_INVALID_TSS) +EXC_HANDLER_CODE(IV_SEGMENT_NOT_PRESENT) +EXC_HANDLER_CODE(IV_STACK_FAULT) +EXC_HANDLER_CODE(IV_GENERAL_PROTECTION) +EXC_HANDLER_CODE(IV_PAGE_FAULT) +EXC_HANDLER(IV_X87_FPU_FP_ERROR) +EXC_HANDLER_CODE(IV_ALIGNMENT_CHECK) +EXC_HANDLER(IV_MACHINE_CHECK) + +#endif /* CONFIG_EXCEPTION_DEBUG */ diff --git a/arch/x86/core/fatal.c b/arch/x86/core/fatal.c index 9733d49f643..5155667a714 100644 --- a/arch/x86/core/fatal.c +++ b/arch/x86/core/fatal.c @@ -27,7 +27,7 @@ This module provides the _NanoFatalErrorHandler() routine. #include #include #include - +#include /* * Define a default ESF for use with _NanoFatalErrorHandler() in the event @@ -119,3 +119,43 @@ FUNC_NORETURN void _NanoFatalErrorHandler( _SysFatalErrorHandler(reason, pEsf); } + +#if CONFIG_EXCEPTION_DEBUG + +static FUNC_NORETURN void generic_exc_handle(char *description, + unsigned int vector, + const NANO_ESF *pEsf) +{ + printk("***** CPU exception %d: %s\n", vector, description); + if (pEsf->errorCode) { + printk("***** Exception code: 0x%x\n", pEsf->errorCode); + } + _NanoFatalErrorHandler(_NANO_ERR_SPURIOUS_INT, pEsf); +} + +#define EXC_FUNC(vector, description) \ +FUNC_NORETURN void handle_exc_##vector(const NANO_ESF *pEsf) \ +{ \ + generic_exc_handle(description, vector, pEsf); \ +} + +EXC_FUNC(IV_DIVIDE_ERROR, "Division by zero"); +EXC_FUNC(IV_NON_MASKABLE_INTERRUPT, "Non-maskable interrupt"); +EXC_FUNC(IV_OVERFLOW, "Overflow"); +EXC_FUNC(IV_BOUND_RANGE, "Bounds"); +EXC_FUNC(IV_INVALID_OPCODE, "Invalid opcode"); +#ifndef CONFIG_FP_SHARING +EXC_FUNC(IV_DEVICE_NOT_AVAILABLE, "FPU device not available"); +#endif +EXC_FUNC(IV_DOUBLE_FAULT, "Double fault"); +EXC_FUNC(IV_INVALID_TSS, "Invalid task state segment"); +EXC_FUNC(IV_SEGMENT_NOT_PRESENT, "Segment not present"); +EXC_FUNC(IV_STACK_FAULT, "Stack fault"); +EXC_FUNC(IV_GENERAL_PROTECTION, "General protection fault"); +EXC_FUNC(IV_PAGE_FAULT, "Page fault"); +EXC_FUNC(IV_X87_FPU_FP_ERROR, "Floating point error"); +EXC_FUNC(IV_ALIGNMENT_CHECK, "Alignment error"); +EXC_FUNC(IV_MACHINE_CHECK, "Machine check"); + +#endif /* CONFIG_EXCEPTION_DEBUG */ +