From eb562f2c860061868e4ea1a821a84147b694dd07 Mon Sep 17 00:00:00 2001 From: Joel Sherrill Date: Fri, 21 Aug 1998 16:39:52 +0000 Subject: Patch from Eric Valette : Here is a patch that enables to catch exception and get message before crashing RTEMS :) It should be generic to any Intel port although enabled only for pc386 BSP... [Joel] I fixed the bug I introduced in irq_asm.s... --- c/src/exec/score/cpu/i386/cpu.c | 90 +++++++++++++++++++++++++++++++++ c/src/exec/score/cpu/i386/cpu.h | 27 ++++++++++ c/src/exec/score/cpu/i386/cpu_asm.s | 99 +++++++++++++++++++++++++++++++++++++ 3 files changed, 216 insertions(+) (limited to 'c/src/exec/score') diff --git a/c/src/exec/score/cpu/i386/cpu.c b/c/src/exec/score/cpu/i386/cpu.c index 70d7fd3267..1f0900fceb 100644 --- a/c/src/exec/score/cpu/i386/cpu.c +++ b/c/src/exec/score/cpu/i386/cpu.c @@ -15,6 +15,9 @@ #include #include +#include +#include + /* _CPU_Initialize * @@ -82,3 +85,90 @@ void _CPU_Thread_Idle_body () asm volatile ("hlt"); } } + +void _defaultExcHandler (CPU_Exception_frame *ctx) +{ + printk("----------------------------------------------------------\n"); + printk("Exception %d caught at PC %x by thread %d\n", + ctx->idtIndex, + ctx->eip, + _Thread_Executing->Object.id); + printk("----------------------------------------------------------\n"); + printk("Processor execution context at time of the fault was :\n"); + printk("----------------------------------------------------------\n"); + printk(" EAX = %x EBX = %x ECX = %x EDX = %x\n", + ctx->eax, ctx->ebx, ctx->ecx, ctx->edx); + printk(" ESI = %x EDI = %x EBP = %x ESP = %x\n", + ctx->esi, ctx->edi, ctx->ebp, ctx->esp0); + printk("----------------------------------------------------------\n"); + printk("Error code pushed by processor itself (if not 0) = %x\n", + ctx->faultCode); + printk("----------------------------------------------------------\n\n"); + printk(" ************ FAULTY THREAD WILL BE DELETED **************\n"); + /* + * OK I could probably use a simplified version but at least this + * should work. + */ + rtems_task_delete(_Thread_Executing->Object.id); +} + +cpuExcHandlerType _currentExcHandler = _defaultExcHandler; + +extern void rtems_exception_prologue_0(); +extern void rtems_exception_prologue_1(); +extern void rtems_exception_prologue_2(); +extern void rtems_exception_prologue_3(); +extern void rtems_exception_prologue_4(); +extern void rtems_exception_prologue_5(); +extern void rtems_exception_prologue_6(); +extern void rtems_exception_prologue_7(); +extern void rtems_exception_prologue_8(); +extern void rtems_exception_prologue_9(); +extern void rtems_exception_prologue_10(); +extern void rtems_exception_prologue_11(); +extern void rtems_exception_prologue_12(); +extern void rtems_exception_prologue_13(); +extern void rtems_exception_prologue_14(); +extern void rtems_exception_prologue_16(); +extern void rtems_exception_prologue_17(); +extern void rtems_exception_prologue_18(); + +static rtems_raw_irq_hdl tbl[] = { + rtems_exception_prologue_0, + rtems_exception_prologue_1, + rtems_exception_prologue_2, + rtems_exception_prologue_3, + rtems_exception_prologue_4, + rtems_exception_prologue_5, + rtems_exception_prologue_6, + rtems_exception_prologue_7, + rtems_exception_prologue_8, + rtems_exception_prologue_9, + rtems_exception_prologue_10, + rtems_exception_prologue_11, + rtems_exception_prologue_12, + rtems_exception_prologue_13, + rtems_exception_prologue_14, + rtems_exception_prologue_16, + rtems_exception_prologue_17, + rtems_exception_prologue_18, +}; + +void rtems_exception_init_mngt() +{ + unsigned int i,j; + interrupt_gate_descriptor *currentIdtEntry; + unsigned limit; + unsigned level; + + i = sizeof(tbl) / sizeof (rtems_raw_irq_hdl); + + i386_get_info_from_IDTR (¤tIdtEntry, &limit); + + _CPU_ISR_Disable(level); + for (j = 0; j < i; j++) { + create_interrupt_gate_descriptor (¤tIdtEntry[j], tbl[j]); + } + _CPU_ISR_Enable(level); +} + diff --git a/c/src/exec/score/cpu/i386/cpu.h b/c/src/exec/score/cpu/i386/cpu.h index d4806a2be4..8620ad8392 100644 --- a/c/src/exec/score/cpu/i386/cpu.h +++ b/c/src/exec/score/cpu/i386/cpu.h @@ -138,6 +138,10 @@ typedef struct { unsigned32 eflags; } CPU_Exception_frame; +typedef void (*cpuExcHandlerType) (CPU_Exception_frame*); +extern cpuExcHandlerType _currentExcHandler; +extern void rtems_exception_init_mngt(); + /* * The following structure defines the set of information saved * on the current stack by RTEMS upon receipt of each interrupt @@ -146,6 +150,29 @@ typedef struct { typedef CPU_Exception_frame CPU_Interrupt_frame; +typedef enum { + DIVIDE_BY_ZERO = 0, + DEBUG = 1, + NMI = 2, + BREAKPOINT = 3, + OVERFLOW = 4, + BOUND = 5, + ILLEGAL_INSTR = 6, + MATH_COPROC_UNAVAIL = 7, + DOUBLE_FAULT = 8, + I386_COPROC_SEG_ERR = 9, + INVALID_TSS = 10, + SEGMENT_NOT_PRESENT = 11, + STACK_SEGMENT_FAULT = 12, + GENERAL_PROT_ERR = 13, + PAGE_FAULT = 14, + INTEL_RES15 = 15, + FLOAT_ERROR = 16, + ALIGN_CHECK = 17, + MACHINE_CHECK = 18 +} Intel_symbolic_exception_name; + + /* * The following table contains the information required to configure * the i386 specific parameters. diff --git a/c/src/exec/score/cpu/i386/cpu_asm.s b/c/src/exec/score/cpu/i386/cpu_asm.s index a0bd6ece2c..16d0a7c205 100644 --- a/c/src/exec/score/cpu/i386/cpu_asm.s +++ b/c/src/exec/score/cpu/i386/cpu_asm.s @@ -109,6 +109,105 @@ SYM (_CPU_Context_restore_fp): frstor (eax) # restore FP context ret +SYM (_Exception_Handler): + pusha # Push general purpose registers + pushl esp # Push exception frame address + movl _currentExcHandler, eax # Call function storead in _currentExcHandler + call * eax + addl $4, esp + popa # restore general purpose registers + addl $8, esp # skill vector number and faultCode + iret + +#define DISTINCT_EXCEPTION_WITH_FAULTCODE_ENTRY(_vector) \ + .p2align 4 ; \ + PUBLIC (rtems_exception_prologue_ ## _vector ) ; \ +SYM (rtems_exception_prologue_ ## _vector ): \ + pushl $ _vector ; \ + jmp SYM (_Exception_Handler) ; + +#define DISTINCT_EXCEPTION_WITHOUT_FAULTCODE_ENTRY(_vector) \ + .p2align 4 ; \ + PUBLIC (rtems_exception_prologue_ ## _vector ) ; \ +SYM (rtems_exception_prologue_ ## _vector ): \ + pushl $ 0 ; \ + pushl $ _vector ; \ + jmp SYM (_Exception_Handler) ; + +/* + * Divide Error + */ +DISTINCT_EXCEPTION_WITHOUT_FAULTCODE_ENTRY (0) +/* + * Debug Exception + */ +DISTINCT_EXCEPTION_WITHOUT_FAULTCODE_ENTRY (1) +/* + * NMI + */ +DISTINCT_EXCEPTION_WITHOUT_FAULTCODE_ENTRY (2) +/* + * Breakpoint + */ +DISTINCT_EXCEPTION_WITHOUT_FAULTCODE_ENTRY (3) +/* + * Overflow + */ +DISTINCT_EXCEPTION_WITHOUT_FAULTCODE_ENTRY (4) +/* + * Bound Range Exceeded + */ +DISTINCT_EXCEPTION_WITHOUT_FAULTCODE_ENTRY (5) +/* + * Invalid Opcode + */ +DISTINCT_EXCEPTION_WITHOUT_FAULTCODE_ENTRY (6) +/* + * No Math Coproc + */ +DISTINCT_EXCEPTION_WITHOUT_FAULTCODE_ENTRY (7) +/* + * Double Fault + */ +DISTINCT_EXCEPTION_WITH_FAULTCODE_ENTRY (8) +/* + * Coprocessor segment overrun + */ +DISTINCT_EXCEPTION_WITHOUT_FAULTCODE_ENTRY (9) +/* + * Invalid TSS + */ +DISTINCT_EXCEPTION_WITH_FAULTCODE_ENTRY (10) +/* + * Segment Not Present + */ +DISTINCT_EXCEPTION_WITH_FAULTCODE_ENTRY (11) +/* + * Stack segment Fault + */ +DISTINCT_EXCEPTION_WITH_FAULTCODE_ENTRY (12) +/* + * General Protection Fault + */ +DISTINCT_EXCEPTION_WITH_FAULTCODE_ENTRY (13) +/* + * Page Fault + */ +DISTINCT_EXCEPTION_WITH_FAULTCODE_ENTRY (14) +/* + * Floating point error (NB 15 is reserved it is therefor skipped) + */ +DISTINCT_EXCEPTION_WITHOUT_FAULTCODE_ENTRY (16) +/* + * Aligment Check + */ +DISTINCT_EXCEPTION_WITH_FAULTCODE_ENTRY (17) +/* + * Machine Check + */ +DISTINCT_EXCEPTION_WITH_FAULTCODE_ENTRY (18) + + /* * GO32 does not require these segment related routines. */ -- cgit v1.2.3