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