summaryrefslogtreecommitdiffstats
path: root/c/src/exec/score/cpu/m68k/m68k.h
blob: 0eb3f0fd4ca68a47e44609f546d196587cf19c1f (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
/*  m68k.h
 *
 *  This include file contains information pertaining to the Motorola
 *  m68xxx processor family.
 *
 *  COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994.
 *  On-Line Applications Research Corporation (OAR).
 *  All rights assigned to U.S. Government, 1994.
 *
 *  This material may be reproduced by or for the U.S. Government pursuant
 *  to the copyright license under the clause at DFARS 252.227-7013.  This
 *  notice must appear in all copies of this file and its derivatives.
 *
 *  $Id$
 */

#ifndef __M68k_h
#define __M68k_h

#ifdef __cplusplus
extern "C" {
#endif

/*
 *  This section contains the information required to build
 *  RTEMS for a particular member of the Motorola MC68xxx
 *  family.  It does this by setting variables to indicate
 *  which implementation dependent features are present in
 *  a particular member of the family.
 *
 *  Currently recognized:
 *     m68000        (no FP)
 *     m68020        (implies FP)
 *     m68020_nofp   (no FP)
 *     m68030        (implies FP)
 *     m68040        (implies FP)
 *     m68lc040      (no FP)
 *     m68ec040      (no FP)
 *     m68302        (no FP)
 *     m68332        (no FP)
 *     mcpu32        (no FP)  (includes m68360)
 *
 *  Primary difference (for RTEMS) between m68040, m680lc040, and 
 *  m68ec040 is the presence or absence of the FPU.
 *
 *  Here is some information on the 040 variants (courtesy of Doug McBride,
 *  mcbride@rodin.colorado.edu):
 *
 *    "The 68040 is a superset of the 68EC040 and the 68LC040.  The
 *    68EC040 and 68LC040 do not have FPU's.  The 68LC040 and the
 *    68EC040 have renamed the DLE pin as JS0 which must be tied to
 *    Gnd or Vcc. The 68EC040 has renamed the MDIS pin as JS1.  The
 *    68EC040 has access control units instead of memory management units.
 *    The 68EC040 should not have the PFLUSH or PTEST instructions executed
 *    (cause an indeterminate result).  The 68EC040 and 68LC040 do not
 *    implement the DLE or multiplexed bus modes.  The 68EC040 does not
 *    implement the output buffer impedance selection mode of operation."
 *
 *  M68K_HAS_EXTB_L is used to enable/disable usage of the extb.l instruction
 *  which is not available for 68000 or 68ec000 cores (68000, 68001, 68008, 
 *  68010, 68302, 68306, 68307).  This instruction is available on the 68020
 *  up and the cpu32 based models.  
 *
 *  NOTE:
 *    Eventually it would be nice to evaluate doing a lot of this section
 *    by having each model specify which core it uses and then go from there.
 */

#if defined(m68000)
 
#define CPU_MODEL_NAME         "m68000"
#define M68K_HAS_VBR             0
#define M68K_HAS_SEPARATE_STACKS 0
#define M68K_HAS_FPU             0
#define M68K_HAS_BFFFO           0
#define M68K_HAS_PREINDEXING     0
#define M68K_HAS_EXTB_L          0
#define M68K_HAS_FPSP_PACKAGE    0

#elif defined(m68020)
 
#define CPU_MODEL_NAME         "m68020"
#define M68K_HAS_VBR             1
#define M68K_HAS_SEPARATE_STACKS 1
#define M68K_HAS_FPU             1
#define M68K_HAS_BFFFO           1
#define M68K_HAS_PREINDEXING     1
#define M68K_HAS_EXTB_L          1
#define M68K_HAS_FPSP_PACKAGE    0
 
#elif defined(m68020_nofp)
 
#define CPU_MODEL_NAME         "m68020 w/o fp"
#define M68K_HAS_VBR             1
#define M68K_HAS_SEPARATE_STACKS 1
#define M68K_HAS_FPU             0
#define M68K_HAS_BFFFO           1
#define M68K_HAS_PREINDEXING     1
#define M68K_HAS_EXTB_L          1
#define M68K_HAS_FPSP_PACKAGE    0
 
#elif defined(m68030)
 
#define CPU_MODEL_NAME         "m68030"
#define M68K_HAS_VBR             1
#define M68K_HAS_SEPARATE_STACKS 1
#define M68K_HAS_FPU             1
#define M68K_HAS_BFFFO           1
#define M68K_HAS_PREINDEXING     1
#define M68K_HAS_EXTB_L          1
#define M68K_HAS_FPSP_PACKAGE    0
 
#elif defined(m68040)

#define CPU_MODEL_NAME         "m68040"
#define M68K_HAS_VBR             1
#define M68K_HAS_SEPARATE_STACKS 1
#define M68K_HAS_FPU             1
#define M68K_HAS_BFFFO           1
#define M68K_HAS_PREINDEXING     1
#define M68K_HAS_EXTB_L          1
#define M68K_HAS_FPSP_PACKAGE    1
 
#elif defined(m68lc040)

#define CPU_MODEL_NAME         "m68lc040"
#define M68K_HAS_VBR             1
#define M68K_HAS_SEPARATE_STACKS 1
#define M68K_HAS_FPU             0
#define M68K_HAS_BFFFO           1
#define M68K_HAS_PREINDEXING     1
#define M68K_HAS_EXTB_L          1
#define M68K_HAS_FPSP_PACKAGE    0
 
#elif defined(m68ec040)

#define CPU_MODEL_NAME         "m68ec040"
#define M68K_HAS_VBR             1
#define M68K_HAS_SEPARATE_STACKS 1
#define M68K_HAS_FPU             0
#define M68K_HAS_BFFFO           1
#define M68K_HAS_PREINDEXING     1
#define M68K_HAS_EXTB_L          1
#define M68K_HAS_FPSP_PACKAGE    0

#elif defined(m68302)
 /* essentially a m68000 with onboard peripherals */
#define CPU_MODEL_NAME         "m68302"
#define M68K_HAS_VBR             0
#define M68K_HAS_SEPARATE_STACKS 0
#define M68K_HAS_FPU             0
#define M68K_HAS_BFFFO           0
#define M68K_HAS_PREINDEXING     0
#define M68K_HAS_EXTB_L          0
#define M68K_HAS_FPSP_PACKAGE    0

#elif defined(m68332)
 
#define CPU_MODEL_NAME         "m68332"
#define M68K_HAS_VBR             1
#define M68K_HAS_SEPARATE_STACKS 0
#define M68K_HAS_FPU             0
#define M68K_HAS_BFFFO           0
#define M68K_HAS_PREINDEXING     0
#define M68K_HAS_EXTB_L          1
#define M68K_HAS_FPSP_PACKAGE    0

#elif defined(mcpu32)
 
#define CPU_MODEL_NAME         "mcpu32"
#define M68K_HAS_VBR             1
#define M68K_HAS_SEPARATE_STACKS 0
#define M68K_HAS_FPU             0
#define M68K_HAS_BFFFO           0
#define M68K_HAS_PREINDEXING     1
#define M68K_HAS_EXTB_L          1
#define M68K_HAS_FPSP_PACKAGE    0

#else

#error "Unsupported CPU Model"

#endif

/*
 *  Define the name of the CPU family.
 */

#define CPU_NAME "Motorola MC68xxx"

#ifndef ASM

#define m68k_disable_interrupts( _level ) \
  asm volatile ( "movew   %%sr,%0\n\t" \
                 "orw     #0x0700,%%sr" \
                    : "=d" (_level))

#define m68k_enable_interrupts( _level ) \
  asm volatile ( "movew   %0,%%sr " : : "d" (_level));

#define m68k_flash_interrupts( _level ) \
  asm volatile ( "movew   %0,%%sr\n\t" \
                 "orw     #0x0700,%%sr" \
                    : : "d" (_level))

#define m68k_get_interrupt_level( _level ) \
  do { \
    register unsigned32 _tmpsr; \
    \
    asm volatile( "movw  %%sr,%0" : "=d" (_tmpsr)); \
    _level = (_tmpsr & 0x0700) >> 8; \
  } while (0)
    
#define m68k_set_interrupt_level( _newlevel ) \
  do { \
    register unsigned32 _tmpsr; \
    \
    asm volatile( "movw  %%sr,%0" : "=d" (_tmpsr)); \
    _tmpsr = (_tmpsr & 0xf8ff) | ((_newlevel) << 8); \
    asm volatile( "movw  %0,%%sr" : : "d" (_tmpsr)); \
  } while (0)

#if ( M68K_HAS_VBR == 1 )
#define m68k_get_vbr( vbr ) \
  asm volatile ( "movec   %%vbr,%0 " : "=r" (vbr))

#define m68k_set_vbr( vbr ) \
  asm volatile ( "movec   %0,%%vbr " : : "r" (vbr))
#else
#define m68k_get_vbr( _vbr ) _vbr = (void *)_VBR
#define m68k_set_vbr( _vbr )
#endif

/*
 *  The following routine swaps the endian format of an unsigned int.
 *  It must be static because it is referenced indirectly.
 */

static inline unsigned int m68k_swap_u32(
  unsigned int value
)
{
  unsigned int swapped = value;

  asm volatile( "rorw  #8,%0" : "=d" (swapped) : "0" (swapped) );
  asm volatile( "swap  %0"    : "=d" (swapped) : "0" (swapped) );
  asm volatile( "rorw  #8,%0" : "=d" (swapped) : "0" (swapped) );

  return( swapped );
}

/* XXX this is only valid for some m68k family members and should be fixed */

#define m68k_enable_caching() \
  { register unsigned32 _ctl=0x01; \
    asm volatile ( "movec   %0,%%cacr" \
                       : "=d" (_ctl) : "0" (_ctl) ); \
  }

#define CPU_swap_u32( value )  m68k_swap_u32( value )

#ifdef __cplusplus
}
#endif

#endif  /* !ASM */

#endif
/* end of include file */