2005-06-24 09:01:16 +04:00
/ *
* arch/ x t e n s a / k e r n e l / c o p r o c e s s o r . S
*
* Xtensa p r o c e s s o r c o n f i g u r a t i o n - s p e c i f i c t a b l e o f c o p r o c e s s o r a n d
* other c u s t o m r e g i s t e r l a y o u t i n f o r m a t i o n .
*
* This f i l e i s s u b j e c t t o t h e t e r m s a n d c o n d i t i o n s o f t h e G N U G e n e r a l P u b l i c
* License. S e e t h e f i l e " C O P Y I N G " i n t h e m a i n d i r e c t o r y o f t h i s a r c h i v e
* for m o r e d e t a i l s .
*
2008-02-13 00:17:07 +03:00
* Copyright ( C ) 2 0 0 3 - 2 0 0 7 T e n s i l i c a I n c .
2005-06-24 09:01:16 +04:00
* /
# include < l i n u x / l i n k a g e . h >
2008-02-13 00:17:07 +03:00
# include < a s m / a s m - o f f s e t s . h >
2005-06-24 09:01:16 +04:00
# include < a s m / p r o c e s s o r . h >
2008-02-13 00:17:07 +03:00
# include < a s m / c o p r o c e s s o r . h >
# include < a s m / t h r e a d _ i n f o . h >
# include < a s m / u a c c e s s . h >
# include < a s m / u n i s t d . h >
# include < a s m / p t r a c e . h >
# include < a s m / c u r r e n t . h >
# include < a s m / p g t a b l e . h >
# include < a s m / p a g e . h >
# include < a s m / s i g n a l . h >
# include < a s m / t l b f l u s h . h >
2005-06-24 09:01:16 +04:00
2008-02-13 00:17:07 +03:00
/ *
* Entry c o n d i t i o n :
*
* a0 : trashed, o r i g i n a l v a l u e s a v e d o n s t a c k ( P T _ A R E G 0 )
* a1 : a1
* a2 : new s t a c k p o i n t e r , o r i g i n a l i n D E P C
* a3 : dispatch t a b l e
* depc : a2 , o r i g i n a l v a l u e s a v e d o n s t a c k ( P T _ D E P C )
* excsave_1 : a3
*
* PT_ D E P C > = V A L I D _ D O U B L E _ E X C E P T I O N _ A D D R E S S : d o u b l e e x c e p t i o n , D E P C
* < VALID_DOUBLE_EXCEPTION_ADDRESS : regular e x c e p t i o n
* /
2005-06-24 09:01:16 +04:00
2008-02-13 00:17:07 +03:00
/* IO protection is currently unsupported. */
2005-06-24 09:01:16 +04:00
2008-02-13 00:17:07 +03:00
ENTRY( f a s t _ i o _ p r o t e c t )
2012-10-15 03:55:38 +04:00
wsr a0 , e x c s a v e 1
2008-02-13 00:17:07 +03:00
movi a0 , u n r e c o v e r a b l e _ e x c e p t i o n
callx0 a0
2005-06-24 09:01:16 +04:00
2008-02-13 00:17:07 +03:00
# if X T E N S A _ H A V E _ C O P R O C E S S O R S
2005-06-24 09:01:16 +04:00
2008-02-13 00:17:07 +03:00
/ *
* Macros f o r l a z y c o n t e x t s w i t c h .
* /
2005-06-24 09:01:16 +04:00
2008-02-13 00:17:07 +03:00
# define S A V E _ C P _ R E G S ( x ) \
.align 4 ; \
.Lsave_cp_regs_cp # # x : \
.if XTENSA_ H A V E _ C O P R O C E S S O R ( x ) ; \
xchal_ c p ## x # # _ s t o r e a 2 a4 a5 a6 a7 ; \
.endif ; \
jx a0
2005-06-24 09:01:16 +04:00
2008-02-13 00:17:07 +03:00
# define S A V E _ C P _ R E G S _ T A B ( x ) \
.if XTENSA_ H A V E _ C O P R O C E S S O R ( x ) ; \
.long .Lsave_cp_regs_cp # # x - . L s a v e _ c p _ r e g s _ j u m p _ t a b l e ; \
.else ; \
.long 0 ; \
.endif ; \
.long THREAD_ X T R E G S _ C P ## x
2005-06-24 09:01:16 +04:00
2008-02-13 00:17:07 +03:00
# define L O A D _ C P _ R E G S ( x ) \
.align 4 ; \
.Lload_cp_regs_cp # # x : \
.if XTENSA_ H A V E _ C O P R O C E S S O R ( x ) ; \
xchal_ c p ## x # # _ l o a d a 2 a4 a5 a6 a7 ; \
.endif ; \
jx a0
2005-06-24 09:01:16 +04:00
2008-02-13 00:17:07 +03:00
# define L O A D _ C P _ R E G S _ T A B ( x ) \
.if XTENSA_ H A V E _ C O P R O C E S S O R ( x ) ; \
.long .Lload_cp_regs_cp # # x - . L l o a d _ c p _ r e g s _ j u m p _ t a b l e ; \
.else ; \
.long 0 ; \
.endif ; \
.long THREAD_ X T R E G S _ C P ## x
2005-06-24 09:01:16 +04:00
2008-02-13 00:17:07 +03:00
SAVE_ C P _ R E G S ( 0 )
SAVE_ C P _ R E G S ( 1 )
SAVE_ C P _ R E G S ( 2 )
SAVE_ C P _ R E G S ( 3 )
SAVE_ C P _ R E G S ( 4 )
SAVE_ C P _ R E G S ( 5 )
SAVE_ C P _ R E G S ( 6 )
SAVE_ C P _ R E G S ( 7 )
2005-06-24 09:01:16 +04:00
2008-02-13 00:17:07 +03:00
LOAD_ C P _ R E G S ( 0 )
LOAD_ C P _ R E G S ( 1 )
LOAD_ C P _ R E G S ( 2 )
LOAD_ C P _ R E G S ( 3 )
LOAD_ C P _ R E G S ( 4 )
LOAD_ C P _ R E G S ( 5 )
LOAD_ C P _ R E G S ( 6 )
LOAD_ C P _ R E G S ( 7 )
2005-06-24 09:01:16 +04:00
2008-02-13 00:17:07 +03:00
.align 4
.Lsave_cp_regs_jump_table :
SAVE_ C P _ R E G S _ T A B ( 0 )
SAVE_ C P _ R E G S _ T A B ( 1 )
SAVE_ C P _ R E G S _ T A B ( 2 )
SAVE_ C P _ R E G S _ T A B ( 3 )
SAVE_ C P _ R E G S _ T A B ( 4 )
SAVE_ C P _ R E G S _ T A B ( 5 )
SAVE_ C P _ R E G S _ T A B ( 6 )
SAVE_ C P _ R E G S _ T A B ( 7 )
2005-06-24 09:01:16 +04:00
2008-02-13 00:17:07 +03:00
.Lload_cp_regs_jump_table :
LOAD_ C P _ R E G S _ T A B ( 0 )
LOAD_ C P _ R E G S _ T A B ( 1 )
LOAD_ C P _ R E G S _ T A B ( 2 )
LOAD_ C P _ R E G S _ T A B ( 3 )
LOAD_ C P _ R E G S _ T A B ( 4 )
LOAD_ C P _ R E G S _ T A B ( 5 )
LOAD_ C P _ R E G S _ T A B ( 6 )
LOAD_ C P _ R E G S _ T A B ( 7 )
2005-06-24 09:01:16 +04:00
2008-02-13 00:17:07 +03:00
/ *
* coprocessor_ s a v e ( b u f f e r , i n d e x )
* a2 a3
* coprocessor_ l o a d ( b u f f e r , i n d e x )
* a2 a3
*
* Save o r l o a d c o p r o c e s s o r r e g i s t e r s f o r c o p r o c e s s o r ' i n d e x ' .
* The r e g i s t e r v a l u e s a r e s a v e d t o o r l o a d e d f r o m t h e m ' b u f f e r ' a d d r e s s .
*
* Note t h a t t h e s e f u n c t i o n s d o n ' t u p d a t e t h e c o p r o c e s s o r _ o w n e r i n f o r m a t i o n !
*
* /
2005-06-24 09:01:16 +04:00
2008-02-13 00:17:07 +03:00
ENTRY( c o p r o c e s s o r _ s a v e )
entry a1 , 3 2
s3 2 i a0 , a1 , 0
movi a0 , . L s a v e _ c p _ r e g s _ j u m p _ t a b l e
addx8 a3 , a3 , a0
l3 2 i a3 , a3 , 0
beqz a3 , 1 f
add a0 , a0 , a3
callx0 a0
1 : l3 2 i a0 , a1 , 0
2005-06-24 09:01:16 +04:00
retw
2008-02-13 00:17:07 +03:00
ENTRY( c o p r o c e s s o r _ l o a d )
entry a1 , 3 2
s3 2 i a0 , a1 , 0
movi a0 , . L l o a d _ c p _ r e g s _ j u m p _ t a b l e
addx4 a3 , a3 , a0
l3 2 i a3 , a3 , 0
beqz a3 , 1 f
add a0 , a0 , a3
callx0 a0
1 : l3 2 i a0 , a1 , 0
2005-06-24 09:01:16 +04:00
retw
2008-02-13 00:17:07 +03:00
/ *
* coprocessor_ f l u s h ( s t r u c t t a s k _ i n f o * , i n d e x )
* a2 a3
* coprocessor_ r e s t o r e ( s t r u c t t a s k _ i n f o * , i n d e x )
* a2 a3
*
* Save o r l o a d c o p r o c e s s o r r e g i s t e r s f o r c o p r o c e s s o r ' i n d e x ' .
* The r e g i s t e r v a l u e s a r e s a v e d t o o r l o a d e d f r o m t h e c o p r o c e s s o r a r e a
* inside t h e t a s k _ i n f o s t r u c t u r e .
*
* Note t h a t t h e s e f u n c t i o n s d o n ' t u p d a t e t h e c o p r o c e s s o r _ o w n e r i n f o r m a t i o n !
*
* /
ENTRY( c o p r o c e s s o r _ f l u s h )
entry a1 , 3 2
s3 2 i a0 , a1 , 0
movi a0 , . L s a v e _ c p _ r e g s _ j u m p _ t a b l e
addx8 a3 , a3 , a0
l3 2 i a4 , a3 , 4
l3 2 i a3 , a3 , 0
add a2 , a2 , a4
beqz a3 , 1 f
add a0 , a0 , a3
callx0 a0
1 : l3 2 i a0 , a1 , 0
2005-06-24 09:01:16 +04:00
retw
2008-02-13 00:17:07 +03:00
ENTRY( c o p r o c e s s o r _ r e s t o r e )
entry a1 , 3 2
s3 2 i a0 , a1 , 0
movi a0 , . L l o a d _ c p _ r e g s _ j u m p _ t a b l e
addx4 a3 , a3 , a0
l3 2 i a4 , a3 , 4
l3 2 i a3 , a3 , 0
add a2 , a2 , a4
beqz a3 , 1 f
add a0 , a0 , a3
callx0 a0
1 : l3 2 i a0 , a1 , 0
retw
2005-06-24 09:01:16 +04:00
/ *
2008-02-13 00:17:07 +03:00
* Entry c o n d i t i o n :
2005-06-24 09:01:16 +04:00
*
2008-02-13 00:17:07 +03:00
* a0 : trashed, o r i g i n a l v a l u e s a v e d o n s t a c k ( P T _ A R E G 0 )
* a1 : a1
* a2 : new s t a c k p o i n t e r , o r i g i n a l i n D E P C
* a3 : dispatch t a b l e
* depc : a2 , o r i g i n a l v a l u e s a v e d o n s t a c k ( P T _ D E P C )
* excsave_1 : a3
2005-06-24 09:01:16 +04:00
*
2008-02-13 00:17:07 +03:00
* PT_ D E P C > = V A L I D _ D O U B L E _ E X C E P T I O N _ A D D R E S S : d o u b l e e x c e p t i o n , D E P C
* < VALID_DOUBLE_EXCEPTION_ADDRESS : regular e x c e p t i o n
2005-06-24 09:01:16 +04:00
* /
2008-02-13 00:17:07 +03:00
ENTRY( f a s t _ c o p r o c e s s o r _ d o u b l e )
2012-10-15 03:55:38 +04:00
wsr a0 , e x c s a v e 1
2008-02-13 00:17:07 +03:00
movi a0 , u n r e c o v e r a b l e _ e x c e p t i o n
callx0 a0
2005-06-24 09:01:16 +04:00
2008-02-13 00:17:07 +03:00
ENTRY( f a s t _ c o p r o c e s s o r )
/* Save remaining registers a1-a3 and SAR */
2012-10-15 03:55:38 +04:00
xsr a3 , e x c s a v e 1
2008-02-13 00:17:07 +03:00
s3 2 i a3 , a2 , P T _ A R E G 3
2012-10-15 03:55:38 +04:00
rsr a3 , s a r
2008-02-13 00:17:07 +03:00
s3 2 i a1 , a2 , P T _ A R E G 1
s3 2 i a3 , a2 , P T _ S A R
mov a1 , a2
2012-10-15 03:55:38 +04:00
rsr a2 , d e p c
2008-02-13 00:17:07 +03:00
s3 2 i a2 , a1 , P T _ A R E G 2
/ *
* The h a l m a c r o s r e q u i r e u p t o 4 t e m p o r a r y r e g i s t e r s . W e u s e a3 . . a6 .
* /
s3 2 i a4 , a1 , P T _ A R E G 4
s3 2 i a5 , a1 , P T _ A R E G 5
s3 2 i a6 , a1 , P T _ A R E G 6
/* Find coprocessor number. Subtract first CP EXCCAUSE from EXCCAUSE */
2012-10-15 03:55:38 +04:00
rsr a3 , e x c c a u s e
2008-02-13 00:17:07 +03:00
addi a3 , a3 , - E X C C A U S E _ C O P R O C E S S O R 0 _ D I S A B L E D
/* Set corresponding CPENABLE bit -> (sar:cp-index, a3: 1<<cp-index)*/
ssl a3 # S A R : 32 - c o p r o c e s s o r _ n u m b e r
movi a2 , 1
2012-10-15 03:55:38 +04:00
rsr a0 , c p e n a b l e
2008-02-13 00:17:07 +03:00
sll a2 , a2
or a0 , a0 , a2
2012-10-15 03:55:38 +04:00
wsr a0 , c p e n a b l e
2008-02-13 00:17:07 +03:00
rsync
/* Retrieve previous owner. (a3 still holds CP number) */
movi a0 , c o p r o c e s s o r _ o w n e r # l i s t o f o w n e r s
addx4 a0 , a3 , a0 # e n t r y f o r C P
l3 2 i a4 , a0 , 0
beqz a4 , 1 f # s k i p ' s a v e ' i f n o p r e v i o u s o w n e r
/* Disable coprocessor for previous owner. (a2 = 1 << CP number) */
l3 2 i a5 , a4 , T H R E A D _ C P E N A B L E
xor a5 , a5 , a2 # ( 1 < < c p - i d ) s t i l l i n a2
s3 2 i a5 , a4 , T H R E A D _ C P E N A B L E
/ *
* Get c o n t e x t s a v e a r e a a n d ' c a l l ' s a v e r o u t i n e .
* ( a4 s t i l l h o l d s p r e v i o u s o w n e r ( t h r e a d _ i n f o ) , a3 C P n u m b e r )
* /
movi a5 , . L s a v e _ c p _ r e g s _ j u m p _ t a b l e
movi a0 , 2 f # a 0 : ' r e t u r n ' a d d r e s s
addx8 a3 , a3 , a5 # a 3 : c o p r o c e s s o r n u m b e r
l3 2 i a2 , a3 , 4 # a 2 : x t r e g s o f f s e t
l3 2 i a3 , a3 , 0 # a 3 : j u m p o f f s e t
add a2 , a2 , a4
add a4 , a3 , a5 # a 4 : a d d r e s s o f s a v e r o u t i n e
jx a4
/* Note that only a0 and a1 were preserved. */
2012-10-15 03:55:38 +04:00
2 : rsr a3 , e x c c a u s e
2008-02-13 00:17:07 +03:00
addi a3 , a3 , - E X C C A U S E _ C O P R O C E S S O R 0 _ D I S A B L E D
movi a0 , c o p r o c e s s o r _ o w n e r
addx4 a0 , a3 , a0
/* Set new 'owner' (a0 points to the CP owner, a3 contains the CP nr) */
1 : GET_ T H R E A D _ I N F O ( a4 , a1 )
s3 2 i a4 , a0 , 0
/* Get context save area and 'call' load routine. */
movi a5 , . L l o a d _ c p _ r e g s _ j u m p _ t a b l e
movi a0 , 1 f
addx8 a3 , a3 , a5
l3 2 i a2 , a3 , 4 # a 2 : x t r e g s o f f s e t
l3 2 i a3 , a3 , 0 # a 3 : j u m p o f f s e t
add a2 , a2 , a4
add a4 , a3 , a5
jx a4
/* Restore all registers and return from exception handler. */
1 : l3 2 i a6 , a1 , P T _ A R E G 6
l3 2 i a5 , a1 , P T _ A R E G 5
l3 2 i a4 , a1 , P T _ A R E G 4
l3 2 i a0 , a1 , P T _ S A R
l3 2 i a3 , a1 , P T _ A R E G 3
l3 2 i a2 , a1 , P T _ A R E G 2
2012-10-15 03:55:38 +04:00
wsr a0 , s a r
2008-02-13 00:17:07 +03:00
l3 2 i a0 , a1 , P T _ A R E G 0
l3 2 i a1 , a1 , P T _ A R E G 1
rfe
.data
ENTRY( c o p r o c e s s o r _ o w n e r )
.fill XCHAL_ C P _ M A X , 4 , 0
# endif / * X T E N S A _ H A V E _ C O P R O C E S S O R S * /
2005-06-24 09:01:16 +04:00