source: rtems/cpukit/score/cpu/i386/rtems/score/cpu.h @ 84c53452

4.104.114.84.95
Last change on this file since 84c53452 was 84c53452, checked in by Ralf Corsepius <ralf.corsepius@…>, on Apr 16, 2004 at 11:08:36 AM

Remove stray white spaces.

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