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 ++++++++++++++++++++++++++ c/src/lib/libbsp/i386/pc386/Makefile.in | 6 +- c/src/lib/libbsp/i386/pc386/start/start16.s | 12 +++- c/src/lib/libbsp/i386/pc386/startup/bspstart.c | 7 +- c/src/lib/libbsp/i386/pc386/wrapup/Makefile.in | 6 +- c/src/lib/libbsp/i386/shared/irq/irq.c | 23 ++++-- c/src/lib/libbsp/i386/shared/irq/irq_asm.s | 5 ++ c/src/lib/libcpu/i386/displayCpu.c | 3 +- 10 files changed, 258 insertions(+), 20 deletions(-) (limited to 'c') 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. */ diff --git a/c/src/lib/libbsp/i386/pc386/Makefile.in b/c/src/lib/libbsp/i386/pc386/Makefile.in index 4862454e13..f30692edfc 100644 --- a/c/src/lib/libbsp/i386/pc386/Makefile.in +++ b/c/src/lib/libbsp/i386/pc386/Makefile.in @@ -11,9 +11,9 @@ PROJECT_ROOT = @PROJECT_ROOT@ include $(RTEMS_ROOT)/make/custom/$(RTEMS_BSP).cfg include $(RTEMS_ROOT)/make/directory.cfg -# We only build the Network library if HAS_NETWORKING was defined -NETWORK_yes_V = network -NETWORK = $(NETWORK_$(HAS_NETWORKING)_V) +# # We only build the Network library if HAS_NETWORKING was defined +# NETWORK_yes_V = network +# NETWORK = $(NETWORK_$(HAS_NETWORKING)_V) # wrapup is the one that actually builds and installs the library # from the individual .rel files built in other directories diff --git a/c/src/lib/libbsp/i386/pc386/start/start16.s b/c/src/lib/libbsp/i386/pc386/start/start16.s index c10a658718..778c0dd597 100644 --- a/c/src/lib/libbsp/i386/pc386/start/start16.s +++ b/c/src/lib/libbsp/i386/pc386/start/start16.s @@ -33,7 +33,7 @@ .set HDROFF, 0x24 # offset into bin2boot header of start32 addr .set STACKOFF, 0x200-0x10 # offset to load into %esp, from start of image - +/* #define NEW_GAS*/ /*----------------------------------------------------------------------------+ | CODE section +----------------------------------------------------------------------------*/ @@ -78,14 +78,20 @@ _start16: /*---------------------------------------------------------------------+ | Bare PC machines boot in real mode! We have to turn protected mode on. +---------------------------------------------------------------------*/ - +#ifdef NEW_GAS + data32 + addr32 +#endif lgdt gdtptr - start16 # load Global Descriptor Table - movl %cr0, %eax orl $CR0_PE, %eax movl %eax, %cr0 # turn on protected mode +#ifdef NEW_GAS + ljmpl $PROT_CODE_SEG, $1f # flush prefetch queue, and reload %cs +#else ljmp $PROT_CODE_SEG, $1f # flush prefetch queue, and reload %cs +#endif 1: .code32 diff --git a/c/src/lib/libbsp/i386/pc386/startup/bspstart.c b/c/src/lib/libbsp/i386/pc386/startup/bspstart.c index 13e8610c42..7ebcc60685 100644 --- a/c/src/lib/libbsp/i386/pc386/startup/bspstart.c +++ b/c/src/lib/libbsp/i386/pc386/startup/bspstart.c @@ -173,10 +173,13 @@ void bsp_start( void ) console_reserve_resources(&BSP_Configuration); /* - * Init rtems_interrupt_management + * Init rtems interrupt management */ rtems_irq_mngt_init(); - + /* + * Init rtems exceptions management + */ + rtems_exception_init_mngt(); /* * The following information is very useful when debugging. */ diff --git a/c/src/lib/libbsp/i386/pc386/wrapup/Makefile.in b/c/src/lib/libbsp/i386/pc386/wrapup/Makefile.in index 70515fdb8e..c8672490d7 100644 --- a/c/src/lib/libbsp/i386/pc386/wrapup/Makefile.in +++ b/c/src/lib/libbsp/i386/pc386/wrapup/Makefile.in @@ -8,9 +8,9 @@ VPATH = @srcdir@ RTEMS_ROOT = @top_srcdir@ PROJECT_ROOT = @PROJECT_ROOT@ -# We only build the Network library if HAS_NETWORKING was defined -NETWORK_yes_V = network -NETWORK = $(NETWORK_$(HAS_NETWORKING)_V) +# # We only build the Network library if HAS_NETWORKING was defined +# NETWORK_yes_V = network +# NETWORK = $(NETWORK_$(HAS_NETWORKING)_V) BSP_PIECES=startup clock console timer pc386dev $(NETWORK) GENERIC_PIECES= diff --git a/c/src/lib/libbsp/i386/shared/irq/irq.c b/c/src/lib/libbsp/i386/shared/irq/irq.c index 356112076f..9dea372e0f 100644 --- a/c/src/lib/libbsp/i386/shared/irq/irq.c +++ b/c/src/lib/libbsp/i386/shared/irq/irq.c @@ -14,7 +14,9 @@ #include #include - +#include +#include + /* * pointer to the mask representing the additionnal irq vectors * that must be disabled when a particular entry is activated. @@ -360,11 +362,18 @@ int pc386_rtems_irq_mngt_get(rtems_irq_global_settings** config) void _ThreadProcessSignalsFromIrq (CPU_Exception_frame* ctx) { /* - * If I understand the _Thread_Dispatch routine correctly - * I do not see how this routine can be called given the - * actual code. I plan to use this so far unused feature - * to implement remote debugger ptrace("attach", ...) - * command. + * Process pending signals that have not already been + * processed by _Thread_Displatch. This happens quite + * unfrequently : the ISR must have posted an action + * to the current running thread. + */ + if ( _Thread_Do_post_task_switch_extension || + _Thread_Executing->do_post_task_switch_extension ) { + _Thread_Executing->do_post_task_switch_extension = FALSE; + _API_extensions_Run_postswitch(); + } + /* + * I plan to process other thread related events here. + * This will include DEBUG session requsted from keyboard... */ - printk(" _ThreadProcessSignalsFromIrq called! mail valette@crf.canon.fr\n"); } diff --git a/c/src/lib/libbsp/i386/shared/irq/irq_asm.s b/c/src/lib/libbsp/i386/shared/irq/irq_asm.s index a3954d0961..4be08ed992 100644 --- a/c/src/lib/libbsp/i386/shared/irq/irq_asm.s +++ b/c/src/lib/libbsp/i386/shared/irq/irq_asm.s @@ -14,6 +14,8 @@ #include "asm.h" #include + BEGIN_CODE + SYM (_ISR_Handler): /* * Before this was point is reached the vectors unique @@ -243,3 +245,6 @@ SYM (default_raw_idt_handler): popa iret +END_CODE + +END diff --git a/c/src/lib/libcpu/i386/displayCpu.c b/c/src/lib/libcpu/i386/displayCpu.c index ff748b7b43..eb9725b38b 100644 --- a/c/src/lib/libcpu/i386/displayCpu.c +++ b/c/src/lib/libcpu/i386/displayCpu.c @@ -19,8 +19,7 @@ #include #include #include - -extern void printk(const char*, ...); +#include unsigned char Cx86_step = 0; static const char *Cx86_type[] = { -- cgit v1.2.3