blob: 399e6f0c2d98ee7be7926c490f3b356f2053f7d0 [file] [log] [blame]
Palmer Dabbelt5d8544e2017-07-10 18:03:19 -07001#include <linux/linkage.h>
2#include <asm/asm.h>
3#include <asm/csr.h>
4
5 .altmacro
6 .macro fixup op reg addr lbl
7 LOCAL _epc
8_epc:
9 \op \reg, \addr
10 .section __ex_table,"a"
11 .balign RISCV_SZPTR
12 RISCV_PTR _epc, \lbl
13 .previous
14 .endm
15
Luc Van Oostenryck86406d52018-06-09 02:33:51 +020016ENTRY(__asm_copy_to_user)
17ENTRY(__asm_copy_from_user)
Palmer Dabbelt5d8544e2017-07-10 18:03:19 -070018
19 /* Enable access to user memory */
20 li t6, SR_SUM
21 csrs sstatus, t6
22
23 add a3, a1, a2
24 /* Use word-oriented copy only if low-order bits match */
25 andi t0, a0, SZREG-1
26 andi t1, a1, SZREG-1
27 bne t0, t1, 2f
28
29 addi t0, a1, SZREG-1
30 andi t1, a3, ~(SZREG-1)
31 andi t0, t0, ~(SZREG-1)
32 /*
33 * a3: terminal address of source region
34 * t0: lowest XLEN-aligned address in source
35 * t1: highest XLEN-aligned address in source
36 */
37 bgeu t0, t1, 2f
38 bltu a1, t0, 4f
391:
40 fixup REG_L, t2, (a1), 10f
41 fixup REG_S, t2, (a0), 10f
42 addi a1, a1, SZREG
43 addi a0, a0, SZREG
44 bltu a1, t1, 1b
452:
46 bltu a1, a3, 5f
47
483:
49 /* Disable access to user memory */
50 csrc sstatus, t6
51 li a0, 0
52 ret
534: /* Edge case: unalignment */
54 fixup lbu, t2, (a1), 10f
55 fixup sb, t2, (a0), 10f
56 addi a1, a1, 1
57 addi a0, a0, 1
58 bltu a1, t0, 4b
59 j 1b
605: /* Edge case: remainder */
61 fixup lbu, t2, (a1), 10f
62 fixup sb, t2, (a0), 10f
63 addi a1, a1, 1
64 addi a0, a0, 1
65 bltu a1, a3, 5b
66 j 3b
Luc Van Oostenryck86406d52018-06-09 02:33:51 +020067ENDPROC(__asm_copy_to_user)
68ENDPROC(__asm_copy_from_user)
Palmer Dabbelt5d8544e2017-07-10 18:03:19 -070069
70
71ENTRY(__clear_user)
72
73 /* Enable access to user memory */
74 li t6, SR_SUM
75 csrs sstatus, t6
76
77 add a3, a0, a1
78 addi t0, a0, SZREG-1
79 andi t1, a3, ~(SZREG-1)
80 andi t0, t0, ~(SZREG-1)
81 /*
82 * a3: terminal address of target region
83 * t0: lowest doubleword-aligned address in target region
84 * t1: highest doubleword-aligned address in target region
85 */
86 bgeu t0, t1, 2f
87 bltu a0, t0, 4f
881:
Alan Kaoebcbd752018-05-08 10:59:33 +080089 fixup REG_S, zero, (a0), 11f
Palmer Dabbelt5d8544e2017-07-10 18:03:19 -070090 addi a0, a0, SZREG
91 bltu a0, t1, 1b
922:
93 bltu a0, a3, 5f
94
953:
96 /* Disable access to user memory */
97 csrc sstatus, t6
98 li a0, 0
99 ret
1004: /* Edge case: unalignment */
Alan Kaoebcbd752018-05-08 10:59:33 +0800101 fixup sb, zero, (a0), 11f
Palmer Dabbelt5d8544e2017-07-10 18:03:19 -0700102 addi a0, a0, 1
103 bltu a0, t0, 4b
104 j 1b
1055: /* Edge case: remainder */
Alan Kaoebcbd752018-05-08 10:59:33 +0800106 fixup sb, zero, (a0), 11f
Palmer Dabbelt5d8544e2017-07-10 18:03:19 -0700107 addi a0, a0, 1
108 bltu a0, a3, 5b
109 j 3b
110ENDPROC(__clear_user)
111
112 .section .fixup,"ax"
113 .balign 4
Alan Kaoebcbd752018-05-08 10:59:33 +0800114 /* Fixup code for __copy_user(10) and __clear_user(11) */
Palmer Dabbelt5d8544e2017-07-10 18:03:19 -070011510:
116 /* Disable access to user memory */
117 csrs sstatus, t6
Alan Kaoebcbd752018-05-08 10:59:33 +0800118 mv a0, a2
119 ret
12011:
121 csrs sstatus, t6
122 mv a0, a1
Palmer Dabbelt5d8544e2017-07-10 18:03:19 -0700123 ret
124 .previous