summaryrefslogtreecommitdiffstats
path: root/c/src/exec/score/cpu/m68k
diff options
context:
space:
mode:
Diffstat (limited to 'c/src/exec/score/cpu/m68k')
-rw-r--r--c/src/exec/score/cpu/m68k/asm.h127
-rw-r--r--c/src/exec/score/cpu/m68k/cpu.c97
-rw-r--r--c/src/exec/score/cpu/m68k/cpu.h412
-rw-r--r--c/src/exec/score/cpu/m68k/cpu_asm.s202
-rw-r--r--c/src/exec/score/cpu/m68k/m68k.h282
-rw-r--r--c/src/exec/score/cpu/m68k/rtems.s46
6 files changed, 1166 insertions, 0 deletions
diff --git a/c/src/exec/score/cpu/m68k/asm.h b/c/src/exec/score/cpu/m68k/asm.h
new file mode 100644
index 0000000000..068c58058c
--- /dev/null
+++ b/c/src/exec/score/cpu/m68k/asm.h
@@ -0,0 +1,127 @@
+/* asm.h
+ *
+ * This include file attempts to address the problems
+ * caused by incompatible flavors of assemblers and
+ * toolsets. It primarily addresses variations in the
+ * use of leading underscores on symbols and the requirement
+ * that register names be preceded by a %.
+ *
+ *
+ * NOTE: The spacing in the use of these macros
+ * is critical to them working as advertised.
+ *
+ * COPYRIGHT:
+ *
+ * This file is based on similar code found in newlib available
+ * from ftp.cygnus.com. The file which was used had no copyright
+ * notice. This file is freely distributable as long as the source
+ * of the file is noted. This file is:
+ *
+ * COPYRIGHT (c) 1994.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * $Id$
+ */
+
+#ifndef __M68k_ASM_h
+#define __M68k_ASM_h
+
+/*
+ * Indicate we are in an assembly file and get the basic CPU definitions.
+ */
+
+#define ASM
+#include <m68k.h>
+
+/*
+ * Recent versions of GNU cpp define variables which indicate the
+ * need for underscores and percents. If not using GNU cpp or
+ * the version does not support this, then you will obviously
+ * have to define these as appropriate.
+ */
+
+#ifndef __USER_LABEL_PREFIX__
+#define __USER_LABEL_PREFIX__ _
+#endif
+
+#ifndef __REGISTER_PREFIX__
+#define __REGISTER_PREFIX__
+#endif
+
+/* ANSI concatenation macros. */
+
+#define CONCAT1(a, b) CONCAT2(a, b)
+#define CONCAT2(a, b) a ## b
+
+/* Use the right prefix for global labels. */
+
+#define SYM(x) CONCAT1 (__USER_LABEL_PREFIX__, x)
+
+/* Use the right prefix for registers. */
+
+#define REG(x) CONCAT1 (__REGISTER_PREFIX__, x)
+
+#define d0 REG (d0)
+#define d1 REG (d1)
+#define d2 REG (d2)
+#define d3 REG (d3)
+#define d4 REG (d4)
+#define d5 REG (d5)
+#define d6 REG (d6)
+#define d7 REG (d7)
+#define a0 REG (a0)
+#define a1 REG (a1)
+#define a2 REG (a2)
+#define a3 REG (a3)
+#define a4 REG (a4)
+#define a5 REG (a5)
+#define a6 REG (a6)
+#define a7 REG (a7)
+
+#define msp REG (msp)
+#define usp REG (usp)
+#define isp REG (isp)
+#define sr REG (sr)
+
+#define fp0 REG (fp0)
+#define fp1 REG (fp1)
+#define fp2 REG (fp2)
+#define fp3 REG (fp3)
+#define fp4 REG (fp4)
+#define fp5 REG (fp5)
+#define fp6 REG (fp6)
+#define fp7 REG (fp7)
+
+#define fpc REG (fpc)
+#define fpi REG (fpi)
+#define fps REG (fps)
+
+/*
+ * Define macros to handle section beginning and ends.
+ */
+
+
+#define BEGIN_CODE_DCL .text
+#define END_CODE_DCL
+#define BEGIN_DATA_DCL .data
+#define END_DATA_DCL
+#define BEGIN_CODE .text
+#define END_CODE
+#define BEGIN_DATA
+#define END_DATA
+#define BEGIN_BSS
+#define END_BSS
+#define END
+
+/*
+ * Following must be tailor for a particular flavor of the C compiler.
+ * They may need to put underscores in front of the symbols.
+ */
+
+#define PUBLIC(sym) .globl SYM (sym)
+#define EXTERN(sym) .globl SYM (sym)
+
+#endif
+/* end of include file */
+
+
diff --git a/c/src/exec/score/cpu/m68k/cpu.c b/c/src/exec/score/cpu/m68k/cpu.c
new file mode 100644
index 0000000000..45484da1f4
--- /dev/null
+++ b/c/src/exec/score/cpu/m68k/cpu.c
@@ -0,0 +1,97 @@
+/*
+ * Motorola MC68020 Dependent Source
+ *
+ * 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$
+ */
+
+#include <rtems/system.h>
+#include <rtems/fatal.h>
+#include <rtems/isr.h>
+
+/* _CPU_Initialize
+ *
+ * This routine performs processor dependent initialization.
+ *
+ * INPUT PARAMETERS:
+ * cpu_table - CPU table to initialize
+ * thread_dispatch - entry pointer to thread dispatcher
+ *
+ * OUTPUT PARAMETERS: NONE
+ */
+
+void _CPU_Initialize(
+ rtems_cpu_table *cpu_table,
+ void (*thread_dispatch) /* ignored on this CPU */
+)
+{
+
+ if ( cpu_table == NULL )
+ rtems_fatal_error_occurred( RTEMS_NOT_CONFIGURED );
+
+ _CPU_Table = *cpu_table;
+
+}
+
+/* _CPU_ISR_install_vector
+ *
+ * This kernel routine installs the RTEMS handler for the
+ * specified vector.
+ *
+ * Input parameters:
+ * vector - interrupt vector number
+ * new_handler - replacement ISR for this vector number
+ * old_handler - former ISR for this vector number
+ *
+ * Output parameters: NONE
+ *
+ * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * 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$
+ */
+
+void _CPU_ISR_install_vector(
+ unsigned32 vector,
+ proc_ptr new_handler,
+ proc_ptr *old_handler
+)
+{
+ proc_ptr *interrupt_table = NULL;
+
+ m68k_get_vbr( interrupt_table );
+
+ *old_handler = _ISR_Vector_table[ vector ];
+
+ _ISR_Vector_table[ vector ] = new_handler;
+ interrupt_table[ vector ] = _ISR_Handler;
+}
+
+
+/*PAGE
+ *
+ * _CPU_Install_interrupt_stack
+ */
+
+void _CPU_Install_interrupt_stack( void )
+{
+#if ( M68K_HAS_SEPARATE_STACKS == 1 )
+ void *isp = _CPU_Interrupt_stack_high;
+
+ asm volatile ( "movec %0,%%isp" : "=r" (isp) : "0" (isp) );
+#else
+#warning "FIX ME... HOW DO I INSTALL THE INTERRUPT STACK!!!"
+#endif
+}
+
diff --git a/c/src/exec/score/cpu/m68k/cpu.h b/c/src/exec/score/cpu/m68k/cpu.h
new file mode 100644
index 0000000000..a1dd27db57
--- /dev/null
+++ b/c/src/exec/score/cpu/m68k/cpu.h
@@ -0,0 +1,412 @@
+/* cpu.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 __CPU_h
+#define __CPU_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * If defined, this causes some of the macros to initialize their
+ * variables to zero before doing inline assembly. This gets rid
+ * of compile time warnings at the cost of a little execution time
+ * in some time critical routines.
+ */
+
+#define NO_UNINITIALIZED_WARNINGS
+
+#include <m68k.h>
+
+/* conditional compilation parameters */
+
+#define CPU_INLINE_ENABLE_DISPATCH TRUE
+#define CPU_UNROLL_ENQUEUE_PRIORITY FALSE
+
+/*
+ * Use the m68k's hardware interrupt stack support and have the
+ * interrupt manager allocate the memory for it.
+ */
+
+#define CPU_HAS_SOFTWARE_INTERRUPT_STACK FALSE
+#define CPU_HAS_HARDWARE_INTERRUPT_STACK TRUE
+#define CPU_ALLOCATE_INTERRUPT_STACK TRUE
+
+/*
+ * Some family members have no FP, some have an FPU such as the
+ * MC68881/MC68882 for the MC68020, others have it built in (MC68030, 040).
+ */
+
+#if ( M68K_HAS_FPU == 1 )
+#define CPU_HARDWARE_FP TRUE
+#else
+#define CPU_HARDWARE_FP FALSE
+#endif
+
+/*
+ * All tasks are not by default floating point tasks on this CPU.
+ * The IDLE task does not have a floating point context on this CPU.
+ * It is safe to use the deferred floating point context switch
+ * algorithm on this CPU.
+ */
+
+#define CPU_ALL_TASKS_ARE_FP FALSE
+#define CPU_IDLE_TASK_IS_FP FALSE
+#define CPU_USE_DEFERRED_FP_SWITCH TRUE
+
+#define CPU_PROVIDES_IDLE_THREAD_BODY FALSE
+#define CPU_STACK_GROWS_UP FALSE
+#define CPU_STRUCTURE_ALIGNMENT
+
+/* structures */
+
+/*
+ * Basic integer context for the m68k family.
+ */
+
+typedef struct {
+ unsigned32 sr; /* (sr) status register */
+ unsigned32 d2; /* (d2) data register 2 */
+ unsigned32 d3; /* (d3) data register 3 */
+ unsigned32 d4; /* (d4) data register 4 */
+ unsigned32 d5; /* (d5) data register 5 */
+ unsigned32 d6; /* (d6) data register 6 */
+ unsigned32 d7; /* (d7) data register 7 */
+ void *a2; /* (a2) address register 2 */
+ void *a3; /* (a3) address register 3 */
+ void *a4; /* (a4) address register 4 */
+ void *a5; /* (a5) address register 5 */
+ void *a6; /* (a6) address register 6 */
+ void *a7_msp; /* (a7) master stack pointer */
+} Context_Control;
+
+/*
+ * FP context save area for the M68881/M68882 numeric coprocessors.
+ */
+
+typedef struct {
+ unsigned8 fp_save_area[332]; /* 216 bytes for FSAVE/FRESTORE */
+ /* 96 bytes for FMOVEM FP0-7 */
+ /* 12 bytes for FMOVEM CREGS */
+ /* 4 bytes for non-null flag */
+} Context_Control_fp;
+
+/*
+ * The following structure defines the set of information saved
+ * on the current stack by RTEMS upon receipt of each interrupt.
+ */
+
+typedef struct {
+ unsigned32 TBD; /* XXX Fix for this CPU */
+} CPU_Interrupt_frame;
+
+/*
+ * The following table contains the information required to configure
+ * the m68k specific parameters.
+ */
+
+typedef struct {
+ void (*pretasking_hook)( void );
+ void (*predriver_hook)( void );
+ void (*postdriver_hook)( void );
+ void (*idle_task)( void );
+ boolean do_zero_of_workspace;
+ unsigned32 interrupt_stack_size;
+ unsigned32 extra_system_initialization_stack;
+ m68k_isr *interrupt_vector_table;
+} rtems_cpu_table;
+
+/* variables */
+
+EXTERN void *_CPU_Interrupt_stack_low;
+EXTERN void *_CPU_Interrupt_stack_high;
+
+/* constants */
+
+/*
+ * This defines the number of levels and the mask used to pick those
+ * bits out of a thread mode.
+ */
+
+#define CPU_MODES_INTERRUPT_LEVEL 0x00000007 /* interrupt level in mode */
+#define CPU_MODES_INTERRUPT_MASK 0x00000007 /* interrupt level in mode */
+
+/*
+ * context size area for floating point
+ */
+
+#define CPU_CONTEXT_FP_SIZE sizeof( Context_Control_fp )
+
+/*
+ * extra stack required by system initialization thread
+ */
+
+#define CPU_SYSTEM_INITIALIZATION_THREAD_EXTRA_STACK 1024
+
+/*
+ * m68k family supports 256 distinct vectors.
+ */
+
+#define CPU_INTERRUPT_NUMBER_OF_VECTORS 256
+
+/*
+ * Minimum size of a thread's stack.
+ *
+ * NOTE: 256 bytes is probably too low in most cases.
+ */
+
+#define CPU_STACK_MINIMUM_SIZE 256
+
+/*
+ * m68k is pretty tolerant of alignment. Just put things on 4 byte boundaries.
+ */
+
+#define CPU_ALIGNMENT 4
+#define CPU_HEAP_ALIGNMENT CPU_ALIGNMENT
+#define CPU_PARTITION_ALIGNMENT CPU_ALIGNMENT
+
+/*
+ * On m68k thread stacks require no further alignment after allocation
+ * from the Workspace.
+ */
+
+#define CPU_STACK_ALIGNMENT 0
+
+/* macros */
+
+/*
+ * ISR handler macros
+ *
+ * These macros perform the following functions:
+ * + disable all maskable CPU interrupts
+ * + restore previous interrupt level (enable)
+ * + temporarily restore interrupts (flash)
+ * + set a particular level
+ */
+
+#define _CPU_ISR_Disable( _level ) \
+ m68k_disable_interrupts( _level )
+
+#define _CPU_ISR_Enable( _level ) \
+ m68k_enable_interrupts( _level )
+
+#define _CPU_ISR_Flash( _level ) \
+ m68k_flash_interrupts( _level )
+
+#define _CPU_ISR_Set_level( _newlevel ) \
+ m68k_set_interrupt_level( _newlevel )
+
+/* end of ISR handler macros */
+
+/*
+ * Context handler macros
+ *
+ * These macros perform the following functions:
+ * + initialize a context area
+ * + restart the current thread
+ * + calculate the initial pointer into a FP context area
+ * + initialize an FP context area
+ */
+
+#define _CPU_Context_Initialize( _the_context, _stack_base, _size, \
+ _isr, _entry_point ) \
+ do { \
+ void *_stack; \
+ \
+ (_the_context)->sr = 0x3000 | ((_isr) << 8); \
+ _stack = (void *)(_stack_base) + (_size) - 4; \
+ (_the_context)->a7_msp = _stack; \
+ *(void **)_stack = (_entry_point); \
+ } while ( 0 )
+
+#define _CPU_Context_Restart_self( _the_context ) \
+ { asm volatile( "movew %0,%%sr ; " \
+ "moval %1,%%a7 ; " \
+ "rts" \
+ : "=d" ((_the_context)->sr), "=d" ((_the_context)->a7_msp) \
+ : "0" ((_the_context)->sr), "1" ((_the_context)->a7_msp) ); \
+ }
+
+#define _CPU_Context_Fp_start( _base, _offset ) \
+ ((void *) \
+ _Addresses_Add_offset( \
+ (_base), \
+ (_offset) + CPU_CONTEXT_FP_SIZE - 4 \
+ ) \
+ )
+
+#define _CPU_Context_Initialize_fp( _fp_area ) \
+ { unsigned32 *_fp_context = (unsigned32 *)*(_fp_area); \
+ \
+ *(--(_fp_context)) = 0; \
+ *(_fp_area) = (unsigned8 *)(_fp_context); \
+ }
+
+/* end of Context handler macros */
+
+/*
+ * Fatal Error manager macros
+ *
+ * These macros perform the following functions:
+ * + disable interrupts and halt the CPU
+ */
+
+#define _CPU_Fatal_halt( _error ) \
+ { asm volatile( "movl %0,%%d0; " \
+ "orw #0x0700,%%sr; " \
+ "stop #0x2700" : "=d" ((_error)) : "0" ((_error)) ); \
+ }
+
+/* end of Fatal Error manager macros */
+
+/*
+ * Bitfield handler macros
+ *
+ * These macros perform the following functions:
+ * + scan for the highest numbered (MSB) set in a 16 bit bitfield
+ *
+ * NOTE:
+ *
+ * It appears that on the M68020 bitfield are always 32 bits wide
+ * when in a register. This code forces the bitfield to be in
+ * memory (it really always is anyway). This allows us to
+ * have a real 16 bit wide bitfield which operates "correctly."
+ */
+
+#if ( M68K_HAS_BFFFO == 1 )
+#ifdef NO_UNINITIALIZED_WARNINGS
+
+#define _CPU_Bitfield_Find_first_bit( _value, _output ) \
+ { \
+ register void *__base = (void *)&(_value); \
+ \
+ (_output) = 0; /* avoids warnings */ \
+ asm volatile( "bfffo (%0),#0,#16,%1" \
+ : "=a" (__base), "=d" ((_output)) \
+ : "0" (__base), "1" ((_output)) ) ; \
+ }
+#else
+#define _CPU_Bitfield_Find_first_bit( _value, _output ) \
+ { \
+ register void *__base = (void *)&(_value); \
+ \
+ asm volatile( "bfffo (%0),#0,#16,%1" \
+ : "=a" (__base), "=d" ((_output)) \
+ : "0" (__base), "1" ((_output)) ) ; \
+ }
+#endif
+
+#else
+
+#define _CPU_Bitfield_Find_first_bit( _value, _output ) \
+ (_output) = 0 /* avoids warnings */
+
+#warning "FIX ME... NEEDS A SOFTWARE BFFFO IMPLEMENTATION"
+#warning "SEE no_cpu/cpu.h FOR POSSIBLE ALGORITHMS"
+
+#endif
+
+/* end of Bitfield handler macros */
+
+/*
+ * Priority handler macros
+ *
+ * These macros perform the following functions:
+ * + return a mask with the bit for this major/minor portion of
+ * of thread priority set.
+ * + translate the bit number returned by "Bitfield_find_first_bit"
+ * into an index into the thread ready chain bit maps
+ */
+
+#define _CPU_Priority_Mask( _bit_number ) \
+ ( 0x8000 >> (_bit_number) )
+
+#define _CPU_Priority_Bits_index( _priority ) \
+ (_priority)
+
+/* end of Priority handler macros */
+
+/* functions */
+
+/*
+ * _CPU_Initialize
+ *
+ * This routine performs CPU dependent initialization.
+ */
+
+void _CPU_Initialize(
+ rtems_cpu_table *cpu_table,
+ void (*thread_dispatch)
+);
+
+/*
+ * _CPU_ISR_install_vector
+ *
+ * This routine installs an interrupt vector.
+ */
+
+void _CPU_ISR_install_vector(
+ unsigned32 vector,
+ proc_ptr new_handler,
+ proc_ptr *old_handler
+);
+
+/*
+ * _CPU_Install_interrupt_stack
+ *
+ * This routine installs the hardware interrupt stack pointer.
+ */
+
+void _CPU_Install_interrupt_stack( void );
+
+/*
+ * _CPU_Context_switch
+ *
+ * This routine switches from the run context to the heir context.
+ */
+
+void _CPU_Context_switch(
+ Context_Control *run,
+ Context_Control *heir
+);
+
+/*
+ * _CPU_Context_save_fp
+ *
+ * This routine saves the floating point context passed to it.
+ */
+
+void _CPU_Context_restore_fp(
+ void **fp_context_ptr
+);
+
+/*
+ * _CPU_Context_restore_fp
+ *
+ * This routine restores the floating point context passed to it.
+ */
+
+void _CPU_Context_save_fp(
+ void **fp_context_ptr
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/c/src/exec/score/cpu/m68k/cpu_asm.s b/c/src/exec/score/cpu/m68k/cpu_asm.s
new file mode 100644
index 0000000000..d8615627a0
--- /dev/null
+++ b/c/src/exec/score/cpu/m68k/cpu_asm.s
@@ -0,0 +1,202 @@
+/* cpu_asm.s
+ *
+ * This file contains all assembly code for the MC68020 implementation
+ * of RTEMS.
+ *
+ * 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$
+ */
+
+
+#include <asm.h>
+
+ .text
+
+/* void _CPU_Context_switch( run_context, heir_context )
+ *
+ * This routine performs a normal non-FP context.
+ */
+
+ .align 4
+ .global SYM (_CPU_Context_switch)
+
+.set RUNCONTEXT_ARG, 4 | save context argument
+.set HEIRCONTEXT_ARG, 8 | restore context argument
+
+SYM (_CPU_Context_switch):
+ moval a7@(RUNCONTEXT_ARG),a0| a0 = running thread context
+ movw sr,d1 | d1 = status register
+ movml d1-d7/a2-a7,a0@ | save context
+
+ moval a7@(HEIRCONTEXT_ARG),a0| a0 = heir thread context
+restore: movml a0@,d1-d7/a2-a7 | restore context
+ movw d1,sr | restore status register
+ rts
+
+/*PAGE
+ * void __CPU_Context_save_fp_context( &fp_context_ptr )
+ * void __CPU_Context_restore_fp_context( &fp_context_ptr )
+ *
+ * These routines are used to context switch a MC68881 or MC68882.
+ *
+ * NOTE: Context save and restore code is based upon the code shown
+ * on page 6-38 of the MC68881/68882 Users Manual (rev 1).
+ *
+ * CPU_FP_CONTEXT_SIZE is higher than expected to account for the
+ * -1 pushed at end of this sequence.
+ */
+
+.set FPCONTEXT_ARG, 4 | save FP context argument
+
+ .align 4
+ .global SYM (_CPU_Context_save_fp)
+SYM (_CPU_Context_save_fp):
+#if ( M68K_HAS_FPU == 1 )
+ moval a7@(FPCONTEXT_ARG),a1 | a1 = &ptr to context area
+ moval a1@,a0 | a0 = Save context area
+ fsave a0@- | save 68881/68882 state frame
+ tstb a0@ | check for a null frame
+ beq nosv | Yes, skip save of user model
+ fmovem fp0-fp7,a0@- | save data registers (fp0-fp7)
+ fmovem fpc/fps/fpi,a0@- | and save control registers
+ movl #-1,a0@- | place not-null flag on stack
+nosv: movl a0,a1@ | save pointer to saved context
+#endif
+ rts
+
+ .align 4
+ .global SYM (_CPU_Context_restore_fp)
+SYM (_CPU_Context_restore_fp):
+#if ( M68K_HAS_FPU == 1 )
+ moval a7@(FPCONTEXT_ARG),a1 | a1 = &ptr to context area
+ moval a1@,a0 | a0 = address of saved context
+ tstb a0@ | Null context frame?
+ beq norst | Yes, skip fp restore
+ addql #4,a0 | throwaway non-null flag
+ fmovem a0@+,fpc/fps/fpi | restore control registers
+ fmovem a0@+,fp0-fp7 | restore data regs (fp0-fp7)
+norst: frestore a0@+ | restore the fp state frame
+ movl a0,a1@ | save pointer to saved context
+#endif
+ rts
+
+/*PAGE
+ * void _ISR_Handler()
+ *
+ * This routine provides the RTEMS interrupt management.
+ *
+ * NOTE:
+ * Upon entry, the master stack will contain an interrupt stack frame
+ * back to the interrupted thread and the interrupt stack will contain
+ * a throwaway interrupt stack frame. If dispatching is enabled, this
+ * is the outer most interrupt, and (a context switch is necessary or
+ * the current thread has signals), then set up the master stack to
+ * transfer control to the interrupt dispatcher.
+ */
+
+.set SR_OFFSET, 0 | Status register offset
+.set PC_OFFSET, 2 | Program Counter offset
+.set FVO_OFFSET, 6 | Format/vector offset
+
+.set SAVED, 16 | space for saved registers
+
+ .align 4
+ .global SYM (_ISR_Handler)
+
+SYM (_ISR_Handler):
+ moveml d0-d1/a0-a1,a7@- | save d0-d1,a0-a1
+ addql #1,SYM (_ISR_Nest_level) | one nest level deeper
+ addql #1,SYM (_Thread_Dispatch_disable_level)
+ | disable multitasking
+ movew a7@(SAVED+FVO_OFFSET),d0 | d0 = F/VO
+ andl #0x0fff,d0 | d0 = vector offset in vbr
+
+#if ( M68K_HAS_PREINDEXING == 1 )
+ movel @( SYM (_ISR_Vector_table),d0:w:1),a0| fetch the ISR
+#else
+ movel # SYM (_ISR_Vector_table),a0 | a0 = base of RTEMS table
+ addal d0,a0 | a0 = address of vector
+ movel @(a0),a0 | a0 = address of user routine
+#warning "UNTESTED CODE!!!"
+#endif
+
+ lsrl #2,d0 | d0 = vector number
+ movel d0,a7@- | push vector number
+ jbsr a0@ | invoke the user ISR
+ addql #4,a7 | remove vector number
+
+ subql #1,SYM (_ISR_Nest_level) | one less nest level
+ subql #1,SYM (_Thread_Dispatch_disable_level)
+ | unnest multitasking
+ bne exit | If dispatch disabled, exit
+
+ movew #0xf000,d0 | isolate format nibble
+ andw a7@(SAVED+FVO_OFFSET),d0 | get F/VO
+ cmpiw #0x1000,d0 | is it a throwaway isf?
+ bne exit | NOT outer level, so branch
+
+ tstl SYM (_Context_Switch_necessary)
+ | Is thread switch necessary?
+ bne bframe | Yes, invoke dispatcher
+
+ tstl SYM (_ISR_Signals_to_thread_executing)
+ | signals sent to Run_thread
+ | while in interrupt handler?
+ beq exit | No, then exit
+
+
+bframe: clrl SYM (_ISR_Signals_to_thread_executing)
+ | If sent, will be processed
+#if ( M68K_HAS_SEPARATE_STACKS == 1 )
+ movec msp,a0 | a0 = master stack pointer
+ movew #0,a0@- | push format word
+ movel # SYM (_ISR_Dispatch),a0@- | push return addr
+ movew a0@(6+SR_OFFSET),a0@- | push thread sr
+ movec a0,msp | set master stack pointer
+#else
+#warning "FIX ME ... HOW DO I DISPATCH FROM AN INTERRUPT?"
+/* probably will simply need to push the _ISR_Dispatch frame */
+#endif
+
+exit: moveml a7@+,d0-d1/a0-a1 | restore d0-d1,a0-a1
+ rte | return to thread
+ | OR _Isr_dispatch
+
+/*PAGE
+ * void _ISR_Dispatch()
+ *
+ * Entry point from the outermost interrupt service routine exit.
+ * The current stack is the supervisor mode stack if this processor
+ * has separate stacks.
+ *
+ * 1. save all registers not preserved across C calls.
+ * 2. invoke the _Thread_Dispatch routine to switch tasks
+ * or a signal to the currently executing task.
+ * 3. restore all registers not preserved across C calls.
+ * 4. return from interrupt
+ */
+
+ .global SYM (_ISR_Dispatch)
+SYM (_ISR_Dispatch):
+ movml d0-d1/a0-a1,a7@-
+ jsr SYM (_Thread_Dispatch)
+ movml a7@+,d0-d1/a0-a1
+ rte
+
+
+
+
+
+
+
+
+
+
+
diff --git a/c/src/exec/score/cpu/m68k/m68k.h b/c/src/exec/score/cpu/m68k/m68k.h
new file mode 100644
index 0000000000..3a62b7553b
--- /dev/null
+++ b/c/src/exec/score/cpu/m68k/m68k.h
@@ -0,0 +1,282 @@
+/* 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
+
+/*
+ * The following define the CPU Family and Model within the family
+ *
+ * NOTE: The string "REPLACE_THIS_WITH_THE_CPU_MODEL" is replaced
+ * with the name of the appropriate macro for this target CPU.
+ */
+
+#define m68k
+#define REPLACE_THIS_WITH_THE_CPU_MODEL
+#define REPLACE_THIS_WITH_THE_BSP
+
+/*
+ * 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)
+ *
+ * Primary difference (for RTEMS) between m68040, m680lc040, and
+ * m68ec040 is the presence or abscense 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."
+ */
+
+#if defined(m68000)
+
+#define RTEMS_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
+
+#elif defined(m68020)
+
+#define RTEMS_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
+
+#elif defined(m68020_nofp)
+
+#define RTEMS_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
+
+#elif defined(m68030)
+
+#define RTEMS_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
+
+#elif defined(m68040)
+
+#define RTEMS_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
+
+#elif defined(m68lc040)
+
+#define RTEMS_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
+
+#elif defined(m68ec040)
+
+#define RTEMS_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
+
+#else
+
+#error "Unsupported CPU Model"
+
+#endif
+
+/*
+ * If defined, this causes some of the macros to initialize their
+ * variables to zero before doing inline assembly. This gets rid
+ * of compile time warnings at the cost of a little execution time
+ * in some time critical routines.
+ */
+
+#define NO_UNINITIALIZED_WARNINGS
+
+/*
+ * Define the name of the CPU family.
+ */
+
+#define CPU_NAME "Motorola MC68xxx"
+
+#ifndef ASM
+
+/*
+ * This section defines the basic types for this processor.
+ */
+
+typedef unsigned char unsigned8; /* unsigned 8-bit integer */
+typedef unsigned short unsigned16; /* unsigned 16-bit integer */
+typedef unsigned int unsigned32; /* unsigned 32-bit integer */
+typedef unsigned long long unsigned64; /* unsigned 64-bit integer */
+
+typedef unsigned16 Priority_Bit_map_control;
+
+typedef char signed8; /* signed 8-bit integer */
+typedef short signed16; /* signed 16-bit integer */
+typedef int signed32; /* signed 32-bit integer */
+typedef long long signed64; /* signed 64-bit integer */
+
+typedef unsigned32 boolean; /* Boolean value */
+
+typedef float single_precision; /* single precision float */
+typedef double double_precision; /* double precision float */
+
+/*
+ *
+ */
+
+typedef void ( *m68k_isr )( void );
+
+#ifdef NO_UNINITIALIZED_WARNINGS
+#define m68k_disable_interrupts( _level ) \
+ { \
+ (_level) = 0; /* avoids warnings */ \
+ asm volatile ( "movew %%sr,%0 ; \
+ orw #0x0700,%%sr" \
+ : "=d" ((_level)) : "0" ((_level)) \
+ ); \
+ }
+#else
+#define m68k_disable_interrupts( _level ) \
+ { \
+ asm volatile ( "movew %%sr,%0 ; \
+ orw #0x0700,%%sr" \
+ : "=d" ((_level)) : "0" ((_level)) \
+ ); \
+ }
+#endif
+
+#define m68k_enable_interrupts( _level ) \
+ { \
+ asm volatile ( "movew %0,%%sr " \
+ : "=d" ((_level)) : "0" ((_level)) \
+ ); \
+ }
+
+#define m68k_flash_interrupts( _level ) \
+ { \
+ asm volatile ( "movew %0,%%sr ; \
+ orw #0x0700,%%sr" \
+ : "=d" ((_level)) : "0" ((_level)) \
+ ); \
+ }
+
+#define m68k_set_interrupt_level( _newlevel ) \
+ { \
+ register unsigned32 _tmpsr = 0; \
+ \
+ asm volatile( "movw %%sr,%0" \
+ : "=d" (_tmpsr) : "0" (_tmpsr) \
+ ); \
+ \
+ _tmpsr = (_tmpsr & 0xf8ff) | ((_newlevel) << 8); \
+ \
+ asm volatile( "movw %0,%%sr" \
+ : "=d" (_tmpsr) : "0" (_tmpsr) \
+ ); \
+ }
+
+#if ( M68K_HAS_VBR == 1 )
+#define m68k_get_vbr( vbr ) \
+ { (vbr) = 0; \
+ asm volatile ( "movec %%vbr,%0 " \
+ : "=r" (vbr) : "0" (vbr) ); \
+ }
+
+#define m68k_set_vbr( vbr ) \
+ { register m68k_isr *_vbr= (m68k_isr *)(vbr); \
+ asm volatile ( "movec %0,%%vbr " \
+ : "=a" (_vbr) : "0" (_vbr) ); \
+ }
+#else
+#define m68k_get_vbr( _vbr ) _vbr = 0
+#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 */
diff --git a/c/src/exec/score/cpu/m68k/rtems.s b/c/src/exec/score/cpu/m68k/rtems.s
new file mode 100644
index 0000000000..faae97e487
--- /dev/null
+++ b/c/src/exec/score/cpu/m68k/rtems.s
@@ -0,0 +1,46 @@
+/* rtems.s
+ *
+ * This file contains the single entry point code for
+ * the m68k implementation of RTEMS.
+ *
+ * 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$
+ */
+
+
+#include <asm.h>
+
+/*
+ * There seems to be no reason to have two versions of this.
+ * The following version should work across the entire family.
+ * The worst assumption is that gcc will put entry in a scratch
+ * register and not screw up the stack.
+ *
+ * NOTE: This is a 68020 version:
+ *
+ * jmpl @(%%d0:l:4)@(__Entry_points)
+ */
+
+ EXTERN (_Entry_points)
+
+ BEGIN_CODE
+
+ .align 4
+ .global SYM (RTEMS)
+
+SYM (RTEMS):
+ moveal SYM (_Entry_points), a0
+ lsll #2, d0
+ addal d0, a0
+ moveal @(a0),a0
+ jmpl @(a0)
+
+ END_CODE
+END