source: rtems/cpukit/score/cpu/m68k/rtems/score/cpu.h @ 84fff68d

4.104.114.95
Last change on this file since 84fff68d was 2fd427c, checked in by Joel Sherrill <joel.sherrill@…>, on 06/05/08 at 14:30:07

2008-06-05 Joel Sherrill <joel.sherrill@…>

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