Commit | Line | Data |
---|---|---|
5d8544e2 PD |
1 | #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 | ||
16 | ENTRY(__copy_user) | |
17 | ||
18 | /* Enable access to user memory */ | |
19 | li t6, SR_SUM | |
20 | csrs sstatus, t6 | |
21 | ||
22 | add a3, a1, a2 | |
23 | /* Use word-oriented copy only if low-order bits match */ | |
24 | andi t0, a0, SZREG-1 | |
25 | andi t1, a1, SZREG-1 | |
26 | bne t0, t1, 2f | |
27 | ||
28 | addi t0, a1, SZREG-1 | |
29 | andi t1, a3, ~(SZREG-1) | |
30 | andi t0, t0, ~(SZREG-1) | |
31 | /* | |
32 | * a3: terminal address of source region | |
33 | * t0: lowest XLEN-aligned address in source | |
34 | * t1: highest XLEN-aligned address in source | |
35 | */ | |
36 | bgeu t0, t1, 2f | |
37 | bltu a1, t0, 4f | |
38 | 1: | |
39 | fixup REG_L, t2, (a1), 10f | |
40 | fixup REG_S, t2, (a0), 10f | |
41 | addi a1, a1, SZREG | |
42 | addi a0, a0, SZREG | |
43 | bltu a1, t1, 1b | |
44 | 2: | |
45 | bltu a1, a3, 5f | |
46 | ||
47 | 3: | |
48 | /* Disable access to user memory */ | |
49 | csrc sstatus, t6 | |
50 | li a0, 0 | |
51 | ret | |
52 | 4: /* Edge case: unalignment */ | |
53 | fixup lbu, t2, (a1), 10f | |
54 | fixup sb, t2, (a0), 10f | |
55 | addi a1, a1, 1 | |
56 | addi a0, a0, 1 | |
57 | bltu a1, t0, 4b | |
58 | j 1b | |
59 | 5: /* Edge case: remainder */ | |
60 | fixup lbu, t2, (a1), 10f | |
61 | fixup sb, t2, (a0), 10f | |
62 | addi a1, a1, 1 | |
63 | addi a0, a0, 1 | |
64 | bltu a1, a3, 5b | |
65 | j 3b | |
66 | ENDPROC(__copy_user) | |
67 | ||
68 | ||
69 | ENTRY(__clear_user) | |
70 | ||
71 | /* Enable access to user memory */ | |
72 | li t6, SR_SUM | |
73 | csrs sstatus, t6 | |
74 | ||
75 | add a3, a0, a1 | |
76 | addi t0, a0, SZREG-1 | |
77 | andi t1, a3, ~(SZREG-1) | |
78 | andi t0, t0, ~(SZREG-1) | |
79 | /* | |
80 | * a3: terminal address of target region | |
81 | * t0: lowest doubleword-aligned address in target region | |
82 | * t1: highest doubleword-aligned address in target region | |
83 | */ | |
84 | bgeu t0, t1, 2f | |
85 | bltu a0, t0, 4f | |
86 | 1: | |
87 | fixup REG_S, zero, (a0), 10f | |
88 | addi a0, a0, SZREG | |
89 | bltu a0, t1, 1b | |
90 | 2: | |
91 | bltu a0, a3, 5f | |
92 | ||
93 | 3: | |
94 | /* Disable access to user memory */ | |
95 | csrc sstatus, t6 | |
96 | li a0, 0 | |
97 | ret | |
98 | 4: /* Edge case: unalignment */ | |
99 | fixup sb, zero, (a0), 10f | |
100 | addi a0, a0, 1 | |
101 | bltu a0, t0, 4b | |
102 | j 1b | |
103 | 5: /* Edge case: remainder */ | |
104 | fixup sb, zero, (a0), 10f | |
105 | addi a0, a0, 1 | |
106 | bltu a0, a3, 5b | |
107 | j 3b | |
108 | ENDPROC(__clear_user) | |
109 | ||
110 | .section .fixup,"ax" | |
111 | .balign 4 | |
112 | 10: | |
113 | /* Disable access to user memory */ | |
114 | csrs sstatus, t6 | |
115 | sub a0, a3, a0 | |
116 | ret | |
117 | .previous |