2019-05-29 07:12:41 -07:00
/* SPDX-License-Identifier: GPL-2.0-only */
2011-10-31 18:39:14 -05: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-19 16:22:02 -05: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-10-31 18:39:14 -05:00
* /
# 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