2017-07-11 04:03:19 +03:00
# include < l i n u x / l i n k a g e . h >
2019-12-22 12:26:04 +03:00
# include < a s m - g e n e r i c / e x p o r t . h >
2017-07-11 04:03:19 +03:00
# include < a s m / a s m . h >
# include < a s m / c s r . h >
.macro fixup op r e g a d d r l b l
2020-02-27 22:16:28 +03:00
100 :
2017-07-11 04:03:19 +03:00
\ op \ r e g , \ a d d r
.section _ _ ex_ t a b l e ," a "
.balign RISCV_SZPTR
2020-02-27 22:16:28 +03:00
RISCV_ P T R 1 0 0 b , \ l b l
2017-07-11 04:03:19 +03:00
.previous
.endm
2018-06-09 03:33:51 +03:00
ENTRY( _ _ a s m _ c o p y _ t o _ u s e r )
ENTRY( _ _ a s m _ c o p y _ f r o m _ u s e r )
2017-07-11 04:03:19 +03:00
/* Enable access to user memory */
li t 6 , S R _ S U M
2019-10-28 15:10:32 +03:00
csrs C S R _ S T A T U S , t 6
2017-07-11 04:03:19 +03:00
2021-06-23 15:40:39 +03:00
/* Save for return value */
mv t 5 , a2
2017-07-11 04:03:19 +03:00
/ *
2021-06-23 15:40:39 +03:00
* Register a l l o c a t i o n f o r c o d e b e l o w :
* a0 - s t a r t o f u n c o p i e d d s t
* a1 - s t a r t o f u n c o p i e d s r c
* a2 - s i z e
* t0 - e n d o f u n c o p i e d d s t
2017-07-11 04:03:19 +03:00
* /
2021-06-23 15:40:39 +03:00
add t 0 , a0 , a2
/ *
* Use b y t e c o p y o n l y i f t o o s m a l l .
2021-07-20 11:53:23 +03:00
* SZREG h o l d s 4 f o r R V 3 2 a n d 8 f o r R V 6 4
2021-06-23 15:40:39 +03:00
* /
2021-07-20 11:50:52 +03:00
li a3 , 9 * S Z R E G / * s i z e m u s t b e l a r g e r t h a n s i z e i n w o r d _ c o p y * /
2021-06-23 15:40:39 +03:00
bltu a2 , a3 , . L b y t e _ c o p y _ t a i l
/ *
2021-07-20 11:53:23 +03:00
* Copy f i r s t b y t e s u n t i l d s t i s a l i g n e d t o w o r d b o u n d a r y .
2021-06-23 15:40:39 +03:00
* a0 - s t a r t o f d s t
* t1 - s t a r t o f a l i g n e d d s t
* /
addi t 1 , a0 , S Z R E G - 1
andi t 1 , t 1 , ~ ( S Z R E G - 1 )
/* dst is already aligned, skip */
2021-07-20 11:53:23 +03:00
beq a0 , t 1 , . L s k i p _ a l i g n _ d s t
2017-07-11 04:03:19 +03:00
1 :
2021-06-23 15:40:39 +03:00
/* a5 - one byte for copying data */
fixup l b a5 , 0 ( a1 ) , 1 0 f
addi a1 , a1 , 1 / * s r c * /
fixup s b a5 , 0 ( a0 ) , 1 0 f
addi a0 , a0 , 1 / * d s t * /
bltu a0 , t 1 , 1 b / * t 1 - s t a r t o f a l i g n e d d s t * /
2021-07-20 11:53:23 +03:00
.Lskip_align_dst :
2021-06-23 15:40:39 +03:00
/ *
* Now d s t i s a l i g n e d .
* Use s h i f t - c o p y i f s r c i s m i s a l i g n e d .
* Use w o r d - c o p y i f b o t h s r c a n d d s t a r e a l i g n e d b e c a u s e
* can n o t u s e s h i f t - c o p y w h i c h d o n o t r e q u i r e s h i f t i n g
* /
/* a1 - start of src */
andi a3 , a1 , S Z R E G - 1
bnez a3 , . L s h i f t _ c o p y
.Lword_copy :
/ *
* Both s r c a n d d s t a r e a l i g n e d , u n r o l l e d w o r d c o p y
*
* a0 - s t a r t o f a l i g n e d d s t
* a1 - s t a r t o f a l i g n e d s r c
* t0 - e n d o f a l i g n e d d s t
* /
2021-07-20 11:50:52 +03:00
addi t 0 , t 0 , - ( 8 * S Z R E G ) / * n o t t o o v e r r u n * /
2017-07-11 04:03:19 +03:00
2 :
2021-06-23 15:40:39 +03:00
fixup R E G _ L a4 , 0 ( a1 ) , 1 0 f
fixup R E G _ L a5 , S Z R E G ( a1 ) , 1 0 f
fixup R E G _ L a6 , 2 * S Z R E G ( a1 ) , 1 0 f
fixup R E G _ L a7 , 3 * S Z R E G ( a1 ) , 1 0 f
fixup R E G _ L t 1 , 4 * S Z R E G ( a1 ) , 1 0 f
fixup R E G _ L t 2 , 5 * S Z R E G ( a1 ) , 1 0 f
fixup R E G _ L t 3 , 6 * S Z R E G ( a1 ) , 1 0 f
fixup R E G _ L t 4 , 7 * S Z R E G ( a1 ) , 1 0 f
fixup R E G _ S a4 , 0 ( a0 ) , 1 0 f
fixup R E G _ S a5 , S Z R E G ( a0 ) , 1 0 f
fixup R E G _ S a6 , 2 * S Z R E G ( a0 ) , 1 0 f
fixup R E G _ S a7 , 3 * S Z R E G ( a0 ) , 1 0 f
fixup R E G _ S t 1 , 4 * S Z R E G ( a0 ) , 1 0 f
fixup R E G _ S t 2 , 5 * S Z R E G ( a0 ) , 1 0 f
fixup R E G _ S t 3 , 6 * S Z R E G ( a0 ) , 1 0 f
fixup R E G _ S t 4 , 7 * S Z R E G ( a0 ) , 1 0 f
addi a0 , a0 , 8 * S Z R E G
addi a1 , a1 , 8 * S Z R E G
bltu a0 , t 0 , 2 b
2021-07-20 11:50:52 +03:00
addi t 0 , t 0 , 8 * S Z R E G / * r e v e r t t o o r i g i n a l v a l u e * /
2021-06-23 15:40:39 +03:00
j . L b y t e _ c o p y _ t a i l
.Lshift_copy :
/ *
* Word c o p y w i t h s h i f t i n g .
* For m i s a l i g n e d c o p y w e s t i l l p e r f o r m a l i g n e d w o r d c o p y , b u t
* we n e e d t o u s e t h e v a l u e f e t c h e d f r o m t h e p r e v i o u s i t e r a t i o n a n d
* do s o m e s h i f t s .
2021-07-20 11:53:23 +03:00
* This i s s a f e b e c a u s e r e a d i n g i s l e s s t h a n a w o r d s i z e .
2021-06-23 15:40:39 +03:00
*
* a0 - s t a r t o f a l i g n e d d s t
* a1 - s t a r t o f s r c
* a3 - a1 & m a s k : ( S Z R E G - 1 )
* t0 - e n d o f u n c o p i e d d s t
* t1 - e n d o f a l i g n e d d s t
* /
/* calculating aligned word boundary for dst */
andi t 1 , t 0 , ~ ( S Z R E G - 1 )
2021-07-20 11:53:23 +03:00
/* Converting unaligned src to aligned src */
2021-06-23 15:40:39 +03:00
andi a1 , a1 , ~ ( S Z R E G - 1 )
/ *
* Calculate s h i f t s
* t3 - p r e v s h i f t
* t4 - c u r r e n t s h i f t
* /
2021-07-20 11:51:45 +03:00
slli t 3 , a3 , 3 / * c o n v e r t i n g b y t e s i n a3 t o b i t s * /
2021-06-23 15:40:39 +03:00
li a5 , S Z R E G * 8
sub t 4 , a5 , t 3
2021-07-20 11:53:23 +03:00
/* Load the first word to combine with second word */
2021-06-23 15:40:39 +03:00
fixup R E G _ L a5 , 0 ( a1 ) , 1 0 f
2017-07-11 04:03:19 +03:00
3 :
2021-06-23 15:40:39 +03:00
/ * Main s h i f t i n g c o p y
*
* a0 - s t a r t o f a l i g n e d d s t
* a1 - s t a r t o f a l i g n e d s r c
* t1 - e n d o f a l i g n e d d s t
* /
/* At least one iteration will be executed */
srl a4 , a5 , t 3
fixup R E G _ L a5 , S Z R E G ( a1 ) , 1 0 f
addi a1 , a1 , S Z R E G
sll a2 , a5 , t 4
or a2 , a2 , a4
fixup R E G _ S a2 , 0 ( a0 ) , 1 0 f
addi a0 , a0 , S Z R E G
bltu a0 , t 1 , 3 b
/* Revert src to original unaligned value */
add a1 , a1 , a3
.Lbyte_copy_tail :
/ *
* Byte c o p y a n y t h i n g l e f t .
*
* a0 - s t a r t o f r e m a i n i n g d s t
* a1 - s t a r t o f r e m a i n i n g s r c
* t0 - e n d o f r e m a i n i n g d s t
* /
2021-07-20 11:53:23 +03:00
bgeu a0 , t 0 , . L o u t _ c o p y _ u s e r / * c h e c k i f e n d o f c o p y * /
2021-06-23 15:40:39 +03:00
4 :
fixup l b a5 , 0 ( a1 ) , 1 0 f
addi a1 , a1 , 1 / * s r c * /
fixup s b a5 , 0 ( a0 ) , 1 0 f
addi a0 , a0 , 1 / * d s t * /
bltu a0 , t 0 , 4 b / * t 0 - e n d o f d s t * /
2021-07-20 11:53:23 +03:00
.Lout_copy_user :
2017-07-11 04:03:19 +03:00
/* Disable access to user memory */
2019-10-28 15:10:32 +03:00
csrc C S R _ S T A T U S , t 6
2021-06-23 15:40:39 +03:00
li a0 , 0
2017-07-11 04:03:19 +03:00
ret
2018-06-09 03:33:51 +03:00
ENDPROC( _ _ a s m _ c o p y _ t o _ u s e r )
ENDPROC( _ _ a s m _ c o p y _ f r o m _ u s e r )
2019-12-22 12:26:04 +03:00
EXPORT_ S Y M B O L ( _ _ a s m _ c o p y _ t o _ u s e r )
EXPORT_ S Y M B O L ( _ _ a s m _ c o p y _ f r o m _ u s e r )
2017-07-11 04:03:19 +03:00
ENTRY( _ _ c l e a r _ u s e r )
/* Enable access to user memory */
li t 6 , S R _ S U M
2019-10-28 15:10:32 +03:00
csrs C S R _ S T A T U S , t 6
2017-07-11 04:03:19 +03:00
add a3 , a0 , a1
addi t 0 , a0 , S Z R E G - 1
andi t 1 , a3 , ~ ( S Z R E G - 1 )
andi t 0 , t 0 , ~ ( S Z R E G - 1 )
/ *
* a3 : terminal a d d r e s s o f t a r g e t r e g i o n
* t0 : lowest d o u b l e w o r d - a l i g n e d a d d r e s s i n t a r g e t r e g i o n
* t1 : highest d o u b l e w o r d - a l i g n e d a d d r e s s i n t a r g e t r e g i o n
* /
bgeu t 0 , t 1 , 2 f
bltu a0 , t 0 , 4 f
1 :
2018-05-08 05:59:33 +03:00
fixup R E G _ S , z e r o , ( a0 ) , 1 1 f
2017-07-11 04:03:19 +03:00
addi a0 , a0 , S Z R E G
bltu a0 , t 1 , 1 b
2 :
bltu a0 , a3 , 5 f
3 :
/* Disable access to user memory */
2019-10-28 15:10:32 +03:00
csrc C S R _ S T A T U S , t 6
2017-07-11 04:03:19 +03:00
li a0 , 0
ret
4 : /* Edge case: unalignment */
2018-05-08 05:59:33 +03:00
fixup s b , z e r o , ( a0 ) , 1 1 f
2017-07-11 04:03:19 +03:00
addi a0 , a0 , 1
bltu a0 , t 0 , 4 b
j 1 b
5 : /* Edge case: remainder */
2018-05-08 05:59:33 +03:00
fixup s b , z e r o , ( a0 ) , 1 1 f
2017-07-11 04:03:19 +03:00
addi a0 , a0 , 1
bltu a0 , a3 , 5 b
j 3 b
ENDPROC( _ _ c l e a r _ u s e r )
2019-12-22 12:26:04 +03:00
EXPORT_ S Y M B O L ( _ _ c l e a r _ u s e r )
2017-07-11 04:03:19 +03:00
.section .fixup , " ax"
.balign 4
2018-05-08 05:59:33 +03:00
/* Fixup code for __copy_user(10) and __clear_user(11) */
2017-07-11 04:03:19 +03:00
10 :
/* Disable access to user memory */
2019-10-28 15:10:32 +03:00
csrs C S R _ S T A T U S , t 6
2021-06-23 15:40:39 +03:00
mv a0 , t 5
2018-05-08 05:59:33 +03:00
ret
11 :
2019-10-28 15:10:32 +03:00
csrs C S R _ S T A T U S , t 6
2018-05-08 05:59:33 +03:00
mv a0 , a1
2017-07-11 04:03:19 +03:00
ret
.previous