Skip to content

Commit

Permalink
x86: improve exception APIs
Browse files Browse the repository at this point in the history
Previously, exception stubs had to be declared in assembly
language files. Now we have two new APIs to regsiter exception
handlers at C toplevel:

 _EXCEPTION_CONNECT_CODE(handler, vector)
 _EXCEPTION_CONNECT_NOCODE(handler, vector)

For x86 exceptions that do and do not push error codes onto
the stack respectively.

In addition, it's now no longer necessary to #define around
exception registration. We now use .gnu.linkonce magic such that
the first _EXCEPTION_CONNECT_*() that the linker finds is used
for the specified vector. Applications are free to install their
own exception handlers which will take precedence over default
handlers such as installed by arch/x86/core/fatal.c

Some Makefiles have been adjusted so that the default exception
handlers in arch/x86/core/fatal.c are linked last. The code has
been tested that the right order of precedence is taken for
exceptions overridden in the floating point, gdb debug, or
application code. The asm SYS_NANO_CPU_EXC_CONNECT API has been
removed; it was ill- conceived as it only worked for exceptions
that didn't push error codes. All the asm NANO_CPU_EXC_CONNECT_*
APIs are gone as well in favor of the new _EXCEPTION_CONNNECT_*()
APIs.

CONFIG_EXCEPTION_DEBUG no longer needs to be disabled for test
cases that define their own exception handlers.

Issue: ZEP-203
Change-Id: I782e0143fba832d18cdf4daaa7e47820595fe041
Signed-off-by: Andrew Boie <[email protected]>
  • Loading branch information
Andrew Boie committed Jul 28, 2016
1 parent d677457 commit 17c0b37
Show file tree
Hide file tree
Showing 16 changed files with 132 additions and 218 deletions.
4 changes: 3 additions & 1 deletion arch/x86/Kbuild
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
obj-y += core/
obj-$(CONFIG_GDB_SERVER) += debug/
obj-y += soc/$(SOC_PATH)/
# Must be last so that debug/ or soc/ can override default exception
# handlers
obj-y += core/
5 changes: 4 additions & 1 deletion arch/x86/core/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ endif
# character starts a comment
KBUILD_AFLAGS += -Wa,--divide

obj-y += fatal.o cpuhalt.o \
obj-y += cpuhalt.o \
msr.o dynamic.o intconnect.o \
excconnect.o sys_fatal_error_handler.o \
crt0.o cache_s.o cache.o excstub.o \
Expand All @@ -25,3 +25,6 @@ obj-$(CONFIG_REBOOT_RST_CNT) += reboot_rst_cnt.o

obj-$(CONFIG_DEBUG_INFO) += debug/
obj-$(CONFIG_REBOOT_RST_CNT) += reboot_rst_cnt.o

# Last since we declare default exception handlers here
obj-y += fatal.o
32 changes: 0 additions & 32 deletions arch/x86/core/excstub.S
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@
#include <offsets.h> /* nanokernel structure offset definitions */


#include <asmPrv.h>

/* exports (internal APIs) */

Expand Down Expand Up @@ -298,37 +297,6 @@ BRANCH_LABEL(nestedException)
/* Pop of EFLAGS will re-enable interrupts and restore direction flag */
iret

/* Static exception handler stubs */
#if CONFIG_FP_SHARING
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)

#if !defined(CONFIG_DEBUGGER_OWNS_FATAL_PROG_EXC_HANDLERS)
EXC_HANDLER(IV_DIVIDE_ERROR)
EXC_HANDLER_CODE(IV_PAGE_FAULT)
#endif

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(IV_X87_FPU_FP_ERROR)
EXC_HANDLER_CODE(IV_ALIGNMENT_CHECK)
EXC_HANDLER(IV_MACHINE_CHECK)
#endif /* CONFIG_EXCEPTION_DEBUG */

#if ALL_DYN_EXC_STUBS > 0
BRANCH_LABEL(_DynExcStubCommon)
Expand Down
53 changes: 34 additions & 19 deletions arch/x86/core/fatal.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@
#include <nanokernel.h>
#include <nano_private.h>
#include <misc/printk.h>
#include <asmPrv.h>
#include <drivers/loapic.h>
#include <exception.h>

__weak void _debug_fatal_hook(const NANO_ESF *esf) { ARG_UNUSED(esf); }

Expand Down Expand Up @@ -138,29 +138,44 @@ static FUNC_NORETURN void generic_exc_handle(unsigned int vector,
_NanoFatalErrorHandler(_NANO_ERR_CPU_EXCEPTION, pEsf);
}

#define EXC_FUNC(vector) \
#define _EXC_FUNC(vector) \
FUNC_NORETURN void handle_exc_##vector(const NANO_ESF *pEsf) \
{ \
generic_exc_handle(vector, pEsf); \
}

