2005-04-17 02:20:36 +04:00
/ *
* 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 .
*
* Copyright ( C ) 1 9 9 4 - 2 0 0 0 , 2 0 0 1 , 2 0 0 3 R a l f B a e c h l e
* Copyright ( C ) 1 9 9 9 , 2 0 0 0 S i l i c o n G r a p h i c s , I n c .
* Copyright ( C ) 2 0 0 1 M I P S T e c h n o l o g i e s , I n c .
* /
# include < a s m / a s m . h >
# include < a s m / a s m m a c r o . h >
# include < a s m / r e g d e f . h >
# include < a s m / m i p s r e g s . h >
# include < a s m / s t a c k f r a m e . h >
# include < a s m / i s a d e p . h >
# include < a s m / t h r e a d _ i n f o . h >
# include < a s m / w a r . h >
2006-04-05 12:45:45 +04:00
# ifdef C O N F I G _ M I P S _ M T _ S M T C
# include < a s m / m i p s m t r e g s . h >
# endif
2005-04-17 02:20:36 +04:00
2006-10-08 20:24:23 +04:00
# ifndef C O N F I G _ P R E E M P T
2005-04-17 02:20:36 +04:00
# define r e s u m e _ k e r n e l r e s t o r e _ a l l
2007-02-13 16:50:18 +03:00
# else
# define _ _ r e t _ f r o m _ i r q r e t _ f r o m _ e x c e p t i o n
2005-04-17 02:20:36 +04:00
# endif
.text
.align 5
2007-02-13 16:50:18 +03:00
# ifndef C O N F I G _ P R E E M P T
2005-04-17 02:20:36 +04:00
FEXPORT( r e t _ f r o m _ e x c e p t i o n )
2007-02-13 16:50:18 +03:00
local_ i r q _ d i s a b l e # p r e e m p t s t o p
b _ _ r e t _ f r o m _ i r q
2006-10-08 20:24:23 +04:00
# endif
2007-02-13 16:50:18 +03:00
FEXPORT( r e t _ f r o m _ i r q )
LONG_ S s0 , T I _ R E G S ( $ 2 8 )
FEXPORT( _ _ r e t _ f r o m _ i r q )
2005-04-17 02:20:36 +04:00
LONG_ L t 0 , P T _ S T A T U S ( s p ) # r e t u r n i n g t o k e r n e l m o d e ?
andi t 0 , t 0 , K U _ U S E R
beqz t 0 , r e s u m e _ k e r n e l
2004-12-10 15:56:33 +03:00
resume_userspace :
local_ i r q _ d i s a b l e # m a k e s u r e w e d o n t m i s s a n
2005-04-17 02:20:36 +04:00
# interrupt s e t t i n g n e e d _ r e s c h e d
# between s a m p l i n g a n d r e t u r n
LONG_ L a2 , T I _ F L A G S ( $ 2 8 ) # c u r r e n t - > w o r k
2004-12-10 15:56:33 +03:00
andi t 0 , a2 , _ T I F _ W O R K _ M A S K # ( i g n o r i n g s y s c a l l _ t r a c e )
bnez t 0 , w o r k _ p e n d i n g
2005-04-17 02:20:36 +04:00
j r e s t o r e _ a l l
# ifdef C O N F I G _ P R E E M P T
2004-12-10 15:56:33 +03:00
resume_kernel :
2005-02-07 05:54:29 +03:00
local_ i r q _ d i s a b l e
2005-04-17 02:20:36 +04:00
lw t 0 , T I _ P R E _ C O U N T ( $ 2 8 )
bnez t 0 , r e s t o r e _ a l l
need_resched :
LONG_ L t 0 , T I _ F L A G S ( $ 2 8 )
andi t 1 , t 0 , _ T I F _ N E E D _ R E S C H E D
beqz t 1 , r e s t o r e _ a l l
LONG_ L t 0 , P T _ S T A T U S ( s p ) # I n t e r r u p t s o f f ?
andi t 0 , 1
beqz t 0 , r e s t o r e _ a l l
2005-02-07 05:54:29 +03:00
jal p r e e m p t _ s c h e d u l e _ i r q
2005-03-04 15:35:42 +03:00
b n e e d _ r e s c h e d
2005-04-17 02:20:36 +04:00
# endif
2012-10-10 00:27:45 +04:00
FEXPORT( r e t _ f r o m _ k e r n e l _ t h r e a d )
jal s c h e d u l e _ t a i l # a 0 = s t r u c t t a s k _ s t r u c t * p r e v
move a0 , s1
jal s0
li a0 , 0
j s y s _ e x i t
2005-04-17 02:20:36 +04:00
FEXPORT( r e t _ f r o m _ f o r k )
2006-07-03 11:25:41 +04:00
jal s c h e d u l e _ t a i l # a 0 = s t r u c t t a s k _ s t r u c t * p r e v
2005-04-17 02:20:36 +04:00
FEXPORT( s y s c a l l _ e x i t )
local_ i r q _ d i s a b l e # m a k e s u r e n e e d _ r e s c h e d a n d
# signals d o n t c h a n g e b e t w e e n
# sampling a n d r e t u r n
LONG_ L a2 , T I _ F L A G S ( $ 2 8 ) # c u r r e n t - > w o r k
li t 0 , _ T I F _ A L L W O R K _ M A S K
and t 0 , a2 , t 0
bnez t 0 , s y s c a l l _ e x i t _ w o r k
2012-05-06 00:11:35 +04:00
restore_all : # restore f u l l f r a m e
2006-04-05 12:45:45 +04:00
# ifdef C O N F I G _ M I P S _ M T _ S M T C
2007-07-12 19:21:08 +04:00
# ifdef C O N F I G _ M I P S _ M T _ S M T C _ I M _ B A C K S T O P
2006-04-05 12:45:45 +04:00
/* Re-arm any temporarily masked interrupts not explicitly "acked" */
mfc0 v0 , C P 0 _ T C S T A T U S
ori v1 , v0 , T C S T A T U S _ I X M T
mtc0 v1 , C P 0 _ T C S T A T U S
andi v0 , T C S T A T U S _ I X M T
2006-06-04 01:40:15 +04:00
_ ehb
2006-04-05 12:45:45 +04:00
mfc0 t 0 , C P 0 _ T C C O N T E X T
DMT 9 # d m t t 1
jal m i p s _ i h b
mfc0 t 2 , C P 0 _ S T A T U S
andi t 3 , t 0 , 0 x f f00
or t 2 , t 2 , t 3
mtc0 t 2 , C P 0 _ S T A T U S
2006-06-04 01:40:15 +04:00
_ ehb
2006-04-05 12:45:45 +04:00
andi t 1 , t 1 , V P E C O N T R O L _ T E
beqz t 1 , 1 f
EMT
1 :
mfc0 v1 , C P 0 _ T C S T A T U S
2006-04-27 18:44:50 +04:00
/* We set IXMT above, XOR should clear it here */
2006-04-05 12:45:45 +04:00
xori v1 , v1 , T C S T A T U S _ I X M T
or v1 , v0 , v1
mtc0 v1 , C P 0 _ T C S T A T U S
2006-06-04 01:40:15 +04:00
_ ehb
2006-04-05 12:45:45 +04:00
xor t 0 , t 0 , t 3
mtc0 t 0 , C P 0 _ T C C O N T E X T
2007-07-12 19:21:08 +04:00
# endif / * C O N F I G _ M I P S _ M T _ S M T C _ I M _ B A C K S T O P * /
2008-09-09 23:35:01 +04:00
/* Detect and execute deferred IPI "interrupts" */
LONG_ L s0 , T I _ R E G S ( $ 2 8 )
LONG_ S s p , T I _ R E G S ( $ 2 8 )
jal d e f e r r e d _ s m t c _ i p i
LONG_ S s0 , T I _ R E G S ( $ 2 8 )
2006-04-05 12:45:45 +04:00
# endif / * C O N F I G _ M I P S _ M T _ S M T C * /
2005-04-17 02:20:36 +04:00
.set noat
RESTORE_ T E M P
RESTORE_ A T
RESTORE_ S T A T I C
2012-05-06 00:11:35 +04:00
restore_partial : # restore p a r t i a l f r a m e
2006-07-07 17:07:18 +04:00
# ifdef C O N F I G _ T R A C E _ I R Q F L A G S
SAVE_ S T A T I C
SAVE_ A T
SAVE_ T E M P
LONG_ L v0 , P T _ S T A T U S ( s p )
2007-03-26 17:47:06 +04:00
# if d e f i n e d ( C O N F I G _ C P U _ R 3 0 0 0 ) | | d e f i n e d ( C O N F I G _ C P U _ T X 3 9 X X )
and v0 , S T 0 _ I E P
# else
and v0 , S T 0 _ I E
# endif
2006-07-07 17:07:18 +04:00
beqz v0 , 1 f
jal t r a c e _ h a r d i r q s _ o n
b 2 f
1 : jal t r a c e _ h a r d i r q s _ o f f
2 :
RESTORE_ T E M P
RESTORE_ A T
RESTORE_ S T A T I C
# endif
2005-04-17 02:20:36 +04:00
RESTORE_ S O M E
RESTORE_ S P _ A N D _ R E T
.set at
2004-12-10 15:56:33 +03:00
work_pending :
andi t 0 , a2 , _ T I F _ N E E D _ R E S C H E D # a 2 i s p r e l o a d e d w i t h T I _ F L A G S
2005-04-17 02:20:36 +04:00
beqz t 0 , w o r k _ n o t i f y s i g
work_resched :
jal s c h e d u l e
2004-12-10 15:56:33 +03:00
local_ i r q _ d i s a b l e # m a k e s u r e n e e d _ r e s c h e d a n d
2005-04-17 02:20:36 +04:00
# signals d o n t c h a n g e b e t w e e n
# sampling a n d r e t u r n
LONG_ L a2 , T I _ F L A G S ( $ 2 8 )
andi t 0 , a2 , _ T I F _ W O R K _ M A S K # i s t h e r e a n y w o r k t o b e d o n e
# other t h a n s y s c a l l t r a c i n g ?
beqz t 0 , r e s t o r e _ a l l
andi t 0 , a2 , _ T I F _ N E E D _ R E S C H E D
bnez t 0 , w o r k _ r e s c h e d
work_notifysig : # deal w i t h p e n d i n g s i g n a l s a n d
# notify- r e s u m e r e q u e s t s
move a0 , s p
li a1 , 0
jal d o _ n o t i f y _ r e s u m e # a 2 a l r e a d y l o a d e d
2005-09-15 20:43:50 +04:00
j r e s u m e _ u s e r s p a c e
2005-04-17 02:20:36 +04:00
2012-05-06 00:11:35 +04:00
FEXPORT( s y s c a l l _ e x i t _ p a r t i a l )
local_ i r q _ d i s a b l e # m a k e s u r e n e e d _ r e s c h e d d o e s n ' t
# change b e t w e e n a n d r e t u r n
LONG_ L a2 , T I _ F L A G S ( $ 2 8 ) # c u r r e n t - > w o r k
li t 0 , _ T I F _ A L L W O R K _ M A S K
and t 0 , a2
beqz t 0 , r e s t o r e _ p a r t i a l
2005-04-17 02:20:36 +04:00
SAVE_ S T A T I C
2004-12-10 15:56:33 +03:00
syscall_exit_work :
2012-05-03 05:45:12 +04:00
LONG_ L t 0 , P T _ S T A T U S ( s p ) # r e t u r n i n g t o k e r n e l m o d e ?
andi t 0 , t 0 , K U _ U S E R
beqz t 0 , r e s u m e _ k e r n e l
2011-05-19 12:21:28 +04:00
li t 0 , _ T I F _ W O R K _ S Y S C A L L _ E X I T
2004-12-10 15:56:33 +03:00
and t 0 , a2 # a 2 i s p r e l o a d e d w i t h T I _ F L A G S
beqz t 0 , w o r k _ p e n d i n g # t r a c e b i t s e t ?
2011-05-19 12:21:29 +04:00
local_ i r q _ e n a b l e # c o u l d l e t s y s c a l l _ t r a c e _ l e a v e ( )
2005-04-17 02:20:36 +04:00
# call s c h e d u l e ( ) i n s t e a d
move a0 , s p
2011-05-19 12:21:29 +04:00
jal s y s c a l l _ t r a c e _ l e a v e
2005-04-17 02:20:36 +04:00
b r e s u m e _ u s e r s p a c e
2006-04-05 12:45:45 +04:00
2012-10-09 23:16:07 +04:00
LEAF( r e t _ f r o m _ k e r n e l _ e x e c v e )
move s p , a0
ori $ 2 8 , s p , _ T H R E A D _ S I Z E - 1
xori $ 2 8 , $ 2 8 , _ T H R E A D _ S I Z E - 1
li v0 , 0
li a3 , 0
j s y s c a l l _ e x i t _ p a r t i a l
END( r e t _ f r o m _ k e r n e l _ e x e c v e )
2006-04-05 12:45:45 +04:00
# if d e f i n e d ( C O N F I G _ C P U _ M I P S R 2 ) | | d e f i n e d ( C O N F I G _ M I P S _ M T )
/ *
* MIPS3 2 R 2 I n s t r u c t i o n H a z a r d B a r r i e r - m u s t b e c a l l e d
*
* For C c o d e u s e t h e i n l i n e v e r s i o n n a m e d i n s t r u c t i o n _ h a z a r d ( ) .
* /
LEAF( m i p s _ i h b )
.set mips32r2
jr. h b r a
nop
END( m i p s _ i h b )
# endif / * C O N F I G _ C P U _ M I P S R 2 o r C O N F I G _ M I P S _ M T * /