source: rtems/cpukit/score/cpu/i386/cpu.c @ cca8379

4.104.11
Last change on this file since cca8379 was cca8379, checked in by Joel Sherrill <joel.sherrill@…>, on Feb 12, 2009 at 3:55:55 PM

2009-02-12 Joel Sherrill <joel.sherrill@…>

  • cpu.c, rtems/score/cpu.h: Change prototype of IDLE thread to consistently return void * and take a uintptr_t argument.
  • Property mode set to 100644
File size: 5.4 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    asm volatile( "fsave (%0)" : "=r" (fp_context)
60                               : "0"  (fp_context)
61                );
62  }
63#endif
64}
65
66/*PAGE
67 *
68 *  _CPU_ISR_Get_level
69 */
70
71uint32_t   _CPU_ISR_Get_level( void )
72{
73  uint32_t   level;
74
75  i386_get_interrupt_level( level );
76
77  return level;
78}
79
80void *_CPU_Thread_Idle_body( uintptr_t ignored )
81{
82  while(1){
83    asm volatile ("hlt");
84  }
85  return NULL;
86}
87
88void _defaultExcHandler (CPU_Exception_frame *ctx)
89{
90  unsigned int faultAddr = 0;
91  printk("----------------------------------------------------------\n");
92  printk("Exception %d caught at PC %x by thread %d\n",
93         ctx->idtIndex,
94         ctx->eip,
95         _Thread_Executing->Object.id);
96  printk("----------------------------------------------------------\n");
97  printk("Processor execution context at time of the fault was  :\n");
98  printk("----------------------------------------------------------\n");
99  printk(" EAX = %x     EBX = %x        ECX = %x        EDX = %x\n",
100         ctx->eax, ctx->ebx, ctx->ecx, ctx->edx);
101  printk(" ESI = %x     EDI = %x        EBP = %x        ESP = %x\n",
102         ctx->esi, ctx->edi, ctx->ebp, ctx->esp0);
103  printk("----------------------------------------------------------\n");
104  printk("Error code pushed by processor itself (if not 0) = %x\n",
105         ctx->faultCode);
106  printk("----------------------------------------------------------\n");
107  if (ctx->idtIndex == I386_EXCEPTION_PAGE_FAULT){
108    faultAddr = i386_get_cr2();
109    printk("Page fault linear address (CR2) = %x\n", faultAddr);
110    printk("----------------------------------------------------------\n\n");
111  }
112 if (_ISR_Nest_level > 0) {
113    /*
114     * In this case we shall not delete the task interrupted as
115     * it has nothing to do with the fault. We cannot return either
116     * because the eip points to the faulty instruction so...
117     */
118    printk("Exception while executing ISR!!!. System locked\n");
119    _CPU_Fatal_halt(faultAddr);
120  }
121  else {
122    /*
123     * OK I could probably use a simplified version but at least this
124     * should work.
125     */
126    printk(" ************ FAULTY THREAD WILL BE DELETED **************\n");
127    rtems_task_delete(_Thread_Executing->Object.id);
128  }
129}
130
131cpuExcHandlerType _currentExcHandler = _defaultExcHandler;
132
133extern void rtems_exception_prologue_0(void);
134extern void rtems_exception_prologue_1(void);
135extern void rtems_exception_prologue_2(void);
136extern void rtems_exception_prologue_3(void);
137extern void rtems_exception_prologue_4(void);
138extern void rtems_exception_prologue_5(void);
139extern void rtems_exception_prologue_6(void);
140extern void rtems_exception_prologue_7(void);
141extern void rtems_exception_prologue_8(void);
142extern void rtems_exception_prologue_9(void);
143extern void rtems_exception_prologue_10(void);
144extern void rtems_exception_prologue_11(void);
145extern void rtems_exception_prologue_12(void);
146extern void rtems_exception_prologue_13(void);
147extern void rtems_exception_prologue_14(void);
148extern void rtems_exception_prologue_16(void);
149extern void rtems_exception_prologue_17(void);
150extern void rtems_exception_prologue_18(void);
151
152static rtems_raw_irq_hdl tbl[] = {
153         rtems_exception_prologue_0,
154         rtems_exception_prologue_1,
155         rtems_exception_prologue_2,
156         rtems_exception_prologue_3,
157         rtems_exception_prologue_4,
158         rtems_exception_prologue_5,
159         rtems_exception_prologue_6,
160         rtems_exception_prologue_7,
161         rtems_exception_prologue_8,
162         rtems_exception_prologue_9,
163         rtems_exception_prologue_10,
164         rtems_exception_prologue_11,
165         rtems_exception_prologue_12,
166         rtems_exception_prologue_13,
167         rtems_exception_prologue_14,
168         rtems_exception_prologue_16,
169         rtems_exception_prologue_17,
170         rtems_exception_prologue_18,
171};
172
173void rtems_exception_init_mngt(void)
174{
175      size_t                     i,j;
176      interrupt_gate_descriptor  *currentIdtEntry;
177      unsigned                   limit;
178      unsigned                   level;
179
180      i = sizeof(tbl) / sizeof (rtems_raw_irq_hdl);
181
182      i386_get_info_from_IDTR (&currentIdtEntry, &limit);
183
184      _CPU_ISR_Disable(level);
185      for (j = 0; j < i; j++) {
186        create_interrupt_gate_descriptor (&currentIdtEntry[j], tbl[j]);
187      }
188      _CPU_ISR_Enable(level);
189}
Note: See TracBrowser for help on using the repository browser.