EXC_FUNC(IV_DIVIDE_ERROR);
EXC_FUNC(IV_NON_MASKABLE_INTERRUPT);
EXC_FUNC(IV_OVERFLOW);
EXC_FUNC(IV_BOUND_RANGE);
EXC_FUNC(IV_INVALID_OPCODE);
#ifndef CONFIG_FP_SHARING
EXC_FUNC(IV_DEVICE_NOT_AVAILABLE);
#endif
EXC_FUNC(IV_DOUBLE_FAULT);
EXC_FUNC(IV_INVALID_TSS);
EXC_FUNC(IV_SEGMENT_NOT_PRESENT);
EXC_FUNC(IV_STACK_FAULT);
EXC_FUNC(IV_GENERAL_PROTECTION);
EXC_FUNC(IV_PAGE_FAULT);
EXC_FUNC(IV_X87_FPU_FP_ERROR);
EXC_FUNC(IV_ALIGNMENT_CHECK);
EXC_FUNC(IV_MACHINE_CHECK);
#define _EXC_FUNC_CODE(vector) \
_EXC_FUNC(vector) \
_EXCEPTION_CONNECT_CODE(handle_exc_##vector, vector)

#define _EXC_FUNC_NOCODE(vector) \
_EXC_FUNC(vector) \
_EXCEPTION_CONNECT_NOCODE(handle_exc_##vector, vector)

/* Necessary indirection to ensure 'vector' is expanded before we expand
* the handle_exc_##vector
*/
#define EXC_FUNC_NOCODE(vector) \
_EXC_FUNC_NOCODE(vector)

#define EXC_FUNC_CODE(vector) \
_EXC_FUNC_CODE(vector)

EXC_FUNC_NOCODE(IV_DIVIDE_ERROR);
EXC_FUNC_NOCODE(IV_NON_MASKABLE_INTERRUPT);
EXC_FUNC_NOCODE(IV_OVERFLOW);
EXC_FUNC_NOCODE(IV_BOUND_RANGE);
EXC_FUNC_NOCODE(IV_INVALID_OPCODE);
EXC_FUNC_NOCODE(IV_DEVICE_NOT_AVAILABLE);
EXC_FUNC_CODE(IV_DOUBLE_FAULT);
EXC_FUNC_CODE(IV_INVALID_TSS);
EXC_FUNC_CODE(IV_SEGMENT_NOT_PRESENT);
EXC_FUNC_CODE(IV_STACK_FAULT);
EXC_FUNC_CODE(IV_GENERAL_PROTECTION);
EXC_FUNC_CODE(IV_PAGE_FAULT);
EXC_FUNC_NOCODE(IV_X87_FPU_FP_ERROR);
EXC_FUNC_CODE(IV_ALIGNMENT_CHECK);
EXC_FUNC_NOCODE(IV_MACHINE_CHECK);

#endif /* CONFIG_EXCEPTION_DEBUG */

1 change: 1 addition & 0 deletions arch/x86/core/float.c
Original file line number Diff line number Diff line change
Expand Up @@ -425,5 +425,6 @@ void _FpNotAvailableExcHandler(NANO_ESF * pEsf)

_FpEnable(_nanokernel.current, enableOption);
}
_EXCEPTION_CONNECT_NOCODE(_FpNotAvailableExcHandler, IV_DEVICE_NOT_AVAILABLE);

#endif /* CONFIG_FP_SHARING */
2 changes: 1 addition & 1 deletion arch/x86/debug/Makefile
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
ccflags-y += -I$(srctree)/kernel/nanokernel/include

obj-$(CONFIG_GDB_SERVER) = gdb_arch.o gdb_dbg_regs.o gdb_arch_exc.o
obj-$(CONFIG_GDB_SERVER) = gdb_arch.o gdb_dbg_regs.o
5 changes: 4 additions & 1 deletion arch/x86/debug/gdb_arch.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@
#include <string.h>
#include <debug/gdb_arch.h>
#include <misc/debug/gdb_server.h>
#include <asmPrv.h>

#define TRACE_FLAG 0x0100 /* EFLAGS:TF */
#define INT_FLAG 0x0200 /* EFLAGS:IF */
Expand Down Expand Up @@ -636,6 +635,7 @@ void gdb_trace_handler(NANO_ESF *esf)
(void)irq_lock();
_do_gdb_trace_handler(esf);
}
_EXCEPTION_CONNECT_NOCODE(gdb_trace_handler, IV_DEBUG);

/**
* @brief GDB breakpoint handler
Expand All @@ -658,6 +658,7 @@ void gdb_bp_handler(NANO_ESF *esf)

gdb_handler(GDB_EXC_BP, esf, GDB_SIG_TRAP);
}
_EXCEPTION_CONNECT_NOCODE(gdb_bp_handler, IV_BREAKPOINT);

/**
* @brief GDB division-by-zero handler
Expand All @@ -675,6 +676,7 @@ void gdb_div_by_zero_handler(NANO_ESF *esf)
gdb_debug_status = DEBUGGING;
gdb_handler(GDB_EXC_OTHER, esf, GDB_SIG_FPE);
}
_EXCEPTION_CONNECT_NOCODE(gdb_div_by_zero_handler, IV_DIVIDE_ERROR);

/**
* @brief GDB page fault handler
Expand All @@ -692,5 +694,6 @@ void gdb_pfault_handler(NANO_ESF *esf)
gdb_debug_status = DEBUGGING;
gdb_handler(GDB_EXC_OTHER, esf, GDB_SIG_SIGSEGV);
}
_EXCEPTION_CONNECT_CODE(gdb_pfault_handler, IV_PAGE_FAULT);

#endif /* GDB_ARCH_HAS_RUNCONTROL */
41 changes: 0 additions & 41 deletions arch/x86/debug/gdb_arch_exc.S

This file was deleted.

97 changes: 0 additions & 97 deletions arch/x86/include/asmPrv.h

This file was deleted.

7 changes: 1 addition & 6 deletions arch/x86/include/asm_inline_gcc.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,7 @@ extern "C" {
* Include asm_inline.h instead
*/

#ifdef _ASMLANGUAGE

#define SYS_NANO_CPU_EXC_CONNECT(handler, vector) \
NANO_CPU_EXC_CONNECT_NO_ERR(handler, vector, 0)

#else /* !_ASMLANGUAGE */
#ifndef _ASMLANGUAGE

/**
*
Expand Down
Loading

0 comments on commit 17c0b37

Please sign in to comment.