diff options
Diffstat (limited to 'c/src/exec/score/cpu/i960')
-rw-r--r-- | c/src/exec/score/cpu/i960/asm.h | 107 | ||||
-rw-r--r-- | c/src/exec/score/cpu/i960/cpu.c | 124 | ||||
-rw-r--r-- | c/src/exec/score/cpu/i960/cpu.h | 424 | ||||
-rw-r--r-- | c/src/exec/score/cpu/i960/cpu_asm.s | 199 | ||||
-rw-r--r-- | c/src/exec/score/cpu/i960/i960.h | 289 | ||||
-rw-r--r-- | c/src/exec/score/cpu/i960/rtems.s | 25 |
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) + |