diff options
Diffstat (limited to 'cpukit/score/cpu/i960')
-rw-r--r-- | cpukit/score/cpu/i960/asm.h | 107 | ||||
-rw-r--r-- | cpukit/score/cpu/i960/cpu.c | 124 |
2 files changed, 231 insertions, 0 deletions
diff --git a/cpukit/score/cpu/i960/asm.h b/cpukit/score/cpu/i960/asm.h new file mode 100644 index 0000000000..1c40601473 --- /dev/null +++ b/cpukit/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/cpukit/score/cpu/i960/cpu.c b/cpukit/score/cpu/i960/cpu.c new file mode 100644 index 0000000000..68ecb0525c --- /dev/null +++ b/cpukit/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 ); +} |