source: rtems/cpukit/score/cpu/m68k/rtems/score/cpu.h @ 458bd34

4.104.114.84.95
Last change on this file since 458bd34 was 458bd34, checked in by Joel Sherrill <joel.sherrill@…>, on 11/05/99 at 16:44:02

This is another pass at making sure that nothing outside the BSP
unnecessarily uses any variables defined by the BSP. On this
sweep, use of BSP_Configuration and Cpu_table was eliminated.

A significant part of this modification was the addition of
macros to access fields in the RTEMS configuration structures.

This is necessary to strengthen the division between the BSP independent
parts of RTEMS and the BSPs themselves. This started after
comments and analysis by Ralf Corsepius <corsepiu@…>.

  • Property mode set to 100644
File size: 17.1 KB
Line 
1/*  cpu.h
2 *
3 *  This include file contains information pertaining to the Motorola
4 *  m68xxx processor family.
5 *
6 *  COPYRIGHT (c) 1989-1998.
7 *  On-Line Applications Research Corporation (OAR).
8 *  Copyright assigned to U.S. Government, 1994.
9 *
10 *  The license and distribution terms for this file may be
11 *  found in the file LICENSE in this distribution or at
12 *  http://www.OARcorp.com/rtems/license.html.
13 *
14 *  $Id$
15 */
16
17#ifndef __CPU_h
18#define __CPU_h
19
20#ifdef __cplusplus
21extern "C" {
22#endif
23
24#include <rtems/score/m68k.h>              /* pick up machine definitions */
25#ifndef ASM
26#include <rtems/score/m68ktypes.h>
27#endif
28
29/* conditional compilation parameters */
30
31#define CPU_INLINE_ENABLE_DISPATCH       TRUE
32#define CPU_UNROLL_ENQUEUE_PRIORITY      FALSE
33
34/*
35 *  Use the m68k's hardware interrupt stack support and have the
36 *  interrupt manager allocate the memory for it.
37 */
38
39#if ( M68K_HAS_SEPARATE_STACKS == 1)
40#define CPU_HAS_SOFTWARE_INTERRUPT_STACK 0
41#define CPU_HAS_HARDWARE_INTERRUPT_STACK 1
42#else
43#define CPU_HAS_SOFTWARE_INTERRUPT_STACK 1
44#define CPU_HAS_HARDWARE_INTERRUPT_STACK 0
45#endif
46#define CPU_ALLOCATE_INTERRUPT_STACK     1
47
48/*
49 *  Does the RTEMS invoke the user's ISR with the vector number and
50 *  a pointer to the saved interrupt frame (1) or just the vector
51 *  number (0)?
52 */
53
54#define CPU_ISR_PASSES_FRAME_POINTER 0
55
56/*
57 *  Some family members have no FP, some have an FPU such as the
58 *  MC68881/MC68882 for the MC68020, others have it built in (MC68030, 040).
59 *
60 *  NOTE:  If on a CPU without hardware FP, then one can use software
61 *         emulation.  The gcc software FP emulation code has data which
62 *         must be contexted switched on a per task basis.
63 */
64
65#if ( M68K_HAS_FPU == 1 )
66#define CPU_HARDWARE_FP     TRUE
67#define CPU_SOFTWARE_FP     FALSE
68#else
69#define CPU_HARDWARE_FP     FALSE
70#if defined(__GCC__)
71#define CPU_SOFTWARE_FP     TRUE
72#else
73#define CPU_SOFTWARE_FP     FALSE
74#endif
75#endif
76
77/*
78 *  All tasks are not by default floating point tasks on this CPU.
79 *  The IDLE task does not have a floating point context on this CPU.
80 *  It is safe to use the deferred floating point context switch
81 *  algorithm on this CPU.
82 */
83
84#define CPU_ALL_TASKS_ARE_FP             FALSE
85#define CPU_IDLE_TASK_IS_FP              FALSE
86#define CPU_USE_DEFERRED_FP_SWITCH       TRUE
87
88#define CPU_PROVIDES_IDLE_THREAD_BODY    FALSE
89#define CPU_STACK_GROWS_UP               FALSE
90#define CPU_STRUCTURE_ALIGNMENT
91
92/*
93 *  Define what is required to specify how the network to host conversion
94 *  routines are handled.
95 */
96
97#define CPU_HAS_OWN_HOST_TO_NETWORK_ROUTINES     FALSE
98#define CPU_BIG_ENDIAN                           TRUE
99#define CPU_LITTLE_ENDIAN                        FALSE
100
101#ifndef ASM
102/* structures */
103
104/*
105 *  Basic integer context for the m68k family.
106 */
107
108typedef struct {
109  unsigned32  sr;                /* (sr) status register */
110  unsigned32  d2;                /* (d2) data register 2 */
111  unsigned32  d3;                /* (d3) data register 3 */
112  unsigned32  d4;                /* (d4) data register 4 */
113  unsigned32  d5;                /* (d5) data register 5 */
114  unsigned32  d6;                /* (d6) data register 6 */
115  unsigned32  d7;                /* (d7) data register 7 */
116  void       *a2;                /* (a2) address register 2 */
117  void       *a3;                /* (a3) address register 3 */
118  void       *a4;                /* (a4) address register 4 */
119  void       *a5;                /* (a5) address register 5 */
120  void       *a6;                /* (a6) address register 6 */
121  void       *a7_msp;            /* (a7) master stack pointer */
122}   Context_Control;
123
124/*
125 *  Floating point context ares
126 */
127
128#if (CPU_SOFTWARE_FP == TRUE)
129
130/*
131 *  This is the same as gcc's view of the software FP condition code
132 *  register _fpCCR.  The implementation of the emulation code is
133 *  in the gcc-VERSION/config/m68k directory.  This structure is
134 *  correct as of gcc 2.7.2.2.
135 */
136
137typedef struct {
138  unsigned16   _exception_bits;
139  unsigned16   _trap_enable_bits;
140  unsigned16   _sticky_bits;
141  unsigned16   _rounding_mode;
142  unsigned16   _format;
143  unsigned16   _last_operation;
144  union {
145    float sf;
146    double df;
147  } _operand1;
148  union {
149    float sf;
150    double df;
151  } _operand2;
152} Context_Control_fp;
153
154#else
155
156/*
157 *  FP context save area for the M68881/M68882 numeric coprocessors.
158 */
159
160typedef struct {
161  unsigned8   fp_save_area[332];    /*   216 bytes for FSAVE/FRESTORE    */
162                                    /*    96 bytes for FMOVEM FP0-7      */
163                                    /*    12 bytes for FMOVEM CREGS      */
164                                    /*     4 bytes for non-null flag     */
165} Context_Control_fp;
166#endif
167
168/*
169 *  The following structure defines the set of information saved
170 *  on the current stack by RTEMS upon receipt of each interrupt.
171 */
172
173typedef struct {
174  unsigned32   TBD;   /* XXX Fix for this CPU */
175} CPU_Interrupt_frame;
176
177/*
178 *  The following table contains the information required to configure
179 *  the m68k specific parameters.
180 */
181
182typedef struct {
183  void       (*pretasking_hook)( void );
184  void       (*predriver_hook)( void );
185  void       (*postdriver_hook)( void );
186  void       (*idle_task)( void );
187  boolean      do_zero_of_workspace;
188  unsigned32   idle_task_stack_size;
189  unsigned32   interrupt_stack_size;
190  unsigned32   extra_mpci_receive_server_stack;
191  void *     (*stack_allocate_hook)( unsigned32 );
192  void       (*stack_free_hook)( void* );
193  /* end of fields required on all CPUs */
194
195  m68k_isr    *interrupt_vector_table;
196}   rtems_cpu_table;
197
198/*
199 *  Macros to access required entires in the CPU Table are in
200 *  the file rtems/system.h.
201 */
202
203/*
204 *  Macros to access M68K specific additions to the CPU Table
205 */
206
207#define rtems_cpu_configuration_get_interrupt_vector_table() \
208   (_CPU_Table.interrupt_vector_table)
209
210/* variables */
211
212SCORE_EXTERN void                   *_CPU_Interrupt_stack_low;
213SCORE_EXTERN void                   *_CPU_Interrupt_stack_high;
214
215extern char                         _VBR[];
216
217#if ( M68K_HAS_VBR == 0 )
218
219/*
220 * Table of ISR handler entries that resides in RAM. The FORMAT/ID is
221 * pushed onto the stack. This is not is the same order as VBR processors.
222 * The ISR handler takes the format and uses it for dispatching the user
223 * handler.
224 *
225 * FIXME : should be moved to below CPU_INTERRUPT_NUMBER_OF_VECTORS
226 *
227 */
228
229typedef struct {
230  unsigned16 move_a7;            /* move #FORMAT_ID,%a7@- */
231  unsigned16 format_id;
232  unsigned16 jmp;                /* jmp  _ISR_Handlers */
233  unsigned32 isr_handler;
234} _CPU_ISR_handler_entry;
235
236#define M68K_MOVE_A7 0x3F3C
237#define M68K_JMP     0x4EF9
238
239      /* points to jsr-exception-table in targets wo/ VBR register */
240SCORE_EXTERN _CPU_ISR_handler_entry _CPU_ISR_jump_table[256];
241
242#endif /* M68K_HAS_VBR */
243#endif /* ASM */
244
245/* constants */
246
247/*
248 *  This defines the number of levels and the mask used to pick those
249 *  bits out of a thread mode.
250 */
251
252#define CPU_MODES_INTERRUPT_LEVEL  0x00000007 /* interrupt level in mode */
253#define CPU_MODES_INTERRUPT_MASK   0x00000007 /* interrupt level in mode */
254
255/*
256 *  context size area for floating point
257 */
258
259#define CPU_CONTEXT_FP_SIZE sizeof( Context_Control_fp )
260
261/*
262 *  extra stack required by the MPCI receive server thread
263 */
264
265#define CPU_MPCI_RECEIVE_SERVER_EXTRA_STACK 1024
266
267/*
268 *  m68k family supports 256 distinct vectors.
269 */
270
271#define CPU_INTERRUPT_NUMBER_OF_VECTORS      256
272#define CPU_INTERRUPT_MAXIMUM_VECTOR_NUMBER  (CPU_INTERRUPT_NUMBER_OF_VECTORS - 1)
273
274/*
275 *  Minimum size of a thread's stack.
276 */
277
278#define CPU_STACK_MINIMUM_SIZE           2048
279
280/*
281 *  m68k is pretty tolerant of alignment.  Just put things on 4 byte boundaries.
282 */
283
284#define CPU_ALIGNMENT                    4
285#define CPU_HEAP_ALIGNMENT               CPU_ALIGNMENT
286#define CPU_PARTITION_ALIGNMENT          CPU_ALIGNMENT
287
288/*
289 *  On m68k thread stacks require no further alignment after allocation
290 *  from the Workspace.
291 */
292
293#define CPU_STACK_ALIGNMENT        0
294
295#ifndef ASM
296
297/* macros */
298
299/*
300 *  ISR handler macros
301 *
302 *  These macros perform the following functions:
303 *     + disable all maskable CPU interrupts
304 *     + restore previous interrupt level (enable)
305 *     + temporarily restore interrupts (flash)
306 *     + set a particular level
307 */
308
309#define _CPU_ISR_Disable( _level ) \
310  m68k_disable_interrupts( _level )
311
312#define _CPU_ISR_Enable( _level ) \
313  m68k_enable_interrupts( _level )
314
315#define _CPU_ISR_Flash( _level ) \
316  m68k_flash_interrupts( _level )
317
318#define _CPU_ISR_Set_level( _newlevel ) \
319   m68k_set_interrupt_level( _newlevel )
320
321unsigned32 _CPU_ISR_Get_level( void );
322
323/* end of ISR handler macros */
324
325/*
326 *  Context handler macros
327 *
328 *  These macros perform the following functions:
329 *     + initialize a context area
330 *     + restart the current thread
331 *     + calculate the initial pointer into a FP context area
332 *     + initialize an FP context area
333 */
334
335#define _CPU_Context_Initialize( _the_context, _stack_base, _size, \
336                                 _isr, _entry_point, _is_fp ) \
337   do { \
338     unsigned32 _stack; \
339     \
340     (_the_context)->sr      = 0x3000 | ((_isr) << 8); \
341     _stack                  = (unsigned32)(_stack_base) + (_size) - 4; \
342     (_the_context)->a7_msp  = (void *)_stack; \
343     *(void **)_stack        = (void *)(_entry_point); \
344   } while ( 0 )
345
346#define _CPU_Context_Restart_self( _the_context ) \
347  { asm volatile( "movew %0,%%sr ; " \
348                  "moval %1,%%a7 ; " \
349                  "rts"  \
350        : "=d" ((_the_context)->sr), "=d" ((_the_context)->a7_msp) \
351        : "0" ((_the_context)->sr), "1" ((_the_context)->a7_msp) ); \
352  }
353
354/*
355 *  Floating Point Context Area Support routines
356 */
357
358#if (CPU_SOFTWARE_FP == TRUE)
359
360/*
361 *  This software FP implementation is only for GCC.
362 */
363
364#define _CPU_Context_Fp_start( _base, _offset ) \
365   ((void *) _Addresses_Add_offset( (_base), (_offset) ) )
366
367
368#define _CPU_Context_Initialize_fp( _fp_area ) \
369   { \
370   Context_Control_fp *_fp; \
371   _fp = *(Context_Control_fp **)_fp_area; \
372   _fp->_exception_bits = 0; \
373   _fp->_trap_enable_bits = 0; \
374   _fp->_sticky_bits = 0; \
375   _fp->_rounding_mode = 0;  /* ROUND_TO_NEAREST */ \
376   _fp->_format = 0;         /* NIL */ \
377   _fp->_last_operation = 0;  /* NOOP */ \
378   _fp->_operand1.df = 0; \
379   _fp->_operand2.df = 0; \
380   }
381#else
382#define _CPU_Context_Fp_start( _base, _offset ) \
383   ((void *) \
384     _Addresses_Add_offset( \
385        (_base), \
386        (_offset) + CPU_CONTEXT_FP_SIZE - 4 \
387     ) \
388   )
389
390#define _CPU_Context_Initialize_fp( _fp_area ) \
391   { unsigned32 *_fp_context = (unsigned32 *)*(_fp_area); \
392     \
393     *(--(_fp_context)) = 0; \
394     *(_fp_area) = (unsigned8 *)(_fp_context); \
395   }
396#endif
397
398/* end of Context handler macros */
399
400/*
401 *  Fatal Error manager macros
402 *
403 *  These macros perform the following functions:
404 *    + disable interrupts and halt the CPU
405 */
406
407#if ( M68K_COLDFIRE_ARCH == 1 )
408#define _CPU_Fatal_halt( _error ) \
409  { asm volatile( "move.w %%sr,%%d0\n\t" \
410                  "or.l %2,%%d0\n\t" \
411                  "move.w %%d0,%%sr\n\t" \
412                  "move.l %1,%%d0\n\t" \
413                  "move.l #0xDEADBEEF,%%d1\n\t" \
414                  "halt" \
415                  : "=g" (_error) \
416                  : "0" (_error), "d"(0x0700) \
417                  : "d0", "d1" ); \
418  }
419#else
420#define _CPU_Fatal_halt( _error ) \
421  { asm volatile( "movl  %0,%%d0; " \
422                  "orw   #0x0700,%%sr; " \
423                  "stop  #0x2700" : "=d" ((_error)) : "0" ((_error)) ); \
424  }
425#endif
426
427/* end of Fatal Error manager macros */
428
429/*
430 *  Bitfield handler macros
431 *
432 *  These macros perform the following functions:
433 *     + scan for the highest numbered (MSB) set in a 16 bit bitfield
434 *
435 *  NOTE:
436 *
437 *    It appears that on the M68020 bitfield are always 32 bits wide
438 *    when in a register.  This code forces the bitfield to be in
439 *    memory (it really always is anyway). This allows us to
440 *    have a real 16 bit wide bitfield which operates "correctly."
441 */
442
443#define CPU_USE_GENERIC_BITFIELD_CODE FALSE
444#define CPU_USE_GENERIC_BITFIELD_DATA FALSE
445
446#if ( M68K_HAS_BFFFO == 1 )
447
448#define _CPU_Bitfield_Find_first_bit( _value, _output ) \
449  asm volatile( "bfffo (%1),#0,#16,%0" : "=d" (_output) : "a" (&_value));
450#else
451
452/* duplicates BFFFO results for 16 bits (i.e., 15-(_priority) in
453   _CPU_Priority_bits_index is not needed), handles the 0 case, and
454   does not molest _value -- jsg */
455#if ( M68K_COLDFIRE_ARCH == 1 )
456#define _CPU_Bitfield_Find_first_bit( _value, _output ) \
457  { \
458    extern const unsigned char __BFFFOtable[256]; \
459    register int dumby; \
460    \
461    asm volatile ( \
462       "   clr.l   %1\n"         \
463       "   move.w  %2,%1\n"      \
464       "   lsr.l   #8,%1\n"      \
465       "   beq.s   1f\n"         \
466       "   move.b  (%3,%1),%0\n" \
467       "   bra.s   0f\n"         \
468       "1: move.w  %2,%1\n"      \
469       "   move.b  (%3,%1),%0\n" \
470       "   addq.l  #8,%0\n"      \
471       "0: and.l   #0xff,%0\n"   \
472       : "=&d" ((_output)), "=&d" ((dumby))    \
473       : "d" ((_value)), "ao" ((__BFFFOtable)) \
474       : "cc" ) ; \
475  }
476#elif ( M68K_HAS_EXTB_L == 1 )
477#define _CPU_Bitfield_Find_first_bit( _value, _output ) \
478  { \
479    extern const unsigned char __BFFFOtable[256]; \
480    register int dumby; \
481    \
482    asm volatile ( "   move.w  %2,%1\n"        \
483       "   lsr.w   #8,%1\n"        \
484       "   beq.s   1f\n"           \
485       "   move.b  (%3,%1.w),%0\n" \
486       "   extb.l  %0\n"           \
487       "   bra.s   0f\n"           \
488       "1: moveq.l #8,%0\n"        \
489       "   add.b   (%3,%2.w),%0\n" \
490       "0:\n"                      \
491       : "=&d" ((_output)), "=&d" ((dumby)) \
492       : "d" ((_value)), "ao" ((__BFFFOtable)) \
493       : "cc" ) ; \
494  }
495#else
496#define _CPU_Bitfield_Find_first_bit( _value, _output ) \
497  { \
498    extern const unsigned char __BFFFOtable[256]; \
499    register int dumby; \
500    \
501    asm volatile ( "   move.w  %2,%1\n"        \
502       "   lsr.w   #8,%1\n"        \
503       "   beq.s   1f\n"           \
504       "   move.b  (%3,%1.w),%0\n" \
505       "   and.l   #0x000000ff,%0\n"\
506       "   bra.s   0f\n"           \
507       "1: moveq.l #8,%0\n"        \
508       "   add.b   (%3,%2.w),%0\n" \
509       "0:\n"                      \
510       : "=&d" ((_output)), "=&d" ((dumby)) \
511       : "d" ((_value)), "ao" ((__BFFFOtable)) \
512       : "cc" ) ; \
513  }
514#endif
515
516#endif
517
518/* end of Bitfield handler macros */
519
520/*
521 *  Priority handler macros
522 *
523 *  These macros perform the following functions:
524 *    + return a mask with the bit for this major/minor portion of
525 *      of thread priority set.
526 *    + translate the bit number returned by "Bitfield_find_first_bit"
527 *      into an index into the thread ready chain bit maps
528 */
529
530#define _CPU_Priority_Mask( _bit_number ) \
531  ( 0x8000 >> (_bit_number) )
532
533#define _CPU_Priority_bits_index( _priority ) \
534  (_priority)
535
536/* end of Priority handler macros */
537
538/* functions */
539
540/*
541 *  _CPU_Initialize
542 *
543 *  This routine performs CPU dependent initialization.
544 */
545
546void _CPU_Initialize(
547  rtems_cpu_table  *cpu_table,
548  void      (*thread_dispatch)
549);
550
551/*
552 *  _CPU_ISR_install_raw_handler
553 *
554 *  This routine installs a "raw" interrupt handler directly into the
555 *  processor's vector table.
556 */
557 
558void _CPU_ISR_install_raw_handler(
559  unsigned32  vector,
560  proc_ptr    new_handler,
561  proc_ptr   *old_handler
562);
563
564/*
565 *  _CPU_ISR_install_vector
566 *
567 *  This routine installs an interrupt vector.
568 */
569
570void _CPU_ISR_install_vector(
571  unsigned32       vector,
572  proc_ptr         new_handler,
573  proc_ptr        *old_handler
574);
575
576/*
577 *  _CPU_Install_interrupt_stack
578 *
579 *  This routine installs the hardware interrupt stack pointer.
580 */
581
582void _CPU_Install_interrupt_stack( void );
583
584/*
585 *  _CPU_Context_switch
586 *
587 *  This routine switches from the run context to the heir context.
588 */
589
590void _CPU_Context_switch(
591  Context_Control  *run,
592  Context_Control  *heir
593);
594
595/*
596 *  _CPU_Context_save_fp
597 *
598 *  This routine saves the floating point context passed to it.
599 */
600
601void _CPU_Context_save_fp(
602  void **fp_context_ptr
603);
604
605/*
606 *  _CPU_Context_restore_fp
607 *
608 *  This routine restores the floating point context passed to it.
609 */
610
611void _CPU_Context_restore_fp(
612  void **fp_context_ptr
613);
614
615#if (M68K_HAS_FPSP_PACKAGE == 1)
616/*
617 *  Hooks for the Floating Point Support Package (FPSP) provided by Motorola
618 *
619 *  NOTES: 
620 *
621 *  Motorola 68k family CPU's before the 68040 used a coprocessor
622 *  (68881 or 68882) to handle floating point.  The 68040 has internal
623 *  floating point support -- but *not* the complete support provided by
624 *  the 68881 or 68882.  The leftover functions are taken care of by the
625 *  M68040 Floating Point Support Package.  Quoting from the MC68040
626 *  Microprocessors User's Manual, Section 9, Floating-Point Unit (MC68040):
627 *
628 *    "When used with the M68040FPSP, the MC68040 FPU is fully
629 *    compliant with IEEE floating-point standards."
630 *
631 *  M68KFPSPInstallExceptionHandlers is in libcpu/m68k/MODEL/fpsp and
632 *  is invoked early in the application code to insure that proper FP
633 *  behavior is installed.  This is not left to the BSP to call, since
634 *  this would force all applications using that BSP to use FPSP which
635 *  is not necessarily desirable.
636 *
637 *  There is a similar package for the 68060 but RTEMS does not yet
638 *  support the 68060.
639 */
640
641void M68KFPSPInstallExceptionHandlers (void);
642
643SCORE_EXTERN int (*_FPSP_install_raw_handler)(
644  unsigned32 vector,
645  proc_ptr new_handler,
646  proc_ptr *old_handler
647);
648
649#endif
650
651
652#endif
653
654#ifdef __cplusplus
655}
656#endif
657
658#endif
659/* end of include file */
Note: See TracBrowser for help on using the repository browser.