2017-07-11 04:03:19 +03:00
# include < l i n u x / l i n k a g e . h >
# include < a s m / a s m . h >
# include < a s m / c s r . h >
.altmacro
.macro fixup op r e g a d d r l b l
LOCAL _ e p c
_epc :
\ op \ r e g , \ a d d r
.section _ _ ex_ t a b l e ," a "
.balign RISCV_SZPTR
RISCV_ P T R _ e p c , \ l b l
.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
csrs s s t a t u s , t 6
add a3 , a1 , a2
/* Use word-oriented copy only if low-order bits match */
andi t 0 , a0 , S Z R E G - 1
andi t 1 , a1 , S Z R E G - 1
bne t 0 , t 1 , 2 f
addi t 0 , a1 , 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 s o u r c e r e g i o n
* t0 : lowest X L E N - a l i g n e d a d d r e s s i n s o u r c e
* t1 : highest X L E N - a l i g n e d a d d r e s s i n s o u r c e
* /
bgeu t 0 , t 1 , 2 f
bltu a1 , t 0 , 4 f
1 :
fixup R E G _ L , t 2 , ( a1 ) , 1 0 f
fixup R E G _ S , t 2 , ( a0 ) , 1 0 f
addi a1 , a1 , S Z R E G
addi a0 , a0 , S Z R E G
bltu a1 , t 1 , 1 b
2 :
bltu a1 , a3 , 5 f
3 :
/* Disable access to user memory */
csrc s s t a t u s , t 6
li a0 , 0
ret
4 : /* Edge case: unalignment */
fixup l b u , t 2 , ( a1 ) , 1 0 f
fixup s b , t 2 , ( a0 ) , 1 0 f
addi a1 , a1 , 1
addi a0 , a0 , 1
bltu a1 , t 0 , 4 b
j 1 b
5 : /* Edge case: remainder */
fixup l b u , t 2 , ( a1 ) , 1 0 f
fixup s b , t 2 , ( a0 ) , 1 0 f
addi a1 , a1 , 1
addi a0 , a0 , 1
bltu a1 , a3 , 5 b
j 3 b
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 )
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
csrs s s t a t u s , t 6
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 */
csrc s s t a t u s , t 6
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 )
.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 */
csrs s s t a t u s , t 6
2018-05-08 05:59:33 +03:00
mv a0 , a2
ret
11 :
csrs s s t a t u s , t 6
mv a0 , a1
2017-07-11 04:03:19 +03:00
ret
.previous