2005-04-17 02:20:36 +04:00
/ *
* Linux/ P A - R I S C P r o j e c t ( h t t p : / / w w w . p a r i s c - l i n u x . o r g / )
*
* System c a l l e n t r y c o d e C o p y r i g h t ( c ) M a t t h e w W i l c o x 1 9 9 9 < w i l l y @bofh.ai>
* Licensed u n d e r t h e G N U G P L .
* thanks t o P h i l i p p R u m p f , M i k e S h a v e r a n d v a r i o u s o t h e r s
* sorry a b o u t t h e w a l l , p u f f i n . .
* /
2005-09-09 22:57:26 +04:00
# include < a s m / a s m - o f f s e t s . h >
2005-04-17 02:20:36 +04:00
# include < a s m / u n i s t d . h >
# include < a s m / e r r n o . h >
2007-10-18 11:04:34 +04:00
# include < a s m / p a g e . h >
2005-04-17 02:20:36 +04:00
# include < a s m / p s w . h >
# include < a s m / t h r e a d _ i n f o . h >
# include < a s m / a s s e m b l y . h >
# include < a s m / p r o c e s s o r . h >
2007-01-25 00:36:32 +03:00
# include < l i n u x / l i n k a g e . h >
2005-04-17 02:20:36 +04:00
/ * We f i l l t h e e m p t y p a r t s o f t h e g a t e w a y p a g e w i t h
* something t h a t w i l l k i l l t h e k e r n e l o r a
* userspace a p p l i c a t i o n .
* /
# define K I L L _ I N S N b r e a k 0 ,0
2007-01-28 16:52:57 +03:00
.level LEVEL
2007-01-25 00:36:32 +03:00
2008-05-22 22:36:31 +04:00
.text
2005-04-17 02:20:36 +04:00
.import syscall_ e x i t ,c o d e
.import syscall_ e x i t _ r f i ,c o d e
/ * Linux g a t e w a y p a g e i s a l i a s e d t o v i r t u a l p a g e 0 i n t h e k e r n e l
* address s p a c e . S i n c e i t i s a g a t e w a y p a g e i t c a n n o t b e
* dereferenced, s o n u l l p o i n t e r s w i l l s t i l l f a u l t . W e s t a r t
* the a c t u a l e n t r y p o i n t a t 0 x10 0 . W e p u t b r e a k i n s t r u c t i o n s
* at t h e b e g i n n i n g o f t h e p a g e t o t r a p n u l l i n d i r e c t f u n c t i o n
* pointers.
* /
2007-10-18 11:04:34 +04:00
.align PAGE_SIZE
2007-01-25 00:36:32 +03:00
ENTRY( l i n u x _ g a t e w a y _ p a g e )
2005-04-17 02:20:36 +04:00
/* ADDRESS 0x00 to 0xb0 = 176 bytes / 4 bytes per insn = 44 insns */
.rept 44
KILL_ I N S N
.endr
/* ADDRESS 0xb0 to 0xb4, lws uses 1 insns for entry */
/* Light-weight-syscall entry must always be located at 0xb0 */
/* WARNING: Keep this number updated with table size changes */
# define _ _ N R _ l w s _ e n t r i e s ( 2 )
lws_entry :
/ * Unconditional b r a n c h t o l w s _ s t a r t , l o c a t e d o n t h e
same g a t e w a y p a g e * /
b,n l w s _ s t a r t
/* Fill from 0xb4 to 0xe0 */
.rept 11
KILL_ I N S N
.endr
/ * This f u n c t i o n M U S T b e l o c a t e d a t 0 x e 0 f o r g l i b c ' s t h r e a d i n g
mechanism t o w o r k . D O N O T M O V E T H I S C O D E E V E R ! * /
set_thread_pointer :
gate . + 8 , % r0 / * i n c r e a s e p r i v i l e g e * /
depi 3 , 3 1 , 2 , % r31 / * E n s u r e w e r e t u r n i n t o u s e r m o d e . * /
be 0 ( % s r7 ,% r31 ) / * r e t u r n t o u s e r s p a c e * /
mtctl % r26 , % c r27 / * m o v e a r g 0 t o t h e c o n t r o l r e g i s t e r * /
/ * Increase t h e c h a n c e o f t r a p p i n g i f r a n d o m j u m p s o c c u r t o t h i s
address, f i l l f r o m 0 x f0 t o 0 x10 0 * /
.rept 4
KILL_ I N S N
.endr
/* This address must remain fixed at 0x100 for glibc's syscalls to work */
.align 256
linux_gateway_entry :
gate . + 8 , % r0 / * b e c o m e p r i v i l e g e d * /
mtsp % r0 ,% s r4 / * g e t k e r n e l s p a c e i n t o s r4 * /
mtsp % r0 ,% s r5 / * g e t k e r n e l s p a c e i n t o s r5 * /
mtsp % r0 ,% s r6 / * g e t k e r n e l s p a c e i n t o s r6 * /
mfsp % s r7 ,% r1 / * s a v e u s e r s r7 * /
mtsp % r1 ,% s r3 / * a n d s t o r e i t i n s r3 * /
2005-10-22 06:46:48 +04:00
# ifdef C O N F I G _ 6 4 B I T
2005-04-17 02:20:36 +04:00
/ * for n o w w e c a n * a l w a y s * s e t t h e W b i t o n e n t r y t o t h e s y s c a l l
* since w e d o n ' t s u p p o r t w i d e u s e r l a n d p r o c e s s e s . W e c o u l d
* also s a v e t h e c u r r e n t S M o t h e r t h a n i n r0 a n d r e s t o r e i t o n
* exit f r o m t h e s y s c a l l , a n d a l s o u s e t h a t v a l u e t o k n o w
* whether t o d o n a r r o w o r w i d e s y s c a l l s . - P B
* /
ssm P S W _ S M _ W , % r1
extrd,u % r1 ,P S W _ W _ B I T ,1 ,% r1
/ * sp m u s t b e a l i g n e d o n 4 , s o d e p o s i t t h e W b i t s e t t i n g i n t o
* the b o t t o m o f s p t e m p o r a r i l y * /
or,e v % r1 ,% r30 ,% r30
b,n 1 f
/ * The t o p h a l v e s o f a r g u m e n t r e g i s t e r s m u s t b e c l e a r e d o n s y s c a l l
* entry f r o m n a r r o w e x e c u t a b l e .
* /
depdi 0 , 3 1 , 3 2 , % r26
depdi 0 , 3 1 , 3 2 , % r25
depdi 0 , 3 1 , 3 2 , % r24
depdi 0 , 3 1 , 3 2 , % r23
depdi 0 , 3 1 , 3 2 , % r22
depdi 0 , 3 1 , 3 2 , % r21
1 :
# endif
mfctl % c r30 ,% r1
xor % r1 ,% r30 ,% r30 / * y e o l d e x o r t r i c k * /
xor % r1 ,% r30 ,% r1
xor % r1 ,% r30 ,% r30
ldo T H R E A D _ S Z _ A L G N + F R A M E _ S I Z E ( % r30 ) ,% r30 / * s e t u p k e r n e l s t a c k * /
/ * N. B . : I t i s c r i t i c a l t h a t w e d o n ' t s e t s r7 t o 0 u n t i l r30
* contains a v a l i d k e r n e l s t a c k p o i n t e r . I t i s a l s o
* critical t h a t w e d o n ' t s t a r t u s i n g t h e k e r n e l s t a c k
* until a f t e r s r7 h a s b e e n s e t t o 0 .
* /
mtsp % r0 ,% s r7 / * g e t k e r n e l s p a c e i n t o s r7 * /
STREGM % r1 ,F R A M E _ S I Z E ( % r30 ) / * s a v e r1 ( u s p ) h e r e f o r n o w * /
mfctl % c r30 ,% r1 / * g e t t a s k p t r i n % r1 * /
LDREG T I _ T A S K ( % r1 ) ,% r1
/ * Save s o m e r e g i s t e r s f o r s i g c o n t e x t a n d p o t e n t i a l t a s k
switch ( s e e e n t r y . S f o r t h e d e t a i l s o f w h i c h o n e s a r e
saved/ r e s t o r e d ) . T A S K _ P T _ P S W i s z e r o e d s o w e c a n s e e w h e t h e r
a p r o c e s s i s o n a s y s c a l l o r n o t . F o r a n i n t e r r u p t t h e r e a l
PSW v a l u e i s s t o r e d . T h i s i s n e e d e d f o r g d b a n d s y s _ p t r a c e . * /
STREG % r0 , T A S K _ P T _ P S W ( % r1 )
STREG % r2 , T A S K _ P T _ G R 2 ( % r1 ) / * p r e s e r v e r p * /
STREG % r19 , T A S K _ P T _ G R 1 9 ( % r1 )
LDREGM - F R A M E _ S I Z E ( % r30 ) , % r2 / * g e t u s e r s s p b a c k * /
2005-10-22 06:46:48 +04:00
# ifdef C O N F I G _ 6 4 B I T
2005-04-17 02:20:36 +04:00
extrd,u % r2 ,6 3 ,1 ,% r19 / * W h i d d e n i n b o t t o m b i t * /
# if 0
xor % r19 ,% r2 ,% r2 / * c l e a r b o t t o m b i t * /
depd,z % r19 ,1 ,1 ,% r19
std % r19 ,T A S K _ P T _ P S W ( % r1 )
# endif
# endif
STREG % r2 , T A S K _ P T _ G R 3 0 ( % r1 ) / * . . . a n d s a v e i t * /
2005-11-18 00:32:46 +03:00
STREG % r20 , T A S K _ P T _ G R 2 0 ( % r1 ) / * S y s c a l l n u m b e r * /
2005-04-17 02:20:36 +04:00
STREG % r21 , T A S K _ P T _ G R 2 1 ( % r1 )
STREG % r22 , T A S K _ P T _ G R 2 2 ( % r1 )
STREG % r23 , T A S K _ P T _ G R 2 3 ( % r1 ) / * 4 t h a r g u m e n t * /
STREG % r24 , T A S K _ P T _ G R 2 4 ( % r1 ) / * 3 r d a r g u m e n t * /
STREG % r25 , T A S K _ P T _ G R 2 5 ( % r1 ) / * 2 n d a r g u m e n t * /
STREG % r26 , T A S K _ P T _ G R 2 6 ( % r1 ) / * 1 s t a r g u m e n t * /
STREG % r27 , T A S K _ P T _ G R 2 7 ( % r1 ) / * u s e r d p * /
STREG % r28 , T A S K _ P T _ G R 2 8 ( % r1 ) / * r e t u r n v a l u e 0 * /
STREG % r28 , T A S K _ P T _ O R I G _ R 2 8 ( % r1 ) / * r e t u r n v a l u e 0 ( s a v e d f o r s i g n a l s ) * /
STREG % r29 , T A S K _ P T _ G R 2 9 ( % r1 ) / * r e t u r n v a l u e 1 * /
STREG % r31 , T A S K _ P T _ G R 3 1 ( % r1 ) / * p r e s e r v e s y s c a l l r e t u r n p t r * /
ldo T A S K _ P T _ F R 0 ( % r1 ) , % r27 / * s a v e f p r e g s f r o m t h e k e r n e l * /
save_ f p % r27 / * o r p o t e n t i a l t a s k s w i t c h * /
mfctl % c r11 , % r27 / * i . e . S A R * /
STREG % r27 , T A S K _ P T _ S A R ( % r1 )
loadgp
2005-10-22 06:46:48 +04:00
# ifdef C O N F I G _ 6 4 B I T
2005-04-17 02:20:36 +04:00
ldo - 1 6 ( % r30 ) ,% r29 / * R e f e r e n c e p a r a m s a v e a r e a * /
copy % r19 ,% r2 / * W b i t b a c k t o r2 * /
# else
/ * no n e e d t o s a v e t h e s e o n s t a c k i n w i d e m o d e b e c a u s e t h e f i r s t 8
* args a r e p a s s e d i n r e g i s t e r s * /
stw % r22 , - 5 2 ( % r30 ) / * 5 t h a r g u m e n t * /
stw % r21 , - 5 6 ( % r30 ) / * 6 t h a r g u m e n t * /
# endif
/* Are we being ptraced? */
mfctl % c r30 , % r1
LDREG T I _ T A S K ( % r1 ) ,% r1
2007-05-30 10:27:46 +04:00
ldw T A S K _ P T R A C E ( % r1 ) , % r1
2005-04-17 02:20:36 +04:00
bb,< ,n % r1 ,3 1 ,. L t r a c e s y s
/ * Note! W e c a n n o t u s e t h e s y s c a l l t a b l e t h a t i s m a p p e d
nearby s i n c e t h e g a t e w a y p a g e i s m a p p e d e x e c u t e - o n l y . * /
2005-10-22 06:46:48 +04:00
# ifdef C O N F I G _ 6 4 B I T
2005-04-17 02:20:36 +04:00
ldil L % s y s _ c a l l _ t a b l e , % r1
or,= % r2 ,% r2 ,% r2
addil L % ( s y s _ c a l l _ t a b l e 6 4 - s y s _ c a l l _ t a b l e ) , % r1
ldo R % s y s _ c a l l _ t a b l e ( % r1 ) , % r19
or,= % r2 ,% r2 ,% r2
ldo R % s y s _ c a l l _ t a b l e 6 4 ( % r1 ) , % r19
# else
ldil L % s y s _ c a l l _ t a b l e , % r1
ldo R % s y s _ c a l l _ t a b l e ( % r1 ) , % r19
# endif
2007-06-04 01:47:00 +04:00
comiclr,> > _ _ N R _ L i n u x _ s y s c a l l s , % r20 , % r0
2005-04-17 02:20:36 +04:00
b,n . L s y s c a l l _ n o s y s
LDREGX % r20 ( % r19 ) , % r19
/ * If t h i s i s a s y s _ r t _ s i g r e t u r n c a l l , a n d t h e s i g n a l w a s r e c e i v e d
* when n o t i n _ s y s c a l l , t h e n w e w a n t t o r e t u r n v i a s y s c a l l _ e x i t _ r f i ,
* not s y s c a l l _ e x i t . S i g n a l n o . i n r20 , i n _ s y s c a l l i n r25 ( s e e
* trampoline c o d e i n s i g n a l . c ) .
* /
ldi _ _ N R _ r t _ s i g r e t u r n ,% r2
comb,= % r2 ,% r20 ,. L r t _ s i g r e t u r n
.Lin_syscall :
ldil L % s y s c a l l _ e x i t ,% r2
be 0 ( % s r7 ,% r19 )
ldo R % s y s c a l l _ e x i t ( % r2 ) ,% r2
.Lrt_sigreturn :
comib,< > 0 ,% r25 ,. L i n _ s y s c a l l
ldil L % s y s c a l l _ e x i t _ r f i ,% r2
be 0 ( % s r7 ,% r19 )
ldo R % s y s c a l l _ e x i t _ r f i ( % r2 ) ,% r2
/ * Note! B e c a u s e w e a r e n o t r u n n i n g w h e r e w e w e r e l i n k e d , a n y
calls t o f u n c t i o n s e x t e r n a l t o t h i s f i l e m u s t b e i n d i r e c t . T o
be s a f e , w e a p p l y t h e o p p o s i t e r u l e t o f u n c t i o n s w i t h i n t h i s
file, w i t h l o c a l l a b e l s g i v e n t o t h e m t o e n s u r e c o r r e c t n e s s . * /
.Lsyscall_nosys :
syscall_nosys :
ldil L % s y s c a l l _ e x i t ,% r1
be R % s y s c a l l _ e x i t ( % s r7 ,% r1 )
ldo - E N O S Y S ( % r0 ) ,% r28 / * s e t e r r n o * /
/ * Warning! T h i s t r a c e c o d e i s a v i r t u a l d u p l i c a t e o f t h e c o d e a b o v e s o b e
* sure t o m a i n t a i n b o t h ! * /
.Ltracesys :
tracesys :
/ * Need t o s a v e m o r e r e g i s t e r s s o t h e d e b u g g e r c a n s e e w h e r e w e
* are. T h i s s a v e s o n l y t h e l o w e r 8 b i t s o f P S W , s o t h a t t h e C
* bit i s s t i l l c l e a r o n s y s c a l l s , a n d t h e D b i t i s s e t i f t h i s
* full r e g i s t e r s a v e p a t h h a s b e e n e x e c u t e d . W e c h e c k t h e D
* bit o n s y s c a l l _ r e t u r n _ r f i t o d e t e r m i n e w h i c h r e g i s t e r s t o
* restore. A n i n t e r r u p t r e s u l t s i n a f u l l P S W s a v e d w i t h t h e
* C b i t s e t , a n o n - s t r a c e d s y s c a l l e n t r y r e s u l t s i n C a n d D c l e a r
* in t h e s a v e d P S W .
* /
ldo - T H R E A D _ S Z _ A L G N - F R A M E _ S I Z E ( % r30 ) ,% r1 / * g e t t a s k p t r * /
LDREG T I _ T A S K ( % r1 ) , % r1
ssm 0 ,% r2
STREG % r2 ,T A S K _ P T _ P S W ( % r1 ) / * L o w e r 8 b i t s o n l y ! ! * /
mfsp % s r0 ,% r2
STREG % r2 ,T A S K _ P T _ S R 0 ( % r1 )
mfsp % s r1 ,% r2
STREG % r2 ,T A S K _ P T _ S R 1 ( % r1 )
mfsp % s r2 ,% r2
STREG % r2 ,T A S K _ P T _ S R 2 ( % r1 )
mfsp % s r3 ,% r2
STREG % r2 ,T A S K _ P T _ S R 3 ( % r1 )
STREG % r2 ,T A S K _ P T _ S R 4 ( % r1 )
STREG % r2 ,T A S K _ P T _ S R 5 ( % r1 )
STREG % r2 ,T A S K _ P T _ S R 6 ( % r1 )
STREG % r2 ,T A S K _ P T _ S R 7 ( % r1 )
STREG % r2 ,T A S K _ P T _ I A S Q 0 ( % r1 )
STREG % r2 ,T A S K _ P T _ I A S Q 1 ( % r1 )
LDREG T A S K _ P T _ G R 3 1 ( % r1 ) ,% r2
STREG % r2 ,T A S K _ P T _ I A O Q 0 ( % r1 )
ldo 4 ( % r2 ) ,% r2
STREG % r2 ,T A S K _ P T _ I A O Q 1 ( % r1 )
ldo T A S K _ R E G S ( % r1 ) ,% r2
/* reg_save %r2 */
STREG % r3 ,P T _ G R 3 ( % r2 )
STREG % r4 ,P T _ G R 4 ( % r2 )
STREG % r5 ,P T _ G R 5 ( % r2 )
STREG % r6 ,P T _ G R 6 ( % r2 )
STREG % r7 ,P T _ G R 7 ( % r2 )
STREG % r8 ,P T _ G R 8 ( % r2 )
STREG % r9 ,P T _ G R 9 ( % r2 )
STREG % r10 ,P T _ G R 1 0 ( % r2 )
STREG % r11 ,P T _ G R 1 1 ( % r2 )
STREG % r12 ,P T _ G R 1 2 ( % r2 )
STREG % r13 ,P T _ G R 1 3 ( % r2 )
STREG % r14 ,P T _ G R 1 4 ( % r2 )
STREG % r15 ,P T _ G R 1 5 ( % r2 )
STREG % r16 ,P T _ G R 1 6 ( % r2 )
STREG % r17 ,P T _ G R 1 7 ( % r2 )
STREG % r18 ,P T _ G R 1 8 ( % r2 )
/* Finished saving things for the debugger */
2009-07-05 22:36:16 +04:00
copy % r2 ,% r26
ldil L % d o _ s y s c a l l _ t r a c e _ e n t e r ,% r1
2005-04-17 02:20:36 +04:00
ldil L % t r a c e s y s _ n e x t ,% r2
2009-07-05 22:36:16 +04:00
be R % d o _ s y s c a l l _ t r a c e _ e n t e r ( % s r7 ,% r1 )
2005-04-17 02:20:36 +04:00
ldo R % t r a c e s y s _ n e x t ( % r2 ) ,% r2
2009-07-05 22:36:16 +04:00
tracesys_next :
/ * do_ s y s c a l l _ t r a c e _ e n t e r e i t h e r r e t u r n e d t h e s y s c a l l n o , o r - 1 L ,
* so w e s k i p r e s t o r i n g t h e P T _ G R 2 0 b e l o w , s i n c e w e p u l l e d i t f r o m
* task- > t h r e a d . r e g s . g r [ 2 0 ] a b o v e .
* /
copy % r e t 0 ,% r20
2005-04-17 02:20:36 +04:00
ldil L % s y s _ c a l l _ t a b l e ,% r1
ldo R % s y s _ c a l l _ t a b l e ( % r1 ) , % r19
ldo - T H R E A D _ S Z _ A L G N - F R A M E _ S I Z E ( % r30 ) ,% r1 / * g e t t a s k p t r * /
LDREG T I _ T A S K ( % r1 ) , % r1
LDREG T A S K _ P T _ G R 2 6 ( % r1 ) , % r26 / * R e s t o r e t h e u s e r s a r g s * /
LDREG T A S K _ P T _ G R 2 5 ( % r1 ) , % r25
LDREG T A S K _ P T _ G R 2 4 ( % r1 ) , % r24
LDREG T A S K _ P T _ G R 2 3 ( % r1 ) , % r23
2005-10-22 06:46:48 +04:00
# ifdef C O N F I G _ 6 4 B I T
2005-04-17 02:20:36 +04:00
LDREG T A S K _ P T _ G R 2 2 ( % r1 ) , % r22
LDREG T A S K _ P T _ G R 2 1 ( % r1 ) , % r21
ldo - 1 6 ( % r30 ) ,% r29 / * R e f e r e n c e p a r a m s a v e a r e a * /
# endif
comiclr,> > = _ _ N R _ L i n u x _ s y s c a l l s , % r20 , % r0
b,n . L s y s c a l l _ n o s y s
LDREGX % r20 ( % r19 ) , % r19
/ * If t h i s i s a s y s _ r t _ s i g r e t u r n c a l l , a n d t h e s i g n a l w a s r e c e i v e d
* when n o t i n _ s y s c a l l , t h e n w e w a n t t o r e t u r n v i a s y s c a l l _ e x i t _ r f i ,
* not s y s c a l l _ e x i t . S i g n a l n o . i n r20 , i n _ s y s c a l l i n r25 ( s e e
* trampoline c o d e i n s i g n a l . c ) .
* /
ldi _ _ N R _ r t _ s i g r e t u r n ,% r2
comb,= % r2 ,% r20 ,. L t r a c e _ r t _ s i g r e t u r n
.Ltrace_in_syscall :
ldil L % t r a c e s y s _ e x i t ,% r2
be 0 ( % s r7 ,% r19 )
ldo R % t r a c e s y s _ e x i t ( % r2 ) ,% r2
/ * Do * n o t * c a l l t h i s f u n c t i o n o n t h e g a t e w a y p a g e , b e c a u s e i t
makes a d i r e c t c a l l t o s y s c a l l _ t r a c e . * /
tracesys_exit :
ldo - T H R E A D _ S Z _ A L G N - F R A M E _ S I Z E ( % r30 ) ,% r1 / * g e t t a s k p t r * /
LDREG T I _ T A S K ( % r1 ) , % r1
2005-10-22 06:46:48 +04:00
# ifdef C O N F I G _ 6 4 B I T
2005-04-17 02:20:36 +04:00
ldo - 1 6 ( % r30 ) ,% r29 / * R e f e r e n c e p a r a m s a v e a r e a * /
# endif
2009-07-05 22:36:16 +04:00
ldo T A S K _ R E G S ( % r1 ) ,% r26
bl d o _ s y s c a l l _ t r a c e _ e x i t ,% r2
2005-04-17 02:20:36 +04:00
STREG % r28 ,T A S K _ P T _ G R 2 8 ( % r1 ) / * s a v e r e t u r n v a l u e n o w * /
ldo - T H R E A D _ S Z _ A L G N - F R A M E _ S I Z E ( % r30 ) ,% r1 / * g e t t a s k p t r * /
LDREG T I _ T A S K ( % r1 ) , % r1
LDREG T A S K _ P T _ G R 2 8 ( % r1 ) , % r28 / * R e s t o r e r e t u r n v a l . * /
ldil L % s y s c a l l _ e x i t ,% r1
be,n R % s y s c a l l _ e x i t ( % s r7 ,% r1 )
.Ltrace_rt_sigreturn :
comib,< > 0 ,% r25 ,. L t r a c e _ i n _ s y s c a l l
ldil L % t r a c e s y s _ s i g e x i t ,% r2
be 0 ( % s r7 ,% r19 )
ldo R % t r a c e s y s _ s i g e x i t ( % r2 ) ,% r2
tracesys_sigexit :
ldo - T H R E A D _ S Z _ A L G N - F R A M E _ S I Z E ( % r30 ) ,% r1 / * g e t t a s k p t r * /
2009-07-05 22:39:58 +04:00
LDREG T I _ T A S K ( % r1 ) , % r1
2005-10-22 06:46:48 +04:00
# ifdef C O N F I G _ 6 4 B I T
2005-04-17 02:20:36 +04:00
ldo - 1 6 ( % r30 ) ,% r29 / * R e f e r e n c e p a r a m s a v e a r e a * /
# endif
2009-07-05 22:36:16 +04:00
bl d o _ s y s c a l l _ t r a c e _ e x i t ,% r2
ldo T A S K _ R E G S ( % r1 ) ,% r26
2005-04-17 02:20:36 +04:00
ldil L % s y s c a l l _ e x i t _ r f i ,% r1
be,n R % s y s c a l l _ e x i t _ r f i ( % s r7 ,% r1 )
/ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2008-12-30 05:47:38 +03:00
3 2 / 6 4 - bit L i g h t - W e i g h t - S y s c a l l A B I
2005-04-17 02:20:36 +04:00
2008-12-30 05:47:38 +03:00
* - Indicates a h i n t f o r u s e r s p a c e i n l i n e a s m
implementations.
2005-04-17 02:20:36 +04:00
2008-12-30 05:47:38 +03:00
Syscall n u m b e r ( c a l l e r - s a v e s )
- % r2 0
* In a s m c l o b b e r .
2005-04-17 02:20:36 +04:00
2008-12-30 05:47:38 +03:00
Argument r e g i s t e r s ( c a l l e r - s a v e s )
- % r2 6 , % r25 , % r24 , % r23 , % r22
* In a s m i n p u t .
Return r e g i s t e r s ( c a l l e r - s a v e s )
- % r2 8 ( r e t u r n ) , % r21 ( e r r n o )
* In a s m o u t p u t .
Caller- s a v e s r e g i s t e r s
- % r1 , % r27 , % r29
- % r2 ( r e t u r n p o i n t e r )
- % r3 1 ( b l e l i n k r e g i s t e r )
* In a s m c l o b b e r .
Callee- s a v e s r e g i s t e r s
- % r3 - % r18
- % r3 0 ( s t a c k p o i n t e r )
* Not i n a s m c l o b b e r .
If u s e r s p a c e i s 3 2 - b i t :
Callee- s a v e s r e g i s t e r s
- % r1 9 ( 3 2 - b i t P I C r e g i s t e r )
Differences f r o m 3 2 - b i t c a l l i n g c o n v e n t i o n :
- Syscall n u m b e r i n % r20
- Additional a r g u m e n t r e g i s t e r % r22 ( a r g 4 )
- Callee- s a v e s % r19 .
If u s e r s p a c e i s 6 4 - b i t :
Callee- s a v e s r e g i s t e r s
- % r2 7 ( 6 4 - b i t P I C r e g i s t e r )
Differences f r o m 6 4 - b i t c a l l i n g c o n v e n t i o n :
- Syscall n u m b e r i n % r20
- Additional a r g u m e n t r e g i s t e r % r22 ( a r g 4 )
- Callee- s a v e s % r27 .
2005-04-17 02:20:36 +04:00
Error c o d e s r e t u r n e d b y e n t r y p a t h :
ENOSYS - r20 w a s a n i n v a l i d L W S n u m b e r .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * /
lws_start :
/* Gate and ensure we return to userspace */
gate . + 8 , % r0
depi 3 , 3 1 , 2 , % r31 / * E n s u r e w e r e t u r n t o u s e r s p a c e * /
2005-10-22 06:46:48 +04:00
# ifdef C O N F I G _ 6 4 B I T
2005-04-17 02:20:36 +04:00
/ * FIXME : If w e a r e a 6 4 - b i t k e r n e l j u s t
* turn t h i s o n u n c o n d i t i o n a l l y .
* /
ssm P S W _ S M _ W , % r1
extrd,u % r1 ,P S W _ W _ B I T ,1 ,% r1
/ * sp m u s t b e a l i g n e d o n 4 , s o d e p o s i t t h e W b i t s e t t i n g i n t o
* the b o t t o m o f s p t e m p o r a r i l y * /
or,e v % r1 ,% r30 ,% r30
/* Clip LWS number to a 32-bit value always */
depdi 0 , 3 1 , 3 2 , % r20
# endif
/* Is the lws entry number valid? */
comiclr,> > = _ _ N R _ l w s _ e n t r i e s , % r20 , % r0
b,n l w s _ e x i t _ n o s y s
/* WARNING: Trashing sr2 and sr3 */
mfsp % s r7 ,% r1 / * g e t u s e r s p a c e i n t o s r3 * /
mtsp % r1 ,% s r3
mtsp % r0 ,% s r2 / * g e t k e r n e l s p a c e i n t o s r2 * /
/* Load table start */
ldil L % l w s _ t a b l e , % r1
ldo R % l w s _ t a b l e ( % r1 ) , % r28 / * S c r a t c h u s e o f r28 * /
LDREGX % r20 ( % s r2 ,r28 ) , % r21 / * S c r a t c h u s e o f r21 * /
/* Jump to lws, lws table pointers already relocated */
be,n 0 ( % s r2 ,% r21 )
lws_exit_nosys :
ldo - E N O S Y S ( % r0 ) ,% r21 / * s e t e r r n o * /
/* Fall through: Return to userspace */
lws_exit :
2005-10-22 06:46:48 +04:00
# ifdef C O N F I G _ 6 4 B I T
2005-04-17 02:20:36 +04:00
/ * decide w h e t h e r t o r e s e t t h e w i d e m o d e b i t
*
* For a s y s c a l l , t h e W b i t i s s t o r e d i n t h e l o w e s t b i t
* of s p . E x t r a c t i t a n d r e s e t W i f i t i s z e r o * /
extrd,u ,* < > % r30 ,6 3 ,1 ,% r1
rsm P S W _ S M _ W , % r0
/* now reset the lowest bit of sp if it was set */
xor % r30 ,% r1 ,% r30
# endif
be,n 0 ( % s r3 , % r31 )
/ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Implementing C A S a s a n a t o m i c o p e r a t i o n :
% r2 6 - A d d r e s s t o e x a m i n e
% r2 5 - O l d v a l u e t o c h e c k ( o l d )
% r2 4 - N e w v a l u e t o s e t ( n e w )
% r2 8 - R e t u r n p r e v t h r o u g h t h i s r e g i s t e r .
% r2 1 - K e r n e l e r r o r c o d e
If d e b u g g i n g i s D I S a b l e d :
% r2 1 h a s t h e f o l l o w i n g m e a n i n g s :
EAGAIN - C A S i s b u s y , l d c w f a i l e d , t r y a g a i n .
EFAULT - R e a d o r w r i t e f a i l e d .
If d e b u g g i n g i s e n a b l e d :
EDEADLOCK - C A S c a l l e d r e c u r s i v e l y .
EAGAIN & & r28 = = 1 - C A S i s b u s y . L o c k c o n t e n d e d .
EAGAIN & & r28 = = 2 - C A S i s b u s y . l d c w f a i l e d .
EFAULT - R e a d o r w r i t e f a i l e d .
Scratch : r2 0 , r28 , r1
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * /
/* Do not enable LWS debugging */
# define E N A B L E _ L W S _ D E B U G 0
/* ELF64 Process entry path */
lws_compare_and_swap64 :
2005-10-22 06:46:48 +04:00
# ifdef C O N F I G _ 6 4 B I T
2005-04-17 02:20:36 +04:00
b,n l w s _ c o m p a r e _ a n d _ s w a p
# else
/ * If w e a r e n o t a 6 4 - b i t k e r n e l , t h e n w e d o n ' t
2008-12-30 05:47:38 +03:00
* have 6 4 - b i t i n p u t r e g i s t e r s , a n d c a l l i n g
* the 6 4 - b i t L W S C A S r e t u r n s E N O S Y S .
2005-04-17 02:20:36 +04:00
* /
b,n l w s _ e x i t _ n o s y s
# endif
/* ELF32 Process entry path */
lws_compare_and_swap32 :
2005-10-22 06:46:48 +04:00
# ifdef C O N F I G _ 6 4 B I T
2005-04-17 02:20:36 +04:00
/* Clip all the input registers */
depdi 0 , 3 1 , 3 2 , % r26
depdi 0 , 3 1 , 3 2 , % r25
depdi 0 , 3 1 , 3 2 , % r24
# endif
lws_compare_and_swap :
# ifdef C O N F I G _ S M P
/* Load start of lock table */
ldil L % l w s _ l o c k _ s t a r t , % r20
ldo R % l w s _ l o c k _ s t a r t ( % r20 ) , % r28
/* Extract four bits from r26 and hash lock (Bits 4-7) */
extru % r26 , 2 7 , 4 , % r20
/ * Find l o c k t o u s e , t h e h a s h i s e i t h e r o n e o f 0 t o
1 5 , multiplied b y 1 6 ( k e e p i t 1 6 - b y t e a l i g n e d )
and a d d t o t h e l o c k t a b l e o f f s e t . * /
shlw % r20 , 4 , % r20
add % r20 , % r28 , % r20
2007-05-22 19:38:26 +04:00
# if E N A B L E _ L W S _ D E B U G
2005-04-17 02:20:36 +04:00
/ *
DEBUG, c h e c k f o r d e a d l o c k !
If t h e t h r e a d r e g i s t e r v a l u e s a r e t h e s a m e
then w e w e r e t h e o n e t h a t l o c k e d i t l a s t a n d
this i s a r e c u r i s v e c a l l t h a t w i l l d e a d l o c k .
We * m u s t * g i v e u p t h i s c a l l a n d f a i l .
* /
ldw 4 ( % s r2 ,% r20 ) , % r28 / * L o a d t h r e a d r e g i s t e r * /
2005-11-18 00:32:46 +03:00
/* WARNING: If cr27 cycles to the same value we have problems */
2005-04-17 02:20:36 +04:00
mfctl % c r27 , % r21 / * G e t c u r r e n t t h r e a d r e g i s t e r * /
cmpb,< > ,n % r21 , % r28 , c a s _ l o c k / * C a l l e d r e c u r s i v e ? * /
b l w s _ e x i t / * R e t u r n e r r o r ! * /
ldo - E D E A D L O C K ( % r0 ) , % r21
cas_lock :
cmpb,= ,n % r0 , % r28 , c a s _ n o c o n t e n d / * I s n o b o d y u s i n g i t ? * /
ldo 1 ( % r0 ) , % r28 / * 1 s t c a s e * /
b l w s _ e x i t / * C o n t e n d e d . . . * /
ldo - E A G A I N ( % r0 ) , % r21 / * S p i n i n u s e r s p a c e * /
cas_nocontend :
# endif
/* ENABLE_LWS_DEBUG */
2006-04-22 10:48:22 +04:00
LDCW 0 ( % s r2 ,% r20 ) , % r28 / * T r y t o a c q u i r e t h e l o c k * /
2005-04-17 02:20:36 +04:00
cmpb,< > ,n % r0 , % r28 , c a s _ a c t i o n / * D i d w e g e t i t ? * /
cas_wouldblock :
ldo 2 ( % r0 ) , % r28 / * 2 n d c a s e * /
b l w s _ e x i t / * C o n t e n d e d . . . * /
ldo - E A G A I N ( % r0 ) , % r21 / * S p i n i n u s e r s p a c e * /
# endif
/* CONFIG_SMP */
/ *
prev = * a d d r ;
if ( p r e v = = o l d )
* addr = n e w ;
return p r e v ;
* /
/ * NOTES :
This a l l w o r k s b e c u s e i n t r _ d o _ s i g n a l
and s c h e d u l e b o t h c h e c k t h e r e t u r n i a s q
and s e e t h a t w e a r e o n t h e k e r n e l p a g e
so t h i s p r o c e s s i s n e v e r s c h e d u l e d o f f
or i s e v e r s e n t a n y s i g n a l o f a n y s o r t ,
thus i t i s w h o l l y a t o m i c f r o m u s r s p a c e s
perspective
* /
cas_action :
2007-05-22 19:38:26 +04:00
# if d e f i n e d C O N F I G _ S M P & & E N A B L E _ L W S _ D E B U G
2005-04-17 02:20:36 +04:00
/* DEBUG */
mfctl % c r27 , % r1
stw % r1 , 4 ( % s r2 ,% r20 )
# endif
/* The load and store could fail */
1 : ldw 0 ( % s r3 ,% r26 ) , % r28
sub,< > % r28 , % r25 , % r0
2 : stw % r24 , 0 ( % s r3 ,% r26 )
# ifdef C O N F I G _ S M P
/* Free lock */
stw % r20 , 0 ( % s r2 ,% r20 )
2007-05-22 19:38:26 +04:00
# if E N A B L E _ L W S _ D E B U G
2005-04-17 02:20:36 +04:00
/* Clear thread register indicator */
stw % r0 , 4 ( % s r2 ,% r20 )
# endif
# endif
/* Return to userspace, set no error */
b l w s _ e x i t
copy % r0 , % r21
3 :
/* Error occured on load or store */
# ifdef C O N F I G _ S M P
/* Free lock */
stw % r20 , 0 ( % s r2 ,% r20 )
2007-05-22 19:38:26 +04:00
# if E N A B L E _ L W S _ D E B U G
2005-04-17 02:20:36 +04:00
stw % r0 , 4 ( % s r2 ,% r20 )
# endif
# endif
b l w s _ e x i t
ldo - E F A U L T ( % r0 ) ,% r21 / * s e t e r r n o * /
nop
nop
nop
nop
/ * Two e x c e p t i o n t a b l e e n t r i e s , o n e f o r t h e l o a d ,
the o t h e r f o r t h e s t o r e . E i t h e r r e t u r n - E F A U L T .
Each o f t h e e n t r i e s m u s t b e r e l o c a t e d . * /
.section _ _ ex_ t a b l e ," a w "
2007-01-28 16:52:57 +03:00
ASM_ U L O N G _ I N S N ( 1 b - l i n u x _ g a t e w a y _ p a g e ) , ( 3 b - l i n u x _ g a t e w a y _ p a g e )
ASM_ U L O N G _ I N S N ( 2 b - l i n u x _ g a t e w a y _ p a g e ) , ( 3 b - l i n u x _ g a t e w a y _ p a g e )
2005-04-17 02:20:36 +04:00
.previous
/* Make sure nothing else is placed on this page */
2007-10-18 11:04:34 +04:00
.align PAGE_SIZE
2007-01-25 00:36:32 +03:00
END( l i n u x _ g a t e w a y _ p a g e )
ENTRY( e n d _ l i n u x _ g a t e w a y _ p a g e )
2005-04-17 02:20:36 +04:00
/ * Relocate s y m b o l s a s s u m i n g l i n u x _ g a t e w a y _ p a g e i s m a p p e d
to v i r t u a l a d d r e s s 0 x0 * /
2007-01-25 00:36:32 +03:00
2007-01-28 16:52:57 +03:00
# define L W S _ E N T R Y ( _ n a m e _ ) A S M _ U L O N G _ I N S N ( l w s _ ## _ n a m e _ - l i n u x _ g a t e w a y _ p a g e )
2005-04-17 02:20:36 +04:00
2006-01-13 23:21:06 +03:00
.section .rodata , " a"
2007-10-18 11:04:34 +04:00
.align PAGE_SIZE
2005-04-17 02:20:36 +04:00
/* Light-weight-syscall table */
/* Start of lws table. */
2007-01-25 00:36:32 +03:00
ENTRY( l w s _ t a b l e )
2005-04-17 02:20:36 +04:00
LWS_ E N T R Y ( c o m p a r e _ a n d _ s w a p32 ) / * 0 - E L F 3 2 A t o m i c c o m p a r e a n d s w a p * /
LWS_ E N T R Y ( c o m p a r e _ a n d _ s w a p64 ) / * 1 - E L F 6 4 A t o m i c c o m p a r e a n d s w a p * /
2007-01-25 00:36:32 +03:00
END( l w s _ t a b l e )
2005-04-17 02:20:36 +04:00
/* End of lws table */
2007-10-18 11:04:34 +04:00
.align PAGE_SIZE
2007-01-25 00:36:32 +03:00
ENTRY( s y s _ c a l l _ t a b l e )
2005-04-17 02:20:36 +04:00
# include " s y s c a l l _ t a b l e . S "
2007-01-25 00:36:32 +03:00
END( s y s _ c a l l _ t a b l e )
2005-04-17 02:20:36 +04:00
2005-10-22 06:46:48 +04:00
# ifdef C O N F I G _ 6 4 B I T
2007-10-18 11:04:34 +04:00
.align PAGE_SIZE
2007-01-25 00:36:32 +03:00
ENTRY( s y s _ c a l l _ t a b l e 6 4 )
2005-04-17 02:20:36 +04:00
# define S Y S C A L L _ T A B L E _ 6 4 B I T
# include " s y s c a l l _ t a b l e . S "
2007-01-25 00:36:32 +03:00
END( s y s _ c a l l _ t a b l e 6 4 )
2005-04-17 02:20:36 +04:00
# endif
# ifdef C O N F I G _ S M P
/ *
All l i g h t - w e i g h t - s y s c a l l a t o m i c o p e r a t i o n s
will u s e t h i s s e t o f l o c k s
2008-12-30 05:47:38 +03:00
NOTE : The l w s _ l o c k _ s t a r t s y m b o l m u s t b e
at l e a s t 1 6 - b y t e a l i g n e d f o r s a f e u s e
with l d c w .
2005-04-17 02:20:36 +04:00
* /
2008-05-22 22:36:31 +04:00
.section .data
2007-10-18 11:04:53 +04:00
.align PAGE_SIZE
2007-01-25 00:36:32 +03:00
ENTRY( l w s _ l o c k _ s t a r t )
2005-04-17 02:20:36 +04:00
/* lws locks */
.rept 16
/* Keep locks aligned at 16-bytes */
.word 1
.word 0
.word 0
.word 0
.endr
2007-01-25 00:36:32 +03:00
END( l w s _ l o c k _ s t a r t )
2005-04-17 02:20:36 +04:00
.previous
# endif
/* CONFIG_SMP for lws_lock_start */
.end