source: rtems/cpukit/score/cpu/i386/rtems/score/cpu.h @ 020363d

4.104.11
Last change on this file since 020363d was 020363d, checked in by Till Straumann <strauman@…>, on Oct 20, 2009 at 2:51:37 PM

2009-10-20 Till Straumann <strauman@…>

  • score/cpu/i386/cpu.c, score/cpu/i386/cpu.h: let the default exception handler print a stack trace.
  • Property mode set to 100644
File size: 11.7 KB
Line 
1/**
2 * @file rtems/score/cpu.h
3 */
4
5/*
6 *  This include file contains information pertaining to the Intel
7 *  i386 processor.
8 *
9 *  COPYRIGHT (c) 1989-2008.
10 *  On-Line Applications Research Corporation (OAR).
11 *
12 *  The license and distribution terms for this file may be
13 *  found in the file LICENSE in this distribution or at
14 *  http://www.rtems.com/license/LICENSE.
15 *
16 *  $Id$
17 */
18
19#ifndef _RTEMS_SCORE_CPU_H
20#define _RTEMS_SCORE_CPU_H
21
22#include <string.h> /* for memcpy */
23
24#ifdef __cplusplus
25extern "C" {
26#endif
27
28#include <rtems/score/i386.h>              /* pick up machine definitions */
29
30#ifndef ASM
31#include <rtems/score/types.h>
32#include <rtems/score/interrupts.h>     /* formerly in libcpu/cpu.h> */
33#include <rtems/score/registers.h>      /* formerly part of libcpu */
34#endif
35
36/* conditional compilation parameters */
37
38#define CPU_INLINE_ENABLE_DISPATCH       TRUE
39#define CPU_UNROLL_ENQUEUE_PRIORITY      FALSE
40
41/*
42 *  i386 has an RTEMS allocated and managed interrupt stack.
43 */
44
45#define CPU_HAS_SOFTWARE_INTERRUPT_STACK TRUE
46#define CPU_HAS_HARDWARE_INTERRUPT_STACK FALSE
47#define CPU_ALLOCATE_INTERRUPT_STACK     TRUE
48
49/*
50 *  Does the RTEMS invoke the user's ISR with the vector number and
51 *  a pointer to the saved interrupt frame (1) or just the vector
52 *  number (0)?
53 */
54
55#define CPU_ISR_PASSES_FRAME_POINTER 0
56
57/*
58 *  Some family members have no FP, some have an FPU such as the i387
59 *  for the i386, others have it built in (i486DX, Pentium).
60 */
61
62#if ( I386_HAS_FPU == 1 )
63#define CPU_HARDWARE_FP     TRUE    /* i387 for i386 */
64#else
65#define CPU_HARDWARE_FP     FALSE
66#endif
67#define CPU_SOFTWARE_FP     FALSE
68
69#define CPU_ALL_TASKS_ARE_FP             FALSE
70#define CPU_IDLE_TASK_IS_FP              FALSE
71#define CPU_USE_DEFERRED_FP_SWITCH       TRUE
72
73#define CPU_STACK_GROWS_UP               FALSE
74#define CPU_STRUCTURE_ALIGNMENT
75
76/*
77 *  Does this port provide a CPU dependent IDLE task implementation?
78 *
79 *  If TRUE, then the routine _CPU_Thread_Idle_body
80 *  must be provided and is the default IDLE thread body instead of
81 *  _CPU_Thread_Idle_body.
82 *
83 *  If FALSE, then use the generic IDLE thread body if the BSP does
84 *  not provide one.
85 */
86
87#define CPU_PROVIDES_IDLE_THREAD_BODY    TRUE
88
89/*
90 *  Define what is required to specify how the network to host conversion
91 *  routines are handled.
92 */
93
94#define CPU_BIG_ENDIAN                           FALSE
95#define CPU_LITTLE_ENDIAN                        TRUE
96
97/* structures */
98
99/*
100 *  Basic integer context for the i386 family.
101 */
102
103typedef struct {
104  uint32_t    eflags;   /* extended flags register                   */
105  void       *esp;      /* extended stack pointer register           */
106  void       *ebp;      /* extended base pointer register            */
107  uint32_t    ebx;      /* extended bx register                      */
108  uint32_t    esi;      /* extended source index register            */
109  uint32_t    edi;      /* extended destination index flags register */
110}   Context_Control;
111
112#define _CPU_Context_Get_SP( _context ) \
113  (_context)->esp
114
115/*
116 *  FP context save area for the i387 numeric coprocessors.
117 */
118
119typedef struct {
120  uint8_t     fp_save_area[108];    /* context size area for I80387 */
121                                    /*  28 bytes for environment    */
122} Context_Control_fp;
123
124
125/*
126 *  The following structure defines the set of information saved
127 *  on the current stack by RTEMS upon receipt of execptions.
128 *
129 * idtIndex is either the interrupt number or the trap/exception number.
130 * faultCode is the code pushed by the processor on some exceptions.
131 */
132
133typedef struct {
134  uint32_t    edi;
135  uint32_t    esi;
136  uint32_t    ebp;
137  uint32_t    esp0;
138  uint32_t    ebx;
139  uint32_t    edx;
140  uint32_t    ecx;
141  uint32_t    eax;
142  uint32_t    idtIndex;
143  uint32_t    faultCode;
144  uint32_t    eip;
145  uint32_t    cs;
146  uint32_t    eflags;
147} CPU_Exception_frame;
148
149typedef void (*cpuExcHandlerType) (CPU_Exception_frame*);
150extern cpuExcHandlerType _currentExcHandler;
151extern void rtems_exception_init_mngt(void);
152
153/*
154 *  The following structure defines the set of information saved
155 *  on the current stack by RTEMS upon receipt of each interrupt
156 *  that will lead to re-enter the kernel to signal the thread.
157 */
158
159typedef CPU_Exception_frame CPU_Interrupt_frame;
160
161typedef enum {
162  I386_EXCEPTION_DIVIDE_BY_ZERO      = 0,
163  I386_EXCEPTION_DEBUG               = 1,
164  I386_EXCEPTION_NMI                 = 2,
165  I386_EXCEPTION_BREAKPOINT          = 3,
166  I386_EXCEPTION_OVERFLOW            = 4,
167  I386_EXCEPTION_BOUND               = 5,
168  I386_EXCEPTION_ILLEGAL_INSTR       = 6,
169  I386_EXCEPTION_MATH_COPROC_UNAVAIL = 7,
170  I386_EXCEPTION_DOUBLE_FAULT        = 8,
171  I386_EXCEPTION_I386_COPROC_SEG_ERR = 9,
172  I386_EXCEPTION_INVALID_TSS         = 10,
173  I386_EXCEPTION_SEGMENT_NOT_PRESENT = 11,
174  I386_EXCEPTION_STACK_SEGMENT_FAULT = 12,
175  I386_EXCEPTION_GENERAL_PROT_ERR    = 13,
176  I386_EXCEPTION_PAGE_FAULT          = 14,
177  I386_EXCEPTION_INTEL_RES15         = 15,
178  I386_EXCEPTION_FLOAT_ERROR         = 16,
179  I386_EXCEPTION_ALIGN_CHECK         = 17,
180  I386_EXCEPTION_MACHINE_CHECK       = 18,
181  I386_EXCEPTION_ENTER_RDBG          = 50     /* to enter manually RDBG */
182
183} Intel_symbolic_exception_name;
184
185
186/*
187 *  context size area for floating point
188 *
189 *  NOTE:  This is out of place on the i386 to avoid a forward reference.
190 */
191
192#define CPU_CONTEXT_FP_SIZE sizeof( Context_Control_fp )
193
194/* variables */
195
196SCORE_EXTERN Context_Control_fp  _CPU_Null_fp_context;
197SCORE_EXTERN void               *_CPU_Interrupt_stack_low;
198SCORE_EXTERN void               *_CPU_Interrupt_stack_high;
199
200/* constants */
201
202/*
203 *  This defines the number of levels and the mask used to pick those
204 *  bits out of a thread mode.
205 */
206
207#define CPU_MODES_INTERRUPT_LEVEL  0x00000001 /* interrupt level in mode */
208#define CPU_MODES_INTERRUPT_MASK   0x00000001 /* interrupt level in mode */
209
210/*
211 *  extra stack required by the MPCI receive server thread
212 */
213
214#define CPU_MPCI_RECEIVE_SERVER_EXTRA_STACK 1024
215
216/*
217 *  i386 family supports 256 distinct vectors.
218 */
219
220#define CPU_INTERRUPT_NUMBER_OF_VECTORS      256
221#define CPU_INTERRUPT_MAXIMUM_VECTOR_NUMBER  (CPU_INTERRUPT_NUMBER_OF_VECTORS - 1)
222
223/*
224 *  This is defined if the port has a special way to report the ISR nesting
225 *  level.  Most ports maintain the variable _ISR_Nest_level.
226 */
227
228#define CPU_PROVIDES_ISR_IS_IN_PROGRESS FALSE
229
230/*
231 *  Minimum size of a thread's stack.
232 */
233
234#define CPU_STACK_MINIMUM_SIZE          4096
235
236/*
237 *  i386 is pretty tolerant of alignment.  Just put things on 4 byte boundaries.
238 */
239
240#define CPU_ALIGNMENT                    4
241#define CPU_HEAP_ALIGNMENT               CPU_ALIGNMENT
242#define CPU_PARTITION_ALIGNMENT          CPU_ALIGNMENT
243
244/*
245 *  On i386 thread stacks require no further alignment after allocation
246 *  from the Workspace.
247 */
248
249#define CPU_STACK_ALIGNMENT             0
250
251/* macros */
252
253/*
254 *  ISR handler macros
255 *
256 *  These macros perform the following functions:
257 *     + initialize the RTEMS vector table
258 *     + disable all maskable CPU interrupts
259 *     + restore previous interrupt level (enable)
260 *     + temporarily restore interrupts (flash)
261 *     + set a particular level
262 */
263
264#define _CPU_Initialize_vectors()
265
266#define _CPU_ISR_Disable( _level ) i386_disable_interrupts( _level )
267
268#define _CPU_ISR_Enable( _level )  i386_enable_interrupts( _level )
269
270#define _CPU_ISR_Flash( _level )   i386_flash_interrupts( _level )
271
272#define _CPU_ISR_Set_level( _new_level ) \
273  { \
274    if ( _new_level ) asm volatile ( "cli" ); \
275    else              asm volatile ( "sti" ); \
276  }
277
278uint32_t   _CPU_ISR_Get_level( void );
279
280/* end of ISR handler macros */
281
282/*
283 *  Context handler macros
284 *
285 *  These macros perform the following functions:
286 *     + initialize a context area
287 *     + restart the current thread
288 *     + calculate the initial pointer into a FP context area
289 *     + initialize an FP context area
290 */
291
292#define CPU_EFLAGS_INTERRUPTS_ON  0x00003202
293#define CPU_EFLAGS_INTERRUPTS_OFF 0x00003002
294
295#define _CPU_Context_Initialize( _the_context, _stack_base, _size, \
296                                   _isr, _entry_point, _is_fp ) \
297  do { \
298    uint32_t   _stack; \
299    \
300    if ( (_isr) ) (_the_context)->eflags = CPU_EFLAGS_INTERRUPTS_OFF; \
301    else          (_the_context)->eflags = CPU_EFLAGS_INTERRUPTS_ON; \
302    \
303    _stack = ((uint32_t)(_stack_base)) + (_size) - sizeof(proc_ptr*); \
304    \
305    *((proc_ptr *)(_stack)) = (_entry_point); \
306    (_the_context)->ebp     = (void *) 0; \
307    (_the_context)->esp     = (void *) _stack; \
308  } while (0)
309
310#define _CPU_Context_Restart_self( _the_context ) \
311   _CPU_Context_restore( (_the_context) );
312
313#define _CPU_Context_Fp_start( _base, _offset ) \
314   ( (void *) _Addresses_Add_offset( (_base), (_offset) ) )
315
316#define _CPU_Context_Initialize_fp( _fp_area ) \
317  { \
318    memcpy( *_fp_area, &_CPU_Null_fp_context, CPU_CONTEXT_FP_SIZE ); \
319  }
320
321/* end of Context handler macros */
322
323/*
324 *  Fatal Error manager macros
325 *
326 *  These macros perform the following functions:
327 *    + disable interrupts and halt the CPU
328 */
329
330#define _CPU_Fatal_halt( _error ) \
331  { \
332    asm volatile ( "cli ; \
333                    movl %0,%%eax ; \
334                    hlt" \
335                    : "=r" ((_error)) : "0" ((_error)) \
336    ); \
337  }
338
339/* end of Fatal Error manager macros */
340
341/*
342 *  Bitfield handler macros
343 *
344 *  These macros perform the following functions:
345 *     + scan for the highest numbered (MSB) set in a 16 bit bitfield
346 */
347
348#define CPU_USE_GENERIC_BITFIELD_CODE FALSE
349#define CPU_USE_GENERIC_BITFIELD_DATA FALSE
350
351#define _CPU_Bitfield_Find_first_bit( _value, _output ) \
352  { \
353    register uint16_t   __value_in_register = (_value); \
354    \
355    _output = 0; \
356    \
357    asm volatile ( "bsfw    %0,%1 " \
358                    : "=r" (__value_in_register), "=r" (_output) \
359                    : "0"  (__value_in_register), "1"  (_output) \
360    ); \
361  }
362
363/* end of Bitfield handler macros */
364
365/*
366 *  Priority handler macros
367 *
368 *  These macros perform the following functions:
369 *    + return a mask with the bit for this major/minor portion of
370 *      of thread priority set.
371 *    + translate the bit number returned by "Bitfield_find_first_bit"
372 *      into an index into the thread ready chain bit maps
373 */
374
375#define _CPU_Priority_Mask( _bit_number ) \
376  ( 1 << (_bit_number) )
377
378#define _CPU_Priority_bits_index( _priority ) \
379  (_priority)
380
381/* functions */
382
383/*
384 *  _CPU_Initialize
385 *
386 *  This routine performs CPU dependent initialization.
387 */
388
389void _CPU_Initialize(void);
390
391/*
392 *  _CPU_ISR_install_raw_handler
393 *
394 *  This routine installs a "raw" interrupt handler directly into the
395 *  processor's vector table.
396 */
397
398void _CPU_ISR_install_raw_handler(
399  uint32_t    vector,
400  proc_ptr    new_handler,
401  proc_ptr   *old_handler
402);
403
404/*
405 *  _CPU_ISR_install_vector
406 *
407 *  This routine installs an interrupt vector.
408 */
409
410void _CPU_ISR_install_vector(
411  uint32_t    vector,
412  proc_ptr    new_handler,
413  proc_ptr   *old_handler
414);
415
416/*
417 *  _CPU_Thread_Idle_body
418 *
419 *  Use the halt instruction of low power mode of a particular i386 model.
420 */
421
422#if (CPU_PROVIDES_IDLE_THREAD_BODY == TRUE)
423
424void *_CPU_Thread_Idle_body( uintptr_t ignored );
425
426#endif /* CPU_PROVIDES_IDLE_THREAD_BODY */
427
428/*
429 *  _CPU_Context_switch
430 *
431 *  This routine switches from the run context to the heir context.
432 */
433
434void _CPU_Context_switch(
435  Context_Control  *run,
436  Context_Control  *heir
437);
438
439/*
440 *  _CPU_Context_restore
441 *
442 *  This routine is generally used only to restart self in an
443 *  efficient manner and avoid stack conflicts.
444 */
445
446void _CPU_Context_restore(
447  Context_Control *new_context
448) RTEMS_COMPILER_NO_RETURN_ATTRIBUTE;
449
450/*
451 *  _CPU_Context_save_fp
452 *
453 *  This routine saves the floating point context passed to it.
454 */
455
456void _CPU_Context_save_fp(
457  Context_Control_fp **fp_context_ptr
458);
459
460/*
461 *  _CPU_Context_restore_fp
462 *
463 *  This routine restores the floating point context passed to it.
464 */
465
466void _CPU_Context_restore_fp(
467  Context_Control_fp **fp_context_ptr
468);
469
470#ifdef __cplusplus
471}
472#endif
473
474#endif
Note: See TracBrowser for help on using the repository browser.