summaryrefslogtreecommitdiffstats
path: root/c
diff options
context:
space:
mode:
authorJoel Sherrill <joel.sherrill@OARcorp.com>1998-08-21 16:39:52 +0000
committerJoel Sherrill <joel.sherrill@OARcorp.com>1998-08-21 16:39:52 +0000
commiteb562f2c860061868e4ea1a821a84147b694dd07 (patch)
tree4273d9ac092dab0e00e065a365595a2b30fcc95f /c
parentSpacing changes (diff)
downloadrtems-eb562f2c860061868e4ea1a821a84147b694dd07.tar.bz2
Patch from Eric Valette <valette@crf.canon.fr>:
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...
Diffstat (limited to 'c')
-rw-r--r--c/src/exec/score/cpu/i386/cpu.c90
-rw-r--r--c/src/exec/score/cpu/i386/cpu.h27
-rw-r--r--c/src/exec/score/cpu/i386/cpu_asm.s99
-rw-r--r--c/src/lib/libbsp/i386/pc386/Makefile.in6
-rw-r--r--c/src/lib/libbsp/i386/pc386/start/start16.s12
-rw-r--r--c/src/lib/libbsp/i386/pc386/startup/bspstart.c7
-rw-r--r--c/src/lib/libbsp/i386/pc386/wrapup/Makefile.in6
-rw-r--r--c/src/lib/libbsp/i386/shared/irq/irq.c23
-rw-r--r--c/src/lib/libbsp/i386/shared/irq/irq_asm.s5
-rw-r--r--c/src/lib/libcpu/i386/displayCpu.c3
10 files changed, 258 insertions, 20 deletions
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 <rtems/system.h>
#include <rtems/score/isr.h>
+#include <bspIo.h>
+#include <rtems/score/thread.h>
+
/* _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 (&currentIdtEntry, &limit);
+
+ _CPU_ISR_Disable(level);
+ for (j = 0; j < i; j++) {
+ create_interrupt_gate_descriptor (&currentIdtEntry[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 <bsp.h>
#include <irq.h>
-
+#include <rtems/score/thread.h>
+#include <rtems/score/apiext.h>
+
/*
* 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 <irq_asm.h>
+ 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 <libcpu/cpu.h>
#include <string.h>
#include <libcpu/cpuModel.h>
-
-extern void printk(const char*, ...);
+#include <bspIo.h>
unsigned char Cx86_step = 0;
static const char *Cx86_type[] = {