]> asedeno.scripts.mit.edu Git - linux.git/blob - arch/riscv/lib/uaccess.S
Merge tag 'pnp-5.6-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm
[linux.git] / arch / riscv / lib / uaccess.S
1 #include <linux/linkage.h>
2 #include <asm-generic/export.h>
3 #include <asm/asm.h>
4 #include <asm/csr.h>
5
6         .altmacro
7         .macro fixup op reg addr lbl
8         LOCAL _epc
9 _epc:
10         \op \reg, \addr
11         .section __ex_table,"a"
12         .balign RISCV_SZPTR
13         RISCV_PTR _epc, \lbl
14         .previous
15         .endm
16
17 ENTRY(__asm_copy_to_user)
18 ENTRY(__asm_copy_from_user)
19
20         /* Enable access to user memory */
21         li t6, SR_SUM
22         csrs CSR_STATUS, t6
23
24         add a3, a1, a2
25         /* Use word-oriented copy only if low-order bits match */
26         andi t0, a0, SZREG-1
27         andi t1, a1, SZREG-1
28         bne t0, t1, 2f
29
30         addi t0, a1, SZREG-1
31         andi t1, a3, ~(SZREG-1)
32         andi t0, t0, ~(SZREG-1)
33         /*
34          * a3: terminal address of source region
35          * t0: lowest XLEN-aligned address in source
36          * t1: highest XLEN-aligned address in source
37          */
38         bgeu t0, t1, 2f
39         bltu a1, t0, 4f
40 1:
41         fixup REG_L, t2, (a1), 10f
42         fixup REG_S, t2, (a0), 10f
43         addi a1, a1, SZREG
44         addi a0, a0, SZREG
45         bltu a1, t1, 1b
46 2:
47         bltu a1, a3, 5f
48
49 3:
50         /* Disable access to user memory */
51         csrc CSR_STATUS, t6
52         li a0, 0
53         ret
54 4: /* Edge case: unalignment */
55         fixup lbu, t2, (a1), 10f
56         fixup sb, t2, (a0), 10f
57         addi a1, a1, 1
58         addi a0, a0, 1
59         bltu a1, t0, 4b
60         j 1b
61 5: /* Edge case: remainder */
62         fixup lbu, t2, (a1), 10f
63         fixup sb, t2, (a0), 10f
64         addi a1, a1, 1
65         addi a0, a0, 1
66         bltu a1, a3, 5b
67         j 3b
68 ENDPROC(__asm_copy_to_user)
69 ENDPROC(__asm_copy_from_user)
70 EXPORT_SYMBOL(__asm_copy_to_user)
71 EXPORT_SYMBOL(__asm_copy_from_user)
72
73
74 ENTRY(__clear_user)
75
76         /* Enable access to user memory */
77         li t6, SR_SUM
78         csrs CSR_STATUS, t6
79
80         add a3, a0, a1
81         addi t0, a0, SZREG-1
82         andi t1, a3, ~(SZREG-1)
83         andi t0, t0, ~(SZREG-1)
84         /*
85          * a3: terminal address of target region
86          * t0: lowest doubleword-aligned address in target region
87          * t1: highest doubleword-aligned address in target region
88          */
89         bgeu t0, t1, 2f
90         bltu a0, t0, 4f
91 1:
92         fixup REG_S, zero, (a0), 11f
93         addi a0, a0, SZREG
94         bltu a0, t1, 1b
95 2:
96         bltu a0, a3, 5f
97
98 3:
99         /* Disable access to user memory */
100         csrc CSR_STATUS, t6
101         li a0, 0
102         ret
103 4: /* Edge case: unalignment */
104         fixup sb, zero, (a0), 11f
105         addi a0, a0, 1
106         bltu a0, t0, 4b
107         j 1b
108 5: /* Edge case: remainder */
109         fixup sb, zero, (a0), 11f
110         addi a0, a0, 1
111         bltu a0, a3, 5b
112         j 3b
113 ENDPROC(__clear_user)
114 EXPORT_SYMBOL(__clear_user)
115
116         .section .fixup,"ax"
117         .balign 4
118         /* Fixup code for __copy_user(10) and __clear_user(11) */
119 10:
120         /* Disable access to user memory */
121         csrs CSR_STATUS, t6
122         mv a0, a2
123         ret
124 11:
125         csrs CSR_STATUS, t6
126         mv a0, a1
127         ret
128         .previous