diff options
Diffstat (limited to 'include/rtems/score/m68k.h')
-rw-r--r-- | include/rtems/score/m68k.h | 502 |
1 files changed, 502 insertions, 0 deletions
diff --git a/include/rtems/score/m68k.h b/include/rtems/score/m68k.h new file mode 100644 index 0000000000..818578c078 --- /dev/null +++ b/include/rtems/score/m68k.h @@ -0,0 +1,502 @@ +/** + * @file + * + * @brief Motorola M68K CPU Dependent Source + * + * This include file contains information pertaining to the Motorola + * m68xxx processor family. + */ + +/* + * COPYRIGHT (c) 1989-1999. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#ifndef _RTEMS_SCORE_M68K_H +#define _RTEMS_SCORE_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 + * -m68000 -msoft-float + * -m68020 + * -m68020 -msoft-float + * -m68030 + * -m68040 -msoft-float + * -m68040 + * -m68040 -msoft-float + * -m68060 + * -m68060 -msoft-float + * -m68302 (no FP) (deprecated, use -m68000) + * -m68332 (no FP) (deprecated, use -mcpu32) + * -mcpu32 (no FP) + * -m5200 (no FP) + * -m528x (no FP, ISA A+) + * + * As of gcc 2.8.1 and egcs 1.1, there is no distinction made between + * the CPU32 and CPU32+. The option -mcpu32 generates code which can + * be run on either core. RTEMS distinguishes between these two cores + * because they have different alignment rules which impact performance. + * If you are using a CPU32+, then the symbol RTEMS__mcpu32p__ should + * be defined in your custom file (see make/custom/gen68360.cfg for an + * example of how to do this. If gcc ever distinguishes between these + * two cores, then RTEMS__mcpu32p__ usage will be replaced with the + * appropriate compiler defined predefine. + * + * 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. + * + * M68K_HAS_MISALIGNED is non-zero if the CPU allows byte-misaligned + * data access (68020, 68030, 68040, 68060, CPU32+). + * + * 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. + */ + +/* + * Handle the Coldfire family based on the instruction set. + */ +#if defined(__mcoldfire__) + +# define CPU_NAME "Motorola ColdFire" + +# if defined(__mcfisaa__) +/* Motorola ColdFire ISA A */ +# define CPU_MODEL_NAME "mcfisaa" +# define M68K_HAS_VBR 1 +# define M68K_HAS_BFFFO 0 +# define M68K_HAS_SEPARATE_STACKS 0 +# define M68K_HAS_PREINDEXING 0 +# define M68K_HAS_EXTB_L 1 +# define M68K_HAS_MISALIGNED 1 + +# elif defined(__mcfisaaplus__) +/* Motorola ColdFire ISA A+ */ +# define CPU_MODEL_NAME "mcfisaaplus" +# define M68K_HAS_VBR 1 +# define M68K_HAS_BFFFO 0 +# define M68K_HAS_SEPARATE_STACKS 0 +# define M68K_HAS_PREINDEXING 0 +# define M68K_HAS_EXTB_L 1 +# define M68K_HAS_MISALIGNED 1 + +# elif defined(__mcfisab__) +/* Motorola ColdFire ISA B */ +# define CPU_MODEL_NAME "mcfisab" +# define M68K_HAS_VBR 1 +# define M68K_HAS_BFFFO 0 +# define M68K_HAS_SEPARATE_STACKS 0 +# define M68K_HAS_PREINDEXING 0 +# define M68K_HAS_EXTB_L 1 +# define M68K_HAS_MISALIGNED 1 + +# else +# error "Unsupported Coldfire ISA -- Please notify RTEMS" +# endif + +/* + * Assume the FPU support is independent. I think it is just the ISA B + * instruction set. + */ +# if defined (__mcffpu__) +# define M68K_HAS_FPU 1 + /* + * td: can we be sure that all CFs with FPU also have an EMAC? + */ +# define M68K_HAS_EMAC 1 +# define M68K_HAS_FPSP_PACKAGE 0 +# else +# define M68K_HAS_FPU 0 +# define M68K_HAS_FPSP_PACKAGE 0 +# endif + +/* + * Tiny RTEMS support. Small stack and limited priorities. + * + * These CPUs have very limited on-CPU memory which cannot + * be expanded. We have to be gentle with them or nothing + * will every run. + */ +# if (defined(__mcf_cpu_52221) || \ + defined(__mcf_cpu_52223) || \ + defined(__mcf_cpu_52230) || \ + defined(__mcf_cpu_52231) || \ + defined(__mcf_cpu_52232) || \ + defined(__mcf_cpu_52233) || \ + defined(__mcf_cpu_52234) || \ + defined(__mcf_cpu_52235) || \ + defined(__mcf_cpu_52225) || \ + defined(__mcf_cpu_52235)) + #define M68K_CPU_STACK_MINIMUM_SIZE 1024 + /* Define the lowest priority. Based from 0 to this is 16 levels. */ + #define M68K_CPU_PRIORITY_MAXIMUM 15 +# else + #define M68K_CPU_STACK_MINIMUM_SIZE 4096 + /* Use the default number of priorities */ + #define M68K_CPU_PRIORITY_MAXIMUM 255 +# endif + +#else + +/* + * Figure out all CPU Model Feature Flags based upon compiler + * predefines. Notice the only exception to this is that + * gcc does not distinguish between CPU32 and CPU32+. This + * feature selection logic is setup such that if RTEMS__mcpu32p__ + * is defined, then CPU32+ rules are used. Otherwise, the safe + * but less efficient CPU32 rules are used for the CPU32+. + */ + +# define CPU_NAME "Motorola MC68xxx" + +/* + * One stack size fits all 68000 processors. + */ +# define M68K_CPU_STACK_MINIMUM_SIZE 4096 + +# if (defined(__mc68020__) && !defined(__mcpu32__)) + +# define CPU_MODEL_NAME "m68020" +# define M68K_HAS_VBR 1 +# define M68K_HAS_SEPARATE_STACKS 1 +# define M68K_HAS_BFFFO 1 +# define M68K_HAS_PREINDEXING 1 +# define M68K_HAS_EXTB_L 1 +# define M68K_HAS_MISALIGNED 1 +# if defined (__HAVE_68881__) +# define M68K_HAS_FPU 1 +# define M68K_HAS_FPSP_PACKAGE 0 +# else +# define M68K_HAS_FPU 0 +# define M68K_HAS_FPSP_PACKAGE 0 +# endif + +# elif defined(__mc68030__) + +# define CPU_MODEL_NAME "m68030" +# define M68K_HAS_VBR 1 +# define M68K_HAS_SEPARATE_STACKS 1 +# define M68K_HAS_BFFFO 1 +# define M68K_HAS_PREINDEXING 1 +# define M68K_HAS_EXTB_L 1 +# define M68K_HAS_MISALIGNED 1 +# if defined (__HAVE_68881__) +# define M68K_HAS_FPU 1 +# define M68K_HAS_FPSP_PACKAGE 0 +# else +# define M68K_HAS_FPU 0 +# define M68K_HAS_FPSP_PACKAGE 0 +# endif + +# elif defined(__mc68040__) + +# define CPU_MODEL_NAME "m68040" +# define M68K_HAS_VBR 1 +# define M68K_HAS_SEPARATE_STACKS 1 +# define M68K_HAS_BFFFO 1 +# define M68K_HAS_PREINDEXING 1 +# define M68K_HAS_EXTB_L 1 +# define M68K_HAS_MISALIGNED 1 +# if defined (__HAVE_68881__) +# define M68K_HAS_FPU 1 +# define M68K_HAS_FPSP_PACKAGE 1 +# else +# define M68K_HAS_FPU 0 +# define M68K_HAS_FPSP_PACKAGE 0 +# endif + +# elif defined(__mc68060__) + +# define CPU_MODEL_NAME "m68060" +# define M68K_HAS_VBR 1 +# define M68K_HAS_SEPARATE_STACKS 0 +# define M68K_HAS_BFFFO 1 +# define M68K_HAS_PREINDEXING 1 +# define M68K_HAS_EXTB_L 1 +# define M68K_HAS_MISALIGNED 1 +# if defined (__HAVE_68881__) +# define M68K_HAS_FPU 1 +# define M68K_HAS_FPSP_PACKAGE 0 +# else +# define M68K_HAS_FPU 0 +# define M68K_HAS_FPSP_PACKAGE 0 +# endif + +# elif defined(__mc68302__) + +# define CPU_MODEL_NAME "m68302" +# define M68K_HAS_VBR 0 +# define M68K_HAS_SEPARATE_STACKS 0 +# define M68K_HAS_BFFFO 0 +# define M68K_HAS_PREINDEXING 0 +# define M68K_HAS_EXTB_L 0 +# define M68K_HAS_MISALIGNED 0 +# define M68K_HAS_FPU 0 +# define M68K_HAS_FPSP_PACKAGE 0 + + /* gcc and egcs do not distinguish between CPU32 and CPU32+ */ +# elif defined(RTEMS__mcpu32p__) + +# define CPU_MODEL_NAME "mcpu32+" +# define M68K_HAS_VBR 1 +# define M68K_HAS_SEPARATE_STACKS 0 +# define M68K_HAS_BFFFO 0 +# define M68K_HAS_PREINDEXING 1 +# define M68K_HAS_EXTB_L 1 +# define M68K_HAS_MISALIGNED 1 +# define M68K_HAS_FPU 0 +# 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_BFFFO 0 +# define M68K_HAS_PREINDEXING 1 +# define M68K_HAS_EXTB_L 1 +# define M68K_HAS_MISALIGNED 0 +# define M68K_HAS_FPU 0 +# define M68K_HAS_FPSP_PACKAGE 0 + +# elif defined(__mc68000__) + +# define CPU_MODEL_NAME "m68000" +# define M68K_HAS_VBR 0 +# define M68K_HAS_SEPARATE_STACKS 0 +# define M68K_HAS_BFFFO 0 +# define M68K_HAS_PREINDEXING 0 +# define M68K_HAS_EXTB_L 0 +# define M68K_HAS_MISALIGNED 0 +# if defined (__HAVE_68881__) +# define M68K_HAS_FPU 1 +# define M68K_HAS_FPSP_PACKAGE 0 +# else +# define M68K_HAS_FPU 0 +# define M68K_HAS_FPSP_PACKAGE 0 +# endif + +# else + +# error "Unsupported 68000 CPU model -- are you sure you're running a 68k compiler?" + +# endif + +/* + * No Tiny RTEMS support on the standard 68000 family. + */ +# define M68K_CPU_STACK_MINIMUM_SIZE 4096 +# define M68K_CPU_PRIORITY_MAXIMUM 255 + +#endif + +/* + * OBSOLETE: Backward compatibility only - Don't use. + * Use __mcoldfire__ instead. + */ +#if defined(__mcoldfire__) +#define M68K_COLDFIRE_ARCH 1 +#else +#define M68K_COLDFIRE_ARCH 0 +#endif + +#ifndef ASM + +#if ( defined(__mcoldfire__) ) +#define m68k_disable_interrupts( _level ) \ + do { register uint32_t _tmpsr = 0x0700; \ + __asm__ volatile ( "move.w %%sr,%0\n\t" \ + "or.l %0,%1\n\t" \ + "move.w %1,%%sr" \ + : "=d" (_level), "=d"(_tmpsr) : "1"(_tmpsr) \ + : "cc" ); \ + } while( 0 ) +#else +#define m68k_disable_interrupts( _level ) \ + __asm__ volatile ( "move.w %%sr,%0\n\t" \ + "or.w #0x0700,%%sr" \ + : "=d" (_level) \ + : : "cc" ) +#endif + +#define m68k_enable_interrupts( _level ) \ + __asm__ volatile ( "move.w %0,%%sr " : : "d" (_level) : "cc"); + +#if ( defined(__mcoldfire__) ) +#define m68k_flash_interrupts( _level ) \ + do { register uint32_t _tmpsr = 0x0700; \ + asm volatile ( "move.w %2,%%sr\n\t" \ + "or.l %2,%1\n\t" \ + "move.w %1,%%sr" \ + : "=d"(_tmpsr) : "0"(_tmpsr), "d"(_level) \ + : "cc"); \ + } while( 0 ) +#else +#define m68k_flash_interrupts( _level ) \ + __asm__ volatile ( "move.w %0,%%sr\n\t" \ + "or.w #0x0700,%%sr" \ + : : "d" (_level) \ + : "cc" ) +#endif + +#define m68k_get_interrupt_level( _level ) \ + do { \ + register uint32_t _tmpsr; \ + \ + __asm__ volatile( "move.w %%sr,%0" : "=d" (_tmpsr)); \ + _level = (_tmpsr & 0x0700) >> 8; \ + } while (0) + +#define m68k_set_interrupt_level( _newlevel ) \ + do { \ + register uint32_t _tmpsr; \ + \ + __asm__ volatile( "move.w %%sr,%0" : "=d" (_tmpsr)); \ + _tmpsr = (_tmpsr & 0xf8ff) | ((_newlevel) << 8); \ + __asm__ volatile( "move.w %0,%%sr" : : "d" (_tmpsr)); \ + } while (0) + +#if ( M68K_HAS_VBR == 1 && !defined(__mcoldfire__) ) +#define m68k_get_vbr( vbr ) \ + __asm__ volatile ( "movec %%vbr,%0 " : "=r" (vbr)) + +#define m68k_set_vbr( vbr ) \ + __asm__ volatile ( "movec %0,%%vbr " : : "r" (vbr)) + +#elif ( defined(__mcoldfire__) ) +extern void* _VBR; +#define m68k_get_vbr( _vbr ) _vbr = &_VBR + +#define m68k_set_vbr( _vbr ) \ + do { \ + __asm__ volatile ( "movec %0,%%vbr " : : "r" (_vbr)); \ + _VBR = (void *)_vbr; \ + } while(0) + +#else +#define m68k_get_vbr( _vbr ) _vbr = (void *)_VBR +#define m68k_set_vbr( _vbr ) +#endif + +/* + * Access Control Registers + */ +#define m68k_set_cacr(_cacr) __asm__ volatile ("movec %0,%%cacr" : : "d" (_cacr)) +#define m68k_set_acr0(_acr0) __asm__ volatile ("movec %0,%%acr0" : : "d" (_acr0)) +#define m68k_set_acr1(_acr1) __asm__ volatile ("movec %0,%%acr1" : : "d" (_acr1)) + +/* + * The following routine swaps the endian format of an unsigned int. + * It must be static because it is referenced indirectly. + */ +#if ( defined(__mcoldfire__) ) + +/* There are no rotate commands in Coldfire architecture. We will use + * generic implementation of endian swapping for Coldfire. + */ +static inline uint32_t m68k_swap_u32( + uint32_t value + ) +{ + uint32_t byte1, byte2, byte3, byte4, swapped; + + byte4 = (value >> 24) & 0xff; + byte3 = (value >> 16) & 0xff; + byte2 = (value >> 8) & 0xff; + byte1 = value & 0xff; + + swapped = (byte1 << 24) | (byte2 << 16) | (byte3 << 8) | byte4; + return( swapped ); +} + +static inline uint16_t m68k_swap_u16( + uint16_t value +) +{ + return (((value & 0xff) << 8) | ((value >> 8) & 0xff)); +} + +#else + +static inline uint32_t m68k_swap_u32( + uint32_t value +) +{ + uint32_t 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 ); +} + +static inline uint16_t m68k_swap_u16( + uint16_t value +) +{ + uint16_t swapped = value; + + __asm__ volatile( "rorw #8,%0" : "=d" (swapped) : "0" (swapped) ); + + return( swapped ); +} +#endif + +#define CPU_swap_u32( value ) m68k_swap_u32( value ) +#define CPU_swap_u16( value ) m68k_swap_u16( value ) + + +/* + * _CPU_virtual_to_physical + * + * This function is used to map virtual addresses to physical + * addresses. + * + * FIXME: ASSUMES THAT VIRTUAL ADDRESSES ARE THE SAME AS THE + * PHYSICAL ADDRESSES + */ +static inline void * _CPU_virtual_to_physical ( + const void * d_addr ) +{ + return (void *) d_addr; +} + + +#endif /* !ASM */ + +#ifdef __cplusplus +} +#endif + +#endif /* _RTEMS_SCORE_M68K_H */ |