2015-06-20 01:56:08 +08:00
|
|
|
/* fatal.c - nanokernel fatal error handler */
|
2015-04-11 07:44:37 +08:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Copyright (c) 2013-2014 Wind River Systems, Inc.
|
|
|
|
*
|
2015-10-07 00:00:37 +08:00
|
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
* you may not use this file except in compliance with the License.
|
|
|
|
* You may obtain a copy of the License at
|
2015-04-11 07:44:37 +08:00
|
|
|
*
|
2015-10-07 00:00:37 +08:00
|
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
2015-04-11 07:44:37 +08:00
|
|
|
*
|
2015-10-07 00:00:37 +08:00
|
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
* See the License for the specific language governing permissions and
|
|
|
|
* limitations under the License.
|
2015-04-11 07:44:37 +08:00
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
2015-10-21 00:42:33 +08:00
|
|
|
* DESCRIPTION
|
|
|
|
* This module provides the _NanoFatalErrorHandler() routine.
|
2015-07-02 05:22:39 +08:00
|
|
|
*/
|
2015-04-11 07:44:37 +08:00
|
|
|
|
|
|
|
#include <toolchain.h>
|
|
|
|
#include <sections.h>
|
|
|
|
|
|
|
|
#include <nanokernel.h>
|
2015-06-19 23:07:02 +08:00
|
|
|
#include <nano_private.h>
|
2015-04-11 07:44:37 +08:00
|
|
|
#include <misc/printk.h>
|
2015-10-09 03:42:11 +08:00
|
|
|
#include <asmPrv.h>
|
2015-04-11 07:44:37 +08:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Define a default ESF for use with _NanoFatalErrorHandler() in the event
|
|
|
|
* the caller does not have a NANO_ESF to pass
|
|
|
|
*/
|
2015-05-09 06:12:56 +08:00
|
|
|
const NANO_ESF _default_esf = {
|
2015-10-05 22:48:46 +08:00
|
|
|
0xdeaddead, /* ESP */
|
2015-04-11 07:44:37 +08:00
|
|
|
0xdeaddead, /* EBP */
|
|
|
|
0xdeaddead, /* EBX */
|
|
|
|
0xdeaddead, /* ESI */
|
|
|
|
0xdeaddead, /* EDI */
|
|
|
|
0xdeaddead, /* EDX */
|
|
|
|
0xdeaddead, /* ECX */
|
|
|
|
0xdeaddead, /* EAX */
|
|
|
|
0xdeaddead, /* error code */
|
|
|
|
0xdeaddead, /* EIP */
|
|
|
|
0xdeaddead, /* CS */
|
|
|
|
0xdeaddead, /* EFLAGS */
|
|
|
|
};
|
|
|
|
|
2015-07-02 05:22:39 +08:00
|
|
|
/**
|
|
|
|
*
|
2015-07-02 05:51:40 +08:00
|
|
|
* @brief Nanokernel fatal error handler
|
2015-07-02 05:22:39 +08:00
|
|
|
*
|
|
|
|
* 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>.
|
|
|
|
*
|
2015-10-21 00:42:33 +08:00
|
|
|
* @param reason the reason that the handler was called
|
|
|
|
* @param pEsf pointer to the exception stack frame
|
|
|
|
*
|
2015-07-02 05:29:04 +08:00
|
|
|
* @return This function does not return.
|
2015-07-02 05:22:39 +08:00
|
|
|
*/
|
2015-10-21 00:42:33 +08:00
|
|
|
FUNC_NORETURN void _NanoFatalErrorHandler(unsigned int reason,
|
|
|
|
const NANO_ESF *pEsf)
|
2015-04-11 07:44:37 +08:00
|
|
|
{
|
|
|
|
|
|
|
|
#ifdef CONFIG_PRINTK
|
|
|
|
|
|
|
|
/* Display diagnostic information about the error */
|
|
|
|
|
|
|
|
switch (reason) {
|
|
|
|
case _NANO_ERR_SPURIOUS_INT:
|
|
|
|
printk("***** Unhandled exception/interrupt occurred! "
|
|
|
|
"*****\n");
|
|
|
|
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 */
|
|
|
|
|
|
|
|
|
2015-05-29 01:01:42 +08:00
|
|
|
case _NANO_ERR_ALLOCATION_FAIL:
|
|
|
|
printk("**** Kernel Allocation Failure! ****\n");
|
|
|
|
break;
|
|
|
|
|
2015-04-11 07:44:37 +08:00
|
|
|
default:
|
|
|
|
printk("**** Unknown Fatal Error %d! ****\n", reason);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2015-08-20 23:04:01 +08:00
|
|
|
printk("Current thread ID = 0x%x\n"
|
2015-10-06 00:40:20 +08:00
|
|
|
"Faulting instruction address = 0x%x\n"
|
|
|
|
"eax: %x, ebx: %x, ecx: %x, edx: %x\n"
|
|
|
|
"esi: %x, edi: %x, ebp: %x, esp: %x\n"
|
|
|
|
"eflags: %x\n",
|
|
|
|
sys_thread_self_get(),
|
|
|
|
pEsf->eip,
|
|
|
|
pEsf->eax, pEsf->ebx, pEsf->ecx, pEsf->edx,
|
|
|
|
pEsf->esi, pEsf->edi, pEsf->ebp, pEsf->esp,
|
|
|
|
pEsf->eflags);
|
2015-04-11 07:44:37 +08:00
|
|
|
#endif /* CONFIG_PRINTK */
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
2015-07-28 00:19:36 +08:00
|
|
|
* Error was fatal to a kernel task or a fiber; invoke the system
|
|
|
|
* fatal error handling policy defined for the platform.
|
2015-04-11 07:44:37 +08:00
|
|
|
*/
|
|
|
|
|
|
|
|
_SysFatalErrorHandler(reason, pEsf);
|
|
|
|
}
|
2015-10-09 03:42:11 +08:00
|
|
|
|
|
|
|
#if CONFIG_EXCEPTION_DEBUG
|
|
|
|
|
2015-11-13 06:43:58 +08:00
|
|
|
static FUNC_NORETURN void generic_exc_handle(unsigned int vector,
|
2015-10-09 03:42:11 +08:00
|
|
|
const NANO_ESF *pEsf)
|
|
|
|
{
|
2015-11-13 06:43:58 +08:00
|
|
|
printk("***** CPU exception %d\n", vector);
|
x86: remove dynamically generated IRQ and exception code
We are interested in supporting some XIP x86 platforms which are
unable to fetch CPU instructions from system RAM. This requires
refactoring our dynamic IRQ/exc code which currently synthesizes
assembly language instructions to create IRQ stubs on-the-fly.
Instead, a new approach is taken. Given that the configuration at
build time specifies the number of required stubs, use this
to generate a build time a set of tiny stub functions which simply
push a 'stub id' and then call common dynamic interrupt code.
The handler function and handler argument is saved in a table keyed by
this stub id.
CONFIG_EOI_HANDLER_SUPPORTED removed, the code hasn't been conditionally
compiled for some time and in all cases we call _loapic_eoi() when
finished with an interrupt.
Some other out-of-date verbiage in comments related to supporting
non-APIC removed.
Previously, when dynamic exceptions were created a pointer would
be passed in by the caller reserving ram for the stub code. Since
this is no longer feasible, two new Kconfig options have been added.
CONFIG_NUM_DYNAMIC_EXC_STUBS and CONFIG_NUM_DYNAMIC_EXC_NO_ERR_STUBS
control how many stubs are created for exceptions that push
an error code, and no error code, respectively.
SW Interrupts are no longer triggered by "int <vector>" hard-coded
assembly instructions. Instead this is done by sending a self-directed
inter-processor interrupt from the LOAPIC, using a new API
loapic_int_vect_trigger(). In this way we get rid of dynamically
generated code in irq_test_common.h.
All interrupts call _loapic_eoi() when finished, since this is now
the right thing to do for all IRQs, including SW interrupts.
_irq_handler_set() for x86 no longer requires the old function pointer
to be supplied.
Change-Id: I78993d3d00dd153c9051c518b417cce8d3acee9e
Signed-off-by: Andrew Boie <andrew.p.boie@intel.com>
2015-10-20 05:10:53 +08:00
|
|
|
if ((1 << vector) & _EXC_ERROR_CODE_FAULTS) {
|
2015-10-09 03:42:11 +08:00
|
|
|
printk("***** Exception code: 0x%x\n", pEsf->errorCode);
|
|
|
|
}
|
|
|
|
_NanoFatalErrorHandler(_NANO_ERR_SPURIOUS_INT, pEsf);
|
|
|
|
}
|
|
|
|
|
2015-11-13 06:43:58 +08:00
|
|
|
#define EXC_FUNC(vector) \
|
2015-10-09 03:42:11 +08:00
|
|
|
FUNC_NORETURN void handle_exc_##vector(const NANO_ESF *pEsf) \
|
|
|
|
{ \
|
2015-11-13 06:43:58 +08:00
|
|
|
generic_exc_handle(vector, pEsf); \
|
2015-10-09 03:42:11 +08:00
|
|
|
}
|
|
|
|
|
2015-11-13 06:43:58 +08:00
|
|
|
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);
|
2015-10-09 03:42:11 +08:00
|
|
|
#ifndef CONFIG_FP_SHARING
|
2015-11-13 06:43:58 +08:00
|
|
|
EXC_FUNC(IV_DEVICE_NOT_AVAILABLE);
|
2015-10-09 03:42:11 +08:00
|
|
|
#endif
|
2015-11-13 06:43:58 +08:00
|
|
|
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);
|
2015-10-09 03:42:11 +08:00
|
|
|
|
|
|
|
#endif /* CONFIG_EXCEPTION_DEBUG */
|
|
|
|
|