summaryrefslogtreecommitdiffstats
path: root/c/src/exec/score/cpu/i960
diff options
context:
space:
mode:
Diffstat (limited to 'c/src/exec/score/cpu/i960')
-rw-r--r--c/src/exec/score/cpu/i960/asm.h107
-rw-r--r--c/src/exec/score/cpu/i960/cpu.c124
-rw-r--r--c/src/exec/score/cpu/i960/cpu.h424
-rw-r--r--c/src/exec/score/cpu/i960/cpu_asm.s199
-rw-r--r--c/src/exec/score/cpu/i960/i960.h289
-rw-r--r--c/src/exec/score/cpu/i960/rtems.s25
6 files changed, 1168 insertions, 0 deletions
diff --git a/c/src/exec/score/cpu/i960/asm.h b/c/src/exec/score/cpu/i960/asm.h
new file mode 100644
index 0000000000..1c40601473
--- /dev/null
+++ b/c/src/exec/score/cpu/i960/asm.h
@@ -0,0 +1,107 @@
+/* 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 __i960_ASM_h
+#define __i960_ASM_h
+
+/*
+ * Indicate we are in an assembly file and get the basic CPU definitions.
+ */
+
+#define ASM
+#include <i960.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 g0 REG (g0)
+#define g1 REG (g1)
+#define g2 REG (g2)
+#define g3 REG (g3)
+#define g4 REG (g4)
+#define g5 REG (g5)
+#define g6 REG (g6)
+#define g7 REG (g7)
+#define g8 REG (g8)
+#define g9 REG (g9)
+#define g10 REG (g10)
+#define g11 REG (g11)
+#define g12 REG (g12)
+#define g13 REG (g13)
+#define g14 REG (g14)
+#define g15 REG (g15)
+
+/*
+ * 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/i960/cpu.c b/c/src/exec/score/cpu/i960/cpu.c
new file mode 100644
index 0000000000..68ecb0525c
--- /dev/null
+++ b/c/src/exec/score/cpu/i960/cpu.c
@@ -0,0 +1,124 @@
+/*
+ * Intel i960CA 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$
+ */
+
+#if defined(__i960CA__) || defined(__i960_CA__) || defined(__i960CA)
+#else
+#warning "*** ENTIRE FILE IMPLEMENTED & TESTED FOR CA ONLY ***"
+#warning "*** THIS FILE WILL NOT COMPILE ON ANOTHER FAMILY MEMBER ***"
+#endif
+
+#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 - address of disptaching routine
+ *
+ * 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
+ *
+ * Install the RTEMS vector wrapper in the CPU's interrupt table.
+ *
+ * Input parameters:
+ * vector - interrupt vector number
+ * old_handler - former ISR for this vector number
+ * new_handler - replacement ISR for this vector number
+ *
+ * Output parameters: NONE
+ *
+ */
+
+#define _Is_vector_caching_enabled( _prcb ) \
+ ((_prcb)->control_tbl->icon & 0x2000)
+
+void _CPU_ISR_install_vector(
+ unsigned32 vector,
+ proc_ptr new_handler,
+ proc_ptr *old_handler
+)
+{
+ i960ca_PRCB *prcb = _CPU_Table.Prcb;
+ proc_ptr *cached_intr_tbl = NULL;
+
+/* The i80960CA does not support vectors 0-7. The first 9 entries
+ * in the Interrupt Table are used to manage pending interrupts.
+ * Thus vector 8, the first valid vector number, is actually in
+ * slot 9 in the table.
+ */
+
+ *old_handler = _ISR_Vector_table[ vector ];
+
+ _ISR_Vector_table[ vector ] = new_handler;
+
+ prcb->intr_tbl[ vector + 1 ] = _ISR_Handler;
+ if ( _Is_vector_caching_enabled( prcb ) )
+ if ( (vector & 0xf) == 0x2 ) /* cacheable? */
+ cached_intr_tbl[ vector >> 4 ] = _ISR_Handler;
+}
+
+/*PAGE
+ *
+ * _CPU_Install_interrupt_stack
+ */
+
+#define soft_reset( prcb ) \
+ { register i960ca_PRCB *_prcb = (prcb); \
+ register unsigned32 *_next=0; \
+ register unsigned32 _cmd = 0x30000; \
+ asm volatile( "lda next,%1; \
+ sysctl %0,%1,%2; \
+ next: mov g0,g0" \
+ : "=d" (_cmd), "=d" (_next), "=d" (_prcb) \
+ : "0" (_cmd), "1" (_next), "2" (_prcb) ); \
+ }
+
+void _CPU_Install_interrupt_stack( void )
+{
+ i960ca_PRCB *prcb = _CPU_Table.Prcb;
+ unsigned32 level;
+
+ /*
+ * Set the Interrupt Stack in the PRCB and force a reload of it.
+ * Interrupts are disabled for safety.
+ */
+
+ _CPU_ISR_Disable( level );
+
+ prcb->intr_stack = _CPU_Interrupt_stack_low;
+
+ soft_reset( prcb );
+
+ _CPU_ISR_Enable( level );
+}
diff --git a/c/src/exec/score/cpu/i960/cpu.h b/c/src/exec/score/cpu/i960/cpu.h
new file mode 100644
index 0000000000..71a3341702
--- /dev/null
+++ b/c/src/exec/score/cpu/i960/cpu.h
@@ -0,0 +1,424 @@
+/* cpu.h
+ *
+ * This include file contains information pertaining to the Intel
+ * i960 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
+
+#pragma align 4 /* for GNU C structure alignment */
+
+#include <i960.h>
+
+#define CPU_INLINE_ENABLE_DISPATCH FALSE
+#define CPU_UNROLL_ENQUEUE_PRIORITY FALSE
+
+/*
+ * Use the i960'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 (SA/KA/CA/CF), others have it built in
+ * (KB/MC/MX). There does not appear to be an external coprocessor
+ * for this family.
+ */
+
+#if ( I960_HAS_FPU == 1 )
+#define CPU_HARDWARE_FP TRUE
+#error "Floating point support for i960 family has been implemented!!!"
+#else
+#define CPU_HARDWARE_FP FALSE
+#endif
+
+#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 TRUE
+#define CPU_STRUCTURE_ALIGNMENT __attribute__ ((aligned (16)))
+
+/* structures */
+
+/*
+ * Basic integer context for the i960 family.
+ */
+
+typedef struct {
+ void *r0_pfp; /* (r0) Previous Frame Pointer */
+ void *r1_sp; /* (r1) Stack Pointer */
+ unsigned32 pc; /* (pc) Processor Control */
+ void *g8; /* (g8) Global Register 8 */
+ void *g9; /* (g9) Global Register 9 */
+ void *g10; /* (g10) Global Register 10 */
+ void *g11; /* (g11) Global Register 11 */
+ void *g12; /* (g12) Global Register 12 */
+ void *g13; /* (g13) Global Register 13 */
+ unsigned32 g14; /* (g14) Global Register 14 */
+ void *g15_fp; /* (g15) Frame Pointer */
+} Context_Control;
+
+/*
+ * FP context save area for the i960 Numeric Extension
+ */
+
+typedef struct {
+ unsigned32 fp0_1; /* (fp0) first word */
+ unsigned32 fp0_2; /* (fp0) second word */
+ unsigned32 fp0_3; /* (fp0) third word */
+ unsigned32 fp1_1; /* (fp1) first word */
+ unsigned32 fp1_2; /* (fp1) second word */
+ unsigned32 fp1_3; /* (fp1) third word */
+ unsigned32 fp2_1; /* (fp2) first word */
+ unsigned32 fp2_2; /* (fp2) second word */
+ unsigned32 fp2_3; /* (fp2) third word */
+ unsigned32 fp3_1; /* (fp3) first word */
+ unsigned32 fp3_2; /* (fp3) second word */
+ unsigned32 fp3_3; /* (fp3) third word */
+} 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;
+
+/*
+ * Call frame for the i960 family.
+ */
+
+typedef struct {
+ void *r0_pfp; /* (r0) Previous Frame Pointer */
+ void *r1_sp; /* (r1) Stack Pointer */
+ void *r2_rip; /* (r2) Return Instruction Pointer */
+ void *r3; /* (r3) Local Register 3 */
+ void *r4; /* (r4) Local Register 4 */
+ void *r5; /* (r5) Local Register 5 */
+ void *r6; /* (r6) Local Register 6 */
+ void *r7; /* (r7) Local Register 7 */
+ void *r8; /* (r8) Local Register 8 */
+ void *r9; /* (r9) Local Register 9 */
+ void *r10; /* (r10) Local Register 10 */
+ void *r11; /* (r11) Local Register 11 */
+ void *r12; /* (r12) Local Register 12 */
+ void *r13; /* (r13) Local Register 13 */
+ void *r14; /* (r14) Local Register 14 */
+ void *r15; /* (r15) Local Register 15 */
+ /* XXX Looks like sometimes there is FP stuff here (MC manual)? */
+} CPU_Call_frame;
+
+/*
+ * The following table contains the information required to configure
+ * the i960 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;
+#if defined(__i960CA__) || defined(__i960_CA__) || defined(__i960CA)
+ i960ca_PRCB *Prcb;
+#endif
+} 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 0x0000001f /* interrupt level in mode */
+#define CPU_MODES_INTERRUPT_MASK 0x0000001f /* 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
+ *
+ * NOTE: Make sure this stays positive ...
+ */
+
+#define CPU_SYSTEM_INITIALIZATION_THREAD_EXTRA_STACK \
+ (4096 - CPU_STACK_MINIMUM_SIZE)
+
+/*
+ * i960 family supports 256 distinct vectors.
+ */
+
+#define CPU_INTERRUPT_NUMBER_OF_VECTORS 256
+
+/*
+ * Minimum size of a thread's stack.
+ *
+ * NOTE: See CPU_SYSTEM_INITIALIZATION_THREAD_EXTRA_STACK
+ */
+
+#define CPU_STACK_MINIMUM_SIZE 1024
+
+/*
+ * i960 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
+
+/*
+ * i960ca stack requires 16 byte alignment
+ *
+ * NOTE: This factor may need to be family member dependent.
+ */
+
+#define CPU_STACK_ALIGNMENT 16
+
+/* 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 ) i960_disable_interrupts( _level )
+#define _CPU_ISR_Enable( _level ) i960_enable_interrupts( _level )
+#define _CPU_ISR_Flash( _level ) i960_flash_interrupts( _level )
+
+#define _CPU_ISR_Set_level( newlevel ) \
+ { \
+ unsigned32 _mask, _level=(newlevel); \
+ \
+ __asm__ volatile ( "ldconst 0x1f0000,%0; \
+ modpc 0,%0,%1" : "=d" (_mask), "=d" (_level) \
+ : "0" (_mask), "1" (_level) \
+ ); \
+ }
+
+/* ISR handler section 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 ) \
+ { CPU_Call_frame *_texit_frame; \
+ unsigned32 _mask; \
+ unsigned32 _base_pc; \
+ unsigned32 _stack_tmp; \
+ void *_stack; \
+ \
+ _stack_tmp = (unsigned32)(_stack_base) + CPU_STACK_ALIGNMENT; \
+ _stack_tmp &= ~(CPU_STACK_ALIGNMENT - 1); \
+ _stack = (void *) _stack_tmp; \
+ \
+ __asm__ volatile ( "flushreg" : : ); /* flush register cache */ \
+ \
+ (_the_context)->r0_pfp = _stack; \
+ (_the_context)->g15_fp = _stack + (1 * sizeof(CPU_Call_frame)); \
+ (_the_context)->r1_sp = _stack + (2 * sizeof(CPU_Call_frame)); \
+ __asm__ volatile ( "ldconst 0x1f0000,%0 ; " \
+ "modpc 0,0,%1 ; " \
+ "andnot %0,%1,%1 ; " \
+ : "=d" (_mask), "=d" (_base_pc) : ); \
+ (_the_context)->pc = _base_pc | ((_isr) << 16); \
+ (_the_context)->g14 = 0; \
+ \
+ _texit_frame = (CPU_Call_frame *)_stack; \
+ _texit_frame->r0_pfp = NULL; \
+ _texit_frame->r1_sp = (_the_context)->g15_fp; \
+ _texit_frame->r2_rip = (_entry); \
+ }
+
+#define _CPU_Context_Restart_self( _the_context ) \
+ _CPU_Context_restore( (_the_context) );
+
+#define _CPU_Context_Fp_start( _base, _offset ) NULL
+
+#define _CPU_Context_Initialize_fp( _fp_area )
+
+/* 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( _errorcode ) \
+ { unsigned32 _mask, _level; \
+ unsigned32 _error = (_errorcode); \
+ \
+ __asm__ volatile ( "ldconst 0x1f0000,%0 ; \
+ mov %0,%1 ; \
+ modpc 0,%0,%1 ; \
+ mov %2,g0 ; \
+ self: b self " \
+ : "=d" (_mask), "=d" (_level), "=d" (_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
+ */
+
+#define _CPU_Bitfield_Find_first_bit( _value, _output ) \
+ { unsigned32 _search = (_value); \
+ \
+ __asm__ volatile ( "scanbit %0,%1 " \
+ : "=d" (_search), "=d" (_output) \
+ : "0" (_search), "1" (_output) ); \
+ }
+
+/* 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 ) \
+ ( 15 - (_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_restore
+ *
+ * This routine is generallu used only to restart self in an
+ * efficient manner and avoid stack conflicts.
+ */
+
+void _CPU_Context_restore(
+ Context_Control *new_context
+);
+
+/*
+ * _CPU_Context_save_fp
+ *
+ * This routine saves the floating point context passed to it.
+ */
+
+void _CPU_Context_save_fp(
+ void **fp_context_ptr
+);
+
+/*
+ * _CPU_Context_restore_fp
+ *
+ * This routine restores the floating point context passed to it.
+ */
+
+void _CPU_Context_restore_fp(
+ void **fp_context_ptr
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/c/src/exec/score/cpu/i960/cpu_asm.s b/c/src/exec/score/cpu/i960/cpu_asm.s
new file mode 100644
index 0000000000..eb11e14760
--- /dev/null
+++ b/c/src/exec/score/cpu/i960/cpu_asm.s
@@ -0,0 +1,199 @@
+/* cpu_asm.s
+ *
+ * This file contains all assembly code for the i960CA 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$
+ */
+
+ .text
+/*
+ * Format of i960ca Register structure
+ */
+
+.set REG_R0_PFP , 0 # (r0) Previous Frame Pointer
+.set REG_R1_SP , REG_R0_PFP+4 # (r1) Stack Pointer
+.set REG_PC , REG_R1_SP+4 # (pc) Processor Controls
+.set REG_G8 , REG_PC+4 # (g8) Global Register 8
+.set REG_G9 , REG_G8+4 # (g9) Global Register 9
+.set REG_G10 , REG_G9+4 # (g10) Global Register 10
+.set REG_G11 , REG_G10+4 # (g11) Global Register 11
+.set REG_G12 , REG_G11+4 # (g12) Global Register 12
+.set REG_G13 , REG_G12+4 # (g13) Global Register 13
+.set REG_G14 , REG_G13+4 # (g14) Global Register 14
+.set REG_G15_FP , REG_G14+4 # (g15) Global Register 15
+.set SIZE_REGS , REG_G15_FP+4 # size of cpu_context_registers
+ # structure
+
+/*
+ * void _CPU_Context_switch( run_context, heir_context )
+ *
+ * This routine performs a normal non-FP context.
+ */
+ .align 4
+ .globl __CPU_Context_switch
+
+__CPU_Context_switch:
+ modpc 0,0,g2 # get old intr level (PC)
+ st g2,REG_PC(g0) # save pc
+ stq g8,REG_G8(g0) # save g8-g11
+ stq g12,REG_G12(g0) # save g12-g15
+ stl pfp,REG_R0_PFP(g0) # save pfp, sp
+
+restore: flushreg # flush register cache
+ ldconst 0x001f0000,g2 # g2 = PC mask
+ ld REG_PC(g1),g3 # thread->Regs.pc = pc;
+ ldq REG_G12(g1),g12 # restore g12-g15
+ ldl REG_R0_PFP(g1),pfp # restore pfp, sp
+ ldq REG_G8(g1),g8 # restore g8-g11
+ modpc 0,g2,g3 # restore PC register
+ ret
+
+/*
+ * void _CPU_Context_restore( new_context )
+ *
+ * This routine performs a normal non-FP context.
+ */
+
+ .globl __CPU_Context_restore
+__CPU_Context_restore:
+ mov g0,g1 # g0 = _Thread_executing
+ b restore
+
+/*PAGE
+ * void _CPU_Context_save_fp_context( &fp_context_ptr )
+ * void _CPU_Context_restore_fp_context( &fp_context_ptr )
+ *
+ * There is currently no hardware floating point for the i960.
+ */
+
+ .globl __CPU_Context_save_fp
+ .globl __CPU_Context_restore_fp
+__CPU_Context_save_fp:
+__CPU_Context_restore_fp:
+#if ( I960_HAS_FPU == 1 )
+#error "Floating point support for i960 family has been implemented!!!"
+#endif
+ ret
+
+/*PAGE
+ * void __ISR_Handler()
+ *
+ * This routine provides the RTEMS interrupt management.
+ *
+ * Input parameters: NONE
+ *
+ * Output parameters: NONE
+ *
+ * NOTE:
+ * Upon entry, the supervisor stack will contain a stack frame
+ * back to the interrupted thread and the interrupt stack will contain
+ * an 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 supervisor stack to
+ * transfer control to the interrupt dispatcher.
+ */
+
+ .globl __ISR_Handler
+__ISR_Handler:
+ #ldconst 1,r8
+ #modpc 0,r8,r8 # enable tracing
+
+ # r4 = &_Thread_Dispatch_disable_level
+ ld __Thread_Dispatch_disable_level,r4
+ movl g0,r8 # save g0-g1
+
+ ld -16+8(fp),g0 # g0 = vector number
+ movl g2,r10 # save g2-g3
+
+ ld __ISR_Nest_level,r5 # r5 = &_Isr_nest_level
+ mov g14,r7 # save g14
+
+ lda 0,g14 # NOT Branch and Link
+ movl g4,r12 # save g4-g5
+
+ lda 1(r4),r4 # increment dispatch disable level
+ movl g6,r14 # save g6-g7
+
+ ld __ISR_Vector_table[g0*4],g1 # g1 = Users handler
+ addo 1,r5,r5 # increment ISR level
+
+ st r4,__Thread_Dispatch_disable_level
+ # one ISR nest level deeper
+ subo 1,r4,r4 # decrement dispatch disable level
+
+ st r5,__ISR_Nest_level # disable multitasking
+ subo 1,r5,r5 # decrement ISR nest level
+
+ callx (g1) # invoke user ISR
+
+ st r4,__Thread_Dispatch_disable_level
+ # unnest multitasking
+ st r5,__ISR_Nest_level # one less ISR nest level
+ cmpobne.f 0,r4,exit # If dispatch disabled, exit
+ ldl -16(fp),g0 # g0 = threads PC reg
+ # g1 = threads AC reg
+ ld __Context_Switch_necessary,r6
+ # r6 = Is thread switch necessary?
+ bbs.f 13,g0,exit # not outer level, then exit
+ cmpobne.f 0,r6,bframe # Switch necessary?
+
+ ld __ISR_Signals_to_thread_executing,g2
+ # signals sent to Run_thread
+ # while in interrupt handler?
+ cmpobe.f 0,g2,exit # No, then exit
+
+bframe: mov 0,g2
+ st g2,__ISR_Signals_to_thread_executing
+
+ ldconst 0x1f0000,g2 # g2 = intr disable mask
+ mov g2,g3 # g3 = new intr level
+ modpc 0,g2,g3 # set new level
+
+ andnot 7,pfp,r4 # r4 = pfp without ret type
+ flushreg # flush registers
+ # push _Isr_dispatch ret frame
+ # build ISF in r4-r6
+ ldconst 64,g2 # g2 = size of stack frame
+ ld 4(r4),g3 # g3 = previous sp
+ addo g2,g3,r5 # r5 = _Isr_dispatch SP
+ lda __ISR_Dispatch,r6 # r6 = _Isr_dispatch entry
+ stt r4,(g3) # set _Isr_dispatch ret info
+ st g1,16(g3) # set r4 = AC for ISR disp
+ or 7,g3,pfp # pfp to _Isr_dispatch
+
+exit: mov r7,g14 # restore g14
+ movq r8,g0 # restore g0-g3
+ movq r12,g4 # restore g4-g7
+ ret
+
+
+/*PAGE
+ *
+ * void __ISR_Dispatch()
+ *
+ * Entry point from the outermost interrupt service routine exit.
+ * The current stack is the supervisor mode stack.
+ */
+
+__ISR_Dispatch:
+ mov g14,r7
+ mov 0,g14
+ movq g0,r8
+ movq g4,r12
+ call __Thread_Dispatch
+
+ ldconst -1,r5 # r5 = reload mask
+ modac r5,r4,r4 # restore threads AC register
+ mov r7,g14
+ movq r8,g0
+ movq r12,g4
+ ret
diff --git a/c/src/exec/score/cpu/i960/i960.h b/c/src/exec/score/cpu/i960/i960.h
new file mode 100644
index 0000000000..fe7e68e95f
--- /dev/null
+++ b/c/src/exec/score/cpu/i960/i960.h
@@ -0,0 +1,289 @@
+/* i960.h
+ *
+ * This include file contains information pertaining to the Intel
+ * i960 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 __i960_h
+#define __i960_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 i960
+#define REPLACE_THIS_WITH_THE_CPU_MODEL
+#define REPLACE_THIS_WITH_THE_BSP
+
+/*
+ * This file contains the information required to build
+ * RTEMS for a particular member of the Intel i960
+ * family. It does this by setting variables to indicate
+ * which implementation dependent features are present
+ * in a particular member of the family.
+ *
+ * NOTE: For now i960 is really the i960ca. eventually need
+ * to put in at least support for FPU.
+ */
+
+#if defined(i960ca)
+
+#define RTEMS_MODEL_NAME "i960ca"
+#define I960_HAS_FPU 0
+
+#else
+
+#error "Unsupported CPU Model"
+
+#endif
+
+/*
+ * Define the name of the CPU family.
+ */
+
+#define CPU_NAME "Intel i960"
+
+#ifndef ASM
+
+/*
+ * This section defines the basic types for this processor.
+ */
+
+typedef unsigned char unsigned8; /* 8-bit unsigned integer */
+typedef unsigned short unsigned16; /* 16-bit unsigned integer */
+typedef unsigned int unsigned32; /* 32-bit unsigned integer */
+typedef unsigned long long unsigned64; /* 64-bit unsigned integer */
+
+typedef unsigned32 Priority_Bit_map_control;
+
+typedef char signed8; /* 8-bit signed integer */
+typedef short signed16; /* 16-bit signed integer */
+typedef int signed32; /* 32-bit signed integer */
+typedef long long signed64; /* 64-bit signed integer */
+
+typedef unsigned32 boolean; /* Boolean value */
+
+typedef float single_precision; /* single precision float */
+typedef double double_precision; /* double precision float */
+
+/*
+ * XXX should have an ifdef here and have stuff for the other
+ * XXX family members...
+ */
+
+#if defined(__i960CA__) || defined(__i960_CA__) || defined(__i960CA)
+
+/* i960CA control structures */
+
+/* Intel i960CA Control Table */
+
+typedef struct {
+ /* Control Group 0 */
+ unsigned int ipb0; /* IP breakpoint 0 */
+ unsigned int ipb1; /* IP breakpoint 1 */
+ unsigned int dab0; /* data address breakpoint 0 */
+ unsigned int dab1; /* data address breakpoint 1 */
+ /* Control Group 1 */
+ unsigned int imap0; /* interrupt map 0 */
+ unsigned int imap1; /* interrupt map 1 */
+ unsigned int imap2; /* interrupt map 2 */
+ unsigned int icon; /* interrupt control */
+ /* Control Group 2 */
+ unsigned int mcon0; /* memory region 0 configuration */
+ unsigned int mcon1; /* memory region 1 configuration */
+ unsigned int mcon2; /* memory region 2 configuration */
+ unsigned int mcon3; /* memory region 3 configuration */
+ /* Control Group 3 */
+ unsigned int mcon4; /* memory region 4 configuration */
+ unsigned int mcon5; /* memory region 5 configuration */
+ unsigned int mcon6; /* memory region 6 configuration */
+ unsigned int mcon7; /* memory region 7 configuration */
+ /* Control Group 4 */
+ unsigned int mcon8; /* memory region 8 configuration */
+ unsigned int mcon9; /* memory region 9 configuration */
+ unsigned int mcon10; /* memory region 10 configuration */
+ unsigned int mcon11; /* memory region 11 configuration */
+ /* Control Group 5 */
+ unsigned int mcon12; /* memory region 12 configuration */
+ unsigned int mcon13; /* memory region 13 configuration */
+ unsigned int mcon14; /* memory region 14 configuration */
+ unsigned int mcon15; /* memory region 15 configuration */
+ /* Control Group 6 */
+ unsigned int bpcon; /* breakpoint control */
+ unsigned int tc; /* trace control */
+ unsigned int bcon; /* bus configuration control */
+ unsigned int reserved; /* reserved */
+} i960ca_control_table;
+
+/* Intel i960CA Processor Control Block */
+
+typedef struct {
+ unsigned int *fault_tbl; /* fault table base address */
+ i960ca_control_table
+ *control_tbl; /* control table base address */
+ unsigned int initial_ac; /* AC register initial value */
+ unsigned int fault_config; /* fault configuration word */
+ void **intr_tbl; /* interrupt table base address */
+ void *sys_proc_tbl; /* system procedure table
+ base address */
+ unsigned int reserved; /* reserved */
+ unsigned int *intr_stack; /* interrupt stack pointer */
+ unsigned int ins_cache_cfg; /* instruction cache
+ configuration word */
+ unsigned int reg_cache_cfg; /* register cache configuration word */
+} i960ca_PRCB;
+
+#endif
+
+typedef void ( *i960_isr )( void );
+
+#define i960_disable_interrupts( oldlevel ) \
+ { (oldlevel) = 0x1f0000; \
+ asm volatile ( "modpc 0,%1,%1" \
+ : "=d" ((oldlevel)) \
+ : "0" ((oldlevel)) ); \
+ }
+
+#define i960_enable_interrupts( oldlevel ) \
+ { unsigned int _mask = 0x1f0000; \
+ asm volatile ( "modpc 0,%0,%1" \
+ : "=d" (_mask), "=d" ((oldlevel)) \
+ : "0" (_mask), "1" ((oldlevel)) ); \
+ }
+
+#define i960_flash_interrupts( oldlevel ) \
+ { unsigned int _mask = 0x1f0000; \
+ asm volatile ( "modpc 0,%0,%1 ; \
+ mov %0,%1 ; \
+ modpc 0,%0,%1" \
+ : "=d" (_mask), "=d" ((oldlevel)) \
+ : "0" (_mask), "1" ((oldlevel)) ); \
+ }
+
+#define i960_atomic_modify( mask, addr, prev ) \
+ { register unsigned int _mask = (mask); \
+ register unsigned int *_addr = (unsigned int *)(addr); \
+ asm volatile( "atmod %0,%1,%1" \
+ : "=d" (_addr), "=d" (_mask) \
+ : "0" (_addr), "1" (_mask) ); \
+ (prev) = _mask; \
+ }
+
+
+#define atomic_modify( _mask, _address, _previous ) \
+ i960_atomic_modify( _mask, _address, _previous )
+
+#define i960_enable_tracing() \
+ { register unsigned32 _pc = 0x1; \
+ asm volatile( "modpc 0,%0,%0" : "=d" (_pc) : "0" (_pc) ); \
+ }
+
+#define i960_unmask_intr( xint ) \
+ { register unsigned32 _mask= (1<<(xint)); \
+ asm volatile( "or sf1,%0,sf1" : "=d" (_mask) : "0" (_mask) ); \
+ }
+
+#define i960_mask_intr( xint ) \
+ { register unsigned32 _mask= (1<<(xint)); \
+ asm volatile( "andnot %0,sf1,sf1" : "=d" (_mask) : "0" (_mask) ); \
+ }
+
+#define i960_clear_intr( xint ) \
+ { register unsigned32 _xint=(xint); \
+ asm volatile( "loop_til_cleared:
+ clrbit %0,sf0,sf0 ; \
+ bbs %0,sf0,loop_til_cleared" \
+ : "=d" (_xint) : "0" (_xint) ); \
+ }
+
+#define i960_reload_ctl_group( group ) \
+ { register int _cmd = ((group)|0x400) ; \
+ asm volatile( "sysctl %0,%0,%0" : "=d" (_cmd) : "0" (_cmd) ); \
+ }
+
+#define i960_cause_intr( intr ) \
+ { register int _intr = (intr); \
+ asm volatile( "sysctl %0,%0,%0" : "=d" (_intr) : "0" (_intr) ); \
+ }
+
+#define i960_soft_reset( prcb ) \
+ { register i960ca_PRCB *_prcb = (prcb); \
+ register unsigned32 *_next=0; \
+ register unsigned32 _cmd = 0x30000; \
+ asm volatile( "lda next,%1; \
+ sysctl %0,%1,%2; \
+ next: mov g0,g0" \
+ : "=d" (_cmd), "=d" (_next), "=d" (_prcb) \
+ : "0" (_cmd), "1" (_next), "2" (_prcb) ); \
+ }
+
+static inline unsigned32 i960_pend_intrs()
+{ register unsigned32 _intr=0;
+ asm volatile( "mov sf0,%0" : "=d" (_intr) : "0" (_intr) );
+ return ( _intr );
+}
+
+static inline unsigned32 i960_mask_intrs()
+{ register unsigned32 _intr=0;
+ asm volatile( "mov sf1,%0" : "=d" (_intr) : "0" (_intr) );
+ return( _intr );
+}
+
+static inline unsigned32 i960_get_fp()
+{ register unsigned32 _fp=0;
+ asm volatile( "mov fp,%0" : "=d" (_fp) : "0" (_fp) );
+ return ( _fp );
+}
+
+/*
+ * The following routine swaps the endian format of an unsigned int.
+ * It must be static because it is referenced indirectly.
+ *
+ * This version is based on code presented in Vol. 4, No. 4 of
+ * Insight 960. It is certainly something you wouldn't think
+ * of on your own.
+ */
+
+static inline unsigned int CPU_swap_u32(
+ unsigned int value
+)
+{
+ register unsigned int to_swap = value;
+ register unsigned int temp = 0xFF00FF00;
+ register unsigned int swapped = 0;
+
+ /* to_swap swapped */
+ asm volatile ( "rotate 16,%0,%2 ;" /* 0x12345678 0x56781234 */
+ "modify %1,%0,%2 ;" /* 0x12345678 0x12785634 */
+ "rotate 8,%2,%2" /* 0x12345678 0x78563412 */
+ : "=r" (to_swap), "=r" (temp), "=r" (swapped)
+ : "0" (to_swap), "1" (temp), "2" (swapped)
+ );
+ return( swapped );
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* !ASM */
+
+#endif
+/* end of include file */
diff --git a/c/src/exec/score/cpu/i960/rtems.s b/c/src/exec/score/cpu/i960/rtems.s
new file mode 100644
index 0000000000..8abf47a276
--- /dev/null
+++ b/c/src/exec/score/cpu/i960/rtems.s
@@ -0,0 +1,25 @@
+/* rtems.s
+ *
+ * This file contains the single entry point code for
+ * the i960 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$
+ */
+
+ .text
+
+ .align 4
+ .globl RTEMS
+
+RTEMS:
+ ld __Entry_points[g7*4],r4
+ bx (r4)
+