1 | /* SPDX-License-Identifier: GPL-2.0 */ |
2 | /* |
3 | * Copyright (C) 2020-2022 Loongson Technology Corporation Limited |
4 | */ |
5 | |
6 | #include <linux/export.h> |
7 | #include <asm/alternative-asm.h> |
8 | #include <asm/asm.h> |
9 | #include <asm/asmmacro.h> |
10 | #include <asm/asm-extable.h> |
11 | #include <asm/cpu.h> |
12 | #include <asm/regdef.h> |
13 | #include <asm/unwind_hints.h> |
14 | |
15 | SYM_FUNC_START(__clear_user) |
16 | /* |
17 | * Some CPUs support hardware unaligned access |
18 | */ |
19 | ALTERNATIVE "b __clear_user_generic" , \ |
20 | "b __clear_user_fast" , CPU_FEATURE_UAL |
21 | SYM_FUNC_END(__clear_user) |
22 | |
23 | EXPORT_SYMBOL(__clear_user) |
24 | |
25 | /* |
26 | * unsigned long __clear_user_generic(void *addr, size_t size) |
27 | * |
28 | * a0: addr |
29 | * a1: size |
30 | */ |
31 | SYM_FUNC_START(__clear_user_generic) |
32 | beqz a1, 2f |
33 | |
34 | 1: st.b zero, a0, 0 |
35 | addi.d a0, a0, 1 |
36 | addi.d a1, a1, -1 |
37 | bgtz a1, 1b |
38 | |
39 | 2: move a0, a1 |
40 | jr ra |
41 | |
42 | _asm_extable 1b, 2b |
43 | SYM_FUNC_END(__clear_user_generic) |
44 | |
45 | /* |
46 | * unsigned long __clear_user_fast(void *addr, unsigned long size) |
47 | * |
48 | * a0: addr |
49 | * a1: size |
50 | */ |
51 | SYM_FUNC_START(__clear_user_fast) |
52 | sltui t0, a1, 9 |
53 | bnez t0, .Lsmall |
54 | |
55 | add.d a2, a0, a1 |
56 | 0: st.d zero, a0, 0 |
57 | |
58 | /* align up address */ |
59 | addi.d a0, a0, 8 |
60 | bstrins.d a0, zero, 2, 0 |
61 | |
62 | addi.d a3, a2, -64 |
63 | bgeu a0, a3, .Llt64 |
64 | |
65 | /* set 64 bytes at a time */ |
66 | .Lloop64: |
67 | 1: st.d zero, a0, 0 |
68 | 2: st.d zero, a0, 8 |
69 | 3: st.d zero, a0, 16 |
70 | 4: st.d zero, a0, 24 |
71 | 5: st.d zero, a0, 32 |
72 | 6: st.d zero, a0, 40 |
73 | 7: st.d zero, a0, 48 |
74 | 8: st.d zero, a0, 56 |
75 | addi.d a0, a0, 64 |
76 | bltu a0, a3, .Lloop64 |
77 | |
78 | /* set the remaining bytes */ |
79 | .Llt64: |
80 | addi.d a3, a2, -32 |
81 | bgeu a0, a3, .Llt32 |
82 | 9: st.d zero, a0, 0 |
83 | 10: st.d zero, a0, 8 |
84 | 11: st.d zero, a0, 16 |
85 | 12: st.d zero, a0, 24 |
86 | addi.d a0, a0, 32 |
87 | |
88 | .Llt32: |
89 | addi.d a3, a2, -16 |
90 | bgeu a0, a3, .Llt16 |
91 | 13: st.d zero, a0, 0 |
92 | 14: st.d zero, a0, 8 |
93 | addi.d a0, a0, 16 |
94 | |
95 | .Llt16: |
96 | addi.d a3, a2, -8 |
97 | bgeu a0, a3, .Llt8 |
98 | 15: st.d zero, a0, 0 |
99 | addi.d a0, a0, 8 |
100 | |
101 | .Llt8: |
102 | 16: st.d zero, a2, -8 |
103 | |
104 | /* return */ |
105 | move a0, zero |
106 | jr ra |
107 | |
108 | .align 4 |
109 | .Lsmall: |
110 | pcaddi t0, 4 |
111 | slli.d a2, a1, 4 |
112 | add.d t0, t0, a2 |
113 | jr t0 |
114 | |
115 | .align 4 |
116 | move a0, zero |
117 | jr ra |
118 | |
119 | .align 4 |
120 | 17: st.b zero, a0, 0 |
121 | move a0, zero |
122 | jr ra |
123 | |
124 | .align 4 |
125 | 18: st.h zero, a0, 0 |
126 | move a0, zero |
127 | jr ra |
128 | |
129 | .align 4 |
130 | 19: st.h zero, a0, 0 |
131 | 20: st.b zero, a0, 2 |
132 | move a0, zero |
133 | jr ra |
134 | |
135 | .align 4 |
136 | 21: st.w zero, a0, 0 |
137 | move a0, zero |
138 | jr ra |
139 | |
140 | .align 4 |
141 | 22: st.w zero, a0, 0 |
142 | 23: st.b zero, a0, 4 |
143 | move a0, zero |
144 | jr ra |
145 | |
146 | .align 4 |
147 | 24: st.w zero, a0, 0 |
148 | 25: st.h zero, a0, 4 |
149 | move a0, zero |
150 | jr ra |
151 | |
152 | .align 4 |
153 | 26: st.w zero, a0, 0 |
154 | 27: st.w zero, a0, 3 |
155 | move a0, zero |
156 | jr ra |
157 | |
158 | .align 4 |
159 | 28: st.d zero, a0, 0 |
160 | move a0, zero |
161 | jr ra |
162 | |
163 | /* fixup and ex_table */ |
164 | .Llarge_fixup: |
165 | sub.d a1, a2, a0 |
166 | |
167 | .Lsmall_fixup: |
168 | 29: st.b zero, a0, 0 |
169 | addi.d a0, a0, 1 |
170 | addi.d a1, a1, -1 |
171 | bgt a1, zero, 29b |
172 | |
173 | .Lexit: |
174 | move a0, a1 |
175 | jr ra |
176 | |
177 | _asm_extable 0b, .Lsmall_fixup |
178 | _asm_extable 1b, .Llarge_fixup |
179 | _asm_extable 2b, .Llarge_fixup |
180 | _asm_extable 3b, .Llarge_fixup |
181 | _asm_extable 4b, .Llarge_fixup |
182 | _asm_extable 5b, .Llarge_fixup |
183 | _asm_extable 6b, .Llarge_fixup |
184 | _asm_extable 7b, .Llarge_fixup |
185 | _asm_extable 8b, .Llarge_fixup |
186 | _asm_extable 9b, .Llarge_fixup |
187 | _asm_extable 10b, .Llarge_fixup |
188 | _asm_extable 11b, .Llarge_fixup |
189 | _asm_extable 12b, .Llarge_fixup |
190 | _asm_extable 13b, .Llarge_fixup |
191 | _asm_extable 14b, .Llarge_fixup |
192 | _asm_extable 15b, .Llarge_fixup |
193 | _asm_extable 16b, .Llarge_fixup |
194 | _asm_extable 17b, .Lexit |
195 | _asm_extable 18b, .Lsmall_fixup |
196 | _asm_extable 19b, .Lsmall_fixup |
197 | _asm_extable 20b, .Lsmall_fixup |
198 | _asm_extable 21b, .Lsmall_fixup |
199 | _asm_extable 22b, .Lsmall_fixup |
200 | _asm_extable 23b, .Lsmall_fixup |
201 | _asm_extable 24b, .Lsmall_fixup |
202 | _asm_extable 25b, .Lsmall_fixup |
203 | _asm_extable 26b, .Lsmall_fixup |
204 | _asm_extable 27b, .Lsmall_fixup |
205 | _asm_extable 28b, .Lsmall_fixup |
206 | _asm_extable 29b, .Lexit |
207 | SYM_FUNC_END(__clear_user_fast) |
208 | |
209 | STACK_FRAME_NON_STANDARD __clear_user_fast |
210 | |