2006-11-27 12:06:26 +09:00
/ *
2005-04-16 15:20:36 -07:00
* copy_ p a g e , _ _ c o p y _ u s e r _ p a g e , _ _ c o p y _ u s e r i m p l e m e n t a t i o n o f S u p e r H
*
* Copyright ( C ) 2 0 0 1 N i i b e Y u t a k a & K a z K o j i m a
* Copyright ( C ) 2 0 0 2 T o s h i n o b u S u g i o k a
2006-11-27 12:06:26 +09:00
* Copyright ( C ) 2 0 0 6 P a u l M u n d t
2005-04-16 15:20:36 -07:00
* /
# include < l i n u x / l i n k a g e . h >
2006-11-27 12:06:26 +09:00
# include < a s m / p a g e . h >
2005-04-16 15:20:36 -07:00
/ *
2007-11-20 16:51:28 +09:00
* copy_ p a g e
2005-04-16 15:20:36 -07:00
* @to: P1 address
* @from: P1 address
*
2007-11-20 16:51:28 +09:00
* void c o p y _ p a g e ( v o i d * t o , v o i d * f r o m )
2005-04-16 15:20:36 -07:00
* /
/ *
* r0 , r1 , r2 , r3 , r4 , r5 , r6 , r7 - - - s c r a t c h
2006-11-27 12:06:26 +09:00
* r8 - - - f r o m + P A G E _ S I Z E
2005-04-16 15:20:36 -07:00
* r9 - - - n o t u s e d
* r1 0 - - - t o
* r1 1 - - - f r o m
* /
2007-11-20 16:51:28 +09:00
ENTRY( c o p y _ p a g e )
2005-04-16 15:20:36 -07:00
mov. l r8 ,@-r15
mov. l r10 ,@-r15
mov. l r11 ,@-r15
mov r4 ,r10
mov r5 ,r11
mov r5 ,r8
2009-09-08 16:23:08 +09:00
mov #( P A G E _ S I Z E > > 10 ) , r0
shll8 r0
shll2 r0
2005-04-16 15:20:36 -07:00
add r0 ,r8
!
1 : mov. l @r11+,r0
mov. l @r11+,r1
mov. l @r11+,r2
mov. l @r11+,r3
mov. l @r11+,r4
mov. l @r11+,r5
mov. l @r11+,r6
mov. l @r11+,r7
2008-03-21 18:07:04 +09:00
# if d e f i n e d ( C O N F I G _ C P U _ S H 4 )
2005-04-16 15:20:36 -07:00
movca. l r0 ,@r10
2008-03-21 18:07:04 +09:00
# else
mov. l r0 ,@r10
2005-04-16 15:20:36 -07:00
# endif
add #32 ,r10
mov. l r7 ,@-r10
mov. l r6 ,@-r10
mov. l r5 ,@-r10
mov. l r4 ,@-r10
mov. l r3 ,@-r10
mov. l r2 ,@-r10
mov. l r1 ,@-r10
cmp/ e q r11 ,r8
bf/ s 1 b
add #28 ,r10
!
mov. l @r15+,r11
mov. l @r15+,r10
mov. l @r15+,r8
rts
nop
/ *
* _ _ kernel_ s i z e _ t _ _ c o p y _ u s e r ( v o i d * t o , c o n s t v o i d * f r o m , _ _ k e r n e l _ s i z e _ t n ) ;
* Return t h e n u m b e r o f b y t e s N O T c o p i e d
* /
# define E X ( . . . ) \
9999 : _ _ VA_ A R G S _ _ ; \
.section _ _ ex_ t a b l e , " a " ; \
.long 9 9 9 9 b, 6 0 0 0 f ; \
.previous
2008-10-10 19:49:30 +01:00
# define E X _ N O _ P O P ( . . . ) \
9999 : _ _ VA_ A R G S _ _ ; \
.section _ _ ex_ t a b l e , " a " ; \
.long 9 9 9 9 b, 6 0 0 5 f ; \
.previous
2005-04-16 15:20:36 -07:00
ENTRY( _ _ c o p y _ u s e r )
2007-09-28 12:36:35 +09:00
! Check i f s m a l l n u m b e r o f b y t e s
mov #11 ,r0
2005-04-16 15:20:36 -07:00
mov r4 ,r3
2007-09-28 12:36:35 +09:00
cmp/ g t r0 ,r6 ! r6 ( l e n ) > r0 ( 1 1 )
bf/ s . L _ c l e a n u p _ l o o p _ n o _ p o p
add r6 ,r3 ! l a s t d e s t i n a t i o n a d d r e s s
! Calculate b y t e s n e e d e d t o a l i g n t o s r c
mov. l r11 ,@-r15
neg r5 ,r0
mov. l r10 ,@-r15
2005-04-16 15:20:36 -07:00
add #4 ,r0
2007-09-28 12:36:35 +09:00
mov. l r9 ,@-r15
2005-04-16 15:20:36 -07:00
and #3 ,r0
2007-09-28 12:36:35 +09:00
mov. l r8 ,@-r15
2005-04-16 15:20:36 -07:00
tst r0 ,r0
2007-09-28 12:36:35 +09:00
bt 2 f
2005-04-16 15:20:36 -07:00
2007-09-28 12:36:35 +09:00
1 :
! Copy b y t e s t o l o n g w o r d a l i g n s r c
EX( m o v . b @r5+,r1 )
dt r0
2005-04-16 15:20:36 -07:00
add #- 1 ,r6
2007-09-28 12:36:35 +09:00
EX( m o v . b r1 ,@r4 )
bf/ s 1 b
2005-04-16 15:20:36 -07:00
add #1 ,r4
2007-09-28 12:36:35 +09:00
! Jump t o a p p r o p r i a t e r o u t i n e d e p e n d i n g o n d e s t
2 : mov #3 ,r1
mov r6 , r2
and r4 ,r1
2005-04-16 15:20:36 -07:00
shlr2 r2
shll2 r1
mova . L _ j u m p _ t b l ,r0
mov. l @(r0,r1),r1
jmp @r1
nop
.align 2
.L_jump_tbl :
.long .L_dest00
.long .L_dest01
.long .L_dest10
.long .L_dest11
2007-09-28 12:36:35 +09:00
/ *
* Come h e r e i f t h e r e a r e l e s s t h a n 1 2 b y t e s t o c o p y
*
* Keep t h e b r a n c h t a r g e t c l o s e , s o t h e b f / s c a l l e e d o e s n ' t o v e r f l o w
* and r e s u l t i n a m o r e e x p e n s i v e b r a n c h b e i n g i n s e r t e d . T h i s i s t h e
* fast- p a t h f o r s m a l l c o p i e s , t h e j u m p v i a t h e j u m p t a b l e w i l l h i t t h e
* default s l o w - p a t h c l e a n u p . - P F M .
* /
.L_cleanup_loop_no_pop :
tst r6 ,r6 ! C h e c k e x p l i c i t l y f o r z e r o
bt 1 f
2 :
2008-10-10 19:49:30 +01:00
EX_ N O _ P O P ( m o v . b @r5+,r0 )
2007-09-28 12:36:35 +09:00
dt r6
2008-10-10 19:49:30 +01:00
EX_ N O _ P O P ( m o v . b r0 ,@r4 )
2007-09-28 12:36:35 +09:00
bf/ s 2 b
add #1 ,r4
1 : mov #0 ,r0 ! n o r m a l r e t u r n
5000 :
# Exception h a n d l e r :
.section .fixup , " ax"
2008-10-10 19:49:30 +01:00
6005 :
2007-09-28 12:36:35 +09:00
mov. l 8 0 0 0 f ,r1
mov r3 ,r0
jmp @r1
sub r4 ,r0
.align 2
8000 : .long 5000 b
.previous
rts
nop
2005-04-16 15:20:36 -07:00
! Destination = 0 0
.L_dest00 :
2007-09-28 12:36:35 +09:00
! Skip t h e l a r g e c o p y f o r s m a l l t r a n s f e r s
mov #( 32 + 3 2 - 4 ) , r0
cmp/ g t r6 , r0 ! r0 ( 6 0 ) > r6 ( l e n )
bt 1 f
! Align d e s t t o a 3 2 b y t e b o u n d a r y
neg r4 ,r0
add #0x20 , r0
and #0x1f , r0
tst r0 , r0
bt 2 f
sub r0 , r6
shlr2 r0
3 :
EX( m o v . l @r5+,r1 )
dt r0
EX( m o v . l r1 ,@r4 )
bf/ s 3 b
add #4 ,r4
2005-04-16 15:20:36 -07:00
2 :
EX( m o v . l @r5+,r0 )
2007-09-28 12:36:35 +09:00
EX( m o v . l @r5+,r1 )
EX( m o v . l @r5+,r2 )
EX( m o v . l @r5+,r7 )
2005-04-16 15:20:36 -07:00
EX( m o v . l @r5+,r8 )
EX( m o v . l @r5+,r9 )
EX( m o v . l @r5+,r10 )
2007-09-28 12:36:35 +09:00
EX( m o v . l @r5+,r11 )
2007-11-02 12:14:09 +09:00
# ifdef C O N F I G _ C P U _ S H 4
2007-09-28 12:36:35 +09:00
EX( m o v c a . l r0 ,@r4 )
2007-11-02 12:14:09 +09:00
# else
EX( m o v . l r0 ,@r4 )
# endif
2007-09-28 12:36:35 +09:00
add #- 32 , r6
EX( m o v . l r1 ,@(4,r4) )
mov #32 , r0
EX( m o v . l r2 ,@(8,r4) )
cmp/ g t r6 , r0 ! r0 ( 3 2 ) > r6 ( l e n )
EX( m o v . l r7 ,@(12,r4) )
EX( m o v . l r8 ,@(16,r4) )
EX( m o v . l r9 ,@(20,r4) )
EX( m o v . l r10 ,@(24,r4) )
EX( m o v . l r11 ,@(28,r4) )
2005-04-16 15:20:36 -07:00
bf/ s 2 b
add #32 ,r4
2007-09-28 12:36:35 +09:00
1 : mov r6 , r0
shlr2 r0
tst r0 , r0
2005-04-16 15:20:36 -07:00
bt . L _ c l e a n u p
1 :
2007-09-28 12:36:35 +09:00
EX( m o v . l @r5+,r1 )
dt r0
EX( m o v . l r1 ,@r4 )
2005-04-16 15:20:36 -07:00
bf/ s 1 b
add #4 ,r4
bra . L _ c l e a n u p
nop
! Destination = 1 0
.L_dest10 :
mov r2 ,r7
shlr2 r7
shlr r7
tst r7 ,r7
mov #7 ,r0
bt/ s 1 f
and r0 ,r2
2 :
dt r7
2007-09-28 12:36:35 +09:00
# ifdef C O N F I G _ C P U _ L I T T L E _ E N D I A N
2005-04-16 15:20:36 -07:00
EX( m o v . l @r5+,r0 )
EX( m o v . l @r5+,r1 )
EX( m o v . l @r5+,r8 )
EX( m o v . l @r5+,r9 )
EX( m o v . l @r5+,r10 )
EX( m o v . w r0 ,@r4 )
add #2 ,r4
xtrct r1 ,r0
xtrct r8 ,r1
xtrct r9 ,r8
xtrct r10 ,r9
EX( m o v . l r0 ,@r4 )
EX( m o v . l r1 ,@(4,r4) )
EX( m o v . l r8 ,@(8,r4) )
EX( m o v . l r9 ,@(12,r4) )
EX( m o v . l @r5+,r1 )
EX( m o v . l @r5+,r8 )
EX( m o v . l @r5+,r0 )
xtrct r1 ,r10
xtrct r8 ,r1
xtrct r0 ,r8
shlr1 6 r0
EX( m o v . l r10 ,@(16,r4) )
EX( m o v . l r1 ,@(20,r4) )
EX( m o v . l r8 ,@(24,r4) )
EX( m o v . w r0 ,@(28,r4) )
bf/ s 2 b
add #30 ,r4
# else
EX( m o v . l @(28,r5),r0 )
EX( m o v . l @(24,r5),r8 )
EX( m o v . l @(20,r5),r9 )
EX( m o v . l @(16,r5),r10 )
EX( m o v . w r0 ,@(30,r4) )
add #- 2 ,r4
xtrct r8 ,r0
xtrct r9 ,r8
xtrct r10 ,r9
EX( m o v . l r0 ,@(28,r4) )
EX( m o v . l r8 ,@(24,r4) )
EX( m o v . l r9 ,@(20,r4) )
EX( m o v . l @(12,r5),r0 )
EX( m o v . l @(8,r5),r8 )
xtrct r0 ,r10
EX( m o v . l @(4,r5),r9 )
mov. l r10 ,@(16,r4)
EX( m o v . l @r5,r10 )
xtrct r8 ,r0
xtrct r9 ,r8
xtrct r10 ,r9
EX( m o v . l r0 ,@(12,r4) )
EX( m o v . l r8 ,@(8,r4) )
swap. w r10 ,r0
EX( m o v . l r9 ,@(4,r4) )
EX( m o v . w r0 ,@(2,r4) )
add #32 ,r5
bf/ s 2 b
add #34 ,r4
# endif
tst r2 ,r2
bt . L _ c l e a n u p
1 : ! Read l o n g w o r d , w r i t e t w o w o r d s p e r i t e r a t i o n
EX( m o v . l @r5+,r0 )
dt r2
2007-09-28 12:36:35 +09:00
# ifdef C O N F I G _ C P U _ L I T T L E _ E N D I A N
2005-04-16 15:20:36 -07:00
EX( m o v . w r0 ,@r4 )
shlr1 6 r0
EX( m o v . w r0 ,@(2,r4) )
# else
EX( m o v . w r0 ,@(2,r4) )
shlr1 6 r0
EX( m o v . w r0 ,@r4 )
# endif
bf/ s 1 b
add #4 ,r4
bra . L _ c l e a n u p
nop
! Destination = 0 1 o r 1 1
.L_dest01 :
.L_dest11 :
! Read l o n g w o r d , w r i t e b y t e , w o r d , b y t e p e r i t e r a t i o n
EX( m o v . l @r5+,r0 )
dt r2
2007-09-28 12:36:35 +09:00
# ifdef C O N F I G _ C P U _ L I T T L E _ E N D I A N
2005-04-16 15:20:36 -07:00
EX( m o v . b r0 ,@r4 )
shlr8 r0
add #1 ,r4
EX( m o v . w r0 ,@r4 )
shlr1 6 r0
EX( m o v . b r0 ,@(2,r4) )
bf/ s . L _ d e s t 0 1
add #3 ,r4
# else
EX( m o v . b r0 ,@(3,r4) )
shlr8 r0
swap. w r0 ,r7
EX( m o v . b r7 ,@r4 )
add #1 ,r4
EX( m o v . w r0 ,@r4 )
bf/ s . L _ d e s t 0 1
add #3 ,r4
# endif
! Cleanup l a s t f e w b y t e s
.L_cleanup :
mov r6 ,r0
and #3 ,r0
tst r0 ,r0
bt . L _ e x i t
mov r0 ,r6
.L_cleanup_loop :
EX( m o v . b @r5+,r0 )
dt r6
EX( m o v . b r0 ,@r4 )
bf/ s . L _ c l e a n u p _ l o o p
add #1 ,r4
.L_exit :
mov #0 ,r0 ! n o r m a l r e t u r n
2007-09-28 12:36:35 +09:00
2005-04-16 15:20:36 -07:00
5000 :
# Exception h a n d l e r :
.section .fixup , " ax"
6000 :
mov. l 8 0 0 0 f ,r1
mov r3 ,r0
jmp @r1
sub r4 ,r0
.align 2
8000 : .long 5000 b
.previous
mov. l @r15+,r8
mov. l @r15+,r9
2007-09-28 12:36:35 +09:00
mov. l @r15+,r10
2005-04-16 15:20:36 -07:00
rts
2007-09-28 12:36:35 +09:00
mov. l @r15+,r11