2011-05-04 14:38:26 -04:00
/ *
* Copyright 2 0 1 1 T i l e r a C o r p o r a t i o n . A l l R i g h t s R e s e r v e d .
*
* 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 i t 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
* as 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 , v e r s i o n 2 .
*
* 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 , b u t
* WITHOUT 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 , G O O D T I T L E o r
* NON I N F R I N G E M E N T . S e e 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 f o r
* more d e t a i l s .
* /
# include < l i n u x / l i n k a g e . h >
# include < a s m / p t r a c e . h >
# include < a s m / a s m - o f f s e t s . h >
# include < a r c h / s p r _ d e f . h >
# include < a s m / p r o c e s s o r . h >
2012-03-28 18:30:03 +01:00
# include < a s m / s w i t c h _ t o . h >
2011-05-04 14:38:26 -04:00
/ *
2013-08-13 15:24:14 -04:00
* See < a s m / s w i t c h _ t o . h > ; called with prev and next task_struct pointers.
2011-05-04 14:38:26 -04:00
* " prev" i s r e t u r n e d i n r0 f o r _ s w i t c h _ t o a n d a l s o f o r r e t _ f r o m _ f o r k .
*
* We w a n t t o s a v e p c / s p i n " p r e v " , a n d g e t t h e n e w p c / s p f r o m " n e x t " .
* We a l s o n e e d t o s a v e a l l t h e c a l l e e - s a v e d r e g i s t e r s o n t h e s t a c k .
*
* Intel e n a b l e s / d i s a b l e s a c c e s s t o t h e h a r d w a r e c y c l e c o u n t e r i n
* seccomp ( s e c u r e c o m p u t i n g ) e n v i r o n m e n t s i f n e c e s s a r y , b a s e d o n
* has_ s e c u r e _ c o m p u t i n g ( ) . W e m i g h t w a n t t o d o t h i s a t s o m e p o i n t ,
* though i t w o u l d r e q u i r e v i r t u a l i z i n g t h e o t h e r S P R s u n d e r W O R L D _ A C C E S S .
*
* Since w e ' r e s a v i n g t o t h e s t a c k , w e o m i t s p f r o m t h i s l i s t .
* And f o r p a r a l l e l s w i t h o t h e r a r c h i t e c t u r e s , w e s a v e l r s e p a r a t e l y ,
* in t h e t h r e a d _ s t r u c t i t s e l f ( a s t h e " p c " f i e l d ) .
*
* This c o d e a l s o n e e d s t o b e a l i g n e d w i t h p r o c e s s . c c o p y _ t h r e a d ( )
* /
# if C A L L E E _ S A V E D _ R E G S _ C O U N T ! = 2 4
2013-08-13 15:24:14 -04:00
# error M i s m a t c h b e t w e e n < a s m / s w i t c h _ t o . h > a n d k e r n e l / e n t r y . S
2011-05-04 14:38:26 -04:00
# endif
# define F R A M E _ S I Z E ( ( 2 + C A L L E E _ S A V E D _ R E G S _ C O U N T ) * 8 )
# define S A V E _ R E G ( r ) { s t r12 , r ; addi r12, r12, 8 }
# define L O A D _ R E G ( r ) { l d r , r12 ; addi r12, r12, 8 }
# define F O R _ E A C H _ C A L L E E _ S A V E D _ R E G ( f ) \
f( r30 ) ; f(r31); \
f( r32 ) ; f(r33); f(r34); f(r35); f(r36); f(r37); f(r38); f(r39); \
f( r40 ) ; f(r41); f(r42); f(r43); f(r44); f(r45); f(r46); f(r47); \
f( r48 ) ; f(r49); f(r50); f(r51); f(r52);
STD_ E N T R Y _ S E C T I O N ( _ _ s w i t c h _ t o , . s c h e d . t e x t )
{
move r10 , s p
st s p , l r
}
{
addli r11 , s p , - F R A M E _ S I Z E + 8
addli s p , s p , - F R A M E _ S I Z E
}
{
st r11 , r10
addli r4 , r1 , T A S K _ S T R U C T _ T H R E A D _ K S P _ O F F S E T
}
{
ld r13 , r4 / * L o a d n e w s p t o a t e m p r e g i s t e r e a r l y . * /
addi r12 , s p , 1 6
}
FOR_ E A C H _ C A L L E E _ S A V E D _ R E G ( S A V E _ R E G )
addli r3 , r0 , T A S K _ S T R U C T _ T H R E A D _ K S P _ O F F S E T
{
st r3 , s p
addli r3 , r0 , T A S K _ S T R U C T _ T H R E A D _ P C _ O F F S E T
}
{
st r3 , l r
addli r4 , r1 , T A S K _ S T R U C T _ T H R E A D _ P C _ O F F S E T
}
{
ld l r , r4
addi r12 , r13 , 1 6
}
{
/* Update sp and ksp0 simultaneously to avoid backtracer warnings. */
move s p , r13
mtspr S P R _ S Y S T E M _ S A V E _ K _ 0 , r2
}
FOR_ E A C H _ C A L L E E _ S A V E D _ R E G ( L O A D _ R E G )
.L__switch_to_pc :
{
addli s p , s p , F R A M E _ S I Z E
jrp l r / * r0 i s s t i l l v a l i d h e r e , s o r e t u r n i t * /
}
STD_ E N D P R O C ( _ _ s w i t c h _ t o )
/* Return a suitable address for the backtracer for suspended threads */
STD_ E N T R Y _ S E C T I O N ( g e t _ s w i t c h _ t o _ p c , . s c h e d . t e x t )
lnk r0
{
addli r0 , r0 , . L _ _ s w i t c h _ t o _ p c - .
jrp l r
}
STD_ E N D P R O C ( g e t _ s w i t c h _ t o _ p c )
STD_ E N T R Y ( g e t _ p t _ r e g s )
.irp reg, r0 , r1 , r2 , r3 , r4 , r5 , r6 , r7 , \
r8 , r9 , r10 , r11 , r12 , r13 , r14 , r15 , \
r1 6 , r17 , r18 , r19 , r20 , r21 , r22 , r23 , \
r2 4 , r25 , r26 , r27 , r28 , r29 , r30 , r31 , \
r3 2 , r33 , r34 , r35 , r36 , r37 , r38 , r39 , \
r4 0 , r41 , r42 , r43 , r44 , r45 , r46 , r47 , \
r4 8 , r49 , r50 , r51 , r52 , t p , s p
{
st r0 , \ r e g
addi r0 , r0 , 8
}
.endr
{
st r0 , l r
addi r0 , r0 , P T R E G S _ O F F S E T _ P C - P T R E G S _ O F F S E T _ L R
}
lnk r1
{
st r0 , r1
addi r0 , r0 , P T R E G S _ O F F S E T _ E X 1 - P T R E G S _ O F F S E T _ P C
}
mfspr r1 , I N T E R R U P T _ C R I T I C A L _ S E C T I O N
shli r1 , r1 , S P R _ E X _ C O N T E X T _ 1 _ 1 _ _ I C S _ S H I F T
ori r1 , r1 , K E R N E L _ P L
{
st r0 , r1
addi r0 , r0 , P T R E G S _ O F F S E T _ F A U L T N U M - P T R E G S _ O F F S E T _ E X 1
}
{
st r0 , z e r o / * c l e a r f a u l t n u m * /
addi r0 , r0 , P T R E G S _ O F F S E T _ O R I G _ R 0 - P T R E G S _ O F F S E T _ F A U L T N U M
}
{
st r0 , z e r o / * c l e a r o r i g _ r0 * /
addli r0 , r0 , - P T R E G S _ O F F S E T _ O R I G _ R 0 / * r e s t o r e r0 t o b a s e * /
}
jrp l r
STD_ E N D P R O C ( g e t _ p t _ r e g s )