RTEMS  5.1
m68k.h
Go to the documentation of this file.
1 
12 /*
13  * COPYRIGHT (c) 1989-1999.
14  * On-Line Applications Research Corporation (OAR).
15  *
16  * The license and distribution terms for this file may be
17  * found in the file LICENSE in this distribution or at
18  * http://www.rtems.org/license/LICENSE.
19  */
20 
21 #ifndef _RTEMS_SCORE_M68K_H
22 #define _RTEMS_SCORE_M68K_H
23 
24 #ifdef __cplusplus
25 extern "C" {
26 #endif
27 
28 /*
29  * This section contains the information required to build
30  * RTEMS for a particular member of the Motorola MC68xxx
31  * family. It does this by setting variables to indicate
32  * which implementation dependent features are present in
33  * a particular member of the family.
34  *
35  * Currently recognized:
36  * -m68000
37  * -m68000 -msoft-float
38  * -m68020
39  * -m68020 -msoft-float
40  * -m68030
41  * -m68040 -msoft-float
42  * -m68040
43  * -m68040 -msoft-float
44  * -m68060
45  * -m68060 -msoft-float
46  * -m68302 (no FP) (deprecated, use -m68000)
47  * -m68332 (no FP) (deprecated, use -mcpu32)
48  * -mcpu32 (no FP)
49  * -m5200 (no FP)
50  * -m528x (no FP, ISA A+)
51  *
52  * As of gcc 2.8.1 and egcs 1.1, there is no distinction made between
53  * the CPU32 and CPU32+. The option -mcpu32 generates code which can
54  * be run on either core. RTEMS distinguishes between these two cores
55  * because they have different alignment rules which impact performance.
56  * If you are using a CPU32+, then the symbol RTEMS__mcpu32p__ should
57  * be defined in your custom file (see make/custom/gen68360.cfg for an
58  * example of how to do this. If gcc ever distinguishes between these
59  * two cores, then RTEMS__mcpu32p__ usage will be replaced with the
60  * appropriate compiler defined predefine.
61  *
62  * Here is some information on the 040 variants (courtesy of Doug McBride,
63  * mcbride@rodin.colorado.edu):
64  *
65  * "The 68040 is a superset of the 68EC040 and the 68LC040. The
66  * 68EC040 and 68LC040 do not have FPU's. The 68LC040 and the
67  * 68EC040 have renamed the DLE pin as JS0 which must be tied to
68  * Gnd or Vcc. The 68EC040 has renamed the MDIS pin as JS1. The
69  * 68EC040 has access control units instead of memory management units.
70  * The 68EC040 should not have the PFLUSH or PTEST instructions executed
71  * (cause an indeterminate result). The 68EC040 and 68LC040 do not
72  * implement the DLE or multiplexed bus modes. The 68EC040 does not
73  * implement the output buffer impedance selection mode of operation."
74  *
75  * M68K_HAS_EXTB_L is used to enable/disable usage of the extb.l instruction
76  * which is not available for 68000 or 68ec000 cores (68000, 68001, 68008,
77  * 68010, 68302, 68306, 68307). This instruction is available on the 68020
78  * up and the cpu32 based models.
79  *
80  * M68K_HAS_MISALIGNED is non-zero if the CPU allows byte-misaligned
81  * data access (68020, 68030, 68040, 68060, CPU32+).
82  *
83  * NOTE:
84  * Eventually it would be nice to evaluate doing a lot of this section
85  * by having each model specify which core it uses and then go from there.
86  */
87 
88 /*
89  * Handle the Coldfire family based on the instruction set.
90  */
91 #if defined(__mcoldfire__)
92 
93 # define CPU_NAME "Motorola ColdFire"
94 
95 # if defined(__mcfisaa__)
96 /* Motorola ColdFire ISA A */
97 # define CPU_MODEL_NAME "mcfisaa"
98 # define M68K_HAS_VBR 1
99 # define M68K_HAS_BFFFO 0
100 # define M68K_HAS_SEPARATE_STACKS 0
101 # define M68K_HAS_PREINDEXING 0
102 # define M68K_HAS_EXTB_L 1
103 # define M68K_HAS_MISALIGNED 1
104 
105 # elif defined(__mcfisaaplus__)
106 /* Motorola ColdFire ISA A+ */
107 # define CPU_MODEL_NAME "mcfisaaplus"
108 # define M68K_HAS_VBR 1
109 # define M68K_HAS_BFFFO 0
110 # define M68K_HAS_SEPARATE_STACKS 0
111 # define M68K_HAS_PREINDEXING 0
112 # define M68K_HAS_EXTB_L 1
113 # define M68K_HAS_MISALIGNED 1
114 
115 # elif defined(__mcfisab__)
116 /* Motorola ColdFire ISA B */
117 # define CPU_MODEL_NAME "mcfisab"
118 # define M68K_HAS_VBR 1
119 # define M68K_HAS_BFFFO 0
120 # define M68K_HAS_SEPARATE_STACKS 0
121 # define M68K_HAS_PREINDEXING 0
122 # define M68K_HAS_EXTB_L 1
123 # define M68K_HAS_MISALIGNED 1
124 
125 # else
126 # error "Unsupported Coldfire ISA -- Please notify RTEMS"
127 # endif
128 
129 /*
130  * Assume the FPU support is independent. I think it is just the ISA B
131  * instruction set.
132  */
133 # if defined (__mcffpu__)
134 # define M68K_HAS_FPU 1
135  /*
136  * td: can we be sure that all CFs with FPU also have an EMAC?
137  */
138 # define M68K_HAS_EMAC 1
139 # define M68K_HAS_FPSP_PACKAGE 0
140 # else
141 # define M68K_HAS_FPU 0
142 # define M68K_HAS_FPSP_PACKAGE 0
143 # endif
144 
145 /*
146  * Tiny RTEMS support. Small stack and limited priorities.
147  *
148  * These CPUs have very limited on-CPU memory which cannot
149  * be expanded. We have to be gentle with them or nothing
150  * will every run.
151  */
152 # if (defined(__mcf_cpu_52221) || \
153  defined(__mcf_cpu_52223) || \
154  defined(__mcf_cpu_52230) || \
155  defined(__mcf_cpu_52231) || \
156  defined(__mcf_cpu_52232) || \
157  defined(__mcf_cpu_52233) || \
158  defined(__mcf_cpu_52234) || \
159  defined(__mcf_cpu_52235) || \
160  defined(__mcf_cpu_52225) || \
161  defined(__mcf_cpu_52235))
162  #define M68K_CPU_STACK_MINIMUM_SIZE 1024
163  /* Define the lowest priority. Based from 0 to this is 16 levels. */
164  #define M68K_CPU_PRIORITY_MAXIMUM 15
165 # else
166  #define M68K_CPU_STACK_MINIMUM_SIZE 4096
167  /* Use the default number of priorities */
168  #define M68K_CPU_PRIORITY_MAXIMUM 255
169 # endif
170 
171 #else
172 
173 /*
174  * Figure out all CPU Model Feature Flags based upon compiler
175  * predefines. Notice the only exception to this is that
176  * gcc does not distinguish between CPU32 and CPU32+. This
177  * feature selection logic is setup such that if RTEMS__mcpu32p__
178  * is defined, then CPU32+ rules are used. Otherwise, the safe
179  * but less efficient CPU32 rules are used for the CPU32+.
180  */
181 
182 # define CPU_NAME "Motorola MC68xxx"
183 
184 /*
185  * One stack size fits all 68000 processors.
186  */
187 # define M68K_CPU_STACK_MINIMUM_SIZE 4096
188 
189 # if (defined(__mc68020__) && !defined(__mcpu32__))
190 
191 # define CPU_MODEL_NAME "m68020"
192 # define M68K_HAS_VBR 1
193 # define M68K_HAS_SEPARATE_STACKS 1
194 # define M68K_HAS_BFFFO 1
195 # define M68K_HAS_PREINDEXING 1
196 # define M68K_HAS_EXTB_L 1
197 # define M68K_HAS_MISALIGNED 1
198 # if defined (__HAVE_68881__)
199 # define M68K_HAS_FPU 1
200 # define M68K_HAS_FPSP_PACKAGE 0
201 # else
202 # define M68K_HAS_FPU 0
203 # define M68K_HAS_FPSP_PACKAGE 0
204 # endif
205 
206 # elif defined(__mc68030__)
207 
208 # define CPU_MODEL_NAME "m68030"
209 # define M68K_HAS_VBR 1
210 # define M68K_HAS_SEPARATE_STACKS 1
211 # define M68K_HAS_BFFFO 1
212 # define M68K_HAS_PREINDEXING 1
213 # define M68K_HAS_EXTB_L 1
214 # define M68K_HAS_MISALIGNED 1
215 # if defined (__HAVE_68881__)
216 # define M68K_HAS_FPU 1
217 # define M68K_HAS_FPSP_PACKAGE 0
218 # else
219 # define M68K_HAS_FPU 0
220 # define M68K_HAS_FPSP_PACKAGE 0
221 # endif
222 
223 # elif defined(__mc68040__)
224 
225 # define CPU_MODEL_NAME "m68040"
226 # define M68K_HAS_VBR 1
227 # define M68K_HAS_SEPARATE_STACKS 1
228 # define M68K_HAS_BFFFO 1
229 # define M68K_HAS_PREINDEXING 1
230 # define M68K_HAS_EXTB_L 1
231 # define M68K_HAS_MISALIGNED 1
232 # if defined (__HAVE_68881__)
233 # define M68K_HAS_FPU 1
234 # define M68K_HAS_FPSP_PACKAGE 1
235 # else
236 # define M68K_HAS_FPU 0
237 # define M68K_HAS_FPSP_PACKAGE 0
238 # endif
239 
240 # elif defined(__mc68060__)
241 
242 # define CPU_MODEL_NAME "m68060"
243 # define M68K_HAS_VBR 1
244 # define M68K_HAS_SEPARATE_STACKS 0
245 # define M68K_HAS_BFFFO 1
246 # define M68K_HAS_PREINDEXING 1
247 # define M68K_HAS_EXTB_L 1
248 # define M68K_HAS_MISALIGNED 1
249 # if defined (__HAVE_68881__)
250 # define M68K_HAS_FPU 1
251 # define M68K_HAS_FPSP_PACKAGE 0
252 # else
253 # define M68K_HAS_FPU 0
254 # define M68K_HAS_FPSP_PACKAGE 0
255 # endif
256 
257 # elif defined(__mc68302__)
258 
259 # define CPU_MODEL_NAME "m68302"
260 # define M68K_HAS_VBR 0
261 # define M68K_HAS_SEPARATE_STACKS 0
262 # define M68K_HAS_BFFFO 0
263 # define M68K_HAS_PREINDEXING 0
264 # define M68K_HAS_EXTB_L 0
265 # define M68K_HAS_MISALIGNED 0
266 # define M68K_HAS_FPU 0
267 # define M68K_HAS_FPSP_PACKAGE 0
268 
269  /* gcc and egcs do not distinguish between CPU32 and CPU32+ */
270 # elif defined(RTEMS__mcpu32p__)
271 
272 # define CPU_MODEL_NAME "mcpu32+"
273 # define M68K_HAS_VBR 1
274 # define M68K_HAS_SEPARATE_STACKS 0
275 # define M68K_HAS_BFFFO 0
276 # define M68K_HAS_PREINDEXING 1
277 # define M68K_HAS_EXTB_L 1
278 # define M68K_HAS_MISALIGNED 1
279 # define M68K_HAS_FPU 0
280 # define M68K_HAS_FPSP_PACKAGE 0
281 
282 # elif defined(__mcpu32__)
283 
284 # define CPU_MODEL_NAME "mcpu32"
285 # define M68K_HAS_VBR 1
286 # define M68K_HAS_SEPARATE_STACKS 0
287 # define M68K_HAS_BFFFO 0
288 # define M68K_HAS_PREINDEXING 1
289 # define M68K_HAS_EXTB_L 1
290 # define M68K_HAS_MISALIGNED 0
291 # define M68K_HAS_FPU 0
292 # define M68K_HAS_FPSP_PACKAGE 0
293 
294 # elif defined(__mc68000__)
295 
296 # define CPU_MODEL_NAME "m68000"
297 # define M68K_HAS_VBR 0
298 # define M68K_HAS_SEPARATE_STACKS 0
299 # define M68K_HAS_BFFFO 0
300 # define M68K_HAS_PREINDEXING 0
301 # define M68K_HAS_EXTB_L 0
302 # define M68K_HAS_MISALIGNED 0
303 # if defined (__HAVE_68881__)
304 # define M68K_HAS_FPU 1
305 # define M68K_HAS_FPSP_PACKAGE 0
306 # else
307 # define M68K_HAS_FPU 0
308 # define M68K_HAS_FPSP_PACKAGE 0
309 # endif
310 
311 # else
312 
313 # error "Unsupported 68000 CPU model -- are you sure you're running a 68k compiler?"
314 
315 # endif
316 
317 /*
318  * No Tiny RTEMS support on the standard 68000 family.
319  */
320 # define M68K_CPU_STACK_MINIMUM_SIZE 4096
321 # define M68K_CPU_PRIORITY_MAXIMUM 255
322 
323 #endif
324 
325 /*
326  * OBSOLETE: Backward compatibility only - Don't use.
327  * Use __mcoldfire__ instead.
328  */
329 #if defined(__mcoldfire__)
330 #define M68K_COLDFIRE_ARCH 1
331 #else
332 #define M68K_COLDFIRE_ARCH 0
333 #endif
334 
335 #ifndef ASM
336 
337 #if ( defined(__mcoldfire__) )
338 #define m68k_disable_interrupts( _level ) \
339  do { uint32_t _tmpsr = 0x0700; \
340  __asm__ volatile ( "move.w %%sr,%0\n\t" \
341  "or.l %0,%1\n\t" \
342  "move.w %1,%%sr" \
343  : "=d" (_level), "=d"(_tmpsr) : "1"(_tmpsr) \
344  : "cc" ); \
345  } while( 0 )
346 #else
347 #define m68k_disable_interrupts( _level ) \
348  __asm__ volatile ( "move.w %%sr,%0\n\t" \
349  "or.w #0x0700,%%sr" \
350  : "=d" (_level) \
351  : : "cc" )
352 #endif
353 
354 #define m68k_enable_interrupts( _level ) \
355  __asm__ volatile ( "move.w %0,%%sr " : : "d" (_level) : "cc");
356 
357 #if ( defined(__mcoldfire__) )
358 #define m68k_flash_interrupts( _level ) \
359  do { uint32_t _tmpsr = 0x0700; \
360  asm volatile ( "move.w %2,%%sr\n\t" \
361  "or.l %2,%1\n\t" \
362  "move.w %1,%%sr" \
363  : "=d"(_tmpsr) : "0"(_tmpsr), "d"(_level) \
364  : "cc"); \
365  } while( 0 )
366 #else
367 #define m68k_flash_interrupts( _level ) \
368  __asm__ volatile ( "move.w %0,%%sr\n\t" \
369  "or.w #0x0700,%%sr" \
370  : : "d" (_level) \
371  : "cc" )
372 #endif
373 
374 #define m68k_get_interrupt_level( _level ) \
375  do { \
376  uint32_t _tmpsr; \
377  \
378  __asm__ volatile( "move.w %%sr,%0" : "=d" (_tmpsr)); \
379  _level = (_tmpsr & 0x0700) >> 8; \
380  } while (0)
381 
382 #define m68k_set_interrupt_level( _newlevel ) \
383  do { \
384  uint32_t _tmpsr; \
385  \
386  __asm__ volatile( "move.w %%sr,%0" : "=d" (_tmpsr)); \
387  _tmpsr = (_tmpsr & 0xf8ff) | ((_newlevel) << 8); \
388  __asm__ volatile( "move.w %0,%%sr" : : "d" (_tmpsr)); \
389  } while (0)
390 
391 #if ( M68K_HAS_VBR == 1 && !defined(__mcoldfire__) )
392 #define m68k_get_vbr( vbr ) \
393  __asm__ volatile ( "movec %%vbr,%0 " : "=r" (vbr))
394 
395 #define m68k_set_vbr( vbr ) \
396  __asm__ volatile ( "movec %0,%%vbr " : : "r" (vbr))
397 
398 #elif ( defined(__mcoldfire__) )
399 extern void* _VBR;
400 #define m68k_get_vbr( _vbr ) _vbr = &_VBR
401 
402 #define m68k_set_vbr( _vbr ) \
403  do { \
404  __asm__ volatile ( "movec %0,%%vbr " : : "r" (_vbr)); \
405  _VBR = (void *)_vbr; \
406  } while(0)
407 
408 #else
409 #define m68k_get_vbr( _vbr ) _vbr = (void *)_VBR
410 #define m68k_set_vbr( _vbr )
411 #endif
412 
413 /*
414  * Access Control Registers
415  */
416 #define m68k_set_cacr(_cacr) __asm__ volatile ("movec %0,%%cacr" : : "d" (_cacr))
417 #define m68k_set_acr0(_acr0) __asm__ volatile ("movec %0,%%acr0" : : "d" (_acr0))
418 #define m68k_set_acr1(_acr1) __asm__ volatile ("movec %0,%%acr1" : : "d" (_acr1))
419 
420 /*
421  * The following routine swaps the endian format of an unsigned int.
422  * It must be static because it is referenced indirectly.
423  */
424 #if ( defined(__mcoldfire__) )
425 
426 /* There are no rotate commands in Coldfire architecture. We will use
427  * generic implementation of endian swapping for Coldfire.
428  */
429 static inline uint32_t m68k_swap_u32(
430  uint32_t value
431  )
432 {
433  uint32_t byte1, byte2, byte3, byte4, swapped;
434 
435  byte4 = (value >> 24) & 0xff;
436  byte3 = (value >> 16) & 0xff;
437  byte2 = (value >> 8) & 0xff;
438  byte1 = value & 0xff;
439 
440  swapped = (byte1 << 24) | (byte2 << 16) | (byte3 << 8) | byte4;
441  return( swapped );
442 }
443 
444 static inline uint16_t m68k_swap_u16(
445  uint16_t value
446 )
447 {
448  return (((value & 0xff) << 8) | ((value >> 8) & 0xff));
449 }
450 
451 #else
452 
453 static inline uint32_t m68k_swap_u32(
454  uint32_t value
455 )
456 {
457  uint32_t swapped = value;
458 
459  __asm__ volatile( "rorw #8,%0" : "=d" (swapped) : "0" (swapped) );
460  __asm__ volatile( "swap %0" : "=d" (swapped) : "0" (swapped) );
461  __asm__ volatile( "rorw #8,%0" : "=d" (swapped) : "0" (swapped) );
462 
463  return( swapped );
464 }
465 
466 static inline uint16_t m68k_swap_u16(
467  uint16_t value
468 )
469 {
470  uint16_t swapped = value;
471 
472  __asm__ volatile( "rorw #8,%0" : "=d" (swapped) : "0" (swapped) );
473 
474  return( swapped );
475 }
476 #endif
477 
478 #define CPU_swap_u32( value ) m68k_swap_u32( value )
479 #define CPU_swap_u16( value ) m68k_swap_u16( value )
480 
481 
482 /*
483  * _CPU_virtual_to_physical
484  *
485  * This function is used to map virtual addresses to physical
486  * addresses.
487  *
488  * FIXME: ASSUMES THAT VIRTUAL ADDRESSES ARE THE SAME AS THE
489  * PHYSICAL ADDRESSES
490  */
491 static inline void * _CPU_virtual_to_physical (
492  const void * d_addr )
493 {
494  return (void *) d_addr;
495 }
496 
497 
498 #endif /* !ASM */
499 
500 #ifdef __cplusplus
501 }
502 #endif
503 
504 #endif /* _RTEMS_SCORE_M68K_H */
register struct Per_CPU_Control *_SPARC_Per_CPU_current __asm__("g6")
The pointer to the current per-CPU control is available via register g6.