[a911a77] | 1 | /** |
---|
| 2 | * @file rtems/score/m68k.h |
---|
| 3 | */ |
---|
| 4 | |
---|
| 5 | /* |
---|
[7908ba5b] | 6 | * This include file contains information pertaining to the Motorola |
---|
| 7 | * m68xxx processor family. |
---|
| 8 | * |
---|
[08311cc3] | 9 | * COPYRIGHT (c) 1989-1999. |
---|
[7908ba5b] | 10 | * On-Line Applications Research Corporation (OAR). |
---|
| 11 | * |
---|
| 12 | * The license and distribution terms for this file may be |
---|
| 13 | * found in the file LICENSE in this distribution or at |
---|
[05a98b7] | 14 | * http://www.rtems.com/license/LICENSE. |
---|
[7908ba5b] | 15 | * |
---|
| 16 | * $Id$ |
---|
| 17 | */ |
---|
| 18 | |
---|
| 19 | #ifndef __M68k_h |
---|
| 20 | #define __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 | * |
---|
| 49 | * As of gcc 2.8.1 and egcs 1.1, there is no distinction made between |
---|
| 50 | * the CPU32 and CPU32+. The option -mcpu32 generates code which can |
---|
| 51 | * be run on either core. RTEMS distinguishes between these two cores |
---|
| 52 | * because they have different alignment rules which impact performance. |
---|
| 53 | * If you are using a CPU32+, then the symbol RTEMS__mcpu32p__ should |
---|
| 54 | * be defined in your custom file (see make/custom/gen68360.cfg for an |
---|
| 55 | * example of how to do this. If gcc ever distinguishes between these |
---|
| 56 | * two cores, then RTEMS__mcpu32p__ usage will be replaced with the |
---|
| 57 | * appropriate compiler defined predefine. |
---|
| 58 | * |
---|
| 59 | * Here is some information on the 040 variants (courtesy of Doug McBride, |
---|
| 60 | * mcbride@rodin.colorado.edu): |
---|
| 61 | * |
---|
| 62 | * "The 68040 is a superset of the 68EC040 and the 68LC040. The |
---|
| 63 | * 68EC040 and 68LC040 do not have FPU's. The 68LC040 and the |
---|
| 64 | * 68EC040 have renamed the DLE pin as JS0 which must be tied to |
---|
| 65 | * Gnd or Vcc. The 68EC040 has renamed the MDIS pin as JS1. The |
---|
| 66 | * 68EC040 has access control units instead of memory management units. |
---|
| 67 | * The 68EC040 should not have the PFLUSH or PTEST instructions executed |
---|
| 68 | * (cause an indeterminate result). The 68EC040 and 68LC040 do not |
---|
| 69 | * implement the DLE or multiplexed bus modes. The 68EC040 does not |
---|
| 70 | * implement the output buffer impedance selection mode of operation." |
---|
| 71 | * |
---|
| 72 | * M68K_HAS_EXTB_L is used to enable/disable usage of the extb.l instruction |
---|
| 73 | * which is not available for 68000 or 68ec000 cores (68000, 68001, 68008, |
---|
| 74 | * 68010, 68302, 68306, 68307). This instruction is available on the 68020 |
---|
| 75 | * up and the cpu32 based models. |
---|
| 76 | * |
---|
| 77 | * M68K_HAS_MISALIGNED is non-zero if the CPU allows byte-misaligned |
---|
| 78 | * data access (68020, 68030, 68040, 68060, CPU32+). |
---|
| 79 | * |
---|
| 80 | * NOTE: |
---|
| 81 | * Eventually it would be nice to evaluate doing a lot of this section |
---|
| 82 | * by having each model specify which core it uses and then go from there. |
---|
| 83 | */ |
---|
| 84 | |
---|
[df49c60] | 85 | /* |
---|
| 86 | * Figure out all CPU Model Feature Flags based upon compiler |
---|
| 87 | * predefines. Notice the only exception to this is that |
---|
| 88 | * gcc does not distinguish between CPU32 and CPU32+. This |
---|
| 89 | * feature selection logic is setup such that if RTEMS__mcpu32p__ |
---|
| 90 | * is defined, then CPU32+ rules are used. Otherwise, the safe |
---|
| 91 | * but less efficient CPU32 rules are used for the CPU32+. |
---|
| 92 | */ |
---|
| 93 | |
---|
[7908ba5b] | 94 | #if defined(__mc68020__) |
---|
| 95 | |
---|
| 96 | #define CPU_MODEL_NAME "m68020" |
---|
| 97 | #define M68K_HAS_VBR 1 |
---|
| 98 | #define M68K_HAS_SEPARATE_STACKS 1 |
---|
| 99 | #define M68K_HAS_BFFFO 1 |
---|
| 100 | #define M68K_HAS_PREINDEXING 1 |
---|
| 101 | #define M68K_HAS_EXTB_L 1 |
---|
| 102 | #define M68K_HAS_MISALIGNED 1 |
---|
| 103 | # if defined (__HAVE_68881__) |
---|
| 104 | # define M68K_HAS_FPU 1 |
---|
| 105 | # define M68K_HAS_FPSP_PACKAGE 0 |
---|
| 106 | # else |
---|
| 107 | # define M68K_HAS_FPU 0 |
---|
| 108 | # define M68K_HAS_FPSP_PACKAGE 0 |
---|
| 109 | # endif |
---|
| 110 | |
---|
| 111 | #elif defined(__mc68030__) |
---|
| 112 | |
---|
| 113 | #define CPU_MODEL_NAME "m68030" |
---|
| 114 | #define M68K_HAS_VBR 1 |
---|
| 115 | #define M68K_HAS_SEPARATE_STACKS 1 |
---|
| 116 | #define M68K_HAS_BFFFO 1 |
---|
| 117 | #define M68K_HAS_PREINDEXING 1 |
---|
| 118 | #define M68K_HAS_EXTB_L 1 |
---|
| 119 | #define M68K_HAS_MISALIGNED 1 |
---|
| 120 | # if defined (__HAVE_68881__) |
---|
| 121 | # define M68K_HAS_FPU 1 |
---|
| 122 | # define M68K_HAS_FPSP_PACKAGE 0 |
---|
| 123 | # else |
---|
| 124 | # define M68K_HAS_FPU 0 |
---|
| 125 | # define M68K_HAS_FPSP_PACKAGE 0 |
---|
| 126 | # endif |
---|
| 127 | |
---|
| 128 | #elif defined(__mc68040__) |
---|
| 129 | |
---|
| 130 | #define CPU_MODEL_NAME "m68040" |
---|
| 131 | #define M68K_HAS_VBR 1 |
---|
| 132 | #define M68K_HAS_SEPARATE_STACKS 1 |
---|
| 133 | #define M68K_HAS_BFFFO 1 |
---|
| 134 | #define M68K_HAS_PREINDEXING 1 |
---|
| 135 | #define M68K_HAS_EXTB_L 1 |
---|
| 136 | #define M68K_HAS_MISALIGNED 1 |
---|
| 137 | # if defined (__HAVE_68881__) |
---|
| 138 | # define M68K_HAS_FPU 1 |
---|
| 139 | # define M68K_HAS_FPSP_PACKAGE 1 |
---|
| 140 | # else |
---|
| 141 | # define M68K_HAS_FPU 0 |
---|
| 142 | # define M68K_HAS_FPSP_PACKAGE 0 |
---|
| 143 | # endif |
---|
| 144 | |
---|
| 145 | #elif defined(__mc68060__) |
---|
| 146 | |
---|
| 147 | #define CPU_MODEL_NAME "m68060" |
---|
| 148 | #define M68K_HAS_VBR 1 |
---|
| 149 | #define M68K_HAS_SEPARATE_STACKS 0 |
---|
| 150 | #define M68K_HAS_BFFFO 1 |
---|
| 151 | #define M68K_HAS_PREINDEXING 1 |
---|
| 152 | #define M68K_HAS_EXTB_L 1 |
---|
| 153 | #define M68K_HAS_MISALIGNED 1 |
---|
| 154 | # if defined (__HAVE_68881__) |
---|
| 155 | # define M68K_HAS_FPU 1 |
---|
[2c7e8e51] | 156 | # define M68K_HAS_FPSP_PACKAGE 0 |
---|
[7908ba5b] | 157 | # else |
---|
| 158 | # define M68K_HAS_FPU 0 |
---|
| 159 | # define M68K_HAS_FPSP_PACKAGE 0 |
---|
| 160 | # endif |
---|
| 161 | |
---|
| 162 | #elif defined(__mc68302__) |
---|
[8ef3818] | 163 | |
---|
[7908ba5b] | 164 | #define CPU_MODEL_NAME "m68302" |
---|
| 165 | #define M68K_HAS_VBR 0 |
---|
| 166 | #define M68K_HAS_SEPARATE_STACKS 0 |
---|
| 167 | #define M68K_HAS_BFFFO 0 |
---|
| 168 | #define M68K_HAS_PREINDEXING 0 |
---|
| 169 | #define M68K_HAS_EXTB_L 0 |
---|
| 170 | #define M68K_HAS_MISALIGNED 0 |
---|
| 171 | #define M68K_HAS_FPU 0 |
---|
| 172 | #define M68K_HAS_FPSP_PACKAGE 0 |
---|
| 173 | |
---|
| 174 | /* gcc and egcs do not distinguish between CPU32 and CPU32+ */ |
---|
| 175 | #elif defined(RTEMS__mcpu32p__) |
---|
| 176 | |
---|
| 177 | #define CPU_MODEL_NAME "mcpu32+" |
---|
| 178 | #define M68K_HAS_VBR 1 |
---|
| 179 | #define M68K_HAS_SEPARATE_STACKS 0 |
---|
| 180 | #define M68K_HAS_BFFFO 0 |
---|
| 181 | #define M68K_HAS_PREINDEXING 1 |
---|
| 182 | #define M68K_HAS_EXTB_L 1 |
---|
| 183 | #define M68K_HAS_MISALIGNED 1 |
---|
| 184 | #define M68K_HAS_FPU 0 |
---|
| 185 | #define M68K_HAS_FPSP_PACKAGE 0 |
---|
| 186 | |
---|
| 187 | #elif defined(__mcpu32__) |
---|
| 188 | |
---|
| 189 | #define CPU_MODEL_NAME "mcpu32" |
---|
| 190 | #define M68K_HAS_VBR 1 |
---|
| 191 | #define M68K_HAS_SEPARATE_STACKS 0 |
---|
| 192 | #define M68K_HAS_BFFFO 0 |
---|
| 193 | #define M68K_HAS_PREINDEXING 1 |
---|
| 194 | #define M68K_HAS_EXTB_L 1 |
---|
| 195 | #define M68K_HAS_MISALIGNED 0 |
---|
| 196 | #define M68K_HAS_FPU 0 |
---|
| 197 | #define M68K_HAS_FPSP_PACKAGE 0 |
---|
| 198 | |
---|
| 199 | #elif defined(__mcf5200__) |
---|
| 200 | /* Motorola ColdFire V2 core - RISC/68020 hybrid */ |
---|
| 201 | #define CPU_MODEL_NAME "m5200" |
---|
| 202 | #define M68K_HAS_VBR 1 |
---|
| 203 | #define M68K_HAS_BFFFO 0 |
---|
| 204 | #define M68K_HAS_SEPARATE_STACKS 0 |
---|
| 205 | #define M68K_HAS_PREINDEXING 0 |
---|
| 206 | #define M68K_HAS_EXTB_L 1 |
---|
| 207 | #define M68K_HAS_MISALIGNED 1 |
---|
| 208 | #define M68K_HAS_FPU 0 |
---|
| 209 | #define M68K_HAS_FPSP_PACKAGE 0 |
---|
| 210 | #define M68K_COLDFIRE_ARCH 1 |
---|
| 211 | |
---|
| 212 | #elif defined(__mc68000__) |
---|
| 213 | |
---|
| 214 | #define CPU_MODEL_NAME "m68000" |
---|
| 215 | #define M68K_HAS_VBR 0 |
---|
| 216 | #define M68K_HAS_SEPARATE_STACKS 0 |
---|
| 217 | #define M68K_HAS_BFFFO 0 |
---|
| 218 | #define M68K_HAS_PREINDEXING 0 |
---|
| 219 | #define M68K_HAS_EXTB_L 0 |
---|
| 220 | #define M68K_HAS_MISALIGNED 0 |
---|
| 221 | # if defined (__HAVE_68881__) |
---|
| 222 | # define M68K_HAS_FPU 1 |
---|
| 223 | # define M68K_HAS_FPSP_PACKAGE 0 |
---|
| 224 | # else |
---|
| 225 | # define M68K_HAS_FPU 0 |
---|
| 226 | # define M68K_HAS_FPSP_PACKAGE 0 |
---|
| 227 | # endif |
---|
| 228 | |
---|
| 229 | #else |
---|
| 230 | |
---|
| 231 | #error "Unsupported CPU model -- are you sure you're running a 68k compiler?" |
---|
| 232 | |
---|
| 233 | #endif |
---|
| 234 | |
---|
[9f9871f] | 235 | #ifndef ASM |
---|
[ce3c6f3e] | 236 | #include <rtems/score/types.h> |
---|
[0cc9d277] | 237 | #include <stdint.h> |
---|
[9f9871f] | 238 | #endif |
---|
| 239 | |
---|
[7908ba5b] | 240 | /* |
---|
| 241 | * If the above did not specify a ColdFire architecture, then set |
---|
| 242 | * this flag to indicate that it is not a ColdFire CPU. |
---|
| 243 | */ |
---|
| 244 | |
---|
| 245 | #if !defined(M68K_COLDFIRE_ARCH) |
---|
| 246 | #define M68K_COLDFIRE_ARCH 0 |
---|
| 247 | #endif |
---|
| 248 | |
---|
| 249 | /* |
---|
| 250 | * Define the name of the CPU family. |
---|
| 251 | */ |
---|
| 252 | |
---|
| 253 | #if ( M68K_COLDFIRE_ARCH == 1 ) |
---|
| 254 | #define CPU_NAME "Motorola ColdFire" |
---|
| 255 | #else |
---|
| 256 | #define CPU_NAME "Motorola MC68xxx" |
---|
| 257 | #endif |
---|
| 258 | |
---|
| 259 | #ifndef ASM |
---|
| 260 | |
---|
| 261 | #if ( M68K_COLDFIRE_ARCH == 1 ) |
---|
| 262 | #define m68k_disable_interrupts( _level ) \ |
---|
[d86bae8] | 263 | do { register uint32_t _tmpsr = 0x0700; \ |
---|
[7908ba5b] | 264 | asm volatile ( "move.w %%sr,%0\n\t" \ |
---|
| 265 | "or.l %0,%1\n\t" \ |
---|
| 266 | "move.w %1,%%sr" \ |
---|
| 267 | : "=d" (_level), "=d"(_tmpsr) : "1"(_tmpsr) ); \ |
---|
| 268 | } while( 0 ) |
---|
| 269 | #else |
---|
| 270 | #define m68k_disable_interrupts( _level ) \ |
---|
| 271 | asm volatile ( "move.w %%sr,%0\n\t" \ |
---|
| 272 | "or.w #0x0700,%%sr" \ |
---|
| 273 | : "=d" (_level)) |
---|
| 274 | #endif |
---|
| 275 | |
---|
| 276 | #define m68k_enable_interrupts( _level ) \ |
---|
| 277 | asm volatile ( "move.w %0,%%sr " : : "d" (_level)); |
---|
| 278 | |
---|
| 279 | #if ( M68K_COLDFIRE_ARCH == 1 ) |
---|
| 280 | #define m68k_flash_interrupts( _level ) \ |
---|
[d86bae8] | 281 | do { register uint32_t _tmpsr = 0x0700; \ |
---|
[7908ba5b] | 282 | asm volatile ( "move.w %2,%%sr\n\t" \ |
---|
| 283 | "or.l %2,%1\n\t" \ |
---|
| 284 | "move.w %1,%%sr" \ |
---|
| 285 | : "=d"(_tmpsr) : "0"(_tmpsr), "d"(_level) ); \ |
---|
| 286 | } while( 0 ) |
---|
| 287 | #else |
---|
| 288 | #define m68k_flash_interrupts( _level ) \ |
---|
| 289 | asm volatile ( "move.w %0,%%sr\n\t" \ |
---|
| 290 | "or.w #0x0700,%%sr" \ |
---|
| 291 | : : "d" (_level)) |
---|
| 292 | #endif |
---|
| 293 | |
---|
| 294 | #define m68k_get_interrupt_level( _level ) \ |
---|
| 295 | do { \ |
---|
[d86bae8] | 296 | register uint32_t _tmpsr; \ |
---|
[7908ba5b] | 297 | \ |
---|
| 298 | asm volatile( "move.w %%sr,%0" : "=d" (_tmpsr)); \ |
---|
| 299 | _level = (_tmpsr & 0x0700) >> 8; \ |
---|
| 300 | } while (0) |
---|
| 301 | |
---|
| 302 | #define m68k_set_interrupt_level( _newlevel ) \ |
---|
| 303 | do { \ |
---|
[d86bae8] | 304 | register uint32_t _tmpsr; \ |
---|
[7908ba5b] | 305 | \ |
---|
| 306 | asm volatile( "move.w %%sr,%0" : "=d" (_tmpsr)); \ |
---|
| 307 | _tmpsr = (_tmpsr & 0xf8ff) | ((_newlevel) << 8); \ |
---|
| 308 | asm volatile( "move.w %0,%%sr" : : "d" (_tmpsr)); \ |
---|
| 309 | } while (0) |
---|
| 310 | |
---|
| 311 | #if ( M68K_HAS_VBR == 1 && M68K_COLDFIRE_ARCH == 0 ) |
---|
| 312 | #define m68k_get_vbr( vbr ) \ |
---|
| 313 | asm volatile ( "movec %%vbr,%0 " : "=r" (vbr)) |
---|
| 314 | |
---|
| 315 | #define m68k_set_vbr( vbr ) \ |
---|
| 316 | asm volatile ( "movec %0,%%vbr " : : "r" (vbr)) |
---|
| 317 | |
---|
| 318 | #elif ( M68K_COLDFIRE_ARCH == 1 ) |
---|
| 319 | #define m68k_get_vbr( _vbr ) _vbr = (void *)_VBR |
---|
| 320 | |
---|
| 321 | #define m68k_set_vbr( _vbr ) \ |
---|
| 322 | asm volatile ("move.l %%a7,%%d1 \n\t" \ |
---|
| 323 | "move.l %0,%%a7\n\t" \ |
---|
| 324 | "movec %%a7,%%vbr\n\t" \ |
---|
| 325 | "move.l %%d1,%%a7\n\t" \ |
---|
| 326 | : : "d" (_vbr) : "d1" ); |
---|
| 327 | |
---|
| 328 | #else |
---|
| 329 | #define m68k_get_vbr( _vbr ) _vbr = (void *)_VBR |
---|
| 330 | #define m68k_set_vbr( _vbr ) |
---|
| 331 | #endif |
---|
| 332 | |
---|
| 333 | /* |
---|
| 334 | * The following routine swaps the endian format of an unsigned int. |
---|
| 335 | * It must be static because it is referenced indirectly. |
---|
| 336 | */ |
---|
[9f9871f] | 337 | #if ( M68K_COLDFIRE_ARCH == 1 ) |
---|
| 338 | |
---|
| 339 | /* There are no rotate commands in Coldfire architecture. We will use |
---|
| 340 | * generic implementation of endian swapping for Coldfire. |
---|
| 341 | */ |
---|
[544a600] | 342 | static inline unsigned int m68k_swap_u32( |
---|
[9f9871f] | 343 | unsigned int value |
---|
| 344 | ) |
---|
| 345 | { |
---|
[d86bae8] | 346 | uint32_t byte1, byte2, byte3, byte4, swapped; |
---|
[9f9871f] | 347 | |
---|
| 348 | byte4 = (value >> 24) & 0xff; |
---|
| 349 | byte3 = (value >> 16) & 0xff; |
---|
| 350 | byte2 = (value >> 8) & 0xff; |
---|
| 351 | byte1 = value & 0xff; |
---|
| 352 | |
---|
| 353 | swapped = (byte1 << 24) | (byte2 << 16) | (byte3 << 8) | byte4; |
---|
| 354 | return( swapped ); |
---|
| 355 | } |
---|
| 356 | |
---|
| 357 | static inline unsigned int m68k_swap_u16( |
---|
| 358 | unsigned int value |
---|
| 359 | ) |
---|
| 360 | { |
---|
| 361 | return (((value & 0xff) << 8) | ((value >> 8) & 0xff)); |
---|
| 362 | } |
---|
| 363 | |
---|
| 364 | #else |
---|
[7908ba5b] | 365 | |
---|
| 366 | static inline unsigned int m68k_swap_u32( |
---|
| 367 | unsigned int value |
---|
| 368 | ) |
---|
| 369 | { |
---|
| 370 | unsigned int swapped = value; |
---|
| 371 | |
---|
| 372 | asm volatile( "rorw #8,%0" : "=d" (swapped) : "0" (swapped) ); |
---|
| 373 | asm volatile( "swap %0" : "=d" (swapped) : "0" (swapped) ); |
---|
| 374 | asm volatile( "rorw #8,%0" : "=d" (swapped) : "0" (swapped) ); |
---|
| 375 | |
---|
| 376 | return( swapped ); |
---|
| 377 | } |
---|
| 378 | |
---|
| 379 | static inline unsigned int m68k_swap_u16( |
---|
| 380 | unsigned int value |
---|
| 381 | ) |
---|
| 382 | { |
---|
| 383 | unsigned short swapped = value; |
---|
| 384 | |
---|
| 385 | asm volatile( "rorw #8,%0" : "=d" (swapped) : "0" (swapped) ); |
---|
| 386 | |
---|
| 387 | return( swapped ); |
---|
| 388 | } |
---|
[9f9871f] | 389 | #endif |
---|
[7908ba5b] | 390 | |
---|
[8ef3818] | 391 | #define CPU_swap_u32( value ) m68k_swap_u32( value ) |
---|
| 392 | #define CPU_swap_u16( value ) m68k_swap_u16( value ) |
---|
| 393 | |
---|
| 394 | |
---|
| 395 | /* |
---|
| 396 | * _CPU_virtual_to_physical |
---|
| 397 | * |
---|
| 398 | * DESCRIPTION: |
---|
| 399 | * |
---|
| 400 | * This function is used to map virtual addresses to physical |
---|
| 401 | * addresses. |
---|
| 402 | * |
---|
| 403 | * FIXME: ASSUMES THAT VIRTUAL ADDRESSES ARE THE SAME AS THE |
---|
| 404 | * PHYSICAL ADDRESSES |
---|
| 405 | */ |
---|
| 406 | static inline void * _CPU_virtual_to_physical ( |
---|
| 407 | const void * d_addr ) |
---|
| 408 | { |
---|
| 409 | return (void *) d_addr; |
---|
| 410 | } |
---|
| 411 | |
---|
| 412 | |
---|
[7908ba5b] | 413 | #endif /* !ASM */ |
---|
| 414 | |
---|
| 415 | #ifdef __cplusplus |
---|
| 416 | } |
---|
| 417 | #endif |
---|
| 418 | |
---|
[8ef3818] | 419 | #endif /* __M68K_h */ |
---|
[7908ba5b] | 420 | /* end of include file */ |
---|