2005-04-17 02:20:36 +04:00
/ *
* linux/ a r c h / a r m / k e r n e l / e n t r y - c o m m o n . S
*
* Copyright ( C ) 2 0 0 0 R u s s e l l K i n g
*
* 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 s
* published 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 .
* /
# include < l i n u x / c o n f i g . h >
# include < a s m / u n i s t d . h >
# include " e n t r y - h e a d e r . S "
.align 5
/ *
* This i s t h e f a s t s y s c a l l r e t u r n p a t h . W e d o a s l i t t l e a s
* possible h e r e , a n d t h i s i n c l u d e s s a v i n g r0 b a c k i n t o t h e S V C
* stack.
* /
ret_fast_syscall :
2005-04-26 18:18:26 +04:00
disable_ i r q @ disable interrupts
2005-04-17 02:20:36 +04:00
ldr r1 , [ t s k , #T I _ F L A G S ]
tst r1 , #_ T I F _ W O R K _ M A S K
bne f a s t _ w o r k _ p e n d i n g
2005-04-26 18:20:34 +04:00
@ fast_restore_user_regs
ldr r1 , [ s p , #S _ O F F + S _ P S R ] @ g e t c a l l i n g c p s r
ldr l r , [ s p , #S _ O F F + S _ P C ] ! @ g e t p c
msr s p s r _ c x s f , r1 @ save in spsr_svc
ldmdb s p , { r1 - l r } ^ @ get calling r1 - lr
mov r0 , r0
add s p , s p , #S _ F R A M E _ S I Z E - S _ P C
movs p c , l r @ return & move spsr_svc into cpsr
2005-04-17 02:20:36 +04:00
/ *
* Ok, w e n e e d t o d o e x t r a p r o c e s s i n g , e n t e r t h e s l o w p a t h .
* /
fast_work_pending :
str r0 , [ s p , #S _ R 0 + S _ O F F ] ! @ returned r0
work_pending :
tst r1 , #_ T I F _ N E E D _ R E S C H E D
bne w o r k _ r e s c h e d
tst r1 , #_ T I F _ N O T I F Y _ R E S U M E | _ T I F _ S I G P E N D I N G
beq n o _ w o r k _ p e n d i n g
mov r0 , s p @ 'regs'
mov r2 , w h y @ 'syscall'
bl d o _ n o t i f y _ r e s u m e
2005-11-19 13:01:07 +03:00
b r e t _ s l o w _ s y s c a l l @ Check work again
2005-04-17 02:20:36 +04:00
work_resched :
bl s c h e d u l e
/ *
* " slow" s y s c a l l r e t u r n p a t h . " w h y " t e l l s u s i f t h i s w a s a r e a l s y s c a l l .
* /
ENTRY( r e t _ t o _ u s e r )
ret_slow_syscall :
2005-04-26 18:18:26 +04:00
disable_ i r q @ disable interrupts
2005-04-17 02:20:36 +04:00
ldr r1 , [ t s k , #T I _ F L A G S ]
tst r1 , #_ T I F _ W O R K _ M A S K
bne w o r k _ p e n d i n g
no_work_pending :
2005-04-26 18:20:34 +04:00
@ slow_restore_user_regs
ldr r1 , [ s p , #S _ P S R ] @ g e t c a l l i n g c p s r
ldr l r , [ s p , #S _ P C ] ! @ g e t p c
msr s p s r _ c x s f , r1 @ save in spsr_svc
ldmdb s p , { r0 - l r } ^ @ get calling r1 - lr
mov r0 , r0
add s p , s p , #S _ F R A M E _ S I Z E - S _ P C
movs p c , l r @ return & move spsr_svc into cpsr
2005-04-17 02:20:36 +04:00
/ *
* This i s h o w w e r e t u r n f r o m a f o r k .
* /
ENTRY( r e t _ f r o m _ f o r k )
bl s c h e d u l e _ t a i l
get_ t h r e a d _ i n f o t s k
ldr r1 , [ t s k , #T I _ F L A G S ] @ c h e c k f o r s y s c a l l t r a c i n g
mov w h y , #1
tst r1 , #_ T I F _ S Y S C A L L _ T R A C E @ a r e w e t r a c i n g s y s c a l l s ?
beq r e t _ s l o w _ s y s c a l l
mov r1 , s p
mov r0 , #1 @ trace exit [IP = 1]
bl s y s c a l l _ t r a c e
b r e t _ s l o w _ s y s c a l l
# include " c a l l s . S "
/ * = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
* SWI h a n d l e r
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
* /
/ * If w e ' r e o p t i m i s i n g f o r S t r o n g A R M t h e r e s u l t i n g c o d e w o n ' t
run o n a n A R M 7 a n d w e c a n s a v e a c o u p l e o f i n s t r u c t i o n s .
- - pb * /
# ifdef C O N F I G _ C P U _ A R M 7 1 0
.macro arm7 1 0 _ b u g _ c h e c k , i n s t r , t e m p
and \ t e m p , \ i n s t r , #0x0f000000 @ check for SWI
teq \ t e m p , #0x0f000000
bne . L a r m 7 0 0 b u g
.endm
.Larm700bug :
ldmia s p , { r0 - l r } ^ @ Get calling r0 - lr
mov r0 , r0
add s p , s p , #S _ F R A M E _ S I Z E
2005-10-12 22:51:24 +04:00
subs p c , l r , #4
2005-04-17 02:20:36 +04:00
# else
.macro arm7 1 0 _ b u g _ c h e c k , i n s t r , t e m p
.endm
# endif
.align 5
ENTRY( v e c t o r _ s w i )
2005-04-26 18:20:34 +04:00
sub s p , s p , #S _ F R A M E _ S I Z E
stmia s p , { r0 - r12 } @ Calling r0 - r12
add r8 , s p , #S _ P C
stmdb r8 , { s p , l r } ^ @ Calling sp, lr
mrs r8 , s p s r @ called from non-FIQ mode, so ok.
str l r , [ s p , #S _ P C ] @ S a v e c a l l i n g P C
str r8 , [ s p , #S _ P S R ] @ S a v e C P S R
str r0 , [ s p , #S _ O L D _ R 0 ] @ Save OLD_R0
2005-04-17 02:20:36 +04:00
zero_ f p
2005-04-26 18:19:24 +04:00
/ *
* Get t h e s y s t e m c a l l n u m b e r .
* /
# ifdef C O N F I G _ A R M _ T H U M B
tst r8 , #P S R _ T _ B I T @ t h i s i s S P S R f r o m s a v e _ u s e r _ r e g s
addne s c n o , r7 , #_ _ N R _ S Y S C A L L _ B A S E @ p u t O S n u m b e r i n
ldreq s c n o , [ l r , #- 4 ]
# else
ldr s c n o , [ l r , #- 4 ] @ get SWI instruction
# endif
2005-04-17 02:20:36 +04:00
arm7 1 0 _ b u g _ c h e c k s c n o , i p
# ifdef C O N F I G _ A L I G N M E N T _ T R A P
ldr i p , _ _ c r _ a l i g n m e n t
ldr i p , [ i p ]
mcr p15 , 0 , i p , c1 , c0 @ update control register
# endif
2005-04-26 18:18:26 +04:00
enable_ i r q
2005-04-17 02:20:36 +04:00
str r4 , [ s p , #- S _ O F F ] ! @ p u s h f i f t h a r g
get_ t h r e a d _ i n f o t s k
ldr i p , [ t s k , #T I _ F L A G S ] @ c h e c k f o r s y s c a l l t r a c i n g
bic s c n o , s c n o , #0xff000000 @ mask off SWI op-code
2005-04-26 18:19:24 +04:00
eor s c n o , s c n o , #_ _ N R _ S Y S C A L L _ B A S E @ c h e c k O S n u m b e r
2005-04-17 02:20:36 +04:00
adr t b l , s y s _ c a l l _ t a b l e @ load syscall table pointer
tst i p , #_ T I F _ S Y S C A L L _ T R A C E @ a r e w e t r a c i n g s y s c a l l s ?
bne _ _ s y s _ t r a c e
adr l r , r e t _ f a s t _ s y s c a l l @ return address
cmp s c n o , #N R _ s y s c a l l s @ c h e c k u p p e r s y s c a l l l i m i t
ldrcc p c , [ t b l , s c n o , l s l #2 ] @ call sys_* routine
add r1 , s p , #S _ O F F
2 : mov w h y , #0 @ no longer a real syscall
2005-04-26 18:19:24 +04:00
cmp s c n o , #( _ _ A R M _ N R _ B A S E - _ _ N R _ S Y S C A L L _ B A S E )
eor r0 , s c n o , #_ _ N R _ S Y S C A L L _ B A S E @ p u t O S n u m b e r b a c k
2005-04-17 02:20:36 +04:00
bcs a r m _ s y s c a l l
b s y s _ n i _ s y s c a l l @ not private func
/ *
* This i s t h e r e a l l y s l o w p a t h . W e ' r e g o i n g t o b e d o i n g
* context s w i t c h e s , a n d w a i t i n g f o r o u r p a r e n t t o r e s p o n d .
* /
__sys_trace :
add r1 , s p , #S _ O F F
mov r0 , #0 @ trace entry [IP = 0]
bl s y s c a l l _ t r a c e
adr l r , _ _ s y s _ t r a c e _ r e t u r n @ return address
add r1 , s p , #S _ R 0 + S _ O F F @ pointer to regs
cmp s c n o , #N R _ s y s c a l l s @ c h e c k u p p e r s y s c a l l l i m i t
ldmccia r1 , { r0 - r3 } @ have to reload r0 - r3
ldrcc p c , [ t b l , s c n o , l s l #2 ] @ call sys_* routine
b 2 b
__sys_trace_return :
str r0 , [ s p , #S _ R 0 + S _ O F F ] ! @ save returned r0
mov r1 , s p
mov r0 , #1 @ trace exit [IP = 1]
bl s y s c a l l _ t r a c e
b r e t _ s l o w _ s y s c a l l
.align 5
# ifdef C O N F I G _ A L I G N M E N T _ T R A P
.type _ _ cr_ a l i g n m e n t , #o b j e c t
__cr_alignment :
.word cr_alignment
# endif
.type sys_ c a l l _ t a b l e , #o b j e c t
ENTRY( s y s _ c a l l _ t a b l e )
# include " c a l l s . S "
/ * = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
* Special s y s t e m c a l l w r a p p e r s
* /
@ r0 = syscall number
@ r5 = syscall table
.type sys_ s y s c a l l , #f u n c t i o n
sys_syscall :
2005-04-26 18:19:24 +04:00
eor s c n o , r0 , #_ _ N R _ S Y S C A L L _ B A S E
2005-04-17 02:20:36 +04:00
cmp s c n o , #_ _ N R _ s y s c a l l - _ _ N R _ S Y S C A L L _ B A S E
cmpne s c n o , #N R _ s y s c a l l s @ c h e c k r a n g e
stmloia s p , { r5 , r6 } @ shuffle args
movlo r0 , r1
movlo r1 , r2
movlo r2 , r3
movlo r3 , r4
ldrlo p c , [ t b l , s c n o , l s l #2 ]
b s y s _ n i _ s y s c a l l
sys_fork_wrapper :
add r0 , s p , #S _ O F F
b s y s _ f o r k
sys_vfork_wrapper :
add r0 , s p , #S _ O F F
b s y s _ v f o r k
sys_execve_wrapper :
add r3 , s p , #S _ O F F
b s y s _ e x e c v e
sys_clone_wrapper :
add i p , s p , #S _ O F F
str i p , [ s p , #4 ]
b s y s _ c l o n e
sys_sigsuspend_wrapper :
add r3 , s p , #S _ O F F
b s y s _ s i g s u s p e n d
sys_rt_sigsuspend_wrapper :
add r2 , s p , #S _ O F F
b s y s _ r t _ s i g s u s p e n d
sys_sigreturn_wrapper :
add r0 , s p , #S _ O F F
b s y s _ s i g r e t u r n
sys_rt_sigreturn_wrapper :
add r0 , s p , #S _ O F F
b s y s _ r t _ s i g r e t u r n
sys_sigaltstack_wrapper :
ldr r2 , [ s p , #S _ O F F + S _ S P ]
b d o _ s i g a l t s t a c k
sys_futex_wrapper :
str r5 , [ s p , #4 ] @ push sixth arg
b s y s _ f u t e x
2005-09-01 15:37:13 +04:00
sys_arm_fadvise64_64_wrapper :
str r5 , [ s p , #4 ] @ push r5 to stack
b s y s _ a r m _ f a d v i s e 6 4 _ 6 4
2005-09-09 21:35:12 +04:00
sys_mbind_wrapper :
str r5 , [ s p , #4 ]
b s y s _ m b i n d
2005-09-14 01:55:00 +04:00
sys_ipc_wrapper :
str r5 , [ s p , #4 ] @ push sixth arg
b s y s _ i p c
2005-04-17 02:20:36 +04:00
/ *
* Note : off_ 4 k ( r5 ) i s a l w a y s u n i t s o f 4 K . I f w e c a n ' t d o t h e r e q u e s t e d
* offset, w e r e t u r n E I N V A L .
* /
sys_mmap2 :
# if P A G E _ S H I F T > 1 2
tst r5 , #P G O F F _ M A S K
moveq r5 , r5 , l s r #P A G E _ S H I F T - 12
streq r5 , [ s p , #4 ]
beq d o _ m m a p2
mov r0 , #- E I N V A L
RETINSTR( m o v ,p c , l r )
# else
str r5 , [ s p , #4 ]
b d o _ m m a p2
# endif