RTEMS
6.3
Toggle main menu visibility
Loading...
Searching...
No Matches
cpukit
score
cpu
m68k
include
rtems
score
m68k.h
Go to the documentation of this file.
1
/* SPDX-License-Identifier: BSD-2-Clause */
2
13
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
44
extern
"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__) )
418
extern
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
*/
448
static
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
463
static
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
472
static
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
485
static
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
*/
510
static
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 */
Generated by
1.18.0