summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJoel Sherrill <joel.sherrill@OARcorp.com>1999-07-09 17:08:48 +0000
committerJoel Sherrill <joel.sherrill@OARcorp.com>1999-07-09 17:08:48 +0000
commitb73e57bffe6cf60b1817bb2fc244a2f0c602bd5c (patch)
tree410140b91a7df0566d9f6db8acf7d1a3aa5317cf
parentcc17eba0cb72460db9da49bf8f3243967c4b69f8 (diff)
downloadrtems-b73e57bffe6cf60b1817bb2fc244a2f0c602bd5c.tar.bz2
Patch from Jiri Gaisler <jgais@ws.estec.esa.nl>:
+ interrupt masking correction + FPU rev.B workaround + minor erc32 related fixes
-rw-r--r--c/src/exec/score/cpu/sparc/asm.h1
-rw-r--r--c/src/exec/score/cpu/sparc/cpu_asm.S74
-rw-r--r--c/src/exec/score/cpu/sparc/erc32.h14
-rw-r--r--c/src/exec/score/cpu/sparc/rtems/score/cpu.h10
-rw-r--r--c/src/exec/score/cpu/sparc/rtems/score/sparc.h6
-rw-r--r--c/src/lib/libbsp/sparc/erc32/start/start.S44
-rw-r--r--c/src/lib/libbsp/sparc/erc32/startsis/startsis.S44
-rw-r--r--c/src/lib/libbsp/sparc/erc32/startup/bspclean.c3
-rw-r--r--c/src/lib/libbsp/sparc/erc32/startup/linkcmds34
-rw-r--r--c/src/lib/libbsp/sparc/erc32/startup/spurious.c7
-rw-r--r--c/src/lib/libbsp/sparc/erc32/wrapup/Makefile.in2
-rw-r--r--c/src/lib/libcpu/sparc/Makefile.in2
-rw-r--r--c/src/lib/libcpu/sparc/include/erc32.h14
-rw-r--r--cpukit/score/cpu/sparc/asm.h1
-rw-r--r--cpukit/score/cpu/sparc/cpu_asm.S74
-rw-r--r--cpukit/score/cpu/sparc/rtems/asm.h1
-rw-r--r--cpukit/score/cpu/sparc/rtems/score/cpu.h10
-rw-r--r--cpukit/score/cpu/sparc/rtems/score/sparc.h6
-rw-r--r--make/custom/erc32.cfg4
19 files changed, 285 insertions, 66 deletions
diff --git a/c/src/exec/score/cpu/sparc/asm.h b/c/src/exec/score/cpu/sparc/asm.h
index e76fc27182..cdb906af58 100644
--- a/c/src/exec/score/cpu/sparc/asm.h
+++ b/c/src/exec/score/cpu/sparc/asm.h
@@ -44,6 +44,7 @@
/* XXX __USER_LABEL_PREFIX__ and __REGISTER_PREFIX__ do not work on gcc 2.7.0 */
/* XXX The following ifdef magic fixes the problem but results in a warning */
/* XXX when compiling assembly code. */
+
#ifndef __USER_LABEL_PREFIX__
#define __USER_LABEL_PREFIX__ _
#endif
diff --git a/c/src/exec/score/cpu/sparc/cpu_asm.S b/c/src/exec/score/cpu/sparc/cpu_asm.S
index d980d4bff7..d96256694f 100644
--- a/c/src/exec/score/cpu/sparc/cpu_asm.S
+++ b/c/src/exec/score/cpu/sparc/cpu_asm.S
@@ -498,17 +498,85 @@ dont_switch_stacks:
* when the interrupt handler returns.
*/
+/* This is a fix for ERC32 with FPU rev.B or rev.C */
+
+#if defined(FPU_REVB)
+
+
mov %l0, %g5
- subcc %l3, 0x11, %g0
+ and %l3, 0x0ff, %g4
+ subcc %g4, 0x08, %g0
+ be fpu_revb
+ subcc %g4, 0x11, %g0
bl dont_fix_pil
- subcc %l3, 0x1f, %g0
+ subcc %g4, 0x1f, %g0
bg dont_fix_pil
- sll %l3, 8, %g4
+ sll %g4, 8, %g4
and %g4, SPARC_PSR_PIL_MASK, %g4
andn %l0, SPARC_PSR_PIL_MASK, %g5
or %g4, %g5, %g5
+ srl %l0, 12, %g4
+ andcc %g4, 1, %g0
+ be dont_fix_pil
+ nop
+ ba,a enable_irq
+
+
+fpu_revb:
+ srl %l0, 12, %g4 ! check if EF is set in %psr
+ andcc %g4, 1, %g0
+ be dont_fix_pil ! if FPU disabled than continue as normal
+ and %l3, 0xff, %g4
+ subcc %g4, 0x08, %g0
+ bne enable_irq ! if not a FPU exception then do two fmovs
+ set __sparc_fq, %g4
+ st %fsr, [%g4] ! if FQ is not empty and FQ[1] = fmovs
+ ld [%g4], %g4 ! than this is bug 3.14
+ srl %g4, 13, %g4
+ andcc %g4, 1, %g0
+ be dont_fix_pil
+ set __sparc_fq, %g4
+ std %fq, [%g4]
+ ld [%g4+4], %g4
+ set 0x81a00020, %g5
+ subcc %g4, %g5, %g0
+ bne,a dont_fix_pil2
+ wr %l0, SPARC_PSR_ET_MASK, %psr ! **** ENABLE TRAPS ****
+ ba,a simple_return
+
+enable_irq:
+ or %g5, SPARC_PSR_PIL_MASK, %g4
+ wr %g4, SPARC_PSR_ET_MASK, %psr ! **** ENABLE TRAPS ****
+ nop; nop; nop
+ fmovs %f0, %f0
+ ba dont_fix_pil
+ fmovs %f0, %f0
+
+ .data
+ .global __sparc_fq
+ .align 8
+__sparc_fq:
+ .word 0,0
+
+ .text
+/* end of ERC32 FPU rev.B/C fix */
+
+#else
+
+ mov %l0, %g5
+ subcc %g4, 0x11, %g0
+ bl dont_fix_pil
+ subcc %g4, 0x1f, %g0
+ bg dont_fix_pil
+ sll %g4, 8, %g4
+ and %g4, SPARC_PSR_PIL_MASK, %g4
+ andn %l0, SPARC_PSR_PIL_MASK, %g5
+ or %g4, %g5, %g5
+#endif
+
dont_fix_pil:
wr %g5, SPARC_PSR_ET_MASK, %psr ! **** ENABLE TRAPS ****
+dont_fix_pil2:
/*
* Vector to user's handler.
diff --git a/c/src/exec/score/cpu/sparc/erc32.h b/c/src/exec/score/cpu/sparc/erc32.h
index aa0eef05d9..bfcec909b7 100644
--- a/c/src/exec/score/cpu/sparc/erc32.h
+++ b/c/src/exec/score/cpu/sparc/erc32.h
@@ -345,7 +345,7 @@ extern ERC32_Register_Map ERC32_MEC;
do { \
unsigned32 _level; \
\
- sparc_disable_interrupts( _level ); \
+ _level = sparc_disable_interrupts(); \
ERC32_MEC.Test_Control = ERC32_MEC.Test_Control | 0x80000; \
ERC32_MEC.Interrupt_Force = (1 << (_source)); \
sparc_enable_interrupts( _level ); \
@@ -361,7 +361,7 @@ extern ERC32_Register_Map ERC32_MEC;
do { \
unsigned32 _level; \
\
- sparc_disable_interrupts( _level ); \
+ _level = sparc_disable_interrupts(); \
ERC32_MEC.Interrupt_Mask |= (1 << (_source)); \
sparc_enable_interrupts( _level ); \
} while (0)
@@ -370,7 +370,7 @@ extern ERC32_Register_Map ERC32_MEC;
do { \
unsigned32 _level; \
\
- sparc_disable_interrupts( _level ); \
+ _level = sparc_disable_interrupts(); \
ERC32_MEC.Interrupt_Mask &= ~(1 << (_source)); \
sparc_enable_interrupts( _level ); \
} while (0)
@@ -380,7 +380,7 @@ extern ERC32_Register_Map ERC32_MEC;
unsigned32 _level; \
unsigned32 _mask = 1 << (_source); \
\
- sparc_disable_interrupts( _level ); \
+ _level = sparc_disable_interrupts(); \
(_previous) = ERC32_MEC.Interrupt_Mask; \
ERC32_MEC.Interrupt_Mask = _previous | _mask; \
sparc_enable_interrupts( _level ); \
@@ -392,7 +392,7 @@ extern ERC32_Register_Map ERC32_MEC;
unsigned32 _level; \
unsigned32 _mask = 1 << (_source); \
\
- sparc_disable_interrupts( _level ); \
+ _level = sparc_disable_interrupts(); \
ERC32_MEC.Interrupt_Mask = \
(ERC32_MEC.Interrupt_Mask & ~_mask) | (_previous); \
sparc_enable_interrupts( _level ); \
@@ -464,7 +464,7 @@ extern unsigned32 _ERC32_MEC_Timer_Control_Mirror;
unsigned32 __value; \
\
__value = ((_value) & 0x0f); \
- sparc_disable_interrupts( _level ); \
+ _level = sparc_disable_interrupts(); \
_control = _ERC32_MEC_Timer_Control_Mirror; \
_control &= ERC32_MEC_TIMER_COUNTER_DEFINED_MASK << 8; \
_ERC32_MEC_Timer_Control_Mirror = _control | _value; \
@@ -493,7 +493,7 @@ extern unsigned32 _ERC32_MEC_Timer_Control_Mirror;
unsigned32 __value; \
\
__value = ((_value) & 0x0f) << 8; \
- sparc_disable_interrupts( _level ); \
+ _level = sparc_disable_interrupts(); \
_control = _ERC32_MEC_Timer_Control_Mirror; \
_control &= ERC32_MEC_TIMER_COUNTER_DEFINED_MASK; \
_ERC32_MEC_Timer_Control_Mirror = _control | __value; \
diff --git a/c/src/exec/score/cpu/sparc/rtems/score/cpu.h b/c/src/exec/score/cpu/sparc/rtems/score/cpu.h
index cf50f035d6..7a55ae5d0d 100644
--- a/c/src/exec/score/cpu/sparc/rtems/score/cpu.h
+++ b/c/src/exec/score/cpu/sparc/rtems/score/cpu.h
@@ -725,6 +725,9 @@ SCORE_EXTERN unsigned8 _CPU_Trap_Table_area[ 8192 ]
#ifndef ASM
+extern unsigned int sparc_disable_interrupts();
+extern void sparc_enable_interrupts();
+
/* ISR handler macros */
/*
@@ -733,7 +736,7 @@ SCORE_EXTERN unsigned8 _CPU_Trap_Table_area[ 8192 ]
*/
#define _CPU_ISR_Disable( _level ) \
- sparc_disable_interrupts( _level )
+ (_level) = sparc_disable_interrupts()
/*
* Enable interrupts to the previous level (returned by _CPU_ISR_Disable).
@@ -743,7 +746,6 @@ SCORE_EXTERN unsigned8 _CPU_Trap_Table_area[ 8192 ]
#define _CPU_ISR_Enable( _level ) \
sparc_enable_interrupts( _level )
-
/*
* This temporarily restores the interrupt to _level before immediately
* disabling them again. This is used to divide long critical
@@ -761,7 +763,7 @@ SCORE_EXTERN unsigned8 _CPU_Trap_Table_area[ 8192 ]
*/
#define _CPU_ISR_Set_level( _newlevel ) \
- sparc_set_interrupt_level( _newlevel )
+ sparc_enable_interrupts( _newlevel << 8)
unsigned32 _CPU_ISR_Get_level( void );
@@ -840,7 +842,7 @@ void _CPU_Context_Initialize(
do { \
unsigned32 level; \
\
- sparc_disable_interrupts( level ); \
+ level = sparc_disable_interrupts(); \
asm volatile ( "mov %0, %%g1 " : "=r" (level) : "0" (level) ); \
while (1); /* loop forever */ \
} while (0)
diff --git a/c/src/exec/score/cpu/sparc/rtems/score/sparc.h b/c/src/exec/score/cpu/sparc/rtems/score/sparc.h
index 283548728a..a8f2122c44 100644
--- a/c/src/exec/score/cpu/sparc/rtems/score/sparc.h
+++ b/c/src/exec/score/cpu/sparc/rtems/score/sparc.h
@@ -196,6 +196,7 @@ extern "C" {
*
*/
+/*
#define sparc_disable_interrupts( _level ) \
do { \
register unsigned int _newlevel; \
@@ -204,7 +205,7 @@ extern "C" {
(_newlevel) = (_level) | SPARC_PSR_PIL_MASK; \
sparc_set_psr( _newlevel ); \
} while ( 0 )
-
+
#define sparc_enable_interrupts( _level ) \
do { \
unsigned int _tmp; \
@@ -214,6 +215,7 @@ extern "C" {
_tmp |= (_level) & SPARC_PSR_PIL_MASK; \
sparc_set_psr( _tmp ); \
} while ( 0 )
+*/
#define sparc_flash_interrupts( _level ) \
do { \
@@ -223,6 +225,7 @@ extern "C" {
sparc_disable_interrupts( _ignored ); \
} while ( 0 )
+/*
#define sparc_set_interrupt_level( _new_level ) \
do { \
register unsigned32 _new_psr_level = 0; \
@@ -233,6 +236,7 @@ extern "C" {
(((_new_level) << SPARC_PSR_PIL_BIT_POSITION) & SPARC_PSR_PIL_MASK); \
sparc_set_psr( _new_psr_level ); \
} while ( 0 )
+*/
#define sparc_get_interrupt_level( _level ) \
do { \
diff --git a/c/src/lib/libbsp/sparc/erc32/start/start.S b/c/src/lib/libbsp/sparc/erc32/start/start.S
index f9d4a8f293..4ccdbf0ac8 100644
--- a/c/src/lib/libbsp/sparc/erc32/start/start.S
+++ b/c/src/lib/libbsp/sparc/erc32/start/start.S
@@ -150,7 +150,8 @@ SYM(CLOCK_SPEED):
* installed before.
*/
- SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! 80 - 82
+ TRAP( 0x80, SYM(syscall) ); ! 80 syscall SW trap
+ SOFT_TRAP; SOFT_TRAP; ! 81 - 82
TRAP( 0x83, SYM(window_flush_trap_handler) ); ! 83 flush windows SW trap
SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! 84 - 87
@@ -212,20 +213,44 @@ SYM(hard_reset):
ld [%g3], %g2
set 0xfe080000, %g1
andcc %g1, %g2, %g0
- bne 1f
- set 0x00101000, %g1 ! 2M ROM, 4M RAM
- ! set the Memory Configuration
- st %g1, [ %g3 + ERC32_MEC_MEMORY_CONFIGURATION_OFFSET ]
-
- set SYM(RAM_END), %sp ! End of work-space area
- st %sp, [%g6]
+ bne 2f
+
+ /* Set the correct memory size in MEC memory config register */
+
+ set SYM(PROM_SIZE), %l0
+ set 0, %l1
+ srl %l0, 18, %l0
+1:
+ tst %l0
+ srl %l0, 1, %l0
+ bne,a 1b
+ inc %l1
+ sll %l1, 8, %l1
+
+ set SYM(RAM_SIZE), %l0
+ srl %l0, 19, %l0
+1:
+ tst %l0
+ srl %l0, 1, %l0
+ bne,a 1b
+ inc %l1
+ sll %l1, 10, %l1
+
+ ! set the Memory Configuration
+ st %l1, [ %g3 + ERC32_MEC_MEMORY_CONFIGURATION_OFFSET ]
+
+ set SYM(RAM_START), %l1 ! Cannot use RAM_END due to bug in linker
+ set SYM(RAM_SIZE), %l2
+ add %l1, %l2, %sp
+ st %sp, [%g6]
+
set SYM(CLOCK_SPEED), %g6 ! Use 14 MHz in simulator
set 14, %g1
st %g1, [%g6]
/* Common initialisation */
-1:
+2:
set WIM_INIT, %g1 ! Initialize WIM
mov %g1, %wim
@@ -298,6 +323,7 @@ zerobss:
PUBLIC(BSP_fatal_return)
SYM(BSP_fatal_return):
+ mov 1, %g1
ta 0 ! Halt if _main returns ...
nop
diff --git a/c/src/lib/libbsp/sparc/erc32/startsis/startsis.S b/c/src/lib/libbsp/sparc/erc32/startsis/startsis.S
index f9d4a8f293..4ccdbf0ac8 100644
--- a/c/src/lib/libbsp/sparc/erc32/startsis/startsis.S
+++ b/c/src/lib/libbsp/sparc/erc32/startsis/startsis.S
@@ -150,7 +150,8 @@ SYM(CLOCK_SPEED):
* installed before.
*/
- SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! 80 - 82
+ TRAP( 0x80, SYM(syscall) ); ! 80 syscall SW trap
+ SOFT_TRAP; SOFT_TRAP; ! 81 - 82
TRAP( 0x83, SYM(window_flush_trap_handler) ); ! 83 flush windows SW trap
SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! 84 - 87
@@ -212,20 +213,44 @@ SYM(hard_reset):
ld [%g3], %g2
set 0xfe080000, %g1
andcc %g1, %g2, %g0
- bne 1f
- set 0x00101000, %g1 ! 2M ROM, 4M RAM
- ! set the Memory Configuration
- st %g1, [ %g3 + ERC32_MEC_MEMORY_CONFIGURATION_OFFSET ]
-
- set SYM(RAM_END), %sp ! End of work-space area
- st %sp, [%g6]
+ bne 2f
+
+ /* Set the correct memory size in MEC memory config register */
+
+ set SYM(PROM_SIZE), %l0
+ set 0, %l1
+ srl %l0, 18, %l0
+1:
+ tst %l0
+ srl %l0, 1, %l0
+ bne,a 1b
+ inc %l1
+ sll %l1, 8, %l1
+
+ set SYM(RAM_SIZE), %l0
+ srl %l0, 19, %l0
+1:
+ tst %l0
+ srl %l0, 1, %l0
+ bne,a 1b
+ inc %l1
+ sll %l1, 10, %l1
+
+ ! set the Memory Configuration
+ st %l1, [ %g3 + ERC32_MEC_MEMORY_CONFIGURATION_OFFSET ]
+
+ set SYM(RAM_START), %l1 ! Cannot use RAM_END due to bug in linker
+ set SYM(RAM_SIZE), %l2
+ add %l1, %l2, %sp
+ st %sp, [%g6]
+
set SYM(CLOCK_SPEED), %g6 ! Use 14 MHz in simulator
set 14, %g1
st %g1, [%g6]
/* Common initialisation */
-1:
+2:
set WIM_INIT, %g1 ! Initialize WIM
mov %g1, %wim
@@ -298,6 +323,7 @@ zerobss:
PUBLIC(BSP_fatal_return)
SYM(BSP_fatal_return):
+ mov 1, %g1
ta 0 ! Halt if _main returns ...
nop
diff --git a/c/src/lib/libbsp/sparc/erc32/startup/bspclean.c b/c/src/lib/libbsp/sparc/erc32/startup/bspclean.c
index be9a577fc2..a62b1c6be2 100644
--- a/c/src/lib/libbsp/sparc/erc32/startup/bspclean.c
+++ b/c/src/lib/libbsp/sparc/erc32/startup/bspclean.c
@@ -30,8 +30,9 @@ void bsp_cleanup( void )
{
/*
* "halt" by trapping to the simulator command line.
+ * set %g1 to 1 to detect clean exit.
*/
- asm volatile( "ta 0" );
+ asm volatile( "mov 1, %g1; ta 0" );
}
diff --git a/c/src/lib/libbsp/sparc/erc32/startup/linkcmds b/c/src/lib/libbsp/sparc/erc32/startup/linkcmds
index e1d021e8cf..facb735fa9 100644
--- a/c/src/lib/libbsp/sparc/erc32/startup/linkcmds
+++ b/c/src/lib/libbsp/sparc/erc32/startup/linkcmds
@@ -36,39 +36,49 @@ __DYNAMIC = 0;
*
* _CLOCK_SPEED in Mhz (used to program the counter/timers)
*
- * _PROM_SIZE size of PROM (permissible values are 4K, 8K, 16K
- * 32K, 64K, 128K, 256K, and 512K)
+ * _PROM_SIZE size of PROM (permissible values are 128K, 256K,
+ * 512K, 1M, 2M, 4M, 8M and 16M)
* _RAM_SIZE size of RAM (permissible values are 256K, 512K,
- * 1MB, 2Mb, 4Mb, 8Mb, 16Mb, and 32Mb)
+ * 1M, 2M, 4M, 8M, 16M, and 32M)
*
- * MAKE SURE THESE MATCH THE MEMORY DESCRIPTION SECTION!!!
*/
-/*
-_CLOCK_SPEED = 10;
-*/
+/* Default values, can be overridden */
-_PROM_SIZE = 512K;
-_RAM_SIZE = 2M;
+_PROM_SIZE = 2M;
+_RAM_SIZE = 4M;
_RAM_START = 0x02000000;
_RAM_END = _RAM_START + _RAM_SIZE;
-RAM_END = _RAM_END;
_PROM_START = 0x00000000;
_PROM_END = _PROM_START + _PROM_SIZE;
/*
+ * Alternate names without leading _.
+ */
+
+PROM_START = _PROM_START;
+PROM_SIZE = _PROM_SIZE;
+PROM_END = _PROM_END;
+
+RAM_START = _RAM_START;
+RAM_SIZE = _RAM_SIZE;
+RAM_END = _RAM_END;
+
+/*
* Base address of the on-CPU peripherals
*/
_ERC32_MEC = 0x01f80000;
ERC32_MEC = 0x01f80000;
+/* these are the maximum values */
+
MEMORY
{
- rom : ORIGIN = 0x00000000, LENGTH = 512K
- ram : ORIGIN = 0x02000000, LENGTH = 2M
+ rom : ORIGIN = 0x00000000, LENGTH = 16
+ ram : ORIGIN = 0x02000000, LENGTH = 32M
}
/*
diff --git a/c/src/lib/libbsp/sparc/erc32/startup/spurious.c b/c/src/lib/libbsp/sparc/erc32/startup/spurious.c
index 30b0a0120a..c22a5373e2 100644
--- a/c/src/lib/libbsp/sparc/erc32/startup/spurious.c
+++ b/c/src/lib/libbsp/sparc/erc32/startup/spurious.c
@@ -148,7 +148,7 @@ rtems_isr bsp_spurious_handler(
* What else can we do but stop ...
*/
- asm volatile( "ta 0x0" );
+ asm volatile( "mov 1, %g1; ta 0x0" );
}
/*
@@ -177,8 +177,9 @@ void bsp_spurious_initialize()
* paramaters to the program.
*/
- if (( trap == 5 || trap == 6 || trap == 0x83 ) ||
- (( trap >= 0x70 ) && ( trap <= 0x80 )))
+ if (( trap == 5 || trap == 6 ) ||
+ (( trap >= 0x11 ) && ( trap <= 0x1f )) ||
+ (( trap >= 0x70 ) && ( trap <= 0x83 )))
continue;
set_vector( bsp_spurious_handler, SPARC_SYNCHRONOUS_TRAP( trap ), 1 );
diff --git a/c/src/lib/libbsp/sparc/erc32/wrapup/Makefile.in b/c/src/lib/libbsp/sparc/erc32/wrapup/Makefile.in
index 9f7490f5ce..cfd8aafa5c 100644
--- a/c/src/lib/libbsp/sparc/erc32/wrapup/Makefile.in
+++ b/c/src/lib/libbsp/sparc/erc32/wrapup/Makefile.in
@@ -17,7 +17,7 @@ VPATH = @srcdir@
BSP_PIECES=startup console clock timer gnatsupp
# pieces to pick up out of libcpu/sparc
-CPU_PIECES=reg_win
+CPU_PIECES=reg_win syscall
GENERIC_PIECES=
# bummer; have to use $foreach since % pattern subst rules only replace 1x
diff --git a/c/src/lib/libcpu/sparc/Makefile.in b/c/src/lib/libcpu/sparc/Makefile.in
index 6bf00598c9..88370d5149 100644
--- a/c/src/lib/libcpu/sparc/Makefile.in
+++ b/c/src/lib/libcpu/sparc/Makefile.in
@@ -18,7 +18,7 @@ VPATH = @srcdir@
include $(RTEMS_ROOT)/make/custom/${RTEMS_BSP}.cfg
include $(RTEMS_ROOT)/make/directory.cfg
-SUB_DIRS=reg_win
+SUB_DIRS=reg_win syscall
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
cd $(top_builddir) \
diff --git a/c/src/lib/libcpu/sparc/include/erc32.h b/c/src/lib/libcpu/sparc/include/erc32.h
index aa0eef05d9..bfcec909b7 100644
--- a/c/src/lib/libcpu/sparc/include/erc32.h
+++ b/c/src/lib/libcpu/sparc/include/erc32.h
@@ -345,7 +345,7 @@ extern ERC32_Register_Map ERC32_MEC;
do { \
unsigned32 _level; \
\
- sparc_disable_interrupts( _level ); \
+ _level = sparc_disable_interrupts(); \
ERC32_MEC.Test_Control = ERC32_MEC.Test_Control | 0x80000; \
ERC32_MEC.Interrupt_Force = (1 << (_source)); \
sparc_enable_interrupts( _level ); \
@@ -361,7 +361,7 @@ extern ERC32_Register_Map ERC32_MEC;
do { \
unsigned32 _level; \
\
- sparc_disable_interrupts( _level ); \
+ _level = sparc_disable_interrupts(); \
ERC32_MEC.Interrupt_Mask |= (1 << (_source)); \
sparc_enable_interrupts( _level ); \
} while (0)
@@ -370,7 +370,7 @@ extern ERC32_Register_Map ERC32_MEC;
do { \
unsigned32 _level; \
\
- sparc_disable_interrupts( _level ); \
+ _level = sparc_disable_interrupts(); \
ERC32_MEC.Interrupt_Mask &= ~(1 << (_source)); \
sparc_enable_interrupts( _level ); \
} while (0)
@@ -380,7 +380,7 @@ extern ERC32_Register_Map ERC32_MEC;
unsigned32 _level; \
unsigned32 _mask = 1 << (_source); \
\
- sparc_disable_interrupts( _level ); \
+ _level = sparc_disable_interrupts(); \
(_previous) = ERC32_MEC.Interrupt_Mask; \
ERC32_MEC.Interrupt_Mask = _previous | _mask; \
sparc_enable_interrupts( _level ); \
@@ -392,7 +392,7 @@ extern ERC32_Register_Map ERC32_MEC;
unsigned32 _level; \
unsigned32 _mask = 1 << (_source); \
\
- sparc_disable_interrupts( _level ); \
+ _level = sparc_disable_interrupts(); \
ERC32_MEC.Interrupt_Mask = \
(ERC32_MEC.Interrupt_Mask & ~_mask) | (_previous); \
sparc_enable_interrupts( _level ); \
@@ -464,7 +464,7 @@ extern unsigned32 _ERC32_MEC_Timer_Control_Mirror;
unsigned32 __value; \
\
__value = ((_value) & 0x0f); \
- sparc_disable_interrupts( _level ); \
+ _level = sparc_disable_interrupts(); \
_control = _ERC32_MEC_Timer_Control_Mirror; \
_control &= ERC32_MEC_TIMER_COUNTER_DEFINED_MASK << 8; \
_ERC32_MEC_Timer_Control_Mirror = _control | _value; \
@@ -493,7 +493,7 @@ extern unsigned32 _ERC32_MEC_Timer_Control_Mirror;
unsigned32 __value; \
\
__value = ((_value) & 0x0f) << 8; \
- sparc_disable_interrupts( _level ); \
+ _level = sparc_disable_interrupts(); \
_control = _ERC32_MEC_Timer_Control_Mirror; \
_control &= ERC32_MEC_TIMER_COUNTER_DEFINED_MASK; \
_ERC32_MEC_Timer_Control_Mirror = _control | __value; \
diff --git a/cpukit/score/cpu/sparc/asm.h b/cpukit/score/cpu/sparc/asm.h
index e76fc27182..cdb906af58 100644
--- a/cpukit/score/cpu/sparc/asm.h
+++ b/cpukit/score/cpu/sparc/asm.h
@@ -44,6 +44,7 @@
/* XXX __USER_LABEL_PREFIX__ and __REGISTER_PREFIX__ do not work on gcc 2.7.0 */
/* XXX The following ifdef magic fixes the problem but results in a warning */
/* XXX when compiling assembly code. */
+
#ifndef __USER_LABEL_PREFIX__
#define __USER_LABEL_PREFIX__ _
#endif
diff --git a/cpukit/score/cpu/sparc/cpu_asm.S b/cpukit/score/cpu/sparc/cpu_asm.S
index d980d4bff7..d96256694f 100644
--- a/cpukit/score/cpu/sparc/cpu_asm.S
+++ b/cpukit/score/cpu/sparc/cpu_asm.S
@@ -498,17 +498,85 @@ dont_switch_stacks:
* when the interrupt handler returns.
*/
+/* This is a fix for ERC32 with FPU rev.B or rev.C */
+
+#if defined(FPU_REVB)
+
+
mov %l0, %g5
- subcc %l3, 0x11, %g0
+ and %l3, 0x0ff, %g4
+ subcc %g4, 0x08, %g0
+ be fpu_revb
+ subcc %g4, 0x11, %g0
bl dont_fix_pil
- subcc %l3, 0x1f, %g0
+ subcc %g4, 0x1f, %g0
bg dont_fix_pil
- sll %l3, 8, %g4
+ sll %g4, 8, %g4
and %g4, SPARC_PSR_PIL_MASK, %g4
andn %l0, SPARC_PSR_PIL_MASK, %g5
or %g4, %g5, %g5
+ srl %l0, 12, %g4
+ andcc %g4, 1, %g0
+ be dont_fix_pil
+ nop
+ ba,a enable_irq
+
+
+fpu_revb:
+ srl %l0, 12, %g4 ! check if EF is set in %psr
+ andcc %g4, 1, %g0
+ be dont_fix_pil ! if FPU disabled than continue as normal
+ and %l3, 0xff, %g4
+ subcc %g4, 0x08, %g0
+ bne enable_irq ! if not a FPU exception then do two fmovs
+ set __sparc_fq, %g4
+ st %fsr, [%g4] ! if FQ is not empty and FQ[1] = fmovs
+ ld [%g4], %g4 ! than this is bug 3.14
+ srl %g4, 13, %g4
+ andcc %g4, 1, %g0
+ be dont_fix_pil
+ set __sparc_fq, %g4
+ std %fq, [%g4]
+ ld [%g4+4], %g4
+ set 0x81a00020, %g5
+ subcc %g4, %g5, %g0
+ bne,a dont_fix_pil2
+ wr %l0, SPARC_PSR_ET_MASK, %psr ! **** ENABLE TRAPS ****
+ ba,a simple_return
+
+enable_irq:
+ or %g5, SPARC_PSR_PIL_MASK, %g4
+ wr %g4, SPARC_PSR_ET_MASK, %psr ! **** ENABLE TRAPS ****
+ nop; nop; nop
+ fmovs %f0, %f0
+ ba dont_fix_pil
+ fmovs %f0, %f0
+
+ .data
+ .global __sparc_fq
+ .align 8
+__sparc_fq:
+ .word 0,0
+
+ .text
+/* end of ERC32 FPU rev.B/C fix */
+
+#else
+
+ mov %l0, %g5
+ subcc %g4, 0x11, %g0
+ bl dont_fix_pil
+ subcc %g4, 0x1f, %g0
+ bg dont_fix_pil
+ sll %g4, 8, %g4
+ and %g4, SPARC_PSR_PIL_MASK, %g4
+ andn %l0, SPARC_PSR_PIL_MASK, %g5
+ or %g4, %g5, %g5
+#endif
+
dont_fix_pil:
wr %g5, SPARC_PSR_ET_MASK, %psr ! **** ENABLE TRAPS ****
+dont_fix_pil2:
/*
* Vector to user's handler.
diff --git a/cpukit/score/cpu/sparc/rtems/asm.h b/cpukit/score/cpu/sparc/rtems/asm.h
index e76fc27182..cdb906af58 100644
--- a/cpukit/score/cpu/sparc/rtems/asm.h
+++ b/cpukit/score/cpu/sparc/rtems/asm.h
@@ -44,6 +44,7 @@
/* XXX __USER_LABEL_PREFIX__ and __REGISTER_PREFIX__ do not work on gcc 2.7.0 */
/* XXX The following ifdef magic fixes the problem but results in a warning */
/* XXX when compiling assembly code. */
+
#ifndef __USER_LABEL_PREFIX__
#define __USER_LABEL_PREFIX__ _
#endif
diff --git a/cpukit/score/cpu/sparc/rtems/score/cpu.h b/cpukit/score/cpu/sparc/rtems/score/cpu.h
index cf50f035d6..7a55ae5d0d 100644
--- a/cpukit/score/cpu/sparc/rtems/score/cpu.h
+++ b/cpukit/score/cpu/sparc/rtems/score/cpu.h
@@ -725,6 +725,9 @@ SCORE_EXTERN unsigned8 _CPU_Trap_Table_area[ 8192 ]
#ifndef ASM
+extern unsigned int sparc_disable_interrupts();
+extern void sparc_enable_interrupts();
+
/* ISR handler macros */
/*
@@ -733,7 +736,7 @@ SCORE_EXTERN unsigned8 _CPU_Trap_Table_area[ 8192 ]
*/
#define _CPU_ISR_Disable( _level ) \
- sparc_disable_interrupts( _level )
+ (_level) = sparc_disable_interrupts()
/*
* Enable interrupts to the previous level (returned by _CPU_ISR_Disable).
@@ -743,7 +746,6 @@ SCORE_EXTERN unsigned8 _CPU_Trap_Table_area[ 8192 ]
#define _CPU_ISR_Enable( _level ) \
sparc_enable_interrupts( _level )
-
/*
* This temporarily restores the interrupt to _level before immediately
* disabling them again. This is used to divide long critical
@@ -761,7 +763,7 @@ SCORE_EXTERN unsigned8 _CPU_Trap_Table_area[ 8192 ]
*/
#define _CPU_ISR_Set_level( _newlevel ) \
- sparc_set_interrupt_level( _newlevel )
+ sparc_enable_interrupts( _newlevel << 8)
unsigned32 _CPU_ISR_Get_level( void );
@@ -840,7 +842,7 @@ void _CPU_Context_Initialize(
do { \
unsigned32 level; \
\
- sparc_disable_interrupts( level ); \
+ level = sparc_disable_interrupts(); \
asm volatile ( "mov %0, %%g1 " : "=r" (level) : "0" (level) ); \
while (1); /* loop forever */ \
} while (0)
diff --git a/cpukit/score/cpu/sparc/rtems/score/sparc.h b/cpukit/score/cpu/sparc/rtems/score/sparc.h
index 283548728a..a8f2122c44 100644
--- a/cpukit/score/cpu/sparc/rtems/score/sparc.h
+++ b/cpukit/score/cpu/sparc/rtems/score/sparc.h
@@ -196,6 +196,7 @@ extern "C" {
*
*/
+/*
#define sparc_disable_interrupts( _level ) \
do { \
register unsigned int _newlevel; \
@@ -204,7 +205,7 @@ extern "C" {
(_newlevel) = (_level) | SPARC_PSR_PIL_MASK; \
sparc_set_psr( _newlevel ); \
} while ( 0 )
-
+
#define sparc_enable_interrupts( _level ) \
do { \
unsigned int _tmp; \
@@ -214,6 +215,7 @@ extern "C" {
_tmp |= (_level) & SPARC_PSR_PIL_MASK; \
sparc_set_psr( _tmp ); \
} while ( 0 )
+*/
#define sparc_flash_interrupts( _level ) \
do { \
@@ -223,6 +225,7 @@ extern "C" {
sparc_disable_interrupts( _ignored ); \
} while ( 0 )
+/*
#define sparc_set_interrupt_level( _new_level ) \
do { \
register unsigned32 _new_psr_level = 0; \
@@ -233,6 +236,7 @@ extern "C" {
(((_new_level) << SPARC_PSR_PIL_BIT_POSITION) & SPARC_PSR_PIL_MASK); \
sparc_set_psr( _new_psr_level ); \
} while ( 0 )
+*/
#define sparc_get_interrupt_level( _level ) \
do { \
diff --git a/make/custom/erc32.cfg b/make/custom/erc32.cfg
index fbe3502848..efb1e2c261 100644
--- a/make/custom/erc32.cfg
+++ b/make/custom/erc32.cfg
@@ -60,6 +60,9 @@ START_BASE=startsis
# time spent in the idle task is minimized. This significantly reduces
# the wall time required to execute the RTEMS test suites.
#
+# FPU_REVB (erc32_bsp)
+# If defined, enables work-around for bug 3.14 in FPU rev.B or rev.C
+#
define make-target-options
@echo "/* #define NDEBUG 1 */ " >>$@
@@ -69,6 +72,7 @@ define make-target-options
@echo "#define CONSOLE_USE_INTERRUPTS 1" >>$@
@echo "#define CONSOLE_USE_POLLED ~CONSOLE_USE_INTERRUPTS" >>$@
@echo "/* #define SIMSPARC_FAST_IDLE 1 */" >>$@
+ @echo "#define FPU_REVB 1" >>$@
endef