diff options
Diffstat (limited to 'c/src/exec/score/cpu/m68k')
-rw-r--r-- | c/src/exec/score/cpu/m68k/asm.h | 127 | ||||
-rw-r--r-- | c/src/exec/score/cpu/m68k/cpu.c | 97 | ||||
-rw-r--r-- | c/src/exec/score/cpu/m68k/cpu.h | 412 | ||||
-rw-r--r-- | c/src/exec/score/cpu/m68k/cpu_asm.s | 202 | ||||
-rw-r--r-- | c/src/exec/score/cpu/m68k/m68k.h | 282 | ||||
-rw-r--r-- | c/src/exec/score/cpu/m68k/rtems.s | 46 |
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 |