source: rtems/cpukit/score/cpu/i386/cpu.c @ 67cc389

4.115
Last change on this file since 67cc389 was 67cc389, checked in by Ralf Corsepius <ralf.corsepius@…>, on 12/09/11 at 14:07:58

2011-12-09 Ralf Corsépius <ralf.corsepius@…>

  • cpu.c: Make _defaultExcHandler static.
  • Property mode set to 100644
File size: 6.6 KB
Line 
1/*
2 *  Intel i386 Dependent Source
3 *
4 *  COPYRIGHT (c) 1989-1999.
5 *  On-Line Applications Research Corporation (OAR).
6 *
7 *  The license and distribution terms for this file may be
8 *  found in the file LICENSE in this distribution or at
9 *  http://www.rtems.com/license/LICENSE.
10 *
11 *  $Id$
12 */
13
14#ifdef HAVE_CONFIG_H
15#include "config.h"
16#endif
17
18#include <rtems.h>
19#include <rtems/system.h>
20#include <rtems/score/types.h>
21#include <rtems/score/isr.h>
22#include <rtems/score/idtr.h>
23
24#include <rtems/bspIo.h>
25#include <rtems/score/thread.h>
26
27/*  _CPU_Initialize
28 *
29 *  This routine performs processor dependent initialization.
30 *
31 *  INPUT PARAMETERS: NONE
32 */
33
34void _CPU_Initialize(void)
35{
36#if CPU_HARDWARE_FP
37  register uint16_t             fp_status __asm__ ("ax");
38  register Context_Control_fp  *fp_context;
39#endif
40
41  /*
42   *  The following code saves a NULL i387 context which is given
43   *  to each task at start and restart time.  The following code
44   *  is based upon that provided in the i386 Programmer's
45   *  Manual and should work on any coprocessor greater than
46   *  the i80287.
47   *
48   *  NOTE: The NO WAIT form of the coprocessor instructions
49   *        MUST be used in case there is not a coprocessor
50   *        to wait for.
51   */
52
53#if CPU_HARDWARE_FP
54  fp_status = 0xa5a5;
55  __asm__ volatile( "fninit" );
56  __asm__ volatile( "fnstsw %0" : "=a" (fp_status) : "0" (fp_status) );
57
58  if ( fp_status ==  0 ) {
59
60    fp_context = &_CPU_Null_fp_context;
61
62#ifdef __SSE__
63        asm volatile( "fstcw %0":"=m"(fp_context->fpucw) );
64#else
65    __asm__ volatile( "fsave (%0)" : "=r" (fp_context)
66                               : "0"  (fp_context)
67                );
68#endif
69  }
70#endif
71
72#ifdef __SSE__
73
74  __asm__ volatile("stmxcsr %0":"=m"(fp_context->mxcsr));
75
76  /* The BSP must enable the SSE extensions (early).
77   * If any SSE instruction was already attempted
78   * then that crashed the system.
79   * As a courtesy, we double-check here but it
80   * may be too late (which is also why we don't
81   * enable SSE here).
82   */
83  {
84  uint32_t cr4;
85    __asm__ __volatile__("mov %%cr4, %0":"=r"(cr4));
86    if ( 0x600 != (cr4 & 0x600) ) {
87      printk("PANIC: RTEMS was compiled for SSE but BSP did not enable it (CR4: 0x%08x)\n", cr4);
88      while ( 1 ) {
89        __asm__ __volatile__("hlt");
90          }
91        }
92  }
93#endif
94}
95
96/*
97 *  _CPU_ISR_Get_level
98 */
99
100uint32_t   _CPU_ISR_Get_level( void )
101{
102  uint32_t   level;
103
104  i386_get_interrupt_level( level );
105
106  return level;
107}
108
109void *_CPU_Thread_Idle_body( uintptr_t ignored )
110{
111  while(1){
112    __asm__ volatile ("hlt");
113  }
114  return NULL;
115}
116
117struct Frame_ {
118        struct Frame_  *up;
119        uintptr_t               pc;
120};
121
122static void _defaultExcHandler (CPU_Exception_frame *ctx)
123{
124  unsigned int faultAddr = 0;
125  printk("----------------------------------------------------------\n");
126  printk("Exception %d caught at PC %x by thread %d\n",
127         ctx->idtIndex,
128         ctx->eip,
129         _Thread_Executing->Object.id);
130  printk("----------------------------------------------------------\n");
131  printk("Processor execution context at time of the fault was  :\n");
132  printk("----------------------------------------------------------\n");
133  printk(" EAX = %x     EBX = %x        ECX = %x        EDX = %x\n",
134         ctx->eax, ctx->ebx, ctx->ecx, ctx->edx);
135  printk(" ESI = %x     EDI = %x        EBP = %x        ESP = %x\n",
136         ctx->esi, ctx->edi, ctx->ebp, ctx->esp0);
137  printk("----------------------------------------------------------\n");
138  printk("Error code pushed by processor itself (if not 0) = %x\n",
139         ctx->faultCode);
140  printk("----------------------------------------------------------\n");
141  if (ctx->idtIndex == I386_EXCEPTION_PAGE_FAULT){
142    faultAddr = i386_get_cr2();
143    printk("Page fault linear address (CR2) = %x\n", faultAddr);
144    printk("----------------------------------------------------------\n\n");
145  }
146 if (_ISR_Nest_level > 0) {
147    /*
148     * In this case we shall not delete the task interrupted as
149     * it has nothing to do with the fault. We cannot return either
150     * because the eip points to the faulty instruction so...
151     */
152    printk("Exception while executing ISR!!!. System locked\n");
153    _CPU_Fatal_halt(faultAddr);
154  }
155  else {
156        struct Frame_ *fp = (struct Frame_*)ctx->ebp;
157        int           i;
158
159        printk("Call Stack Trace of EIP:\n");
160        if ( fp ) {
161                for ( i=1; fp->up; fp=fp->up, i++ ) {
162                        printk("0x%08x ",fp->pc);
163                        if ( ! (i&3) )
164                                printk("\n");
165                }
166        }
167        printk("\n");
168    /*
169     * OK I could probably use a simplified version but at least this
170     * should work.
171     */
172#if 0
173    printk(" ************ FAULTY THREAD WILL BE SUSPENDED **************\n");
174    rtems_task_suspend(_Thread_Executing->Object.id);
175#endif
176    bsp_reset();
177  }
178}
179
180cpuExcHandlerType _currentExcHandler = _defaultExcHandler;
181
182extern void rtems_exception_prologue_0(void);
183extern void rtems_exception_prologue_1(void);
184extern void rtems_exception_prologue_2(void);
185extern void rtems_exception_prologue_3(void);
186extern void rtems_exception_prologue_4(void);
187extern void rtems_exception_prologue_5(void);
188extern void rtems_exception_prologue_6(void);
189extern void rtems_exception_prologue_7(void);
190extern void rtems_exception_prologue_8(void);
191extern void rtems_exception_prologue_9(void);
192extern void rtems_exception_prologue_10(void);
193extern void rtems_exception_prologue_11(void);
194extern void rtems_exception_prologue_12(void);
195extern void rtems_exception_prologue_13(void);
196extern void rtems_exception_prologue_14(void);
197extern void rtems_exception_prologue_16(void);
198extern void rtems_exception_prologue_17(void);
199extern void rtems_exception_prologue_18(void);
200#ifdef __SSE__
201extern void rtems_exception_prologue_19(void);
202#endif
203
204static rtems_raw_irq_hdl tbl[] = {
205         rtems_exception_prologue_0,
206         rtems_exception_prologue_1,
207         rtems_exception_prologue_2,
208         rtems_exception_prologue_3,
209         rtems_exception_prologue_4,
210         rtems_exception_prologue_5,
211         rtems_exception_prologue_6,
212         rtems_exception_prologue_7,
213         rtems_exception_prologue_8,
214         rtems_exception_prologue_9,
215         rtems_exception_prologue_10,
216         rtems_exception_prologue_11,
217         rtems_exception_prologue_12,
218         rtems_exception_prologue_13,
219         rtems_exception_prologue_14,
220     0,
221         rtems_exception_prologue_16,
222         rtems_exception_prologue_17,
223         rtems_exception_prologue_18,
224#ifdef __SSE__
225         rtems_exception_prologue_19,
226#endif
227};
228
229void rtems_exception_init_mngt(void)
230{
231      size_t                     i,j;
232      interrupt_gate_descriptor  *currentIdtEntry;
233      unsigned                   limit;
234      unsigned                   level;
235
236      i = sizeof(tbl) / sizeof (rtems_raw_irq_hdl);
237
238      i386_get_info_from_IDTR (&currentIdtEntry, &limit);
239
240      _CPU_ISR_Disable(level);
241      for (j = 0; j < i; j++) {
242        create_interrupt_gate_descriptor (&currentIdtEntry[j], tbl[j]);
243      }
244      _CPU_ISR_Enable(level);
245}
Note: See TracBrowser for help on using the repository browser.