forked from Imagelibrary/rtems
Patch from Jiri Gaisler <jgais@ws.estec.esa.nl>:
+ interrupt masking correction + FPU rev.B workaround + minor erc32 related fixes
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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; \
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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 { \
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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" );
|
||||
}
|
||||
|
||||
@@ -36,28 +36,36 @@ __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
|
||||
*/
|
||||
@@ -65,10 +73,12 @@ _PROM_END = _PROM_START + _PROM_SIZE;
|
||||
_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
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -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 );
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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) \
|
||||
|
||||
@@ -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; \
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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 { \
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user