2012-08-13 11:44:13 +01:00
/ *
* linux/ a r c h / a r m / l i b / u a c c e s s . S
*
* Copyright ( C ) 1 9 9 5 , 1 9 9 6 ,1 9 9 7 ,1 9 9 8 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 .
*
* Routines t o b l o c k c o p y d a t a t o / f r o m u s e r m e m o r y
* These a r e h i g h l y o p t i m i s e d b o t h f o r t h e 4 k p a g e s i z e
* and f o r v a r i o u s a l i g n m e n t s .
* /
# include < l i n u x / l i n k a g e . h >
# include < a s m / a s s e m b l e r . h >
# include < a s m / e r r n o . h >
# include < a s m / d o m a i n . h >
.text
# define P A G E _ S H I F T 1 2
/ * Prototype : int _ _ c o p y _ t o _ u s e r ( v o i d * t o , c o n s t c h a r * f r o m , s i z e _ t n )
* Purpose : c o p y a b l o c k t o u s e r m e m o r y f r o m k e r n e l m e m o r y
* Params : t o - u s e r m e m o r y
* : from - k e r n e l m e m o r y
* : n - n u m b e r o f b y t e s t o c o p y
* Returns : N u m b e r o f b y t e s N O T c o p i e d .
* /
.Lc2u_dest_not_aligned :
rsb i p , i p , #4
cmp i p , #2
ldrb r3 , [ r1 ] , #1
USER( T U S E R ( s t r b ) r3 , [ r0 ] , #1 ) @ May fault
ldrgeb r3 , [ r1 ] , #1
USER( T U S E R ( s t r g e b ) r3 , [ r0 ] , #1 ) @ May fault
ldrgtb r3 , [ r1 ] , #1
USER( T U S E R ( s t r g t b ) r3 , [ r0 ] , #1 ) @ May fault
sub r2 , r2 , i p
b . L c2 u _ d e s t _ a l i g n e d
ENTRY( _ _ c o p y _ t o _ u s e r )
stmfd s p ! , { r2 , r4 - r7 , l r }
cmp r2 , #4
blt . L c2 u _ n o t _ e n o u g h
ands i p , r0 , #3
bne . L c2 u _ d e s t _ n o t _ a l i g n e d
.Lc2u_dest_aligned :
ands i p , r1 , #3
bne . L c2 u _ s r c _ n o t _ a l i g n e d
/ *
* Seeing a s t h e r e h a s t o b e a t l e a s t 8 b y t e s t o c o p y , w e c a n
* copy o n e w o r d , a n d f o r c e a u s e r - m o d e p a g e f a u l t . . .
* /
.Lc2u_0fupi : subs r2 , r2 , #4
addmi i p , r2 , #4
bmi . L c2 u _ 0 n o w o r d s
ldr r3 , [ r1 ] , #4
USER( T U S E R ( s t r ) r3 , [ r0 ] , #4 ) @ May fault
mov i p , r0 , l s l #32 - P A G E _ S H I F T @ On each page, use a ld/st??t instruction
rsb i p , i p , #0
movs i p , i p , l s r #32 - P A G E _ S H I F T
beq . L c2 u _ 0 f u p i
/ *
* ip = m a x n o . o f b y t e s t o c o p y b e f o r e n e e d i n g a n o t h e r " s t r t " i n s n
* /
cmp r2 , i p
movlt i p , r2
sub r2 , r2 , i p
subs i p , i p , #32
blt . L c2 u _ 0 r e m 8 l p
.Lc2u_0cpy8lp : ldmia r1 ! , { r3 - r6 }
stmia r0 ! , { r3 - r6 } @ Shouldnt fault
ldmia r1 ! , { r3 - r6 }
subs i p , i p , #32
stmia r0 ! , { r3 - r6 } @ Shouldnt fault
bpl . L c2 u _ 0 c p y 8 l p
.Lc2u_0rem8lp : cmn i p , #16
ldmgeia r1 ! , { r3 - r6 }
stmgeia r0 ! , { r3 - r6 } @ Shouldnt fault
tst i p , #8
ldmneia r1 ! , { r3 - r4 }
stmneia r0 ! , { r3 - r4 } @ Shouldnt fault
tst i p , #4
ldrne r3 , [ r1 ] , #4
TUSER( s t r n e ) r3 , [ r0 ] , #4 @ Shouldnt fault
ands i p , i p , #3
beq . L c2 u _ 0 f u p i
.Lc2u_0nowords : teq i p , #0
beq . L c2 u _ f i n i s h e d
.Lc2u_nowords : cmp i p , #2
ldrb r3 , [ r1 ] , #1
USER( T U S E R ( s t r b ) r3 , [ r0 ] , #1 ) @ May fault
ldrgeb r3 , [ r1 ] , #1
USER( T U S E R ( s t r g e b ) r3 , [ r0 ] , #1 ) @ May fault
ldrgtb r3 , [ r1 ] , #1
USER( T U S E R ( s t r g t b ) r3 , [ r0 ] , #1 ) @ May fault
b . L c2 u _ f i n i s h e d
.Lc2u_not_enough :
movs i p , r2
bne . L c2 u _ n o w o r d s
.Lc2u_finished : mov r0 , #0
ldmfd s p ! , { r2 , r4 - r7 , p c }
.Lc2u_src_not_aligned :
bic r1 , r1 , #3
ldr r7 , [ r1 ] , #4
cmp i p , #2
bgt . L c2 u _ 3 f u p i
beq . L c2 u _ 2 f u p i
.Lc2u_1fupi : subs r2 , r2 , #4
addmi i p , r2 , #4
bmi . L c2 u _ 1 n o w o r d s
2014-02-25 08:41:09 +01:00
mov r3 , r7 , l s p u l l #8
2012-08-13 11:44:13 +01:00
ldr r7 , [ r1 ] , #4
2014-02-25 08:41:09 +01:00
orr r3 , r3 , r7 , l s p u s h #24
2012-08-13 11:44:13 +01:00
USER( T U S E R ( s t r ) r3 , [ r0 ] , #4 ) @ May fault
mov i p , r0 , l s l #32 - P A G E _ S H I F T
rsb i p , i p , #0
movs i p , i p , l s r #32 - P A G E _ S H I F T
beq . L c2 u _ 1 f u p i
cmp r2 , i p
movlt i p , r2
sub r2 , r2 , i p
subs i p , i p , #16
blt . L c2 u _ 1 r e m 8 l p
2014-02-25 08:41:09 +01:00
.Lc2u_1cpy8lp : mov r3 , r7 , l s p u l l #8
2012-08-13 11:44:13 +01:00
ldmia r1 ! , { r4 - r7 }
subs i p , i p , #16
2014-02-25 08:41:09 +01:00
orr r3 , r3 , r4 , l s p u s h #24
mov r4 , r4 , l s p u l l #8
orr r4 , r4 , r5 , l s p u s h #24
mov r5 , r5 , l s p u l l #8
orr r5 , r5 , r6 , l s p u s h #24
mov r6 , r6 , l s p u l l #8
orr r6 , r6 , r7 , l s p u s h #24
2012-08-13 11:44:13 +01:00
stmia r0 ! , { r3 - r6 } @ Shouldnt fault
bpl . L c2 u _ 1 c p y 8 l p
.Lc2u_1rem8lp : tst i p , #8
2014-02-25 08:41:09 +01:00
movne r3 , r7 , l s p u l l #8
2012-08-13 11:44:13 +01:00
ldmneia r1 ! , { r4 , r7 }
2014-02-25 08:41:09 +01:00
orrne r3 , r3 , r4 , l s p u s h #24
movne r4 , r4 , l s p u l l #8
orrne r4 , r4 , r7 , l s p u s h #24
2012-08-13 11:44:13 +01:00
stmneia r0 ! , { r3 - r4 } @ Shouldnt fault
tst i p , #4
2014-02-25 08:41:09 +01:00
movne r3 , r7 , l s p u l l #8
2012-08-13 11:44:13 +01:00
ldrne r7 , [ r1 ] , #4
2014-02-25 08:41:09 +01:00
orrne r3 , r3 , r7 , l s p u s h #24
2012-08-13 11:44:13 +01:00
TUSER( s t r n e ) r3 , [ r0 ] , #4 @ Shouldnt fault
ands i p , i p , #3
beq . L c2 u _ 1 f u p i
.Lc2u_1nowords : mov r3 , r7 , g e t _ b y t e _ 1
teq i p , #0
beq . L c2 u _ f i n i s h e d
cmp i p , #2
USER( T U S E R ( s t r b ) r3 , [ r0 ] , #1 ) @ May fault
movge r3 , r7 , g e t _ b y t e _ 2
USER( T U S E R ( s t r g e b ) r3 , [ r0 ] , #1 ) @ May fault
movgt r3 , r7 , g e t _ b y t e _ 3
USER( T U S E R ( s t r g t b ) r3 , [ r0 ] , #1 ) @ May fault
b . L c2 u _ f i n i s h e d
.Lc2u_2fupi : subs r2 , r2 , #4
addmi i p , r2 , #4
bmi . L c2 u _ 2 n o w o r d s
2014-02-25 08:41:09 +01:00
mov r3 , r7 , l s p u l l #16
2012-08-13 11:44:13 +01:00
ldr r7 , [ r1 ] , #4
2014-02-25 08:41:09 +01:00
orr r3 , r3 , r7 , l s p u s h #16
2012-08-13 11:44:13 +01:00
USER( T U S E R ( s t r ) r3 , [ r0 ] , #4 ) @ May fault
mov i p , r0 , l s l #32 - P A G E _ S H I F T
rsb i p , i p , #0
movs i p , i p , l s r #32 - P A G E _ S H I F T
beq . L c2 u _ 2 f u p i
cmp r2 , i p
movlt i p , r2
sub r2 , r2 , i p
subs i p , i p , #16
blt . L c2 u _ 2 r e m 8 l p
2014-02-25 08:41:09 +01:00
.Lc2u_2cpy8lp : mov r3 , r7 , l s p u l l #16
2012-08-13 11:44:13 +01:00
ldmia r1 ! , { r4 - r7 }
subs i p , i p , #16
2014-02-25 08:41:09 +01:00
orr r3 , r3 , r4 , l s p u s h #16
mov r4 , r4 , l s p u l l #16
orr r4 , r4 , r5 , l s p u s h #16
mov r5 , r5 , l s p u l l #16
orr r5 , r5 , r6 , l s p u s h #16
mov r6 , r6 , l s p u l l #16
orr r6 , r6 , r7 , l s p u s h #16
2012-08-13 11:44:13 +01:00
stmia r0 ! , { r3 - r6 } @ Shouldnt fault
bpl . L c2 u _ 2 c p y 8 l p
.Lc2u_2rem8lp : tst i p , #8
2014-02-25 08:41:09 +01:00
movne r3 , r7 , l s p u l l #16
2012-08-13 11:44:13 +01:00
ldmneia r1 ! , { r4 , r7 }
2014-02-25 08:41:09 +01:00
orrne r3 , r3 , r4 , l s p u s h #16
movne r4 , r4 , l s p u l l #16
orrne r4 , r4 , r7 , l s p u s h #16
2012-08-13 11:44:13 +01:00
stmneia r0 ! , { r3 - r4 } @ Shouldnt fault
tst i p , #4
2014-02-25 08:41:09 +01:00
movne r3 , r7 , l s p u l l #16
2012-08-13 11:44:13 +01:00
ldrne r7 , [ r1 ] , #4
2014-02-25 08:41:09 +01:00
orrne r3 , r3 , r7 , l s p u s h #16
2012-08-13 11:44:13 +01:00
TUSER( s t r n e ) r3 , [ r0 ] , #4 @ Shouldnt fault
ands i p , i p , #3
beq . L c2 u _ 2 f u p i
.Lc2u_2nowords : mov r3 , r7 , g e t _ b y t e _ 2
teq i p , #0
beq . L c2 u _ f i n i s h e d
cmp i p , #2
USER( T U S E R ( s t r b ) r3 , [ r0 ] , #1 ) @ May fault
movge r3 , r7 , g e t _ b y t e _ 3
USER( T U S E R ( s t r g e b ) r3 , [ r0 ] , #1 ) @ May fault
ldrgtb r3 , [ r1 ] , #0
USER( T U S E R ( s t r g t b ) r3 , [ r0 ] , #1 ) @ May fault
b . L c2 u _ f i n i s h e d
.Lc2u_3fupi : subs r2 , r2 , #4
addmi i p , r2 , #4
bmi . L c2 u _ 3 n o w o r d s
2014-02-25 08:41:09 +01:00
mov r3 , r7 , l s p u l l #24
2012-08-13 11:44:13 +01:00
ldr r7 , [ r1 ] , #4
2014-02-25 08:41:09 +01:00
orr r3 , r3 , r7 , l s p u s h #8
2012-08-13 11:44:13 +01:00
USER( T U S E R ( s t r ) r3 , [ r0 ] , #4 ) @ May fault
mov i p , r0 , l s l #32 - P A G E _ S H I F T
rsb i p , i p , #0
movs i p , i p , l s r #32 - P A G E _ S H I F T
beq . L c2 u _ 3 f u p i
cmp r2 , i p
movlt i p , r2
sub r2 , r2 , i p
subs i p , i p , #16
blt . L c2 u _ 3 r e m 8 l p
2014-02-25 08:41:09 +01:00
.Lc2u_3cpy8lp : mov r3 , r7 , l s p u l l #24
2012-08-13 11:44:13 +01:00
ldmia r1 ! , { r4 - r7 }
subs i p , i p , #16
2014-02-25 08:41:09 +01:00
orr r3 , r3 , r4 , l s p u s h #8
mov r4 , r4 , l s p u l l #24
orr r4 , r4 , r5 , l s p u s h #8
mov r5 , r5 , l s p u l l #24
orr r5 , r5 , r6 , l s p u s h #8
mov r6 , r6 , l s p u l l #24
orr r6 , r6 , r7 , l s p u s h #8
2012-08-13 11:44:13 +01:00
stmia r0 ! , { r3 - r6 } @ Shouldnt fault
bpl . L c2 u _ 3 c p y 8 l p
.Lc2u_3rem8lp : tst i p , #8
2014-02-25 08:41:09 +01:00
movne r3 , r7 , l s p u l l #24
2012-08-13 11:44:13 +01:00
ldmneia r1 ! , { r4 , r7 }
2014-02-25 08:41:09 +01:00
orrne r3 , r3 , r4 , l s p u s h #8
movne r4 , r4 , l s p u l l #24
orrne r4 , r4 , r7 , l s p u s h #8
2012-08-13 11:44:13 +01:00
stmneia r0 ! , { r3 - r4 } @ Shouldnt fault
tst i p , #4
2014-02-25 08:41:09 +01:00
movne r3 , r7 , l s p u l l #24
2012-08-13 11:44:13 +01:00
ldrne r7 , [ r1 ] , #4
2014-02-25 08:41:09 +01:00
orrne r3 , r3 , r7 , l s p u s h #8
2012-08-13 11:44:13 +01:00
TUSER( s t r n e ) r3 , [ r0 ] , #4 @ Shouldnt fault
ands i p , i p , #3
beq . L c2 u _ 3 f u p i
.Lc2u_3nowords : mov r3 , r7 , g e t _ b y t e _ 3
teq i p , #0
beq . L c2 u _ f i n i s h e d
cmp i p , #2
USER( T U S E R ( s t r b ) r3 , [ r0 ] , #1 ) @ May fault
ldrgeb r3 , [ r1 ] , #1
USER( T U S E R ( s t r g e b ) r3 , [ r0 ] , #1 ) @ May fault
ldrgtb r3 , [ r1 ] , #0
USER( T U S E R ( s t r g t b ) r3 , [ r0 ] , #1 ) @ May fault
b . L c2 u _ f i n i s h e d
ENDPROC( _ _ c o p y _ t o _ u s e r )
.pushsection .fixup , " ax"
.align 0
9001 : ldmfd s p ! , { r0 , r4 - r7 , p c }
.popsection
/ * Prototype : unsigned l o n g _ _ c o p y _ f r o m _ u s e r ( v o i d * t o ,c o n s t v o i d * f r o m ,u n s i g n e d l o n g n ) ;
* Purpose : c o p y a b l o c k f r o m u s e r m e m o r y t o k e r n e l m e m o r y
* Params : t o - k e r n e l m e m o r y
* : from - u s e r m e m o r y
* : n - n u m b e r o f b y t e s t o c o p y
* Returns : N u m b e r o f b y t e s N O T c o p i e d .
* /
.Lcfu_dest_not_aligned :
rsb i p , i p , #4
cmp i p , #2
USER( T U S E R ( l d r b ) r3 , [ r1 ] , #1 ) @ May fault
strb r3 , [ r0 ] , #1
USER( T U S E R ( l d r g e b ) r3 , [ r1 ] , #1 ) @ May fault
strgeb r3 , [ r0 ] , #1
USER( T U S E R ( l d r g t b ) r3 , [ r1 ] , #1 ) @ May fault
strgtb r3 , [ r0 ] , #1
sub r2 , r2 , i p
b . L c f u _ d e s t _ a l i g n e d
ENTRY( _ _ c o p y _ f r o m _ u s e r )
stmfd s p ! , { r0 , r2 , r4 - r7 , l r }
cmp r2 , #4
blt . L c f u _ n o t _ e n o u g h
ands i p , r0 , #3
bne . L c f u _ d e s t _ n o t _ a l i g n e d
.Lcfu_dest_aligned :
ands i p , r1 , #3
bne . L c f u _ s r c _ n o t _ a l i g n e d
/ *
* Seeing a s t h e r e h a s t o b e a t l e a s t 8 b y t e s t o c o p y , w e c a n
* copy o n e w o r d , a n d f o r c e a u s e r - m o d e p a g e f a u l t . . .
* /
.Lcfu_0fupi : subs r2 , r2 , #4
addmi i p , r2 , #4
bmi . L c f u _ 0 n o w o r d s
USER( T U S E R ( l d r ) r3 , [ r1 ] , #4 )
str r3 , [ r0 ] , #4
mov i p , r1 , l s l #32 - P A G E _ S H I F T @ On each page, use a ld/st??t instruction
rsb i p , i p , #0
movs i p , i p , l s r #32 - P A G E _ S H I F T
beq . L c f u _ 0 f u p i
/ *
* ip = m a x n o . o f b y t e s t o c o p y b e f o r e n e e d i n g a n o t h e r " s t r t " i n s n
* /
cmp r2 , i p
movlt i p , r2
sub r2 , r2 , i p
subs i p , i p , #32
blt . L c f u _ 0 r e m 8 l p
.Lcfu_0cpy8lp : ldmia r1 ! , { r3 - r6 } @ Shouldnt fault
stmia r0 ! , { r3 - r6 }
ldmia r1 ! , { r3 - r6 } @ Shouldnt fault
subs i p , i p , #32
stmia r0 ! , { r3 - r6 }
bpl . L c f u _ 0 c p y 8 l p
.Lcfu_0rem8lp : cmn i p , #16
ldmgeia r1 ! , { r3 - r6 } @ Shouldnt fault
stmgeia r0 ! , { r3 - r6 }
tst i p , #8
ldmneia r1 ! , { r3 - r4 } @ Shouldnt fault
stmneia r0 ! , { r3 - r4 }
tst i p , #4
TUSER( l d r n e ) r3 , [ r1 ] , #4 @ Shouldnt fault
strne r3 , [ r0 ] , #4
ands i p , i p , #3
beq . L c f u _ 0 f u p i
.Lcfu_0nowords : teq i p , #0
beq . L c f u _ f i n i s h e d
.Lcfu_nowords : cmp i p , #2
USER( T U S E R ( l d r b ) r3 , [ r1 ] , #1 ) @ May fault
strb r3 , [ r0 ] , #1
USER( T U S E R ( l d r g e b ) r3 , [ r1 ] , #1 ) @ May fault
strgeb r3 , [ r0 ] , #1
USER( T U S E R ( l d r g t b ) r3 , [ r1 ] , #1 ) @ May fault
strgtb r3 , [ r0 ] , #1
b . L c f u _ f i n i s h e d
.Lcfu_not_enough :
movs i p , r2
bne . L c f u _ n o w o r d s
.Lcfu_finished : mov r0 , #0
add s p , s p , #8
ldmfd s p ! , { r4 - r7 , p c }
.Lcfu_src_not_aligned :
bic r1 , r1 , #3
USER( T U S E R ( l d r ) r7 , [ r1 ] , #4 ) @ May fault
cmp i p , #2
bgt . L c f u _ 3 f u p i
beq . L c f u _ 2 f u p i
.Lcfu_1fupi : subs r2 , r2 , #4
addmi i p , r2 , #4
bmi . L c f u _ 1 n o w o r d s
2014-02-25 08:41:09 +01:00
mov r3 , r7 , l s p u l l #8
2012-08-13 11:44:13 +01:00
USER( T U S E R ( l d r ) r7 , [ r1 ] , #4 ) @ May fault
2014-02-25 08:41:09 +01:00
orr r3 , r3 , r7 , l s p u s h #24
2012-08-13 11:44:13 +01:00
str r3 , [ r0 ] , #4
mov i p , r1 , l s l #32 - P A G E _ S H I F T
rsb i p , i p , #0
movs i p , i p , l s r #32 - P A G E _ S H I F T
beq . L c f u _ 1 f u p i
cmp r2 , i p
movlt i p , r2
sub r2 , r2 , i p
subs i p , i p , #16
blt . L c f u _ 1 r e m 8 l p
2014-02-25 08:41:09 +01:00
.Lcfu_1cpy8lp : mov r3 , r7 , l s p u l l #8
2012-08-13 11:44:13 +01:00
ldmia r1 ! , { r4 - r7 } @ Shouldnt fault
subs i p , i p , #16
2014-02-25 08:41:09 +01:00
orr r3 , r3 , r4 , l s p u s h #24
mov r4 , r4 , l s p u l l #8
orr r4 , r4 , r5 , l s p u s h #24
mov r5 , r5 , l s p u l l #8
orr r5 , r5 , r6 , l s p u s h #24
mov r6 , r6 , l s p u l l #8
orr r6 , r6 , r7 , l s p u s h #24
2012-08-13 11:44:13 +01:00
stmia r0 ! , { r3 - r6 }
bpl . L c f u _ 1 c p y 8 l p
.Lcfu_1rem8lp : tst i p , #8
2014-02-25 08:41:09 +01:00
movne r3 , r7 , l s p u l l #8
2012-08-13 11:44:13 +01:00
ldmneia r1 ! , { r4 , r7 } @ Shouldnt fault
2014-02-25 08:41:09 +01:00
orrne r3 , r3 , r4 , l s p u s h #24
movne r4 , r4 , l s p u l l #8
orrne r4 , r4 , r7 , l s p u s h #24
2012-08-13 11:44:13 +01:00
stmneia r0 ! , { r3 - r4 }
tst i p , #4
2014-02-25 08:41:09 +01:00
movne r3 , r7 , l s p u l l #8
2012-08-13 11:44:13 +01:00
USER( T U S E R ( l d r n e ) r7 , [ r1 ] , #4 ) @ May fault
2014-02-25 08:41:09 +01:00
orrne r3 , r3 , r7 , l s p u s h #24
2012-08-13 11:44:13 +01:00
strne r3 , [ r0 ] , #4
ands i p , i p , #3
beq . L c f u _ 1 f u p i
.Lcfu_1nowords : mov r3 , r7 , g e t _ b y t e _ 1
teq i p , #0
beq . L c f u _ f i n i s h e d
cmp i p , #2
strb r3 , [ r0 ] , #1
movge r3 , r7 , g e t _ b y t e _ 2
strgeb r3 , [ r0 ] , #1
movgt r3 , r7 , g e t _ b y t e _ 3
strgtb r3 , [ r0 ] , #1
b . L c f u _ f i n i s h e d
.Lcfu_2fupi : subs r2 , r2 , #4
addmi i p , r2 , #4
bmi . L c f u _ 2 n o w o r d s
2014-02-25 08:41:09 +01:00
mov r3 , r7 , l s p u l l #16
2012-08-13 11:44:13 +01:00
USER( T U S E R ( l d r ) r7 , [ r1 ] , #4 ) @ May fault
2014-02-25 08:41:09 +01:00
orr r3 , r3 , r7 , l s p u s h #16
2012-08-13 11:44:13 +01:00
str r3 , [ r0 ] , #4
mov i p , r1 , l s l #32 - P A G E _ S H I F T
rsb i p , i p , #0
movs i p , i p , l s r #32 - P A G E _ S H I F T
beq . L c f u _ 2 f u p i
cmp r2 , i p
movlt i p , r2
sub r2 , r2 , i p
subs i p , i p , #16
blt . L c f u _ 2 r e m 8 l p
2014-02-25 08:41:09 +01:00
.Lcfu_2cpy8lp : mov r3 , r7 , l s p u l l #16
2012-08-13 11:44:13 +01:00
ldmia r1 ! , { r4 - r7 } @ Shouldnt fault
subs i p , i p , #16
2014-02-25 08:41:09 +01:00
orr r3 , r3 , r4 , l s p u s h #16
mov r4 , r4 , l s p u l l #16
orr r4 , r4 , r5 , l s p u s h #16
mov r5 , r5 , l s p u l l #16
orr r5 , r5 , r6 , l s p u s h #16
mov r6 , r6 , l s p u l l #16
orr r6 , r6 , r7 , l s p u s h #16
2012-08-13 11:44:13 +01:00
stmia r0 ! , { r3 - r6 }
bpl . L c f u _ 2 c p y 8 l p
.Lcfu_2rem8lp : tst i p , #8
2014-02-25 08:41:09 +01:00
movne r3 , r7 , l s p u l l #16
2012-08-13 11:44:13 +01:00
ldmneia r1 ! , { r4 , r7 } @ Shouldnt fault
2014-02-25 08:41:09 +01:00
orrne r3 , r3 , r4 , l s p u s h #16
movne r4 , r4 , l s p u l l #16
orrne r4 , r4 , r7 , l s p u s h #16
2012-08-13 11:44:13 +01:00
stmneia r0 ! , { r3 - r4 }
tst i p , #4
2014-02-25 08:41:09 +01:00
movne r3 , r7 , l s p u l l #16
2012-08-13 11:44:13 +01:00
USER( T U S E R ( l d r n e ) r7 , [ r1 ] , #4 ) @ May fault
2014-02-25 08:41:09 +01:00
orrne r3 , r3 , r7 , l s p u s h #16
2012-08-13 11:44:13 +01:00
strne r3 , [ r0 ] , #4
ands i p , i p , #3
beq . L c f u _ 2 f u p i
.Lcfu_2nowords : mov r3 , r7 , g e t _ b y t e _ 2
teq i p , #0
beq . L c f u _ f i n i s h e d
cmp i p , #2
strb r3 , [ r0 ] , #1
movge r3 , r7 , g e t _ b y t e _ 3
strgeb r3 , [ r0 ] , #1
USER( T U S E R ( l d r g t b ) r3 , [ r1 ] , #0 ) @ May fault
strgtb r3 , [ r0 ] , #1
b . L c f u _ f i n i s h e d
.Lcfu_3fupi : subs r2 , r2 , #4
addmi i p , r2 , #4
bmi . L c f u _ 3 n o w o r d s
2014-02-25 08:41:09 +01:00
mov r3 , r7 , l s p u l l #24
2012-08-13 11:44:13 +01:00
USER( T U S E R ( l d r ) r7 , [ r1 ] , #4 ) @ May fault
2014-02-25 08:41:09 +01:00
orr r3 , r3 , r7 , l s p u s h #8
2012-08-13 11:44:13 +01:00
str r3 , [ r0 ] , #4
mov i p , r1 , l s l #32 - P A G E _ S H I F T
rsb i p , i p , #0
movs i p , i p , l s r #32 - P A G E _ S H I F T
beq . L c f u _ 3 f u p i
cmp r2 , i p
movlt i p , r2
sub r2 , r2 , i p
subs i p , i p , #16
blt . L c f u _ 3 r e m 8 l p
2014-02-25 08:41:09 +01:00
.Lcfu_3cpy8lp : mov r3 , r7 , l s p u l l #24
2012-08-13 11:44:13 +01:00
ldmia r1 ! , { r4 - r7 } @ Shouldnt fault
2014-02-25 08:41:09 +01:00
orr r3 , r3 , r4 , l s p u s h #8
mov r4 , r4 , l s p u l l #24
orr r4 , r4 , r5 , l s p u s h #8
mov r5 , r5 , l s p u l l #24
orr r5 , r5 , r6 , l s p u s h #8
mov r6 , r6 , l s p u l l #24
orr r6 , r6 , r7 , l s p u s h #8
2012-08-13 11:44:13 +01:00
stmia r0 ! , { r3 - r6 }
subs i p , i p , #16
bpl . L c f u _ 3 c p y 8 l p
.Lcfu_3rem8lp : tst i p , #8
2014-02-25 08:41:09 +01:00
movne r3 , r7 , l s p u l l #24
2012-08-13 11:44:13 +01:00
ldmneia r1 ! , { r4 , r7 } @ Shouldnt fault
2014-02-25 08:41:09 +01:00
orrne r3 , r3 , r4 , l s p u s h #8
movne r4 , r4 , l s p u l l #24
orrne r4 , r4 , r7 , l s p u s h #8
2012-08-13 11:44:13 +01:00
stmneia r0 ! , { r3 - r4 }
tst i p , #4
2014-02-25 08:41:09 +01:00
movne r3 , r7 , l s p u l l #24
2012-08-13 11:44:13 +01:00
USER( T U S E R ( l d r n e ) r7 , [ r1 ] , #4 ) @ May fault
2014-02-25 08:41:09 +01:00
orrne r3 , r3 , r7 , l s p u s h #8
2012-08-13 11:44:13 +01:00
strne r3 , [ r0 ] , #4
ands i p , i p , #3
beq . L c f u _ 3 f u p i
.Lcfu_3nowords : mov r3 , r7 , g e t _ b y t e _ 3
teq i p , #0
beq . L c f u _ f i n i s h e d
cmp i p , #2
strb r3 , [ r0 ] , #1
USER( T U S E R ( l d r g e b ) r3 , [ r1 ] , #1 ) @ May fault
strgeb r3 , [ r0 ] , #1
USER( T U S E R ( l d r g t b ) r3 , [ r1 ] , #1 ) @ May fault
strgtb r3 , [ r0 ] , #1
b . L c f u _ f i n i s h e d
ENDPROC( _ _ c o p y _ f r o m _ u s e r )
.pushsection .fixup , " ax"
.align 0
/ *
* We t o o k a n e x c e p t i o n . r0 c o n t a i n s a p o i n t e r t o
* the b y t e n o t c o p i e d .
* /
9001 : ldr r2 , [ s p ] , #4 @ void *to
sub r2 , r0 , r2 @ bytes copied
ldr r1 , [ s p ] , #4 @ unsigned long count
subs r4 , r1 , r2 @ bytes left to copy
movne r1 , r4
blne _ _ m e m z e r o
mov r0 , r4
ldmfd s p ! , { r4 - r7 , p c }
.popsection