1
2
3
4
5
6
7 #include <asm/processor.h>
8 #include <asm/cache.h>
9 #include <asm/errno.h>
10 #include <asm/ppc_asm.h>
11 #include <asm/export.h>
12 #include <asm/code-patching-asm.h>
13 #include <asm/kasan.h>
14
15 #define COPY_16_BYTES \
16 lwz r7,4(r4); \
17 lwz r8,8(r4); \
18 lwz r9,12(r4); \
19 lwzu r10,16(r4); \
20 stw r7,4(r6); \
21 stw r8,8(r6); \
22 stw r9,12(r6); \
23 stwu r10,16(r6)
24
25 #define COPY_16_BYTES_WITHEX(n) \
26 8 ## n ## 0: \
27 lwz r7,4(r4); \
28 8 ## n ## 1: \
29 lwz r8,8(r4); \
30 8 ## n ## 2: \
31 lwz r9,12(r4); \
32 8 ## n ## 3: \
33 lwzu r10,16(r4); \
34 8 ## n ## 4: \
35 stw r7,4(r6); \
36 8 ## n ## 5: \
37 stw r8,8(r6); \
38 8 ## n ## 6: \
39 stw r9,12(r6); \
40 8 ## n ## 7: \
41 stwu r10,16(r6)
42
43 #define COPY_16_BYTES_EXCODE(n) \
44 9 ## n ## 0: \
45 addi r5,r5,-(16 * n); \
46 b 104f; \
47 9 ## n ## 1: \
48 addi r5,r5,-(16 * n); \
49 b 105f; \
50 EX_TABLE(8 ## n ## 0b,9 ## n ## 0b); \
51 EX_TABLE(8 ## n ## 1b,9 ## n ## 0b); \
52 EX_TABLE(8 ## n ## 2b,9 ## n ## 0b); \
53 EX_TABLE(8 ## n ## 3b,9 ## n ## 0b); \
54 EX_TABLE(8 ## n ## 4b,9 ## n ## 1b); \
55 EX_TABLE(8 ## n ## 5b,9 ## n ## 1b); \
56 EX_TABLE(8 ## n ## 6b,9 ## n ## 1b); \
57 EX_TABLE(8 ## n ## 7b,9 ## n ## 1b)
58
59 .text
60 .stabs "arch/powerpc/lib/",N_SO,0,0,0f
61 .stabs "copy_32.S",N_SO,0,0,0f
62 0:
63
64 CACHELINE_BYTES = L1_CACHE_BYTES
65 LG_CACHELINE_BYTES = L1_CACHE_SHIFT
66 CACHELINE_MASK = (L1_CACHE_BYTES-1)
67
68 #ifndef CONFIG_KASAN
69 _GLOBAL(memset16)
70 rlwinm. r0 ,r5, 31, 1, 31
71 addi r6, r3, -4
72 beq- 2f
73 rlwimi r4 ,r4 ,16 ,0 ,15
74 mtctr r0
75 1: stwu r4, 4(r6)
76 bdnz 1b
77 2: andi. r0, r5, 1
78 beqlr
79 sth r4, 4(r6)
80 blr
81 EXPORT_SYMBOL(memset16)
82 #endif
83
84
85
86
87
88
89
90
91
92
93 _GLOBAL_KASAN(memset)
94 cmplwi 0,r5,4
95 blt 7f
96
97 rlwimi r4,r4,8,16,23
98 rlwimi r4,r4,16,0,15
99
100 stw r4,0(r3)
101 beqlr
102 andi. r0,r3,3
103 add r5,r0,r5
104 subf r6,r0,r3
105 cmplwi 0,r4,0
106
107
108
109
110 5: b 2f
111 patch_site 5b, patch__memset_nocache
112
113 clrlwi r7,r6,32-LG_CACHELINE_BYTES
114 add r8,r7,r5
115 srwi r9,r8,LG_CACHELINE_BYTES
116 addic. r9,r9,-1
117 ble 2f
118 xori r0,r7,CACHELINE_MASK & ~3
119 srwi. r0,r0,2
120 beq 3f
121 mtctr r0
122 4: stwu r4,4(r6)
123 bdnz 4b
124 3: mtctr r9
125 li r7,4
126 10: dcbz r7,r6
127 addi r6,r6,CACHELINE_BYTES
128 bdnz 10b
129 clrlwi r5,r8,32-LG_CACHELINE_BYTES
130 addi r5,r5,4
131
132 2: srwi r0,r5,2
133 mtctr r0
134 bdz 6f
135 1: stwu r4,4(r6)
136 bdnz 1b
137 6: andi. r5,r5,3
138 beqlr
139 mtctr r5
140 addi r6,r6,3
141 8: stbu r4,1(r6)
142 bdnz 8b
143 blr
144
145 7: cmpwi 0,r5,0
146 beqlr
147 mtctr r5
148 addi r6,r3,-1
149 9: stbu r4,1(r6)
150 bdnz 9b
151 blr
152 EXPORT_SYMBOL(memset)
153 EXPORT_SYMBOL_KASAN(memset)
154
155
156
157
158
159
160
161
162
163
164
165
166 _GLOBAL_KASAN(memmove)
167 cmplw 0,r3,r4
168 bgt backwards_memcpy
169
170
171 _GLOBAL_KASAN(memcpy)
172 1: b generic_memcpy
173 patch_site 1b, patch__memcpy_nocache
174
175 add r7,r3,r5
176 add r8,r4,r5
177 cmplw 0,r4,r7
178 cmplw 1,r3,r8
179 crand 0,0,4
180 blt generic_memcpy
181
182 addi r4,r4,-4
183 addi r6,r3,-4
184 neg r0,r3
185 andi. r0,r0,CACHELINE_MASK
186 beq 58f
187
188 cmplw 0,r5,r0
189 blt 63f
190 andi. r8,r0,3
191 subf r5,r0,r5
192 mtctr r8
193 beq+ 61f
194 70: lbz r9,4(r4)
195 addi r4,r4,1
196 addi r6,r6,1
197 stb r9,3(r6)
198 bdnz 70b
199 61: srwi. r0,r0,2
200 mtctr r0
201 beq 58f
202 72: lwzu r9,4(r4)
203 stwu r9,4(r6)
204 bdnz 72b
205
206 58: srwi. r0,r5,LG_CACHELINE_BYTES
207 clrlwi r5,r5,32-LG_CACHELINE_BYTES
208 li r11,4
209 mtctr r0
210 beq 63f
211 53:
212 dcbz r11,r6
213 COPY_16_BYTES
214 #if L1_CACHE_BYTES >= 32
215 COPY_16_BYTES
216 #if L1_CACHE_BYTES >= 64
217 COPY_16_BYTES
218 COPY_16_BYTES
219 #if L1_CACHE_BYTES >= 128
220 COPY_16_BYTES
221 COPY_16_BYTES
222 COPY_16_BYTES
223 COPY_16_BYTES
224 #endif
225 #endif
226 #endif
227 bdnz 53b
228
229 63: srwi. r0,r5,2
230 mtctr r0
231 beq 64f
232 30: lwzu r0,4(r4)
233 stwu r0,4(r6)
234 bdnz 30b
235
236 64: andi. r0,r5,3
237 mtctr r0
238 beq+ 65f
239 addi r4,r4,3
240 addi r6,r6,3
241 40: lbzu r0,1(r4)
242 stbu r0,1(r6)
243 bdnz 40b
244 65: blr
245 EXPORT_SYMBOL(memcpy)
246 EXPORT_SYMBOL(memmove)
247 EXPORT_SYMBOL_KASAN(memcpy)
248 EXPORT_SYMBOL_KASAN(memmove)
249
250 generic_memcpy:
251 srwi. r7,r5,3
252 addi r6,r3,-4
253 addi r4,r4,-4
254 beq 2f
255 andi. r0,r6,3
256 mtctr r7
257 bne 5f
258 1: lwz r7,4(r4)
259 lwzu r8,8(r4)
260 stw r7,4(r6)
261 stwu r8,8(r6)
262 bdnz 1b
263 andi. r5,r5,7
264 2: cmplwi 0,r5,4
265 blt 3f
266 lwzu r0,4(r4)
267 addi r5,r5,-4
268 stwu r0,4(r6)
269 3: cmpwi 0,r5,0
270 beqlr
271 mtctr r5
272 addi r4,r4,3
273 addi r6,r6,3
274 4: lbzu r0,1(r4)
275 stbu r0,1(r6)
276 bdnz 4b
277 blr
278 5: subfic r0,r0,4
279 mtctr r0
280 6: lbz r7,4(r4)
281 addi r4,r4,1
282 stb r7,4(r6)
283 addi r6,r6,1
284 bdnz 6b
285 subf r5,r0,r5
286 rlwinm. r7,r5,32-3,3,31
287 beq 2b
288 mtctr r7
289 b 1b
290
291 _GLOBAL(backwards_memcpy)
292 rlwinm. r7,r5,32-3,3,31
293 add r6,r3,r5
294 add r4,r4,r5
295 beq 2f
296 andi. r0,r6,3
297 mtctr r7
298 bne 5f
299 1: lwz r7,-4(r4)
300 lwzu r8,-8(r4)
301 stw r7,-4(r6)
302 stwu r8,-8(r6)
303 bdnz 1b
304 andi. r5,r5,7
305 2: cmplwi 0,r5,4
306 blt 3f
307 lwzu r0,-4(r4)
308 subi r5,r5,4
309 stwu r0,-4(r6)
310 3: cmpwi 0,r5,0
311 beqlr
312 mtctr r5
313 4: lbzu r0,-1(r4)
314 stbu r0,-1(r6)
315 bdnz 4b
316 blr
317 5: mtctr r0
318 6: lbzu r7,-1(r4)
319 stbu r7,-1(r6)
320 bdnz 6b
321 subf r5,r0,r5
322 rlwinm. r7,r5,32-3,3,31
323 beq 2b
324 mtctr r7
325 b 1b
326
327 _GLOBAL(__copy_tofrom_user)
328 addi r4,r4,-4
329 addi r6,r3,-4
330 neg r0,r3
331 andi. r0,r0,CACHELINE_MASK
332 beq 58f
333
334 cmplw 0,r5,r0
335 blt 63f
336 andi. r8,r0,3
337 mtctr r8
338 beq+ 61f
339 70: lbz r9,4(r4)
340 71: stb r9,4(r6)
341 addi r4,r4,1
342 addi r6,r6,1
343 bdnz 70b
344 61: subf r5,r0,r5
345 srwi. r0,r0,2
346 mtctr r0
347 beq 58f
348 72: lwzu r9,4(r4)
349 73: stwu r9,4(r6)
350 bdnz 72b
351
352 EX_TABLE(70b,100f)
353 EX_TABLE(71b,101f)
354 EX_TABLE(72b,102f)
355 EX_TABLE(73b,103f)
356
357 58: srwi. r0,r5,LG_CACHELINE_BYTES
358 clrlwi r5,r5,32-LG_CACHELINE_BYTES
359 li r11,4
360 beq 63f
361
362
363 li r3,4
364 cmpwi r0,1
365 li r7,0
366 ble 114f
367 li r7,1
368 #if MAX_COPY_PREFETCH > 1
369
370
371
372 cmpwi r0,MAX_COPY_PREFETCH
373 ble 112f
374 li r7,MAX_COPY_PREFETCH
375 112: mtctr r7
376 111: dcbt r3,r4
377 addi r3,r3,CACHELINE_BYTES
378 bdnz 111b
379 #else
380 dcbt r3,r4
381 addi r3,r3,CACHELINE_BYTES
382 #endif
383
384 114: subf r8,r7,r0
385 mr r0,r7
386 mtctr r8
387
388 53: dcbt r3,r4
389 54: dcbz r11,r6
390 EX_TABLE(54b,105f)
391
392 COPY_16_BYTES_WITHEX(0)
393 #if L1_CACHE_BYTES >= 32
394 COPY_16_BYTES_WITHEX(1)
395 #if L1_CACHE_BYTES >= 64
396 COPY_16_BYTES_WITHEX(2)
397 COPY_16_BYTES_WITHEX(3)
398 #if L1_CACHE_BYTES >= 128
399 COPY_16_BYTES_WITHEX(4)
400 COPY_16_BYTES_WITHEX(5)
401 COPY_16_BYTES_WITHEX(6)
402 COPY_16_BYTES_WITHEX(7)
403 #endif
404 #endif
405 #endif
406 bdnz 53b
407 cmpwi r0,0
408 li r3,4
409 li r7,0
410 bne 114b
411
412 63: srwi. r0,r5,2
413 mtctr r0
414 beq 64f
415 30: lwzu r0,4(r4)
416 31: stwu r0,4(r6)
417 bdnz 30b
418
419 64: andi. r0,r5,3
420 mtctr r0
421 beq+ 65f
422 40: lbz r0,4(r4)
423 41: stb r0,4(r6)
424 addi r4,r4,1
425 addi r6,r6,1
426 bdnz 40b
427 65: li r3,0
428 blr
429
430
431 100: li r9,0
432 b 90f
433
434 101: li r9,1
435 90: subf r5,r8,r5
436 li r3,0
437 b 99f
438
439 102: li r9,0
440 b 91f
441
442 103: li r9,1
443 91: li r3,2
444 b 99f
445
446
447
448
449
450 COPY_16_BYTES_EXCODE(0)
451 #if L1_CACHE_BYTES >= 32
452 COPY_16_BYTES_EXCODE(1)
453 #if L1_CACHE_BYTES >= 64
454 COPY_16_BYTES_EXCODE(2)
455 COPY_16_BYTES_EXCODE(3)
456 #if L1_CACHE_BYTES >= 128
457 COPY_16_BYTES_EXCODE(4)
458 COPY_16_BYTES_EXCODE(5)
459 COPY_16_BYTES_EXCODE(6)
460 COPY_16_BYTES_EXCODE(7)
461 #endif
462 #endif
463 #endif
464
465
466 104: li r9,0
467 b 92f
468
469
470 105: li r9,1
471 92: li r3,LG_CACHELINE_BYTES
472 mfctr r8
473 add r0,r0,r8
474 b 106f
475
476 108: li r9,0
477 b 93f
478
479 109: li r9,1
480 93: andi. r5,r5,3
481 li r3,2
482 b 99f
483
484 110: li r9,0
485 b 94f
486
487 111: li r9,1
488 94: li r5,0
489 li r3,0
490
491
492
493
494 99: mfctr r0
495 106: slw r3,r0,r3
496 add. r3,r3,r5
497 beq 120f
498 cmpwi 0,r9,0
499 bne 120f
500
501 mtctr r3
502 130: lbz r0,4(r4)
503 131: stb r0,4(r6)
504 addi r4,r4,1
505 addi r6,r6,1
506 bdnz 130b
507
508 132: mfctr r3
509 120: blr
510
511 EX_TABLE(30b,108b)
512 EX_TABLE(31b,109b)
513 EX_TABLE(40b,110b)
514 EX_TABLE(41b,111b)
515 EX_TABLE(130b,132b)
516 EX_TABLE(131b,120b)
517
518 EXPORT_SYMBOL(__copy_tofrom_user)