x86: Improve exception/trap debugging

Currently when an unhandled exception or trap occurs, we don't know
specifically which one happened. The CONFIG_EXCEPTION_DEBUG option
installs handlers for various exceptions and prints out details
when they happen.

Change-Id: I4d3fe4544c3e2583c4f83b306b86ac0595d9ce0e
Signed-off-by: Andrew Boie <andrew.p.boie@intel.com>
This commit is contained in:
Andrew Boie 2015-10-08 12:42:11 -07:00 committed by Anas Nashif
commit be3e3b0f8c
3 changed files with 75 additions and 1 deletions

View file

@ -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"

View file

@ -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 */

View file

@ -27,7 +27,7 @@ This module provides the _NanoFatalErrorHandler() routine.
#include <nanokernel.h>
#include <nano_private.h>
#include <misc/printk.h>
#include <asmPrv.h>
/*
* 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 */