source: rtems/cpukit/score/cpu/i386/rtems/score/cpu.h @ 7f70d1b7

4.104.114.84.95
Last change on this file since 7f70d1b7 was 7f70d1b7, checked in by Ralf Corsepius <ralf.corsepius@…>, on 01/28/05 at 15:56:09

New header guard.

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