RTEMS CPU Kit with SuperCore  4.11.3
m68k.h
Go to the documentation of this file.
1 
10 /*
11  * COPYRIGHT (c) 1989-1999.
12  * On-Line Applications Research Corporation (OAR).
13  *
14  * The license and distribution terms for this file may be
15  * found in the file LICENSE in this distribution or at
16  * http://www.rtems.org/license/LICENSE.
17  */
18 
19 #ifndef _RTEMS_SCORE_M68K_H
20 #define _RTEMS_SCORE_M68K_H
21 
22 #ifdef __cplusplus
23 extern "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  * Handle the Coldfire family based on the instruction set.
88  */
89 #if defined(__mcoldfire__)
90 
91 # define CPU_NAME "Motorola ColdFire"
92 
93 # if defined(__mcfisaa__)
94 /* Motorola ColdFire ISA A */
95 # define CPU_MODEL_NAME "mcfisaa"
96 # define M68K_HAS_VBR 1
97 # define M68K_HAS_BFFFO 0
98 # define M68K_HAS_SEPARATE_STACKS 0
99 # define M68K_HAS_PREINDEXING 0
100 # define M68K_HAS_EXTB_L 1
101 # define M68K_HAS_MISALIGNED 1
102 
103 # elif defined(__mcfisaaplus__)
104 /* Motorola ColdFire ISA A+ */
105 # define CPU_MODEL_NAME "mcfisaaplus"
106 # define M68K_HAS_VBR 1
107 # define M68K_HAS_BFFFO 0
108 # define M68K_HAS_SEPARATE_STACKS 0
109 # define M68K_HAS_PREINDEXING 0
110 # define M68K_HAS_EXTB_L 1
111 # define M68K_HAS_MISALIGNED 1
112 
113 # elif defined(__mcfisab__)
114 /* Motorola ColdFire ISA B */
115 # define CPU_MODEL_NAME "mcfisab"
116 # define M68K_HAS_VBR 1
117 # define M68K_HAS_BFFFO 0
118 # define M68K_HAS_SEPARATE_STACKS 0
119 # define M68K_HAS_PREINDEXING 0
120 # define M68K_HAS_EXTB_L 1
121 # define M68K_HAS_MISALIGNED 1
122 
123 # else
124 # error "Unsupported Coldfire ISA -- Please notify RTEMS"
125 # endif
126 
127 /*
128  * Assume the FPU support is independent. I think it is just the ISA B
129  * instruction set.
130  */
131 # if defined (__mcffpu__)
132 # define M68K_HAS_FPU 1
133  /*
134  * td: can we be sure that all CFs with FPU also have an EMAC?
135  */
136 # define M68K_HAS_EMAC 1
137 # define M68K_HAS_FPSP_PACKAGE 0
138 # else
139 # define M68K_HAS_FPU 0
140 # define M68K_HAS_FPSP_PACKAGE 0
141 # endif
142 
143 /*
144  * Tiny RTEMS support. Small stack and limited priorities.
145  *
146  * These CPUs have very limited on-CPU memory which cannot
147  * be expanded. We have to be gentle with them or nothing
148  * will every run.
149  */
150 # if (defined(__mcf_cpu_52221) || \
151  defined(__mcf_cpu_52223) || \
152  defined(__mcf_cpu_52230) || \
153  defined(__mcf_cpu_52231) || \
154  defined(__mcf_cpu_52232) || \
155  defined(__mcf_cpu_52233) || \
156  defined(__mcf_cpu_52234) || \
157  defined(__mcf_cpu_52235) || \
158  defined(__mcf_cpu_52225) || \
159  defined(__mcf_cpu_52235))
160  #define M68K_CPU_STACK_MINIMUM_SIZE 1024
161  /* Define the lowest priority. Based from 0 to this is 16 levels. */
162  #define M68K_CPU_PRIORITY_MAXIMUM 15
163 # else
164  #define M68K_CPU_STACK_MINIMUM_SIZE 4096
165  /* Use the default number of priorities */
166  #define M68K_CPU_PRIORITY_MAXIMUM 255
167 # endif
168 
169 #else
170 
171 /*
172  * Figure out all CPU Model Feature Flags based upon compiler
173  * predefines. Notice the only exception to this is that
174  * gcc does not distinguish between CPU32 and CPU32+. This
175  * feature selection logic is setup such that if RTEMS__mcpu32p__
176  * is defined, then CPU32+ rules are used. Otherwise, the safe
177  * but less efficient CPU32 rules are used for the CPU32+.
178  */
179 
180 # define CPU_NAME "Motorola MC68xxx"
181 
182 /*
183  * One stack size fits all 68000 processors.
184  */
185 # define M68K_CPU_STACK_MINIMUM_SIZE 4096
186 
187 # if (defined(__mc68020__) && !defined(__mcpu32__))
188 
189 # define CPU_MODEL_NAME "m68020"
190 # define M68K_HAS_VBR 1
191 # define M68K_HAS_SEPARATE_STACKS 1
192 # define M68K_HAS_BFFFO 1
193 # define M68K_HAS_PREINDEXING 1
194 # define M68K_HAS_EXTB_L 1
195 # define M68K_HAS_MISALIGNED 1
196 # if defined (__HAVE_68881__)
197 # define M68K_HAS_FPU 1
198 # define M68K_HAS_FPSP_PACKAGE 0
199 # else
200 # define M68K_HAS_FPU 0
201 # define M68K_HAS_FPSP_PACKAGE 0
202 # endif
203 
204 # elif defined(__mc68030__)
205 
206 # define CPU_MODEL_NAME "m68030"
207 # define M68K_HAS_VBR 1
208 # define M68K_HAS_SEPARATE_STACKS 1
209 # define M68K_HAS_BFFFO 1
210 # define M68K_HAS_PREINDEXING 1
211 # define M68K_HAS_EXTB_L 1
212 # define M68K_HAS_MISALIGNED 1
213 # if defined (__HAVE_68881__)
214 # define M68K_HAS_FPU 1
215 # define M68K_HAS_FPSP_PACKAGE 0
216 # else
217 # define M68K_HAS_FPU 0
218 # define M68K_HAS_FPSP_PACKAGE 0
219 # endif
220 
221 # elif defined(__mc68040__)
222 
223 # define CPU_MODEL_NAME "m68040"
224 # define M68K_HAS_VBR 1
225 # define M68K_HAS_SEPARATE_STACKS 1
226 # define M68K_HAS_BFFFO 1
227 # define M68K_HAS_PREINDEXING 1
228 # define M68K_HAS_EXTB_L 1
229 # define M68K_HAS_MISALIGNED 1
230 # if defined (__HAVE_68881__)
231 # define M68K_HAS_FPU 1
232 # define M68K_HAS_FPSP_PACKAGE 1
233 # else
234 # define M68K_HAS_FPU 0
235 # define M68K_HAS_FPSP_PACKAGE 0
236 # endif
237 
238 # elif defined(__mc68060__)
239 
240 # define CPU_MODEL_NAME "m68060"
241 # define M68K_HAS_VBR 1
242 # define M68K_HAS_SEPARATE_STACKS 0
243 # define M68K_HAS_BFFFO 1
244 # define M68K_HAS_PREINDEXING 1
245 # define M68K_HAS_EXTB_L 1
246 # define M68K_HAS_MISALIGNED 1
247 # if defined (__HAVE_68881__)
248 # define M68K_HAS_FPU 1
249 # define M68K_HAS_FPSP_PACKAGE 0
250 # else
251 # define M68K_HAS_FPU 0
252 # define M68K_HAS_FPSP_PACKAGE 0
253 # endif
254 
255 # elif defined(__mc68302__)
256 
257 # define CPU_MODEL_NAME "m68302"
258 # define M68K_HAS_VBR 0
259 # define M68K_HAS_SEPARATE_STACKS 0
260 # define M68K_HAS_BFFFO 0
261 # define M68K_HAS_PREINDEXING 0
262 # define M68K_HAS_EXTB_L 0
263 # define M68K_HAS_MISALIGNED 0
264 # define M68K_HAS_FPU 0
265 # define M68K_HAS_FPSP_PACKAGE 0
266 
267  /* gcc and egcs do not distinguish between CPU32 and CPU32+ */
268 # elif defined(RTEMS__mcpu32p__)
269 
270 # define CPU_MODEL_NAME "mcpu32+"
271 # define M68K_HAS_VBR 1
272 # define M68K_HAS_SEPARATE_STACKS 0
273 # define M68K_HAS_BFFFO 0
274 # define M68K_HAS_PREINDEXING 1
275 # define M68K_HAS_EXTB_L 1
276 # define M68K_HAS_MISALIGNED 1
277 # define M68K_HAS_FPU 0
278 # define M68K_HAS_FPSP_PACKAGE 0
279 
280 # elif defined(__mcpu32__)
281 
282 # define CPU_MODEL_NAME "mcpu32"
283 # define M68K_HAS_VBR 1
284 # define M68K_HAS_SEPARATE_STACKS 0
285 # define M68K_HAS_BFFFO 0
286 # define M68K_HAS_PREINDEXING 1
287 # define M68K_HAS_EXTB_L 1
288 # define M68K_HAS_MISALIGNED 0
289 # define M68K_HAS_FPU 0
290 # define M68K_HAS_FPSP_PACKAGE 0
291 
292 # elif defined(__mc68000__)
293 
294 # define CPU_MODEL_NAME "m68000"
295 # define M68K_HAS_VBR 0
296 # define M68K_HAS_SEPARATE_STACKS 0
297 # define M68K_HAS_BFFFO 0
298 # define M68K_HAS_PREINDEXING 0
299 # define M68K_HAS_EXTB_L 0
300 # define M68K_HAS_MISALIGNED 0
301 # if defined (__HAVE_68881__)
302 # define M68K_HAS_FPU 1
303 # define M68K_HAS_FPSP_PACKAGE 0
304 # else
305 # define M68K_HAS_FPU 0
306 # define M68K_HAS_FPSP_PACKAGE 0
307 # endif
308 
309 # else
310 
311 # error "Unsupported 68000 CPU model -- are you sure you're running a 68k compiler?"
312 
313 # endif
314 
315 /*
316  * No Tiny RTEMS support on the standard 68000 family.
317  */
318 # define M68K_CPU_STACK_MINIMUM_SIZE 4096
319 # define M68K_CPU_PRIORITY_MAXIMUM 255
320 
321 #endif
322 
323 /*
324  * OBSOLETE: Backward compatibility only - Don't use.
325  * Use __mcoldfire__ instead.
326  */
327 #if defined(__mcoldfire__)
328 #define M68K_COLDFIRE_ARCH 1
329 #else
330 #define M68K_COLDFIRE_ARCH 0
331 #endif
332 
333 #ifndef ASM
334 
335 #if ( defined(__mcoldfire__) )
336 #define m68k_disable_interrupts( _level ) \
337  do { register uint32_t _tmpsr = 0x0700; \
338  __asm__ volatile ( "move.w %%sr,%0\n\t" \
339  "or.l %0,%1\n\t" \
340  "move.w %1,%%sr" \
341  : "=d" (_level), "=d"(_tmpsr) : "1"(_tmpsr) \
342  : "cc" ); \
343  } while( 0 )
344 #else
345 #define m68k_disable_interrupts( _level ) \
346  __asm__ volatile ( "move.w %%sr,%0\n\t" \
347  "or.w #0x0700,%%sr" \
348  : "=d" (_level) \
349  : : "cc" )
350 #endif
351 
352 #define m68k_enable_interrupts( _level ) \
353  __asm__ volatile ( "move.w %0,%%sr " : : "d" (_level) : "cc");
354 
355 #if ( defined(__mcoldfire__) )
356 #define m68k_flash_interrupts( _level ) \
357  do { register uint32_t _tmpsr = 0x0700; \
358  asm volatile ( "move.w %2,%%sr\n\t" \
359  "or.l %2,%1\n\t" \
360  "move.w %1,%%sr" \
361  : "=d"(_tmpsr) : "0"(_tmpsr), "d"(_level) \
362  : "cc"); \
363  } while( 0 )
364 #else
365 #define m68k_flash_interrupts( _level ) \
366  __asm__ volatile ( "move.w %0,%%sr\n\t" \
367  "or.w #0x0700,%%sr" \
368  : : "d" (_level) \
369  : "cc" )
370 #endif
371 
372 #define m68k_get_interrupt_level( _level ) \
373  do { \
374  register uint32_t _tmpsr; \
375  \
376  __asm__ volatile( "move.w %%sr,%0" : "=d" (_tmpsr)); \
377  _level = (_tmpsr & 0x0700) >> 8; \
378  } while (0)
379 
380 #define m68k_set_interrupt_level( _newlevel ) \
381  do { \
382  register uint32_t _tmpsr; \
383  \
384  __asm__ volatile( "move.w %%sr,%0" : "=d" (_tmpsr)); \
385  _tmpsr = (_tmpsr & 0xf8ff) | ((_newlevel) << 8); \
386  __asm__ volatile( "move.w %0,%%sr" : : "d" (_tmpsr)); \
387  } while (0)
388 
389 #if ( M68K_HAS_VBR == 1 && !defined(__mcoldfire__) )
390 #define m68k_get_vbr( vbr ) \
391  __asm__ volatile ( "movec %%vbr,%0 " : "=r" (vbr))
392 
393 #define m68k_set_vbr( vbr ) \
394  __asm__ volatile ( "movec %0,%%vbr " : : "r" (vbr))
395 
396 #elif ( defined(__mcoldfire__) )
397 extern void* _VBR;
398 #define m68k_get_vbr( _vbr ) _vbr = &_VBR
399 
400 #define m68k_set_vbr( _vbr ) \
401  do { \
402  __asm__ volatile ( "movec %0,%%vbr " : : "r" (_vbr)); \
403  _VBR = (void *)_vbr; \
404  } while(0)
405 
406 #else
407 #define m68k_get_vbr( _vbr ) _vbr = (void *)_VBR
408 #define m68k_set_vbr( _vbr )
409 #endif
410 
411 /*
412  * Access Control Registers
413  */
414 #define m68k_set_cacr(_cacr) __asm__ volatile ("movec %0,%%cacr" : : "d" (_cacr))
415 #define m68k_set_acr0(_acr0) __asm__ volatile ("movec %0,%%acr0" : : "d" (_acr0))
416 #define m68k_set_acr1(_acr1) __asm__ volatile ("movec %0,%%acr1" : : "d" (_acr1))
417 
418 /*
419  * The following routine swaps the endian format of an unsigned int.
420  * It must be static because it is referenced indirectly.
421  */
422 #if ( defined(__mcoldfire__) )
423 
424 /* There are no rotate commands in Coldfire architecture. We will use
425  * generic implementation of endian swapping for Coldfire.
426  */
427 static inline uint32_t m68k_swap_u32(
428  uint32_t value
429  )
430 {
431  uint32_t byte1, byte2, byte3, byte4, swapped;
432 
433  byte4 = (value >> 24) & 0xff;
434  byte3 = (value >> 16) & 0xff;
435  byte2 = (value >> 8) & 0xff;
436  byte1 = value & 0xff;
437 
438  swapped = (byte1 << 24) | (byte2 << 16) | (byte3 << 8) | byte4;
439  return( swapped );
440 }
441 
442 static inline uint16_t m68k_swap_u16(
443  uint16_t value
444 )
445 {
446  return (((value & 0xff) << 8) | ((value >> 8) & 0xff));
447 }
448 
449 #else
450 
451 static inline uint32_t m68k_swap_u32(
452  uint32_t value
453 )
454 {
455  uint32_t swapped = value;
456 
457  __asm__ volatile( "rorw #8,%0" : "=d" (swapped) : "0" (swapped) );
458  __asm__ volatile( "swap %0" : "=d" (swapped) : "0" (swapped) );
459  __asm__ volatile( "rorw #8,%0" : "=d" (swapped) : "0" (swapped) );
460 
461  return( swapped );
462 }
463 
464 static inline uint16_t m68k_swap_u16(
465  uint16_t value
466 )
467 {
468  uint16_t swapped = value;
469 
470  __asm__ volatile( "rorw #8,%0" : "=d" (swapped) : "0" (swapped) );
471 
472  return( swapped );
473 }
474 #endif
475 
476 #define CPU_swap_u32( value ) m68k_swap_u32( value )
477 #define CPU_swap_u16( value ) m68k_swap_u16( value )
478 
479 
480 /*
481  * _CPU_virtual_to_physical
482  *
483  * This function is used to map virtual addresses to physical
484  * addresses.
485  *
486  * FIXME: ASSUMES THAT VIRTUAL ADDRESSES ARE THE SAME AS THE
487  * PHYSICAL ADDRESSES
488  */
489 static inline void * _CPU_virtual_to_physical (
490  const void * d_addr )
491 {
492  return (void *) d_addr;
493 }
494 
495 
496 #endif /* !ASM */
497 
498 #ifdef __cplusplus
499 }
500 #endif
501 
502 #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.