From 32f415dc501f53c52189bc632eb337560dd90ae9 Mon Sep 17 00:00:00 2001 From: Joel Sherrill Date: Wed, 13 Dec 2000 18:09:48 +0000 Subject: 2000-12-13 Joel Sherrill * cpu_asm.h: Removed. * Makefile.am: Remove cpu_asm.h. * rtems/score/mips64orion.h: Renamed mips.h. * rtems/score/mips.h: New file, formerly mips64orion.h. Header rewritten. (mips_get_sr, mips_set_sr, mips_enable_in_interrupt_mask, mips_disable_in_interrupt_mask): New macros. * rtems/score/Makefile.am: Reflect renaming mips64orion.h. * asm.h: Include not . Now includes the few defines that were in . * cpu.c (_CPU_ISR_Get_level): Added MIPS ISA I version of this routine. MIPS ISA 3 is still in assembly for now. (_CPU_Thread_Idle_body): Rewrote in C. * cpu_asm.S: Rewrote file header. (FRAME,ENDFRAME) now in asm.h. (_CPU_ISR_Get_level): Removed ISA I version and rewrote in C. (_CPU_ISR_Set_level): Removed ISA I version and rewrote in C. (_CPU_Context_switch): MIPS ISA I now manages preserves SR_IEC and leaves other bits in SR alone on task switch. (mips_enable_interrupts,mips_disable_interrupts, mips_enable_global_interrupts,mips_disable_global_interrupts, disable_int, enable_int): Removed. (mips_get_sr): Rewritten as C macro. (_CPU_Thread_Idle_body): Rewritten in C. (init_exc_vecs): Rewritten in C as mips_install_isr_entries() and placed in libcpu. (exc_tlb_code, exc_xtlb_code, exc_cache_code, exc_norm_code): Moved to libcpu/mips/shared/interrupts. (general): Cleaned up comment blocks and #if 0 areas. * idtcpu.h: Made ifdef report an error. * iregdef.h: Removed warning. * rtems/score/cpu.h (CPU_INTERRUPT_NUMBER_OF_VECTORS): Now a variable number defined by libcpu. (_CPU_ISR_Disable, _CPU_ISR_Enable): Rewritten to use new routines to access SR. (_CPU_ISR_Set_level): Rewritten as macro for ISA I. (_CPU_Context_Initialize): Honor ISR level in task initialization. (_CPU_Fatal_halt): Use new _CPU_ISR_Disable() macro. --- c/src/exec/score/cpu/mips/ChangeLog | 41 ++ c/src/exec/score/cpu/mips/Makefile.am | 4 +- c/src/exec/score/cpu/mips/asm.h | 39 +- c/src/exec/score/cpu/mips/cpu.c | 37 +- c/src/exec/score/cpu/mips/cpu_asm.S | 524 +++------------------ c/src/exec/score/cpu/mips/cpu_asm.h | 115 ----- c/src/exec/score/cpu/mips/idtcpu.h | 5 +- c/src/exec/score/cpu/mips/iregdef.h | 2 +- c/src/exec/score/cpu/mips/rtems/score/Makefile.am | 2 +- c/src/exec/score/cpu/mips/rtems/score/cpu.h | 78 +-- c/src/exec/score/cpu/mips/rtems/score/mips.h | 71 ++- .../exec/score/cpu/mips/rtems/score/mips64orion.h | 76 --- cpukit/score/cpu/mips/ChangeLog | 41 ++ cpukit/score/cpu/mips/Makefile.am | 4 +- cpukit/score/cpu/mips/asm.h | 39 +- cpukit/score/cpu/mips/cpu.c | 37 +- cpukit/score/cpu/mips/cpu_asm.S | 524 +++------------------ cpukit/score/cpu/mips/idtcpu.h | 5 +- cpukit/score/cpu/mips/iregdef.h | 2 +- cpukit/score/cpu/mips/rtems/asm.h | 39 +- cpukit/score/cpu/mips/rtems/mips/idtcpu.h | 5 +- cpukit/score/cpu/mips/rtems/mips/iregdef.h | 2 +- cpukit/score/cpu/mips/rtems/score/cpu.h | 78 +-- cpukit/score/cpu/mips/rtems/score/mips.h | 71 ++- 24 files changed, 603 insertions(+), 1238 deletions(-) delete mode 100644 c/src/exec/score/cpu/mips/cpu_asm.h delete mode 100644 c/src/exec/score/cpu/mips/rtems/score/mips64orion.h diff --git a/c/src/exec/score/cpu/mips/ChangeLog b/c/src/exec/score/cpu/mips/ChangeLog index 84248074af..aa674ac86e 100644 --- a/c/src/exec/score/cpu/mips/ChangeLog +++ b/c/src/exec/score/cpu/mips/ChangeLog @@ -1,3 +1,44 @@ +2000-12-13 Joel Sherrill + + * cpu_asm.h: Removed. + * Makefile.am: Remove cpu_asm.h. + * rtems/score/mips64orion.h: Renamed mips.h. + * rtems/score/mips.h: New file, formerly mips64orion.h. + Header rewritten. + (mips_get_sr, mips_set_sr, mips_enable_in_interrupt_mask, + mips_disable_in_interrupt_mask): New macros. + * rtems/score/Makefile.am: Reflect renaming mips64orion.h. + * asm.h: Include not . Now includes the + few defines that were in . + * cpu.c (_CPU_ISR_Get_level): Added MIPS ISA I version of this routine. + MIPS ISA 3 is still in assembly for now. + (_CPU_Thread_Idle_body): Rewrote in C. + * cpu_asm.S: Rewrote file header. + (FRAME,ENDFRAME) now in asm.h. + (_CPU_ISR_Get_level): Removed ISA I version and rewrote in C. + (_CPU_ISR_Set_level): Removed ISA I version and rewrote in C. + (_CPU_Context_switch): MIPS ISA I now manages preserves SR_IEC and + leaves other bits in SR alone on task switch. + (mips_enable_interrupts,mips_disable_interrupts, + mips_enable_global_interrupts,mips_disable_global_interrupts, + disable_int, enable_int): Removed. + (mips_get_sr): Rewritten as C macro. + (_CPU_Thread_Idle_body): Rewritten in C. + (init_exc_vecs): Rewritten in C as mips_install_isr_entries() and + placed in libcpu. + (exc_tlb_code, exc_xtlb_code, exc_cache_code, exc_norm_code): Moved + to libcpu/mips/shared/interrupts. + (general): Cleaned up comment blocks and #if 0 areas. + * idtcpu.h: Made ifdef report an error. + * iregdef.h: Removed warning. + * rtems/score/cpu.h (CPU_INTERRUPT_NUMBER_OF_VECTORS): Now a variable + number defined by libcpu. + (_CPU_ISR_Disable, _CPU_ISR_Enable): Rewritten to use new routines + to access SR. + (_CPU_ISR_Set_level): Rewritten as macro for ISA I. + (_CPU_Context_Initialize): Honor ISR level in task initialization. + (_CPU_Fatal_halt): Use new _CPU_ISR_Disable() macro. + 2000-12-06 Joel Sherrill * rtems/score/cpu.h: When mips ISA level is 1, registers in the diff --git a/c/src/exec/score/cpu/mips/Makefile.am b/c/src/exec/score/cpu/mips/Makefile.am index 07ee2de0a4..0d2689b65d 100644 --- a/c/src/exec/score/cpu/mips/Makefile.am +++ b/c/src/exec/score/cpu/mips/Makefile.am @@ -10,7 +10,7 @@ SUBDIRS = rtems C_FILES = cpu.c C_O_FILES = $(C_FILES:%.c=$(ARCH)/%.o) -H_FILES = asm.h cpu_asm.h idtcpu.h iregdef.h +H_FILES = asm.h idtcpu.h iregdef.h S_FILES = cpu_asm.S S_O_FILES = $(S_FILES:%.S=$(ARCH)/%.o) @@ -44,7 +44,7 @@ all-local: $(ARCH) $(PREINSTALL_FILES) $(rtems_cpu_rel_OBJECTS) $(REL) \ .PRECIOUS: $(REL) -EXTRA_DIST = asm.h cpu.c cpu_asm.S cpu_asm.h idtcpu.h iregdef.h \ +EXTRA_DIST = asm.h cpu.c cpu_asm.S idtcpu.h iregdef.h \ rtems.c include $(top_srcdir)/../../../../../../automake/subdirs.am diff --git a/c/src/exec/score/cpu/mips/asm.h b/c/src/exec/score/cpu/mips/asm.h index 060be295bf..671821afb9 100644 --- a/c/src/exec/score/cpu/mips/asm.h +++ b/c/src/exec/score/cpu/mips/asm.h @@ -35,7 +35,7 @@ #define ASM #endif #include -#include +#include /* * Recent versions of GNU cpp define variables which indicate the @@ -117,6 +117,43 @@ _##name: #define ENDFRAME(name) #endif XDS +/* + * Hardware Floating Point Registers + */ + +#define R_FP0 0 +#define R_FP1 1 +#define R_FP2 2 +#define R_FP3 3 +#define R_FP4 4 +#define R_FP5 5 +#define R_FP6 6 +#define R_FP7 7 +#define R_FP8 8 +#define R_FP9 9 +#define R_FP10 10 +#define R_FP11 11 +#define R_FP12 12 +#define R_FP13 13 +#define R_FP14 14 +#define R_FP15 15 +#define R_FP16 16 +#define R_FP17 17 +#define R_FP18 18 +#define R_FP19 19 +#define R_FP20 20 +#define R_FP21 21 +#define R_FP22 22 +#define R_FP23 23 +#define R_FP24 24 +#define R_FP25 25 +#define R_FP26 26 +#define R_FP27 27 +#define R_FP28 28 +#define R_FP29 29 +#define R_FP30 30 +#define R_FP31 31 + #endif /* end of include file */ diff --git a/c/src/exec/score/cpu/mips/cpu.c b/c/src/exec/score/cpu/mips/cpu.c index db9ae911b4..22d66c95c0 100644 --- a/c/src/exec/score/cpu/mips/cpu.c +++ b/c/src/exec/score/cpu/mips/cpu.c @@ -66,8 +66,7 @@ void _CPU_Initialize( { unsigned int i = ISR_NUMBER_OF_VECTORS; - while ( i-- ) - { + while ( i-- ) { _ISR_Vector_table[i] = (ISR_Handler_entry)null_handler; } @@ -100,15 +99,25 @@ void _CPU_Initialize( /*PAGE * * _CPU_ISR_Get_level + * + * This routine returns the current interrupt level. */ - -#if 0 /* located in cpu_asm.S */ + +#if __mips == 3 + +/* in cpu_asm.S for now */ + +#elif __mips == 1 unsigned32 _CPU_ISR_Get_level( void ) { - /* - * This routine returns the current interrupt level. - */ + unsigned int sr; + + mips_get_sr(sr); + + return ((sr & SR_IEC) ? 0 : 1); } +#else +#error "CPU ISR level: unknown MIPS level for SR handling" #endif /*PAGE @@ -200,14 +209,18 @@ void _CPU_Install_interrupt_stack( void ) * hook with caution. */ -#if 0 /* located in cpu_asm.S */ void _CPU_Thread_Idle_body( void ) { - - for( ; ; ) - /* insert your "halt" instruction here */ ; -} +#if __mips == 3 + for( ; ; ) + asm volatile("wait"); /* use wait to enter low power mode */ +#elif __mips == 1 + for( ; ; ) + ; +#else +#error "IDLE: __mips not set to 1 or 3" #endif +} extern void mips_break( int error ); diff --git a/c/src/exec/score/cpu/mips/cpu_asm.S b/c/src/exec/score/cpu/mips/cpu_asm.S index b074369f17..b3cfd464f8 100644 --- a/c/src/exec/score/cpu/mips/cpu_asm.S +++ b/c/src/exec/score/cpu/mips/cpu_asm.S @@ -1,27 +1,29 @@ -/* cpu_asm.S - * +/* * This file contains the basic algorithms for all assembly code used * in an specific CPU port of RTEMS. These algorithms must be implemented * in assembly language * - * Author: Craig Lebakken - * - * COPYRIGHT (c) 1996 by Transition Networks Inc. - * - * To anyone who acknowledges that this file is provided "AS IS" - * without any express or implied warranty: - * permission to use, copy, modify, and distribute this file - * for any purpose is hereby granted without fee, provided that - * the above copyright notice and this notice appears in all - * copies, and that the name of Transition Networks not be used in - * advertising or publicity pertaining to distribution of the - * software without specific, written prior permission. - * Transition Networks makes no representations about the suitability - * of this software for any purpose. - * - * Derived from c/src/exec/score/cpu/no_cpu/cpu_asm.s: - * - * COPYRIGHT (c) 1989-1999. + * History: + * Baseline: no_cpu + * 1996: Ported to MIPS64ORION by Craig Lebakken + * COPYRIGHT (c) 1996 by Transition Networks Inc. + * To anyone who acknowledges that the modifications to this file to + * port it to the MIPS64ORION are provided "AS IS" without any + * express or implied warranty: + * permission to use, copy, modify, and distribute this file + * for any purpose is hereby granted without fee, provided that + * the above copyright notice and this notice appears in all + * copies, and that the name of Transition Networks not be used in + * advertising or publicity pertaining to distribution of the + * software without specific, written prior permission. Transition + * Networks makes no representations about the suitability + * of this software for any purpose. + * 2000: Reworked by Alan Cudmore to become + * the more general MIPS port. Joel Sherrill + * continued this rework, rewriting as much as possible in + * C and testing on the TX39. + * + * COPYRIGHT (c) 1989-2000. * On-Line Applications Research Corporation (OAR). * * The license and distribution terms for this file may be @@ -30,21 +32,11 @@ * * $Id$ */ -/* @(#)cpu_asm.S 08/20/96 1.15 */ - -#include "cpu_asm.h" +#include #include "iregdef.h" #include "idtcpu.h" -#define FRAME(name,frm_reg,offset,ret_reg) \ - .globl name; \ - .ent name; \ -name:; \ - .frame frm_reg,offset,ret_reg -#define ENDFRAME(name) \ - .end name - #define EXCP_STACK_SIZE (NREGS*R_SZ) #define ISR_VEC_SIZE 4 @@ -123,17 +115,12 @@ name:; \ /*PAGE * * _CPU_ISR_Get_level + * + * unsigned32 _CPU_ISR_Get_level( void ) + * + * This routine returns the current interrupt level. */ -#if 0 -unsigned32 _CPU_ISR_Get_level( void ) -{ - /* - * This routine returns the current interrupt level. - */ -} -#endif - #if __mips == 3 /* return the current exception level for the 4650 */ FRAME(_CPU_ISR_Get_level,sp,0,ra) @@ -188,24 +175,8 @@ ENDFRAME(_CPU_ISR_Set_level) #elif __mips == 1 /* MIPS ISA 1 ( R3000 ) */ -/* These routines might not be needed for the R3000 */ -/* Q:Who calls _CPU_ISR_Get/Set_level? */ -FRAME(_CPU_ISR_Get_level,sp,0,ra) - mfc0 v0,C0_SR - nop - andi v0, SR_IEC - j ra -ENDFRAME(_CPU_ISR_Get_level) - -FRAME(_CPU_ISR_Set_level,sp,0,ra) - nop - mfc0 t0,C0_SR - andi a0, SR_IEC - or t0, a0 - mtc0 t0,C0_SR - nop - j ra -ENDFRAME(_CPU_ISR_Set_level) +/* _CPU_ISR_Get/Set_level are called as part of task mode manipulation. */ +/* and are defined in C for the __mips == 1 */ #else #error "__mips is set to 1 or 3" @@ -225,10 +196,8 @@ ENDFRAME(_CPU_ISR_Set_level) */ /* void _CPU_Context_save_fp( - * void **fp_context_ptr - * ) - * { - * } + * void **fp_context_ptr + * ); */ FRAME(_CPU_Context_save_fp,sp,0,ra) @@ -285,10 +254,8 @@ ENDFRAME(_CPU_Context_save_fp) */ /* void _CPU_Context_restore_fp( - * void **fp_context_ptr + * void **fp_context_ptr * ) - * { - * } */ FRAME(_CPU_Context_restore_fp,sp,0,ra) @@ -337,11 +304,9 @@ ENDFRAME(_CPU_Context_restore_fp) */ /* void _CPU_Context_switch( - * Context_Control *run, - * Context_Control *heir + * Context_Control *run, + * Context_Control *heir * ) - * { - * } */ #if __mips == 3 /* MIPS ISA Level 3 ( R4xxx ) */ @@ -402,7 +367,7 @@ ENDFRAME(_CPU_Context_switch) FRAME(_CPU_Context_switch,sp,0,ra) mfc0 t0,C0_SR - li t1,~SR_IEC + li t1,~SR_IEC sw t0,C0_SR_OFFSET*4(a0) /* save status register */ and t0,t1 mtc0 t0,C0_SR /* first disable ie bit (recommended) */ @@ -436,10 +401,14 @@ _CPU_Context_switch_restore: lw ra,RA_OFFSET*4(a1) lw t0,C0_EPC_OFFSET*4(a1) mtc0 t0,C0_EPC - lw t1, C0_SR_OFFSET*4(a1) - mtc0 t1,C0_SR - - /* Q:Changes needed to SR_IEC bit in SR/_CPU_Context_switch_restore? */ + lw t0, C0_SR_OFFSET*4(a1) + andi t0,SR_IEC /* we know IEC=0, e.g. disabled */ + beq t0,$0,_CPU_Context_1 /* set IEC level from restore context */ + mfc0 t0,C0_SR + nop + or t0,SR_IEC /* new_sr = sr | SR_IEC */ + mtc0 t0,C0_SR /* set with enabled */ + _CPU_Context_1: j ra @@ -459,16 +428,12 @@ ENDFRAME(_CPU_Context_switch) * efficient manner. It may simply be a label in _CPU_Context_switch. * * NOTE: May be unnecessary to reload some registers. + * + * void _CPU_Context_restore( + * Context_Control *new_context + * ); */ -#if 0 -void _CPU_Context_restore( - Context_Control *new_context -) -{ -} -#endif - #if __mips == 3 FRAME(_CPU_Context_restore,sp,0,ra) @@ -502,36 +467,30 @@ EXTERN(_ISR_Signals_to_thread_executing,SZ_INT) * * This routine provides the RTEMS interrupt management. * + * void _ISR_Handler() + * + * + * This discussion ignores a lot of the ugly details in a real + * implementation such as saving enough registers/state to be + * able to do something real. Keep in mind that the goal is + * to invoke a user's ISR handler which is written in C and + * uses a certain set of registers. + * + * Also note that the exact order is to a large extent flexible. + * Hardware will dictate a sequence for a certain subset of + * _ISR_Handler while requirements for setting + * + * At entry to "common" _ISR_Handler, the vector number must be + * available. On some CPUs the hardware puts either the vector + * number or the offset into the vector table for this ISR in a + * known place. If the hardware does not give us this information, + * then the assembly portion of RTEMS for this port will contain + * a set of distinct interrupt entry points which somehow place + * the vector number in a known place (which is safe if another + * interrupt nests this one) and branches to _ISR_Handler. + * */ -#if 0 -void _ISR_Handler() -{ - /* - * This discussion ignores a lot of the ugly details in a real - * implementation such as saving enough registers/state to be - * able to do something real. Keep in mind that the goal is - * to invoke a user's ISR handler which is written in C and - * uses a certain set of registers. - * - * Also note that the exact order is to a large extent flexible. - * Hardware will dictate a sequence for a certain subset of - * _ISR_Handler while requirements for setting - */ - - /* - * At entry to "common" _ISR_Handler, the vector number must be - * available. On some CPUs the hardware puts either the vector - * number or the offset into the vector table for this ISR in a - * known place. If the hardware does not give us this information, - * then the assembly portion of RTEMS for this port will contain - * a set of distinct interrupt entry points which somehow place - * the vector number in a known place (which is safe if another - * interrupt nests this one) and branches to _ISR_Handler. - * - */ -#endif - #if __mips == 3 /* ----------------------------------------------------------------------------- */ FRAME(_ISR_Handler,sp,0,ra) @@ -583,12 +542,13 @@ FRAME(_ISR_Handler,sp,0,ra) /* determine if an interrupt generated this exception */ mfc0 k0,C0_CAUSE and k1,k0,CAUSE_EXCMASK - bnez k1,_ISR_Handler_prom_exit /* not an external interrup -t, pass exception to Monitor */ + bnez k1,_ISR_Handler_prom_exit /* not an external interrupt, + pass exception to Monitor */ mfc0 k1,C0_SR and k0,k1 and k0,CAUSE_IPMASK - beq k0,zero,_ISR_Handler_quick_exit /* external interrupt not enabled, ignore */ + beq k0,zero,_ISR_Handler_quick_exit /* external interrupt not + enabled, ignore */ nop /* @@ -1035,81 +995,6 @@ ENDFRAME(_ISR_Handler) #endif -FRAME(mips_enable_interrupts,sp,0,ra) - mfc0 t0,C0_SR /* get status reg */ - nop - or t0,t0,a0 - mtc0 t0,C0_SR /* save updated status reg */ - j ra - nop -ENDFRAME(mips_enable_interrupts) - -FRAME(mips_disable_interrupts,sp,0,ra) - mfc0 v0,C0_SR /* get status reg */ - li t1,SR_IMASK /* t1 = load interrupt mask word */ - not t0,t1 /* t0 = ~t1 */ - and t0,v0 /* clear imask bits */ - mtc0 t0,C0_SR /* save status reg */ - and v0,t1 /* mask return value (only return imask bits) */ - jr ra - nop -ENDFRAME(mips_disable_interrupts) - -#if __mips == 3 - -FRAME(mips_enable_global_interrupts,sp,0,ra) - mfc0 t0,C0_SR /* get status reg */ - nop - ori t0,SR_IE - mtc0 t0,C0_SR /* save updated status reg */ - j ra - nop -ENDFRAME(mips_enable_global_interrupts) - -FRAME(mips_disable_global_interrupts,sp,0,ra) - li t1,SR_IE - mfc0 t0,C0_SR /* get status reg */ - not t1 - and t0,t1 - mtc0 t0,C0_SR /* save updated status reg */ - j ra - nop -ENDFRAME(mips_disable_global_interrupts) - -#elif __mips == 1 - -FRAME(mips_enable_global_interrupts,sp,0,ra) - mfc0 t0,C0_SR /* get status reg */ - nop - ori t0,SR_IEC - mtc0 t0,C0_SR /* save updated status reg */ - j ra - nop -ENDFRAME(mips_enable_global_interrupts) - -FRAME(mips_disable_global_interrupts,sp,0,ra) - li t1,SR_IEC - mfc0 t0,C0_SR /* get status reg */ - not t1 - and t0,t1 - mtc0 t0,C0_SR /* save updated status reg */ - j ra - nop -ENDFRAME(mips_disable_global_interrupts) - -#else - - #error "__mips is not set to 1 or 3" - -#endif - -/* return the value of the status register in v0. Used for debugging */ -FRAME(mips_get_sr,sp,0,ra) - mfc0 v0,C0_SR - j ra - nop -ENDFRAME(mips_get_sr) - FRAME(mips_break,sp,0,ra) #if 1 break 0x0 @@ -1120,266 +1005,3 @@ FRAME(mips_break,sp,0,ra) nop ENDFRAME(mips_break) - -/************************************************************************** -** -** enable_int(mask) - enables interrupts - mask is positioned so it only -** needs to be or'ed into the status reg. This -** also does some other things !!!! caution should -** be used if invoking this while in the middle -** of a debugging session where the client may have -** nested interrupts. -** -****************************************************************************/ -FRAME(enable_int,sp,0,ra) - .set noreorder - mfc0 t0,C0_SR - or a0,1 - or t0,a0 - mtc0 t0,C0_SR - j ra - nop - .set reorder -ENDFRAME(enable_int) - - -/*************************************************************************** -** -** disable_int(mask) - disable the interrupt - mask is the complement -** of the bits to be cleared - i.e. to clear ext int -** 5 the mask would be - 0xffff7fff -** -****************************************************************************/ -FRAME(disable_int,sp,0,ra) - .set noreorder - mfc0 t0,C0_SR - nop - and t0,a0 - mtc0 t0,C0_SR - j ra - nop -ENDFRAME(disable_int) - - -/*PAGE - * - * _CPU_Internal_threads_Idle_thread_body - * - * NOTES: - * - * 1. This is the same as the regular CPU independent algorithm. - * - * 2. If you implement this using a "halt", "idle", or "shutdown" - * instruction, then don't forget to put it in an infinite loop. - * - * 3. Be warned. Some processors with onboard DMA have been known - * to stop the DMA if the CPU were put in IDLE mode. This might - * also be a problem with other on-chip peripherals. So use this - * hook with caution. - */ - -#if __mips == 3 - -FRAME(_CPU_Thread_Idle_body,sp,0,ra) - wait /* enter low power mode */ - j _CPU_Thread_Idle_body - nop -ENDFRAME(_CPU_Thread_Idle_body) - -#elif __mips == 1 - -FRAME(_CPU_Thread_Idle_body,sp,0,ra) - nop /* no wait instruction */ - j _CPU_Thread_Idle_body - nop -ENDFRAME(_CPU_Thread_Idle_body) - -#else - - #error "__mips not set to 1 or 3" - -#endif - -/************************************************************************** -** -** init_exc_vecs() - moves the exception code into the addresses -** reserved for exception vectors -** -** UTLB Miss exception vector at address 0x80000000 -** -** General exception vector at address 0x80000080 -** -** RESET exception vector is at address 0xbfc00000 -** -***************************************************************************/ - -#define VEC_CODE_LENGTH 10*4 - -FRAME(init_exc_vecs,sp,0,ra) - -#if __mips == 1 - - .set noreorder - la t1,exc_utlb_code - la t2,exc_norm_code - li t3,UT_VEC - li t4,E_VEC - li t5,VEC_CODE_LENGTH -1: - lw t6,0(t1) - lw t7,0(t2) - sw t6,0(t3) - sw t7,0(t4) - addiu t1,4 - addiu t3,4 - addiu t4,4 - subu t5,4 - bne t5,zero,1b - addiu t2,4 - move t5,ra # assumes clear_cache doesnt use t5 - li a0,UT_VEC - jal clear_cache /* Check out clear cache.... */ - li a1,VEC_CODE_LENGTH - nop - li a0,E_VEC - jal clear_cache - li a1,VEC_CODE_LENGTH - move ra,t5 # restore ra - j ra - nop - .set reorder - -#elif __mips == 3 - - .set reorder - move t5,ra # assumes clear_cache doesnt use t5 - - /* TLB exception vector */ - la t1,exc_tlb_code - li t2,T_VEC |K1BASE - li t3,VEC_CODE_LENGTH -1: - lw t6,0(t1) - addiu t1,4 - subu t3,4 - sw t6,0(t2) - addiu t2,4 - bne t3,zero,1b - - li a0,T_VEC - li a1,VEC_CODE_LENGTH - jal clear_cache - - la t1,exc_xtlb_code - li t2,X_VEC |K1BASE - li t3,VEC_CODE_LENGTH -1: - lw t6,0(t1) - addiu t1,4 - subu t3,4 - sw t6,0(t2) - addiu t2,4 - bne t3,zero,1b - - /* extended TLB exception vector */ - li a0,X_VEC - li a1,VEC_CODE_LENGTH - jal clear_cache - - /* cache error exception vector */ - la t1,exc_cache_code - li t2,C_VEC |K1BASE - li t3,VEC_CODE_LENGTH -1: - lw t6,0(t1) - addiu t1,4 - subu t3,4 - sw t6,0(t2) - addiu t2,4 - bne t3,zero,1b - - li a0,C_VEC - li a1,VEC_CODE_LENGTH - jal clear_cache - - /* normal exception vector */ - la t1,exc_norm_code - li t2,E_VEC |K1BASE - li t3,VEC_CODE_LENGTH -1: - lw t6,0(t1) - addiu t1,4 - subu t3,4 - sw t6,0(t2) - addiu t2,4 - bne t3,zero,1b - - li a0,E_VEC - li a1,VEC_CODE_LENGTH - jal clear_cache - - move ra,t5 # restore ra - j ra - -#else - #error "__mips not set to 1 or 3" -#endif - -ENDFRAME(init_exc_vecs) - -FRAME(exc_utlb_code,sp,0,ra) - la k0, _ISR_Handler /* XXX not right -- but need to link*/ - j k0 - nop -ENDFRAME(exc_utlb_code) - -FRAME(exc_norm_code,sp,0,ra) - la k0, _ISR_Handler /* generic external int hndlr */ - j k0 - nop -ENDFRAME(exc_norm_code) - -/* -** Again, reliance on SIM. Not good. -*/ -#if __mips == 3 - -FRAME(exc_tlb_code,sp,0,ra) - la k0, (R_VEC+((112)*8)) /* R4000 Sim location */ - j k0 - nop -ENDFRAME(exc_tlb_code) - -FRAME(exc_xtlb_code,sp,0,ra) - la k0, (R_VEC+((112)*8)) /* R4000 Sim location */ - j k0 - nop - -ENDFRAME(exc_xtlb_code) - -FRAME(exc_cache_code,sp,0,ra) - la k0, (R_VEC+((112)*8)) /* R4000 Sim location */ - j k0 - nop -ENDFRAME(exc_cache_code) - -#elif __mips == 1 -/* ------------------------------------------------------ */ -FRAME(exc_tlb_code,sp,0,ra) - la k0, (R_VEC+((48)*8)) /* Need something else here besides IDT/SIM call */ - j k0 - nop -ENDFRAME(exc_tlb_code) - -FRAME(exc_cache_code,sp,0,ra) - la k0, (R_VEC+((48)*8)) - j k0 - nop -ENDFRAME(exc_cache_code) - -#else - - #error "__mips is not set to 1 or 3" - -#endif - diff --git a/c/src/exec/score/cpu/mips/cpu_asm.h b/c/src/exec/score/cpu/mips/cpu_asm.h deleted file mode 100644 index 287b881068..0000000000 --- a/c/src/exec/score/cpu/mips/cpu_asm.h +++ /dev/null @@ -1,115 +0,0 @@ -/* - * cpu_asm.h - * - * Author: Craig Lebakken - * - * COPYRIGHT (c) 1996 by Transition Networks Inc. - * - * To anyone who acknowledges that this file is provided "AS IS" - * without any express or implied warranty: - * permission to use, copy, modify, and distribute this file - * for any purpose is hereby granted without fee, provided that - * the above copyright notice and this notice appears in all - * copies, and that the name of Transition Networks not be used in - * advertising or publicity pertaining to distribution of the - * software without specific, written prior permission. - * Transition Networks makes no representations about the suitability - * of this software for any purpose. - * - * Derived from c/src/exec/score/cpu/no_cpu/cpu_asm.h: - * - * COPYRIGHT (c) 1989-1999. - * On-Line Applications Research Corporation (OAR). - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.OARcorp.com/rtems/license.html. - * - * $Id$ - * - */ -/* @(#)cpu_asm.h 08/20/96 1.2 */ - -#ifndef __CPU_ASM_h -#define __CPU_ASM_h - -/* pull in the generated offsets */ - -/* #include */ - -/* - * Hardware General Registers - */ - -/* put something here */ - -/* - * Hardware Floating Point Registers - */ - -#define R_FP0 0 -#define R_FP1 1 -#define R_FP2 2 -#define R_FP3 3 -#define R_FP4 4 -#define R_FP5 5 -#define R_FP6 6 -#define R_FP7 7 -#define R_FP8 8 -#define R_FP9 9 -#define R_FP10 10 -#define R_FP11 11 -#define R_FP12 12 -#define R_FP13 13 -#define R_FP14 14 -#define R_FP15 15 -#define R_FP16 16 -#define R_FP17 17 -#define R_FP18 18 -#define R_FP19 19 -#define R_FP20 20 -#define R_FP21 21 -#define R_FP22 22 -#define R_FP23 23 -#define R_FP24 24 -#define R_FP25 25 -#define R_FP26 26 -#define R_FP27 27 -#define R_FP28 28 -#define R_FP29 29 -#define R_FP30 30 -#define R_FP31 31 - -/* - * Hardware Control Registers - */ - -/* put something here */ - -/* - * Calling Convention - */ - -/* put something here */ - -/* - * Temporary registers - */ - -/* put something here */ - -/* - * Floating Point Registers - SW Conventions - */ - -/* put something here */ - -/* - * Temporary floating point registers - */ - -/* put something here */ - -#endif - -/* end of file */ diff --git a/c/src/exec/score/cpu/mips/idtcpu.h b/c/src/exec/score/cpu/mips/idtcpu.h index cfb2fe626a..02153b184f 100644 --- a/c/src/exec/score/cpu/mips/idtcpu.h +++ b/c/src/exec/score/cpu/mips/idtcpu.h @@ -59,12 +59,13 @@ LICENSED MATERIAL - PROGRAM PROPERTY OF IDT #if __mips == 1 #define UT_VEC K0BASE /* utlbmiss vector */ #define E_VEC (K0BASE+0x80) /* exception vevtor */ -#endif -#if __mips == 3 +#elif __mips == 3 #define T_VEC (K0BASE+0x000) /* tlbmiss vector */ #define X_VEC (K0BASE+0x080) /* xtlbmiss vector */ #define C_VEC (K0BASE+0x100) /* cache error vector */ #define E_VEC (K0BASE+0x180) /* exception vector */ +#else +#error "EXCEPTION VECTORS: unknown ISA level" #endif #define R_VEC (K1BASE+0x1fc00000) /* reset vector */ diff --git a/c/src/exec/score/cpu/mips/iregdef.h b/c/src/exec/score/cpu/mips/iregdef.h index ca50207a3b..8463e74245 100644 --- a/c/src/exec/score/cpu/mips/iregdef.h +++ b/c/src/exec/score/cpu/mips/iregdef.h @@ -296,7 +296,7 @@ LICENSED MATERIAL - PROGRAM PROPERTY OF IDT #define R_RA R_R31 /* Ketan added the following */ -#ifdef __mips == 1 +#if __mips == 1 #define sreg sw #define lreg lw #define rmfc0 mfc0 diff --git a/c/src/exec/score/cpu/mips/rtems/score/Makefile.am b/c/src/exec/score/cpu/mips/rtems/score/Makefile.am index be1e4fd6b7..097a177601 100644 --- a/c/src/exec/score/cpu/mips/rtems/score/Makefile.am +++ b/c/src/exec/score/cpu/mips/rtems/score/Makefile.am @@ -4,7 +4,7 @@ AUTOMAKE_OPTIONS = foreign 1.4 -H_FILES = cpu.h mips64orion.h mipstypes.h +H_FILES = cpu.h mips.h mipstypes.h noinst_HEADERS = $(H_FILES) # diff --git a/c/src/exec/score/cpu/mips/rtems/score/cpu.h b/c/src/exec/score/cpu/mips/rtems/score/cpu.h index a12c4369c4..5d5a9a2754 100644 --- a/c/src/exec/score/cpu/mips/rtems/score/cpu.h +++ b/c/src/exec/score/cpu/mips/rtems/score/cpu.h @@ -38,17 +38,12 @@ extern "C" { #endif -#include /* pick up machine definitions */ +#include /* pick up machine definitions */ #ifndef ASM +#include #include #endif -extern int mips_disable_interrupts( void ); -extern void mips_enable_interrupts( int _level ); -extern int mips_disable_global_interrupts( void ); -extern void mips_enable_global_interrupts( void ); -extern void mips_fatal_error ( int error ); - /* conditional compilation parameters */ /* @@ -530,6 +525,7 @@ SCORE_EXTERN void (*_CPU_Thread_dispatch_pointer)(); * by RTEMS. */ +extern unsigned int mips_interrupt_number_of_vectors; #define CPU_INTERRUPT_NUMBER_OF_VECTORS 8 #define CPU_INTERRUPT_MAXIMUM_VECTOR_NUMBER (CPU_INTERRUPT_NUMBER_OF_VECTORS - 1) @@ -593,10 +589,11 @@ SCORE_EXTERN void (*_CPU_Thread_dispatch_pointer)(); * level is returned in _level. */ -#define _CPU_ISR_Disable( _int_level ) \ - do{ \ - _int_level = mips_disable_interrupts(); \ - }while(0) +#define _CPU_ISR_Disable( _level ) \ + do { \ + mips_get_sr( _level ); \ + mips_set_sr( (_level) & ~SR_IEC ); \ + } while(0) /* * Enable interrupts to the previous level (returned by _CPU_ISR_Disable). @@ -605,9 +602,9 @@ SCORE_EXTERN void (*_CPU_Thread_dispatch_pointer)(); */ #define _CPU_ISR_Enable( _level ) \ - do{ \ - mips_enable_interrupts(_level); \ - }while(0) + do { \ + mips_set_sr(_level); \ + } while(0) /* * This temporarily restores the interrupt to _level before immediately @@ -617,11 +614,11 @@ SCORE_EXTERN void (*_CPU_Thread_dispatch_pointer)(); */ #define _CPU_ISR_Flash( _xlevel ) \ - do{ \ - int _scratch; \ - _CPU_ISR_Enable( _xlevel ); \ - _CPU_ISR_Disable( _scratch ); \ - }while(0) + do { \ + unsigned int _scratch; \ + _CPU_ISR_Enable( _xlevel ); \ + _CPU_ISR_Disable( _scratch ); \ + } while(0) /* * Map interrupt level in task mode onto the hardware that the CPU @@ -632,10 +629,30 @@ SCORE_EXTERN void (*_CPU_Thread_dispatch_pointer)(); * 8 - 255 would be available for bsp/application specific meaning. * This could be used to manage a programmable interrupt controller * via the rtems_task_mode directive. + * + * On the MIPS, 0 is all on. Non-zero is all off. This only + * manipulates the IEC. */ + +#if __mips == 3 extern void _CPU_ISR_Set_level( unsigned32 _new_level ); -unsigned32 _CPU_ISR_Get_level( void ); +unsigned32 _CPU_ISR_Get_level( void ); /* in cpu_asm.S */ +#elif __mips == 1 + +#define _CPU_ISR_Set_level( _new_level ) \ + do { \ + unsigned int _sr; \ + mips_get_sr(_sr); \ + (_sr) &= ~SR_IEC; /* clear the IEC bit */ \ + if ( !(_new_level) ) (_sr) |= SR_IEC; /* enable interrupts */ \ + mips_set_sr(_sr); \ + } while (0) + +unsigned32 _CPU_ISR_Get_level( void ); /* in cpu.c */ +#else +#error "CPU ISR level: unknown MIPS level for SR handling" +#endif /* end of ISR handler macros */ @@ -670,7 +687,8 @@ unsigned32 _CPU_ISR_Get_level( void ); (_the_context)->sp = _stack_tmp; \ (_the_context)->fp = _stack_tmp; \ (_the_context)->ra = (unsigned64)_entry_point; \ - (_the_context)->c0_sr = 0; \ + if (_isr) (_the_context)->c0_sr = 0xff00; \ + else (_the_context)->c0_sr = 0xff01; \ } /* @@ -730,11 +748,14 @@ unsigned32 _CPU_ISR_Get_level( void ); * halts/stops the CPU. */ +void mips_fatal_error ( int error ); + #define _CPU_Fatal_halt( _error ) \ - { \ - mips_disable_global_interrupts(); \ + do { \ + unsigned int _level; \ + _CPU_ISR_Disable(_level); \ mips_fatal_error(_error); \ - } + } while (0) /* end of Fatal Error manager macros */ @@ -980,15 +1001,6 @@ static inline unsigned int CPU_swap_u32( #define CPU_swap_u16( value ) \ (((value&0xff) << 8) | ((value >> 8)&0xff)) -/* - * Miscellaneous prototypes - * - * NOTE: The names should have mips64orion in them. - */ - -void disable_int( unsigned32 mask ); -void enable_int( unsigned32 mask ); - #ifdef __cplusplus } #endif diff --git a/c/src/exec/score/cpu/mips/rtems/score/mips.h b/c/src/exec/score/cpu/mips/rtems/score/mips.h index 90e959bd47..1f2740c49d 100644 --- a/c/src/exec/score/cpu/mips/rtems/score/mips.h +++ b/c/src/exec/score/cpu/mips/rtems/score/mips.h @@ -1,23 +1,6 @@ -/* mips64orion.h +/* mips.h * - * Author: Craig Lebakken - * - * COPYRIGHT (c) 1996 by Transition Networks Inc. - * - * To anyone who acknowledges that this file is provided "AS IS" - * without any express or implied warranty: - * permission to use, copy, modify, and distribute this file - * for any purpose is hereby granted without fee, provided that - * the above copyright notice and this notice appears in all - * copies, and that the name of Transition Networks not be used in - * advertising or publicity pertaining to distribution of the - * software without specific, written prior permission. - * Transition Networks makes no representations about the suitability - * of this software for any purpose. - * - * Derived from c/src/exec/score/cpu/no_cpu/no_cpu.h: - * - * COPYRIGHT (c) 1989-1999. + * COPYRIGHT (c) 1989-2000. * On-Line Applications Research Corporation (OAR). * * The license and distribution terms for this file may be @@ -68,6 +51,56 @@ extern "C" { #define CPU_NAME "MIPS" +/* + * Some macros to access registers + */ + +#define mips_get_sr( _x ) \ + do { \ + asm volatile( "mfc0 %0, $12; nop" : "=g" (_x) : ); \ + } while (0) + +#define mips_set_sr( _x ) \ + do { \ + unsigned int __x = (_x); \ + asm volatile( "mtc0 %0, $12; nop" : : "r" (__x) ); \ + } while (0) + +/* + * Manipulate interrupt mask + * + * mips_unmask_interrupt( _mask) + * enables interrupts - mask is positioned so it only needs to be or'ed + * into the status reg. This also does some other things !!!! Caution + * should be used if invoking this while in the middle of a debugging + * session where the client may have nested interrupts. + * + * mips_mask_interrupt( _mask ) + * disable the interrupt - mask is the complement of the bits to be + * cleared - i.e. to clear ext int 5 the mask would be - 0xffff7fff + * + * + * NOTE: mips_mask_interrupt() used to be disable_int(). + * mips_unmask_interrupt() used to be enable_int(). + * + */ + +#define mips_enable_in_interrupt_mask( _mask ) \ + do { \ + unsigned int _sr; \ + mips_get_sr( _sr ); \ + _sr |= (_mask) | SR_IEC; \ + mips_set_sr( _sr ); \ + } while (0) + +#define mips_disable_in_interrupt_mask( _mask ) \ + do { \ + unsigned int _sr; \ + mips_get_sr( _sr ); \ + _sr &= ~(_mask); \ + mips_set_sr( _sr ); \ + } while (0) + #ifdef __cplusplus } #endif diff --git a/c/src/exec/score/cpu/mips/rtems/score/mips64orion.h b/c/src/exec/score/cpu/mips/rtems/score/mips64orion.h deleted file mode 100644 index 90e959bd47..0000000000 --- a/c/src/exec/score/cpu/mips/rtems/score/mips64orion.h +++ /dev/null @@ -1,76 +0,0 @@ -/* mips64orion.h - * - * Author: Craig Lebakken - * - * COPYRIGHT (c) 1996 by Transition Networks Inc. - * - * To anyone who acknowledges that this file is provided "AS IS" - * without any express or implied warranty: - * permission to use, copy, modify, and distribute this file - * for any purpose is hereby granted without fee, provided that - * the above copyright notice and this notice appears in all - * copies, and that the name of Transition Networks not be used in - * advertising or publicity pertaining to distribution of the - * software without specific, written prior permission. - * Transition Networks makes no representations about the suitability - * of this software for any purpose. - * - * Derived from c/src/exec/score/cpu/no_cpu/no_cpu.h: - * - * COPYRIGHT (c) 1989-1999. - * On-Line Applications Research Corporation (OAR). - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.OARcorp.com/rtems/license.html. - * - * $Id$ - */ -/* @(#)mips64orion.h 08/29/96 1.3 */ - -#ifndef _INCLUDE_MIPS_h -#define _INCLUDE_MIPS_h - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * This file contains the information required to build - * RTEMS for a particular member of the "no cpu" - * family when executing in protected mode. It does - * this by setting variables to indicate which implementation - * dependent features are present in a particular member - * of the family. - */ - -#if defined(__mips_soft_float) -#define MIPS_HAS_FPU 0 -#else -#define MIPS_HAS_FPU 1 -#endif - -#if (__mips == 1) -#define CPU_MODEL_NAME "ISA Level 1 or 2" -#elif (__mips == 3) -#if defined(__mips64) -#define CPU_MODEL_NAME "ISA Level 4" -#else -#define CPU_MODEL_NAME "ISA Level 3" -#endif -#else -#error "Unknown MIPS ISA level" -#endif - -/* - * Define the name of the CPU family. - */ - -#define CPU_NAME "MIPS" - -#ifdef __cplusplus -} -#endif - -#endif /* ! _INCLUDE_MIPS_h */ -/* end of include file */ diff --git a/cpukit/score/cpu/mips/ChangeLog b/cpukit/score/cpu/mips/ChangeLog index 84248074af..aa674ac86e 100644 --- a/cpukit/score/cpu/mips/ChangeLog +++ b/cpukit/score/cpu/mips/ChangeLog @@ -1,3 +1,44 @@ +2000-12-13 Joel Sherrill + + * cpu_asm.h: Removed. + * Makefile.am: Remove cpu_asm.h. + * rtems/score/mips64orion.h: Renamed mips.h. + * rtems/score/mips.h: New file, formerly mips64orion.h. + Header rewritten. + (mips_get_sr, mips_set_sr, mips_enable_in_interrupt_mask, + mips_disable_in_interrupt_mask): New macros. + * rtems/score/Makefile.am: Reflect renaming mips64orion.h. + * asm.h: Include not . Now includes the + few defines that were in . + * cpu.c (_CPU_ISR_Get_level): Added MIPS ISA I version of this routine. + MIPS ISA 3 is still in assembly for now. + (_CPU_Thread_Idle_body): Rewrote in C. + * cpu_asm.S: Rewrote file header. + (FRAME,ENDFRAME) now in asm.h. + (_CPU_ISR_Get_level): Removed ISA I version and rewrote in C. + (_CPU_ISR_Set_level): Removed ISA I version and rewrote in C. + (_CPU_Context_switch): MIPS ISA I now manages preserves SR_IEC and + leaves other bits in SR alone on task switch. + (mips_enable_interrupts,mips_disable_interrupts, + mips_enable_global_interrupts,mips_disable_global_interrupts, + disable_int, enable_int): Removed. + (mips_get_sr): Rewritten as C macro. + (_CPU_Thread_Idle_body): Rewritten in C. + (init_exc_vecs): Rewritten in C as mips_install_isr_entries() and + placed in libcpu. + (exc_tlb_code, exc_xtlb_code, exc_cache_code, exc_norm_code): Moved + to libcpu/mips/shared/interrupts. + (general): Cleaned up comment blocks and #if 0 areas. + * idtcpu.h: Made ifdef report an error. + * iregdef.h: Removed warning. + * rtems/score/cpu.h (CPU_INTERRUPT_NUMBER_OF_VECTORS): Now a variable + number defined by libcpu. + (_CPU_ISR_Disable, _CPU_ISR_Enable): Rewritten to use new routines + to access SR. + (_CPU_ISR_Set_level): Rewritten as macro for ISA I. + (_CPU_Context_Initialize): Honor ISR level in task initialization. + (_CPU_Fatal_halt): Use new _CPU_ISR_Disable() macro. + 2000-12-06 Joel Sherrill * rtems/score/cpu.h: When mips ISA level is 1, registers in the diff --git a/cpukit/score/cpu/mips/Makefile.am b/cpukit/score/cpu/mips/Makefile.am index 07ee2de0a4..0d2689b65d 100644 --- a/cpukit/score/cpu/mips/Makefile.am +++ b/cpukit/score/cpu/mips/Makefile.am @@ -10,7 +10,7 @@ SUBDIRS = rtems C_FILES = cpu.c C_O_FILES = $(C_FILES:%.c=$(ARCH)/%.o) -H_FILES = asm.h cpu_asm.h idtcpu.h iregdef.h +H_FILES = asm.h idtcpu.h iregdef.h S_FILES = cpu_asm.S S_O_FILES = $(S_FILES:%.S=$(ARCH)/%.o) @@ -44,7 +44,7 @@ all-local: $(ARCH) $(PREINSTALL_FILES) $(rtems_cpu_rel_OBJECTS) $(REL) \ .PRECIOUS: $(REL) -EXTRA_DIST = asm.h cpu.c cpu_asm.S cpu_asm.h idtcpu.h iregdef.h \ +EXTRA_DIST = asm.h cpu.c cpu_asm.S idtcpu.h iregdef.h \ rtems.c include $(top_srcdir)/../../../../../../automake/subdirs.am diff --git a/cpukit/score/cpu/mips/asm.h b/cpukit/score/cpu/mips/asm.h index 060be295bf..671821afb9 100644 --- a/cpukit/score/cpu/mips/asm.h +++ b/cpukit/score/cpu/mips/asm.h @@ -35,7 +35,7 @@ #define ASM #endif #include -#include +#include /* * Recent versions of GNU cpp define variables which indicate the @@ -117,6 +117,43 @@ _##name: #define ENDFRAME(name) #endif XDS +/* + * Hardware Floating Point Registers + */ + +#define R_FP0 0 +#define R_FP1 1 +#define R_FP2 2 +#define R_FP3 3 +#define R_FP4 4 +#define R_FP5 5 +#define R_FP6 6 +#define R_FP7 7 +#define R_FP8 8 +#define R_FP9 9 +#define R_FP10 10 +#define R_FP11 11 +#define R_FP12 12 +#define R_FP13 13 +#define R_FP14 14 +#define R_FP15 15 +#define R_FP16 16 +#define R_FP17 17 +#define R_FP18 18 +#define R_FP19 19 +#define R_FP20 20 +#define R_FP21 21 +#define R_FP22 22 +#define R_FP23 23 +#define R_FP24 24 +#define R_FP25 25 +#define R_FP26 26 +#define R_FP27 27 +#define R_FP28 28 +#define R_FP29 29 +#define R_FP30 30 +#define R_FP31 31 + #endif /* end of include file */ diff --git a/cpukit/score/cpu/mips/cpu.c b/cpukit/score/cpu/mips/cpu.c index db9ae911b4..22d66c95c0 100644 --- a/cpukit/score/cpu/mips/cpu.c +++ b/cpukit/score/cpu/mips/cpu.c @@ -66,8 +66,7 @@ void _CPU_Initialize( { unsigned int i = ISR_NUMBER_OF_VECTORS; - while ( i-- ) - { + while ( i-- ) { _ISR_Vector_table[i] = (ISR_Handler_entry)null_handler; } @@ -100,15 +99,25 @@ void _CPU_Initialize( /*PAGE * * _CPU_ISR_Get_level + * + * This routine returns the current interrupt level. */ - -#if 0 /* located in cpu_asm.S */ + +#if __mips == 3 + +/* in cpu_asm.S for now */ + +#elif __mips == 1 unsigned32 _CPU_ISR_Get_level( void ) { - /* - * This routine returns the current interrupt level. - */ + unsigned int sr; + + mips_get_sr(sr); + + return ((sr & SR_IEC) ? 0 : 1); } +#else +#error "CPU ISR level: unknown MIPS level for SR handling" #endif /*PAGE @@ -200,14 +209,18 @@ void _CPU_Install_interrupt_stack( void ) * hook with caution. */ -#if 0 /* located in cpu_asm.S */ void _CPU_Thread_Idle_body( void ) { - - for( ; ; ) - /* insert your "halt" instruction here */ ; -} +#if __mips == 3 + for( ; ; ) + asm volatile("wait"); /* use wait to enter low power mode */ +#elif __mips == 1 + for( ; ; ) + ; +#else +#error "IDLE: __mips not set to 1 or 3" #endif +} extern void mips_break( int error ); diff --git a/cpukit/score/cpu/mips/cpu_asm.S b/cpukit/score/cpu/mips/cpu_asm.S index b074369f17..b3cfd464f8 100644 --- a/cpukit/score/cpu/mips/cpu_asm.S +++ b/cpukit/score/cpu/mips/cpu_asm.S @@ -1,27 +1,29 @@ -/* cpu_asm.S - * +/* * This file contains the basic algorithms for all assembly code used * in an specific CPU port of RTEMS. These algorithms must be implemented * in assembly language * - * Author: Craig Lebakken - * - * COPYRIGHT (c) 1996 by Transition Networks Inc. - * - * To anyone who acknowledges that this file is provided "AS IS" - * without any express or implied warranty: - * permission to use, copy, modify, and distribute this file - * for any purpose is hereby granted without fee, provided that - * the above copyright notice and this notice appears in all - * copies, and that the name of Transition Networks not be used in - * advertising or publicity pertaining to distribution of the - * software without specific, written prior permission. - * Transition Networks makes no representations about the suitability - * of this software for any purpose. - * - * Derived from c/src/exec/score/cpu/no_cpu/cpu_asm.s: - * - * COPYRIGHT (c) 1989-1999. + * History: + * Baseline: no_cpu + * 1996: Ported to MIPS64ORION by Craig Lebakken + * COPYRIGHT (c) 1996 by Transition Networks Inc. + * To anyone who acknowledges that the modifications to this file to + * port it to the MIPS64ORION are provided "AS IS" without any + * express or implied warranty: + * permission to use, copy, modify, and distribute this file + * for any purpose is hereby granted without fee, provided that + * the above copyright notice and this notice appears in all + * copies, and that the name of Transition Networks not be used in + * advertising or publicity pertaining to distribution of the + * software without specific, written prior permission. Transition + * Networks makes no representations about the suitability + * of this software for any purpose. + * 2000: Reworked by Alan Cudmore to become + * the more general MIPS port. Joel Sherrill + * continued this rework, rewriting as much as possible in + * C and testing on the TX39. + * + * COPYRIGHT (c) 1989-2000. * On-Line Applications Research Corporation (OAR). * * The license and distribution terms for this file may be @@ -30,21 +32,11 @@ * * $Id$ */ -/* @(#)cpu_asm.S 08/20/96 1.15 */ - -#include "cpu_asm.h" +#include #include "iregdef.h" #include "idtcpu.h" -#define FRAME(name,frm_reg,offset,ret_reg) \ - .globl name; \ - .ent name; \ -name:; \ - .frame frm_reg,offset,ret_reg -#define ENDFRAME(name) \ - .end name - #define EXCP_STACK_SIZE (NREGS*R_SZ) #define ISR_VEC_SIZE 4 @@ -123,17 +115,12 @@ name:; \ /*PAGE * * _CPU_ISR_Get_level + * + * unsigned32 _CPU_ISR_Get_level( void ) + * + * This routine returns the current interrupt level. */ -#if 0 -unsigned32 _CPU_ISR_Get_level( void ) -{ - /* - * This routine returns the current interrupt level. - */ -} -#endif - #if __mips == 3 /* return the current exception level for the 4650 */ FRAME(_CPU_ISR_Get_level,sp,0,ra) @@ -188,24 +175,8 @@ ENDFRAME(_CPU_ISR_Set_level) #elif __mips == 1 /* MIPS ISA 1 ( R3000 ) */ -/* These routines might not be needed for the R3000 */ -/* Q:Who calls _CPU_ISR_Get/Set_level? */ -FRAME(_CPU_ISR_Get_level,sp,0,ra) - mfc0 v0,C0_SR - nop - andi v0, SR_IEC - j ra -ENDFRAME(_CPU_ISR_Get_level) - -FRAME(_CPU_ISR_Set_level,sp,0,ra) - nop - mfc0 t0,C0_SR - andi a0, SR_IEC - or t0, a0 - mtc0 t0,C0_SR - nop - j ra -ENDFRAME(_CPU_ISR_Set_level) +/* _CPU_ISR_Get/Set_level are called as part of task mode manipulation. */ +/* and are defined in C for the __mips == 1 */ #else #error "__mips is set to 1 or 3" @@ -225,10 +196,8 @@ ENDFRAME(_CPU_ISR_Set_level) */ /* void _CPU_Context_save_fp( - * void **fp_context_ptr - * ) - * { - * } + * void **fp_context_ptr + * ); */ FRAME(_CPU_Context_save_fp,sp,0,ra) @@ -285,10 +254,8 @@ ENDFRAME(_CPU_Context_save_fp) */ /* void _CPU_Context_restore_fp( - * void **fp_context_ptr + * void **fp_context_ptr * ) - * { - * } */ FRAME(_CPU_Context_restore_fp,sp,0,ra) @@ -337,11 +304,9 @@ ENDFRAME(_CPU_Context_restore_fp) */ /* void _CPU_Context_switch( - * Context_Control *run, - * Context_Control *heir + * Context_Control *run, + * Context_Control *heir * ) - * { - * } */ #if __mips == 3 /* MIPS ISA Level 3 ( R4xxx ) */ @@ -402,7 +367,7 @@ ENDFRAME(_CPU_Context_switch) FRAME(_CPU_Context_switch,sp,0,ra) mfc0 t0,C0_SR - li t1,~SR_IEC + li t1,~SR_IEC sw t0,C0_SR_OFFSET*4(a0) /* save status register */ and t0,t1 mtc0 t0,C0_SR /* first disable ie bit (recommended) */ @@ -436,10 +401,14 @@ _CPU_Context_switch_restore: lw ra,RA_OFFSET*4(a1) lw t0,C0_EPC_OFFSET*4(a1) mtc0 t0,C0_EPC - lw t1, C0_SR_OFFSET*4(a1) - mtc0 t1,C0_SR - - /* Q:Changes needed to SR_IEC bit in SR/_CPU_Context_switch_restore? */ + lw t0, C0_SR_OFFSET*4(a1) + andi t0,SR_IEC /* we know IEC=0, e.g. disabled */ + beq t0,$0,_CPU_Context_1 /* set IEC level from restore context */ + mfc0 t0,C0_SR + nop + or t0,SR_IEC /* new_sr = sr | SR_IEC */ + mtc0 t0,C0_SR /* set with enabled */ + _CPU_Context_1: j ra @@ -459,16 +428,12 @@ ENDFRAME(_CPU_Context_switch) * efficient manner. It may simply be a label in _CPU_Context_switch. * * NOTE: May be unnecessary to reload some registers. + * + * void _CPU_Context_restore( + * Context_Control *new_context + * ); */ -#if 0 -void _CPU_Context_restore( - Context_Control *new_context -) -{ -} -#endif - #if __mips == 3 FRAME(_CPU_Context_restore,sp,0,ra) @@ -502,36 +467,30 @@ EXTERN(_ISR_Signals_to_thread_executing,SZ_INT) * * This routine provides the RTEMS interrupt management. * + * void _ISR_Handler() + * + * + * This discussion ignores a lot of the ugly details in a real + * implementation such as saving enough registers/state to be + * able to do something real. Keep in mind that the goal is + * to invoke a user's ISR handler which is written in C and + * uses a certain set of registers. + * + * Also note that the exact order is to a large extent flexible. + * Hardware will dictate a sequence for a certain subset of + * _ISR_Handler while requirements for setting + * + * At entry to "common" _ISR_Handler, the vector number must be + * available. On some CPUs the hardware puts either the vector + * number or the offset into the vector table for this ISR in a + * known place. If the hardware does not give us this information, + * then the assembly portion of RTEMS for this port will contain + * a set of distinct interrupt entry points which somehow place + * the vector number in a known place (which is safe if another + * interrupt nests this one) and branches to _ISR_Handler. + * */ -#if 0 -void _ISR_Handler() -{ - /* - * This discussion ignores a lot of the ugly details in a real - * implementation such as saving enough registers/state to be - * able to do something real. Keep in mind that the goal is - * to invoke a user's ISR handler which is written in C and - * uses a certain set of registers. - * - * Also note that the exact order is to a large extent flexible. - * Hardware will dictate a sequence for a certain subset of - * _ISR_Handler while requirements for setting - */ - - /* - * At entry to "common" _ISR_Handler, the vector number must be - * available. On some CPUs the hardware puts either the vector - * number or the offset into the vector table for this ISR in a - * known place. If the hardware does not give us this information, - * then the assembly portion of RTEMS for this port will contain - * a set of distinct interrupt entry points which somehow place - * the vector number in a known place (which is safe if another - * interrupt nests this one) and branches to _ISR_Handler. - * - */ -#endif - #if __mips == 3 /* ----------------------------------------------------------------------------- */ FRAME(_ISR_Handler,sp,0,ra) @@ -583,12 +542,13 @@ FRAME(_ISR_Handler,sp,0,ra) /* determine if an interrupt generated this exception */ mfc0 k0,C0_CAUSE and k1,k0,CAUSE_EXCMASK - bnez k1,_ISR_Handler_prom_exit /* not an external interrup -t, pass exception to Monitor */ + bnez k1,_ISR_Handler_prom_exit /* not an external interrupt, + pass exception to Monitor */ mfc0 k1,C0_SR and k0,k1 and k0,CAUSE_IPMASK - beq k0,zero,_ISR_Handler_quick_exit /* external interrupt not enabled, ignore */ + beq k0,zero,_ISR_Handler_quick_exit /* external interrupt not + enabled, ignore */ nop /* @@ -1035,81 +995,6 @@ ENDFRAME(_ISR_Handler) #endif -FRAME(mips_enable_interrupts,sp,0,ra) - mfc0 t0,C0_SR /* get status reg */ - nop - or t0,t0,a0 - mtc0 t0,C0_SR /* save updated status reg */ - j ra - nop -ENDFRAME(mips_enable_interrupts) - -FRAME(mips_disable_interrupts,sp,0,ra) - mfc0 v0,C0_SR /* get status reg */ - li t1,SR_IMASK /* t1 = load interrupt mask word */ - not t0,t1 /* t0 = ~t1 */ - and t0,v0 /* clear imask bits */ - mtc0 t0,C0_SR /* save status reg */ - and v0,t1 /* mask return value (only return imask bits) */ - jr ra - nop -ENDFRAME(mips_disable_interrupts) - -#if __mips == 3 - -FRAME(mips_enable_global_interrupts,sp,0,ra) - mfc0 t0,C0_SR /* get status reg */ - nop - ori t0,SR_IE - mtc0 t0,C0_SR /* save updated status reg */ - j ra - nop -ENDFRAME(mips_enable_global_interrupts) - -FRAME(mips_disable_global_interrupts,sp,0,ra) - li t1,SR_IE - mfc0 t0,C0_SR /* get status reg */ - not t1 - and t0,t1 - mtc0 t0,C0_SR /* save updated status reg */ - j ra - nop -ENDFRAME(mips_disable_global_interrupts) - -#elif __mips == 1 - -FRAME(mips_enable_global_interrupts,sp,0,ra) - mfc0 t0,C0_SR /* get status reg */ - nop - ori t0,SR_IEC - mtc0 t0,C0_SR /* save updated status reg */ - j ra - nop -ENDFRAME(mips_enable_global_interrupts) - -FRAME(mips_disable_global_interrupts,sp,0,ra) - li t1,SR_IEC - mfc0 t0,C0_SR /* get status reg */ - not t1 - and t0,t1 - mtc0 t0,C0_SR /* save updated status reg */ - j ra - nop -ENDFRAME(mips_disable_global_interrupts) - -#else - - #error "__mips is not set to 1 or 3" - -#endif - -/* return the value of the status register in v0. Used for debugging */ -FRAME(mips_get_sr,sp,0,ra) - mfc0 v0,C0_SR - j ra - nop -ENDFRAME(mips_get_sr) - FRAME(mips_break,sp,0,ra) #if 1 break 0x0 @@ -1120,266 +1005,3 @@ FRAME(mips_break,sp,0,ra) nop ENDFRAME(mips_break) - -/************************************************************************** -** -** enable_int(mask) - enables interrupts - mask is positioned so it only -** needs to be or'ed into the status reg. This -** also does some other things !!!! caution should -** be used if invoking this while in the middle -** of a debugging session where the client may have -** nested interrupts. -** -****************************************************************************/ -FRAME(enable_int,sp,0,ra) - .set noreorder - mfc0 t0,C0_SR - or a0,1 - or t0,a0 - mtc0 t0,C0_SR - j ra - nop - .set reorder -ENDFRAME(enable_int) - - -/*************************************************************************** -** -** disable_int(mask) - disable the interrupt - mask is the complement -** of the bits to be cleared - i.e. to clear ext int -** 5 the mask would be - 0xffff7fff -** -****************************************************************************/ -FRAME(disable_int,sp,0,ra) - .set noreorder - mfc0 t0,C0_SR - nop - and t0,a0 - mtc0 t0,C0_SR - j ra - nop -ENDFRAME(disable_int) - - -/*PAGE - * - * _CPU_Internal_threads_Idle_thread_body - * - * NOTES: - * - * 1. This is the same as the regular CPU independent algorithm. - * - * 2. If you implement this using a "halt", "idle", or "shutdown" - * instruction, then don't forget to put it in an infinite loop. - * - * 3. Be warned. Some processors with onboard DMA have been known - * to stop the DMA if the CPU were put in IDLE mode. This might - * also be a problem with other on-chip peripherals. So use this - * hook with caution. - */ - -#if __mips == 3 - -FRAME(_CPU_Thread_Idle_body,sp,0,ra) - wait /* enter low power mode */ - j _CPU_Thread_Idle_body - nop -ENDFRAME(_CPU_Thread_Idle_body) - -#elif __mips == 1 - -FRAME(_CPU_Thread_Idle_body,sp,0,ra) - nop /* no wait instruction */ - j _CPU_Thread_Idle_body - nop -ENDFRAME(_CPU_Thread_Idle_body) - -#else - - #error "__mips not set to 1 or 3" - -#endif - -/************************************************************************** -** -** init_exc_vecs() - moves the exception code into the addresses -** reserved for exception vectors -** -** UTLB Miss exception vector at address 0x80000000 -** -** General exception vector at address 0x80000080 -** -** RESET exception vector is at address 0xbfc00000 -** -***************************************************************************/ - -#define VEC_CODE_LENGTH 10*4 - -FRAME(init_exc_vecs,sp,0,ra) - -#if __mips == 1 - - .set noreorder - la t1,exc_utlb_code - la t2,exc_norm_code - li t3,UT_VEC - li t4,E_VEC - li t5,VEC_CODE_LENGTH -1: - lw t6,0(t1) - lw t7,0(t2) - sw t6,0(t3) - sw t7,0(t4) - addiu t1,4 - addiu t3,4 - addiu t4,4 - subu t5,4 - bne t5,zero,1b - addiu t2,4 - move t5,ra # assumes clear_cache doesnt use t5 - li a0,UT_VEC - jal clear_cache /* Check out clear cache.... */ - li a1,VEC_CODE_LENGTH - nop - li a0,E_VEC - jal clear_cache - li a1,VEC_CODE_LENGTH - move ra,t5 # restore ra - j ra - nop - .set reorder - -#elif __mips == 3 - - .set reorder - move t5,ra # assumes clear_cache doesnt use t5 - - /* TLB exception vector */ - la t1,exc_tlb_code - li t2,T_VEC |K1BASE - li t3,VEC_CODE_LENGTH -1: - lw t6,0(t1) - addiu t1,4 - subu t3,4 - sw t6,0(t2) - addiu t2,4 - bne t3,zero,1b - - li a0,T_VEC - li a1,VEC_CODE_LENGTH - jal clear_cache - - la t1,exc_xtlb_code - li t2,X_VEC |K1BASE - li t3,VEC_CODE_LENGTH -1: - lw t6,0(t1) - addiu t1,4 - subu t3,4 - sw t6,0(t2) - addiu t2,4 - bne t3,zero,1b - - /* extended TLB exception vector */ - li a0,X_VEC - li a1,VEC_CODE_LENGTH - jal clear_cache - - /* cache error exception vector */ - la t1,exc_cache_code - li t2,C_VEC |K1BASE - li t3,VEC_CODE_LENGTH -1: - lw t6,0(t1) - addiu t1,4 - subu t3,4 - sw t6,0(t2) - addiu t2,4 - bne t3,zero,1b - - li a0,C_VEC - li a1,VEC_CODE_LENGTH - jal clear_cache - - /* normal exception vector */ - la t1,exc_norm_code - li t2,E_VEC |K1BASE - li t3,VEC_CODE_LENGTH -1: - lw t6,0(t1) - addiu t1,4 - subu t3,4 - sw t6,0(t2) - addiu t2,4 - bne t3,zero,1b - - li a0,E_VEC - li a1,VEC_CODE_LENGTH - jal clear_cache - - move ra,t5 # restore ra - j ra - -#else - #error "__mips not set to 1 or 3" -#endif - -ENDFRAME(init_exc_vecs) - -FRAME(exc_utlb_code,sp,0,ra) - la k0, _ISR_Handler /* XXX not right -- but need to link*/ - j k0 - nop -ENDFRAME(exc_utlb_code) - -FRAME(exc_norm_code,sp,0,ra) - la k0, _ISR_Handler /* generic external int hndlr */ - j k0 - nop -ENDFRAME(exc_norm_code) - -/* -** Again, reliance on SIM. Not good. -*/ -#if __mips == 3 - -FRAME(exc_tlb_code,sp,0,ra) - la k0, (R_VEC+((112)*8)) /* R4000 Sim location */ - j k0 - nop -ENDFRAME(exc_tlb_code) - -FRAME(exc_xtlb_code,sp,0,ra) - la k0, (R_VEC+((112)*8)) /* R4000 Sim location */ - j k0 - nop - -ENDFRAME(exc_xtlb_code) - -FRAME(exc_cache_code,sp,0,ra) - la k0, (R_VEC+((112)*8)) /* R4000 Sim location */ - j k0 - nop -ENDFRAME(exc_cache_code) - -#elif __mips == 1 -/* ------------------------------------------------------ */ -FRAME(exc_tlb_code,sp,0,ra) - la k0, (R_VEC+((48)*8)) /* Need something else here besides IDT/SIM call */ - j k0 - nop -ENDFRAME(exc_tlb_code) - -FRAME(exc_cache_code,sp,0,ra) - la k0, (R_VEC+((48)*8)) - j k0 - nop -ENDFRAME(exc_cache_code) - -#else - - #error "__mips is not set to 1 or 3" - -#endif - diff --git a/cpukit/score/cpu/mips/idtcpu.h b/cpukit/score/cpu/mips/idtcpu.h index cfb2fe626a..02153b184f 100644 --- a/cpukit/score/cpu/mips/idtcpu.h +++ b/cpukit/score/cpu/mips/idtcpu.h @@ -59,12 +59,13 @@ LICENSED MATERIAL - PROGRAM PROPERTY OF IDT #if __mips == 1 #define UT_VEC K0BASE /* utlbmiss vector */ #define E_VEC (K0BASE+0x80) /* exception vevtor */ -#endif -#if __mips == 3 +#elif __mips == 3 #define T_VEC (K0BASE+0x000) /* tlbmiss vector */ #define X_VEC (K0BASE+0x080) /* xtlbmiss vector */ #define C_VEC (K0BASE+0x100) /* cache error vector */ #define E_VEC (K0BASE+0x180) /* exception vector */ +#else +#error "EXCEPTION VECTORS: unknown ISA level" #endif #define R_VEC (K1BASE+0x1fc00000) /* reset vector */ diff --git a/cpukit/score/cpu/mips/iregdef.h b/cpukit/score/cpu/mips/iregdef.h index ca50207a3b..8463e74245 100644 --- a/cpukit/score/cpu/mips/iregdef.h +++ b/cpukit/score/cpu/mips/iregdef.h @@ -296,7 +296,7 @@ LICENSED MATERIAL - PROGRAM PROPERTY OF IDT #define R_RA R_R31 /* Ketan added the following */ -#ifdef __mips == 1 +#if __mips == 1 #define sreg sw #define lreg lw #define rmfc0 mfc0 diff --git a/cpukit/score/cpu/mips/rtems/asm.h b/cpukit/score/cpu/mips/rtems/asm.h index 060be295bf..671821afb9 100644 --- a/cpukit/score/cpu/mips/rtems/asm.h +++ b/cpukit/score/cpu/mips/rtems/asm.h @@ -35,7 +35,7 @@ #define ASM #endif #include -#include +#include /* * Recent versions of GNU cpp define variables which indicate the @@ -117,6 +117,43 @@ _##name: #define ENDFRAME(name) #endif XDS +/* + * Hardware Floating Point Registers + */ + +#define R_FP0 0 +#define R_FP1 1 +#define R_FP2 2 +#define R_FP3 3 +#define R_FP4 4 +#define R_FP5 5 +#define R_FP6 6 +#define R_FP7 7 +#define R_FP8 8 +#define R_FP9 9 +#define R_FP10 10 +#define R_FP11 11 +#define R_FP12 12 +#define R_FP13 13 +#define R_FP14 14 +#define R_FP15 15 +#define R_FP16 16 +#define R_FP17 17 +#define R_FP18 18 +#define R_FP19 19 +#define R_FP20 20 +#define R_FP21 21 +#define R_FP22 22 +#define R_FP23 23 +#define R_FP24 24 +#define R_FP25 25 +#define R_FP26 26 +#define R_FP27 27 +#define R_FP28 28 +#define R_FP29 29 +#define R_FP30 30 +#define R_FP31 31 + #endif /* end of include file */ diff --git a/cpukit/score/cpu/mips/rtems/mips/idtcpu.h b/cpukit/score/cpu/mips/rtems/mips/idtcpu.h index cfb2fe626a..02153b184f 100644 --- a/cpukit/score/cpu/mips/rtems/mips/idtcpu.h +++ b/cpukit/score/cpu/mips/rtems/mips/idtcpu.h @@ -59,12 +59,13 @@ LICENSED MATERIAL - PROGRAM PROPERTY OF IDT #if __mips == 1 #define UT_VEC K0BASE /* utlbmiss vector */ #define E_VEC (K0BASE+0x80) /* exception vevtor */ -#endif -#if __mips == 3 +#elif __mips == 3 #define T_VEC (K0BASE+0x000) /* tlbmiss vector */ #define X_VEC (K0BASE+0x080) /* xtlbmiss vector */ #define C_VEC (K0BASE+0x100) /* cache error vector */ #define E_VEC (K0BASE+0x180) /* exception vector */ +#else +#error "EXCEPTION VECTORS: unknown ISA level" #endif #define R_VEC (K1BASE+0x1fc00000) /* reset vector */ diff --git a/cpukit/score/cpu/mips/rtems/mips/iregdef.h b/cpukit/score/cpu/mips/rtems/mips/iregdef.h index ca50207a3b..8463e74245 100644 --- a/cpukit/score/cpu/mips/rtems/mips/iregdef.h +++ b/cpukit/score/cpu/mips/rtems/mips/iregdef.h @@ -296,7 +296,7 @@ LICENSED MATERIAL - PROGRAM PROPERTY OF IDT #define R_RA R_R31 /* Ketan added the following */ -#ifdef __mips == 1 +#if __mips == 1 #define sreg sw #define lreg lw #define rmfc0 mfc0 diff --git a/cpukit/score/cpu/mips/rtems/score/cpu.h b/cpukit/score/cpu/mips/rtems/score/cpu.h index a12c4369c4..5d5a9a2754 100644 --- a/cpukit/score/cpu/mips/rtems/score/cpu.h +++ b/cpukit/score/cpu/mips/rtems/score/cpu.h @@ -38,17 +38,12 @@ extern "C" { #endif -#include /* pick up machine definitions */ +#include /* pick up machine definitions */ #ifndef ASM +#include #include #endif -extern int mips_disable_interrupts( void ); -extern void mips_enable_interrupts( int _level ); -extern int mips_disable_global_interrupts( void ); -extern void mips_enable_global_interrupts( void ); -extern void mips_fatal_error ( int error ); - /* conditional compilation parameters */ /* @@ -530,6 +525,7 @@ SCORE_EXTERN void (*_CPU_Thread_dispatch_pointer)(); * by RTEMS. */ +extern unsigned int mips_interrupt_number_of_vectors; #define CPU_INTERRUPT_NUMBER_OF_VECTORS 8 #define CPU_INTERRUPT_MAXIMUM_VECTOR_NUMBER (CPU_INTERRUPT_NUMBER_OF_VECTORS - 1) @@ -593,10 +589,11 @@ SCORE_EXTERN void (*_CPU_Thread_dispatch_pointer)(); * level is returned in _level. */ -#define _CPU_ISR_Disable( _int_level ) \ - do{ \ - _int_level = mips_disable_interrupts(); \ - }while(0) +#define _CPU_ISR_Disable( _level ) \ + do { \ + mips_get_sr( _level ); \ + mips_set_sr( (_level) & ~SR_IEC ); \ + } while(0) /* * Enable interrupts to the previous level (returned by _CPU_ISR_Disable). @@ -605,9 +602,9 @@ SCORE_EXTERN void (*_CPU_Thread_dispatch_pointer)(); */ #define _CPU_ISR_Enable( _level ) \ - do{ \ - mips_enable_interrupts(_level); \ - }while(0) + do { \ + mips_set_sr(_level); \ + } while(0) /* * This temporarily restores the interrupt to _level before immediately @@ -617,11 +614,11 @@ SCORE_EXTERN void (*_CPU_Thread_dispatch_pointer)(); */ #define _CPU_ISR_Flash( _xlevel ) \ - do{ \ - int _scratch; \ - _CPU_ISR_Enable( _xlevel ); \ - _CPU_ISR_Disable( _scratch ); \ - }while(0) + do { \ + unsigned int _scratch; \ + _CPU_ISR_Enable( _xlevel ); \ + _CPU_ISR_Disable( _scratch ); \ + } while(0) /* * Map interrupt level in task mode onto the hardware that the CPU @@ -632,10 +629,30 @@ SCORE_EXTERN void (*_CPU_Thread_dispatch_pointer)(); * 8 - 255 would be available for bsp/application specific meaning. * This could be used to manage a programmable interrupt controller * via the rtems_task_mode directive. + * + * On the MIPS, 0 is all on. Non-zero is all off. This only + * manipulates the IEC. */ + +#if __mips == 3 extern void _CPU_ISR_Set_level( unsigned32 _new_level ); -unsigned32 _CPU_ISR_Get_level( void ); +unsigned32 _CPU_ISR_Get_level( void ); /* in cpu_asm.S */ +#elif __mips == 1 + +#define _CPU_ISR_Set_level( _new_level ) \ + do { \ + unsigned int _sr; \ + mips_get_sr(_sr); \ + (_sr) &= ~SR_IEC; /* clear the IEC bit */ \ + if ( !(_new_level) ) (_sr) |= SR_IEC; /* enable interrupts */ \ + mips_set_sr(_sr); \ + } while (0) + +unsigned32 _CPU_ISR_Get_level( void ); /* in cpu.c */ +#else +#error "CPU ISR level: unknown MIPS level for SR handling" +#endif /* end of ISR handler macros */ @@ -670,7 +687,8 @@ unsigned32 _CPU_ISR_Get_level( void ); (_the_context)->sp = _stack_tmp; \ (_the_context)->fp = _stack_tmp; \ (_the_context)->ra = (unsigned64)_entry_point; \ - (_the_context)->c0_sr = 0; \ + if (_isr) (_the_context)->c0_sr = 0xff00; \ + else (_the_context)->c0_sr = 0xff01; \ } /* @@ -730,11 +748,14 @@ unsigned32 _CPU_ISR_Get_level( void ); * halts/stops the CPU. */ +void mips_fatal_error ( int error ); + #define _CPU_Fatal_halt( _error ) \ - { \ - mips_disable_global_interrupts(); \ + do { \ + unsigned int _level; \ + _CPU_ISR_Disable(_level); \ mips_fatal_error(_error); \ - } + } while (0) /* end of Fatal Error manager macros */ @@ -980,15 +1001,6 @@ static inline unsigned int CPU_swap_u32( #define CPU_swap_u16( value ) \ (((value&0xff) << 8) | ((value >> 8)&0xff)) -/* - * Miscellaneous prototypes - * - * NOTE: The names should have mips64orion in them. - */ - -void disable_int( unsigned32 mask ); -void enable_int( unsigned32 mask ); - #ifdef __cplusplus } #endif diff --git a/cpukit/score/cpu/mips/rtems/score/mips.h b/cpukit/score/cpu/mips/rtems/score/mips.h index 90e959bd47..1f2740c49d 100644 --- a/cpukit/score/cpu/mips/rtems/score/mips.h +++ b/cpukit/score/cpu/mips/rtems/score/mips.h @@ -1,23 +1,6 @@ -/* mips64orion.h +/* mips.h * - * Author: Craig Lebakken - * - * COPYRIGHT (c) 1996 by Transition Networks Inc. - * - * To anyone who acknowledges that this file is provided "AS IS" - * without any express or implied warranty: - * permission to use, copy, modify, and distribute this file - * for any purpose is hereby granted without fee, provided that - * the above copyright notice and this notice appears in all - * copies, and that the name of Transition Networks not be used in - * advertising or publicity pertaining to distribution of the - * software without specific, written prior permission. - * Transition Networks makes no representations about the suitability - * of this software for any purpose. - * - * Derived from c/src/exec/score/cpu/no_cpu/no_cpu.h: - * - * COPYRIGHT (c) 1989-1999. + * COPYRIGHT (c) 1989-2000. * On-Line Applications Research Corporation (OAR). * * The license and distribution terms for this file may be @@ -68,6 +51,56 @@ extern "C" { #define CPU_NAME "MIPS" +/* + * Some macros to access registers + */ + +#define mips_get_sr( _x ) \ + do { \ + asm volatile( "mfc0 %0, $12; nop" : "=g" (_x) : ); \ + } while (0) + +#define mips_set_sr( _x ) \ + do { \ + unsigned int __x = (_x); \ + asm volatile( "mtc0 %0, $12; nop" : : "r" (__x) ); \ + } while (0) + +/* + * Manipulate interrupt mask + * + * mips_unmask_interrupt( _mask) + * enables interrupts - mask is positioned so it only needs to be or'ed + * into the status reg. This also does some other things !!!! Caution + * should be used if invoking this while in the middle of a debugging + * session where the client may have nested interrupts. + * + * mips_mask_interrupt( _mask ) + * disable the interrupt - mask is the complement of the bits to be + * cleared - i.e. to clear ext int 5 the mask would be - 0xffff7fff + * + * + * NOTE: mips_mask_interrupt() used to be disable_int(). + * mips_unmask_interrupt() used to be enable_int(). + * + */ + +#define mips_enable_in_interrupt_mask( _mask ) \ + do { \ + unsigned int _sr; \ + mips_get_sr( _sr ); \ + _sr |= (_mask) | SR_IEC; \ + mips_set_sr( _sr ); \ + } while (0) + +#define mips_disable_in_interrupt_mask( _mask ) \ + do { \ + unsigned int _sr; \ + mips_get_sr( _sr ); \ + _sr &= ~(_mask); \ + mips_set_sr( _sr ); \ + } while (0) + #ifdef __cplusplus } #endif -- cgit v1.2.3