source: rtems/cpukit/score/cpu/m68k/rtems/score/m68k.h @ 1f24914a

4.104.114.84.95
Last change on this file since 1f24914a was fa9fa1e4, checked in by Eric Norum <WENorum@…>, on 01/28/05 at 19:48:25

ColdFire? ISA A+ instructions.

  • Property mode set to 100644
File size: 12.1 KB
Line 
1/**
2 * @file rtems/score/m68k.h
3 */
4
5/*
6 *  This include file contains information pertaining to the Motorola
7 *  m68xxx processor family.
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_M68K_H
20#define _RTEMS_SCORE_M68K_H
21
22#ifdef __cplusplus
23extern "C" {
24#endif
25
26/*
27 *  This section contains the information required to build
28 *  RTEMS for a particular member of the Motorola MC68xxx
29 *  family.  It does this by setting variables to indicate
30 *  which implementation dependent features are present in
31 *  a particular member of the family.
32 *
33 *  Currently recognized:
34 *     -m68000
35 *     -m68000 -msoft-float
36 *     -m68020
37 *     -m68020 -msoft-float
38 *     -m68030
39 *     -m68040 -msoft-float
40 *     -m68040
41 *     -m68040 -msoft-float
42 *     -m68060
43 *     -m68060 -msoft-float
44 *     -m68302        (no FP) (deprecated, use -m68000)
45 *     -m68332        (no FP) (deprecated, use -mcpu32)
46 *     -mcpu32        (no FP)
47 *     -m5200         (no FP)
48 *     -m528x         (no FP, ISA A+)
49 *
50 *  As of gcc 2.8.1 and egcs 1.1, there is no distinction made between
51 *  the CPU32 and CPU32+.  The option -mcpu32 generates code which can
52 *  be run on either core.  RTEMS distinguishes between these two cores
53 *  because they have different alignment rules which impact performance.
54 *  If you are using a CPU32+, then the symbol RTEMS__mcpu32p__ should
55 *  be defined in your custom file (see make/custom/gen68360.cfg for an
56 *  example of how to do this.  If gcc ever distinguishes between these
57 *  two cores, then RTEMS__mcpu32p__ usage will be replaced with the
58 *  appropriate compiler defined predefine.
59 *
60 *  Here is some information on the 040 variants (courtesy of Doug McBride,
61 *  mcbride@rodin.colorado.edu):
62 *
63 *    "The 68040 is a superset of the 68EC040 and the 68LC040.  The
64 *    68EC040 and 68LC040 do not have FPU's.  The 68LC040 and the
65 *    68EC040 have renamed the DLE pin as JS0 which must be tied to
66 *    Gnd or Vcc. The 68EC040 has renamed the MDIS pin as JS1.  The
67 *    68EC040 has access control units instead of memory management units.
68 *    The 68EC040 should not have the PFLUSH or PTEST instructions executed
69 *    (cause an indeterminate result).  The 68EC040 and 68LC040 do not
70 *    implement the DLE or multiplexed bus modes.  The 68EC040 does not
71 *    implement the output buffer impedance selection mode of operation."
72 *
73 *  M68K_HAS_EXTB_L is used to enable/disable usage of the extb.l instruction
74 *  which is not available for 68000 or 68ec000 cores (68000, 68001, 68008,
75 *  68010, 68302, 68306, 68307).  This instruction is available on the 68020
76 *  up and the cpu32 based models. 
77 *
78 *  M68K_HAS_MISALIGNED is non-zero if the CPU allows byte-misaligned
79 *  data access (68020, 68030, 68040, 68060, CPU32+).
80 *
81 *  NOTE:
82 *    Eventually it would be nice to evaluate doing a lot of this section
83 *    by having each model specify which core it uses and then go from there.
84 */
85
86/*
87 *  Figure out all CPU Model Feature Flags based upon compiler
88 *  predefines.   Notice the only exception to this is that
89 *  gcc does not distinguish between CPU32 and CPU32+.  This
90 *  feature selection logic is setup such that if RTEMS__mcpu32p__
91 *  is defined, then CPU32+ rules are used.  Otherwise, the safe
92 *  but less efficient CPU32 rules are used for the CPU32+.
93 */
94
95#if (defined(__mc68020__) && !defined(__mcpu32__))
96 
97#define CPU_MODEL_NAME          "m68020"
98#define M68K_HAS_VBR             1
99#define M68K_HAS_SEPARATE_STACKS 1
100#define M68K_HAS_BFFFO           1
101#define M68K_HAS_PREINDEXING     1
102#define M68K_HAS_EXTB_L          1
103#define M68K_HAS_MISALIGNED      1
104# if defined (__HAVE_68881__)
105# define M68K_HAS_FPU            1
106# define M68K_HAS_FPSP_PACKAGE   0
107# else
108# define M68K_HAS_FPU            0
109# define M68K_HAS_FPSP_PACKAGE   0
110# endif
111 
112#elif defined(__mc68030__)
113 
114#define CPU_MODEL_NAME          "m68030"
115#define M68K_HAS_VBR             1
116#define M68K_HAS_SEPARATE_STACKS 1
117#define M68K_HAS_BFFFO           1
118#define M68K_HAS_PREINDEXING     1
119#define M68K_HAS_EXTB_L          1
120#define M68K_HAS_MISALIGNED      1
121# if defined (__HAVE_68881__)
122# define M68K_HAS_FPU            1
123# define M68K_HAS_FPSP_PACKAGE   0
124# else
125# define M68K_HAS_FPU            0
126# define M68K_HAS_FPSP_PACKAGE   0
127# endif
128 
129#elif defined(__mc68040__)
130
131#define CPU_MODEL_NAME          "m68040"
132#define M68K_HAS_VBR             1
133#define M68K_HAS_SEPARATE_STACKS 1
134#define M68K_HAS_BFFFO           1
135#define M68K_HAS_PREINDEXING     1
136#define M68K_HAS_EXTB_L          1
137#define M68K_HAS_MISALIGNED      1
138# if defined (__HAVE_68881__)
139# define M68K_HAS_FPU            1
140# define M68K_HAS_FPSP_PACKAGE   1
141# else
142# define M68K_HAS_FPU            0
143# define M68K_HAS_FPSP_PACKAGE   0
144# endif
145 
146#elif defined(__mc68060__)
147
148#define CPU_MODEL_NAME          "m68060"
149#define M68K_HAS_VBR             1
150#define M68K_HAS_SEPARATE_STACKS 0
151#define M68K_HAS_BFFFO           1
152#define M68K_HAS_PREINDEXING     1
153#define M68K_HAS_EXTB_L          1
154#define M68K_HAS_MISALIGNED      1
155# if defined (__HAVE_68881__)
156# define M68K_HAS_FPU            1
157# define M68K_HAS_FPSP_PACKAGE   0
158# else
159# define M68K_HAS_FPU            0
160# define M68K_HAS_FPSP_PACKAGE   0
161# endif
162 
163#elif defined(__mc68302__)
164
165#define CPU_MODEL_NAME          "m68302"
166#define M68K_HAS_VBR             0
167#define M68K_HAS_SEPARATE_STACKS 0
168#define M68K_HAS_BFFFO           0
169#define M68K_HAS_PREINDEXING     0
170#define M68K_HAS_EXTB_L          0
171#define M68K_HAS_MISALIGNED      0
172#define M68K_HAS_FPU             0
173#define M68K_HAS_FPSP_PACKAGE    0
174
175  /* gcc and egcs do not distinguish between CPU32 and CPU32+ */
176#elif defined(RTEMS__mcpu32p__)
177 
178#define CPU_MODEL_NAME          "mcpu32+"
179#define M68K_HAS_VBR             1
180#define M68K_HAS_SEPARATE_STACKS 0
181#define M68K_HAS_BFFFO           0
182#define M68K_HAS_PREINDEXING     1
183#define M68K_HAS_EXTB_L          1
184#define M68K_HAS_MISALIGNED      1
185#define M68K_HAS_FPU             0
186#define M68K_HAS_FPSP_PACKAGE    0
187
188#elif defined(__mcpu32__)
189 
190#define CPU_MODEL_NAME          "mcpu32"
191#define M68K_HAS_VBR             1
192#define M68K_HAS_SEPARATE_STACKS 0
193#define M68K_HAS_BFFFO           0
194#define M68K_HAS_PREINDEXING     1
195#define M68K_HAS_EXTB_L          1
196#define M68K_HAS_MISALIGNED      0
197#define M68K_HAS_FPU             0
198#define M68K_HAS_FPSP_PACKAGE    0
199
200#elif defined(__mcf528x__)
201/* Motorola ColdFire ISA A+ - RISC/68020 hybrid */
202#define CPU_MODEL_NAME         "m528x"
203#define M68K_HAS_VBR             1
204#define M68K_HAS_BFFFO           0
205#define M68K_HAS_SEPARATE_STACKS 0
206#define M68K_HAS_PREINDEXING     0
207#define M68K_HAS_EXTB_L          1
208#define M68K_HAS_MISALIGNED      1
209#define M68K_HAS_FPU             0
210#define M68K_HAS_FPSP_PACKAGE    0
211#define M68K_COLDFIRE_ARCH       1
212#define M68K_HAS_ISA_APLUS       1
213
214#elif defined(__mcf5200__)
215/* Motorola ColdFire V2 core - RISC/68020 hybrid */
216#define CPU_MODEL_NAME         "m5200"
217#define M68K_HAS_VBR             1
218#define M68K_HAS_BFFFO           0
219#define M68K_HAS_SEPARATE_STACKS 0
220#define M68K_HAS_PREINDEXING     0
221#define M68K_HAS_EXTB_L          1
222#define M68K_HAS_MISALIGNED      1
223#define M68K_HAS_FPU             0
224#define M68K_HAS_FPSP_PACKAGE    0
225#define M68K_COLDFIRE_ARCH       1
226#define M68K_HAS_ISA_APLUS       0
227
228#elif defined(__mc68000__)
229 
230#define CPU_MODEL_NAME          "m68000"
231#define M68K_HAS_VBR             0
232#define M68K_HAS_SEPARATE_STACKS 0
233#define M68K_HAS_BFFFO           0
234#define M68K_HAS_PREINDEXING     0
235#define M68K_HAS_EXTB_L          0
236#define M68K_HAS_MISALIGNED      0
237# if defined (__HAVE_68881__)
238# define M68K_HAS_FPU            1
239# define M68K_HAS_FPSP_PACKAGE   0
240# else
241# define M68K_HAS_FPU            0
242# define M68K_HAS_FPSP_PACKAGE   0
243# endif
244
245#else
246
247#error "Unsupported CPU model -- are you sure you're running a 68k compiler?"
248
249#endif
250
251#ifndef ASM
252#include <rtems/score/types.h>
253#include <stdint.h>
254#endif
255
256/*
257 *  If the above did not specify a ColdFire architecture, then set
258 *  this flag to indicate that it is not a ColdFire CPU.
259 */
260
261#if !defined(M68K_COLDFIRE_ARCH)
262#define M68K_COLDFIRE_ARCH       0
263#endif
264
265/*
266 *  Define the name of the CPU family.
267 */
268
269#if ( M68K_COLDFIRE_ARCH == 1 )
270  #define CPU_NAME "Motorola ColdFire"
271#else
272  #define CPU_NAME "Motorola MC68xxx"
273#endif
274
275#ifndef ASM
276
277#if ( M68K_COLDFIRE_ARCH == 1 )
278#define m68k_disable_interrupts( _level ) \
279   do { register uint32_t   _tmpsr = 0x0700; \
280        asm volatile ( "move.w %%sr,%0\n\t" \
281                       "or.l   %0,%1\n\t" \
282                       "move.w %1,%%sr" \
283                       : "=d" (_level), "=d"(_tmpsr) : "1"(_tmpsr) ); \
284   } while( 0 )
285#else
286#define m68k_disable_interrupts( _level ) \
287  asm volatile ( "move.w  %%sr,%0\n\t" \
288                 "or.w    #0x0700,%%sr" \
289                    : "=d" (_level))
290#endif
291
292#define m68k_enable_interrupts( _level ) \
293  asm volatile ( "move.w  %0,%%sr " : : "d" (_level));
294
295#if ( M68K_COLDFIRE_ARCH == 1 )
296#define m68k_flash_interrupts( _level ) \
297   do { register uint32_t   _tmpsr = 0x0700; \
298        asm volatile ( "move.w %2,%%sr\n\t" \
299                       "or.l   %2,%1\n\t" \
300                       "move.w %1,%%sr" \
301                       : "=d"(_tmpsr) : "0"(_tmpsr), "d"(_level) ); \
302   } while( 0 )
303#else
304#define m68k_flash_interrupts( _level ) \
305  asm volatile ( "move.w  %0,%%sr\n\t" \
306                 "or.w    #0x0700,%%sr" \
307                    : : "d" (_level))
308#endif
309
310#define m68k_get_interrupt_level( _level ) \
311  do { \
312    register uint32_t   _tmpsr; \
313    \
314    asm volatile( "move.w %%sr,%0" : "=d" (_tmpsr)); \
315    _level = (_tmpsr & 0x0700) >> 8; \
316  } while (0)
317   
318#define m68k_set_interrupt_level( _newlevel ) \
319  do { \
320    register uint32_t   _tmpsr; \
321    \
322    asm volatile( "move.w  %%sr,%0" : "=d" (_tmpsr)); \
323    _tmpsr = (_tmpsr & 0xf8ff) | ((_newlevel) << 8); \
324    asm volatile( "move.w  %0,%%sr" : : "d" (_tmpsr)); \
325  } while (0)
326
327#if ( M68K_HAS_VBR == 1 && M68K_COLDFIRE_ARCH == 0 )
328#define m68k_get_vbr( vbr ) \
329  asm volatile ( "movec   %%vbr,%0 " : "=r" (vbr))
330
331#define m68k_set_vbr( vbr ) \
332  asm volatile ( "movec   %0,%%vbr " : : "r" (vbr))
333
334#elif ( M68K_COLDFIRE_ARCH == 1 )
335extern void *_ColdFire_VBR;
336#define m68k_get_vbr( _vbr ) _vbr = _ColdFire_VBR
337
338#define m68k_set_vbr( vbr ) \
339  do { \
340    asm volatile ( "movec   %0,%%vbr " : : "r" (vbr)); \
341    _ColdFire_VBR = (void *)vbr; \
342  } while(0)
343 
344#else
345#define m68k_get_vbr( _vbr ) _vbr = (void *)_VBR
346#define m68k_set_vbr( _vbr )
347#endif
348
349/*
350 *  The following routine swaps the endian format of an unsigned int.
351 *  It must be static because it is referenced indirectly.
352 */
353#if ( M68K_COLDFIRE_ARCH == 1 )
354
355/* There are no rotate commands in Coldfire architecture. We will use
356 * generic implementation of endian swapping for Coldfire.
357 */
358static inline uint32_t m68k_swap_u32(
359  uint32_t value
360  )
361{
362  uint32_t   byte1, byte2, byte3, byte4, swapped;
363   
364  byte4 = (value >> 24) & 0xff;
365  byte3 = (value >> 16) & 0xff;
366  byte2 = (value >> 8)  & 0xff;
367  byte1 =  value        & 0xff;
368           
369  swapped = (byte1 << 24) | (byte2 << 16) | (byte3 << 8) | byte4;
370  return( swapped );
371}
372 
373static inline uint16_t m68k_swap_u16(
374  uint16_t value
375)
376{
377  return (((value & 0xff) << 8) | ((value >> 8) & 0xff));
378}
379                 
380#else
381
382static inline uint32_t m68k_swap_u32(
383  uint32_t value
384)
385{
386  uint32_t swapped = value;
387
388  asm volatile( "rorw  #8,%0" : "=d" (swapped) : "0" (swapped) );
389  asm volatile( "swap  %0"    : "=d" (swapped) : "0" (swapped) );
390  asm volatile( "rorw  #8,%0" : "=d" (swapped) : "0" (swapped) );
391
392  return( swapped );
393}
394
395static inline uint16_t m68k_swap_u16(
396  uint16_t value
397)
398{
399  uint16_t swapped = value;
400
401  asm volatile( "rorw  #8,%0" : "=d" (swapped) : "0" (swapped) );
402
403  return( swapped );
404}
405#endif
406
407#define CPU_swap_u32( value )  m68k_swap_u32( value )
408#define CPU_swap_u16( value )  m68k_swap_u16( value )
409
410
411/*
412 *  _CPU_virtual_to_physical
413 *
414 *  DESCRIPTION:
415 *
416 *      This function is used to map virtual addresses to physical
417 *      addresses.
418 *
419 *      FIXME: ASSUMES THAT VIRTUAL ADDRESSES ARE THE SAME AS THE
420 *      PHYSICAL ADDRESSES
421 */
422static inline void * _CPU_virtual_to_physical (
423  const void * d_addr )
424{
425  return (void *) d_addr;
426}
427
428
429#endif  /* !ASM */
430
431#ifdef __cplusplus
432}
433#endif
434
435#endif /* __M68K_h */
Note: See TracBrowser for help on using the repository browser.