source: rtems/cpukit/score/cpu/i386/cpu.c @ 42e243e

4.104.115
Last change on this file since 42e243e was 42e243e, checked in by Ralf Corsepius <ralf.corsepius@…>, on 12/04/09 at 04:27:21

Whitespace removal.

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