RTEMS 5.2
All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
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
25extern "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__) )
399extern 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 */
429static 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
444static 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
453static 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
466static 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 */
491static 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.