2011-11-01 03:39:14 +04:00
/ *
* Context s w i t c h s u p p o r t f o r H e x a g o n
*
2012-09-20 01:22:02 +04:00
* Copyright ( c ) 2 0 1 0 - 2 0 1 1 , T h e L i n u x F o u n d a t i o n . A l l r i g h t s r e s e r v e d .
2011-11-01 03:39:14 +04:00
*
* This p r o g r a m i s f r e e s o f t w a r e ; you can redistribute it and/or modify
* it u n d e r t h e t e r m s o f t h e G N U G e n e r a l P u b l i c L i c e n s e v e r s i o n 2 a n d
* only v e r s i o n 2 a s p u b l i s h e d b y t h e F r e e S o f t w a r e F o u n d a t i o n .
*
* This p r o g r a m i s d i s t r i b u t e d i n t h e h o p e t h a t i t w i l l b e u s e f u l ,
* but W I T H O U T A N Y W A R R A N T Y ; without even the implied warranty of
* MERCHANTABILITY o r F I T N E S S F O R A P A R T I C U L A R P U R P O S E . S e e t h e
* GNU G e n e r a l P u b l i c L i c e n s e f o r m o r e d e t a i l s .
*
* You s h o u l d h a v e r e c e i v e d a c o p y o f t h e G N U G e n e r a l P u b l i c L i c e n s e
* along w i t h t h i s p r o g r a m ; if not, write to the Free Software
* Foundation, I n c . , 5 1 F r a n k l i n S t r e e t , F i f t h F l o o r , B o s t o n , M A
* 0 2 1 1 0 - 1 3 0 1 , USA.
* /
# include < a s m / a s m - o f f s e t s . h >
.text
/ *
* The r e g i s t e r u s e d a s a f a s t - p a t h t h r e a d i n f o r m a t i o n p o i n t e r
* is d e t e r m i n e d a s a k e r n e l c o n f i g u r a t i o n o p t i o n . I f i t h a p p e n s
* to b e a c a l l e e - s a v e r e g i s t e r , w e ' r e g o i n g t o b e s a v i n g a n d
* restoring i t t w i c e h e r e .
*
* This c o d e a n t i c i p a t e s a r e v i s e d A B I w h e r e R 2 0 - 2 3 a r e a d d e d
* to t h e s e t o f c a l l e e - s a v e r e g i s t e r s , b u t t h i s s h o u l d b e
* backward c o m p a t i b l e t o l e g a c y t o o l s .
* /
/ *
* void s w i t c h _ t o ( s t r u c t t a s k _ s t r u c t * p r e v ,
* struct t a s k _ s t r u c t * n e x t , s t r u c t t a s k _ s t r u c t * l a s t ) ;
* /
.p2align 2
.globl __switch_to
.type _ _ switch_ t o , @function
/ *
* When w e e x i t t h e w o r m h o l e , w e n e e d t o s t o r e t h e p r e v i o u s t a s k
* in t h e n e w R 0 ' s p o i n t e r . T e c h n i c a l l y i t s h o u l d b e R 2 , b u t t h e y s h o u l d
* be t h e s a m e ; seems like a legacy thing. In short, don't butcher
* R0 , l e t i t g o b a c k o u t u n m o l e s t e d .
* /
__switch_to :
/ *
* Push c a l l e e - s a v e s o n t o " p r e v " s t a c k .
* Here, w e ' r e s n e a k y b e c a u s e t h e L R a n d F P
* storage o f t h e t h r e a d _ s t a c k s t r u c t u r e
* is a u t o m a g i c a l l y a l l o c a t e d b y a l l o c f r a m e ,
* so w e p a s s s t r u c t s i z e l e s s 8 .
* /
allocframe( #( _ S W I T C H _ S T A C K _ S I Z E - 8 ) ) ;
memd( R 2 9 + #( _ S W I T C H _ R 2726 ) ) =R27 : 2 6 ;
memd( R 2 9 + #( _ S W I T C H _ R 2524 ) ) =R25 : 2 4 ;
memd( R 2 9 + #( _ S W I T C H _ R 2322 ) ) =R23 : 2 2 ;
memd( R 2 9 + #( _ S W I T C H _ R 2120 ) ) =R21 : 2 0 ;
memd( R 2 9 + #( _ S W I T C H _ R 1918 ) ) =R19 : 1 8 ;
memd( R 2 9 + #( _ S W I T C H _ R 1716 ) ) =R17 : 1 6 ;
/* Stash thread_info pointer in task_struct */
memw( R 0 + #_ T A S K _ T H R E A D _ I N F O ) = T H R E A D I N F O _ R E G ;
memw( R 0 + #( _ T A S K _ S T R U C T _ T H R E A D + _ T H R E A D _ S T R U C T _ S W I T C H _ S P ) ) = R 29 ;
/* Switch to "next" stack and restore callee saves from there */
R2 9 = m e m w ( R 1 + #( _ T A S K _ S T R U C T _ T H R E A D + _ T H R E A D _ S T R U C T _ S W I T C H _ S P ) ) ;
{
R27 : 2 6 = memd( R 2 9 + #( _ S W I T C H _ R 2726 ) ) ;
R25 : 2 4 = memd( R 2 9 + #( _ S W I T C H _ R 2524 ) ) ;
}
{
R23 : 2 2 = memd( R 2 9 + #( _ S W I T C H _ R 2322 ) ) ;
R21 : 2 0 = memd( R 2 9 + #( _ S W I T C H _ R 2120 ) ) ;
}
{
R19 : 1 8 = memd( R 2 9 + #( _ S W I T C H _ R 1918 ) ) ;
R17 : 1 6 = memd( R 2 9 + #( _ S W I T C H _ R 1716 ) ) ;
}
{
/ * THREADINFO_ R E G i s c u r r e n t l y o n e o f t h e c a l l e e - s a v e d r e g s
* above, a n d s o b e s u r e t o r e - l o a d i t l a s t .
* /
THREADINFO_ R E G = m e m w ( R 1 + #_ T A S K _ T H R E A D _ I N F O ) ;
R31 : 3 0 = memd( R 2 9 + #_ S W I T C H _ F P ) ;
}
{
R2 9 = a d d ( R 2 9 ,#_ S W I T C H _ S T A C K _ S I Z E ) ;
jumpr R 3 1 ;
}
.size _ _ switch_ t o , . - _ _ s w i t c h _ t o