import of upstream 2.4.34.4 from kernel.org
[linux-2.4.git] / arch / sparc64 / lib / blockops.S
1 /* $Id: blockops.S,v 1.41 2001/12/05 06:05:35 davem Exp $
2  * blockops.S: UltraSparc block zero optimized routines.
3  *
4  * Copyright (C) 1996, 1998, 1999, 2000 David S. Miller (davem@redhat.com)
5  * Copyright (C) 1997 Jakub Jelinek (jakub@redhat.com)
6  */
7
8 #include "VIS.h"
9 #include <asm/visasm.h>
10 #include <asm/page.h>
11 #include <asm/dcu.h>
12 #include <asm/spitfire.h>
13 #include <asm/pgtable.h>
14 #include <asm/asm_offsets.h>
15
16 #define TOUCH(reg0, reg1, reg2, reg3, reg4, reg5, reg6, reg7)   \
17         fmovd   %reg0, %f48;    fmovd   %reg1, %f50;            \
18         fmovd   %reg2, %f52;    fmovd   %reg3, %f54;            \
19         fmovd   %reg4, %f56;    fmovd   %reg5, %f58;            \
20         fmovd   %reg6, %f60;    fmovd   %reg7, %f62;
21
22 #define DCACHE_SIZE     (PAGE_SIZE * 2)
23 #define TLBTEMP_ENT1    (60 << 3)
24 #define TLBTEMP_ENT2    (61 << 3)
25 #define TLBTEMP_ENTSZ   (1 << 3)
26
27 #if (PAGE_SHIFT == 13) || (PAGE_SHIFT == 19)
28 #define PAGE_SIZE_REM   0x80
29 #elif (PAGE_SHIFT == 16) || (PAGE_SHIFT == 22)
30 #define PAGE_SIZE_REM   0x100
31 #else
32 #error Wrong PAGE_SHIFT specified
33 #endif
34
35         .text
36
37         .align          32
38         .globl          copy_user_page
39         .type           copy_user_page,@function
40 copy_user_page: /* %o0=dest, %o1=src, %o2=vaddr */
41         VISEntry
42         sethi           %hi(PAGE_SIZE), %g3
43         sub             %o0, %g4, %g1
44         and             %o2, %g3, %o0
45         sethi           %hi(TLBTEMP_BASE), %o3
46         sethi           %uhi(_PAGE_VALID | _PAGE_SZBITS), %g3
47         sub             %o1, %g4, %g2
48         sllx            %g3, 32, %g3
49         mov             TLB_TAG_ACCESS, %o2
50         or              %g3, (_PAGE_CP | _PAGE_CV | _PAGE_P | _PAGE_L | _PAGE_W), %g3
51         sethi           %hi(DCACHE_SIZE), %o1
52         or              %g1, %g3, %g1
53         or              %g2, %g3, %g2
54         add             %o0, %o3, %o0
55         add             %o0, %o1, %o1
56 #define FIX_INSN_1      0x96102060 /* mov (12 << 3), %o3 */
57 cheetah_patch_1:
58         mov             TLBTEMP_ENT1, %o3
59         rdpr            %pstate, %g3
60         wrpr            %g3, PSTATE_IE, %pstate
61
62         /* Do this now, before loading the fixed TLB entries for copying,
63          * so we do not risk a multiple TLB match condition later when
64          * restoring those entries.
65          */
66         ldub            [%g6 + AOFF_task_thread + AOFF_thread_use_blkcommit], %g3
67
68         /* Spitfire Errata #32 workaround */
69         mov             PRIMARY_CONTEXT, %o4
70         stxa            %g0, [%o4] ASI_DMMU
71         membar          #Sync
72
73         ldxa            [%o3] ASI_DTLB_TAG_READ, %o4
74
75         /* Spitfire Errata #32 workaround */
76         mov             PRIMARY_CONTEXT, %o5
77         stxa            %g0, [%o5] ASI_DMMU
78         membar          #Sync
79
80         ldxa            [%o3] ASI_DTLB_DATA_ACCESS, %g0
81         ldxa            [%o3] ASI_DTLB_DATA_ACCESS, %o5
82         stxa            %o0, [%o2] ASI_DMMU
83         stxa            %g1, [%o3] ASI_DTLB_DATA_ACCESS
84         membar          #Sync
85         add             %o3, (TLBTEMP_ENTSZ), %o3
86
87         /* Spitfire Errata #32 workaround */
88         mov             PRIMARY_CONTEXT, %g5
89         stxa            %g0, [%g5] ASI_DMMU
90         membar          #Sync
91
92         ldxa            [%o3] ASI_DTLB_TAG_READ, %g5
93
94         /* Spitfire Errata #32 workaround */
95         mov             PRIMARY_CONTEXT, %g7
96         stxa            %g0, [%g7] ASI_DMMU
97         membar          #Sync
98
99         ldxa            [%o3] ASI_DTLB_DATA_ACCESS, %g0
100         ldxa            [%o3] ASI_DTLB_DATA_ACCESS, %g7
101         stxa            %o1, [%o2] ASI_DMMU
102         stxa            %g2, [%o3] ASI_DTLB_DATA_ACCESS
103         membar          #Sync
104
105         cmp             %g3, 0
106         bne,pn          %xcc, copy_page_using_blkcommit
107          nop
108
109         BRANCH_IF_ANY_CHEETAH(g3,o2,cheetah_copy_user_page)
110         ba,pt           %xcc, spitfire_copy_user_page
111          nop
112
113 cheetah_copy_user_page:
114         .globl          cheetah_copy_user_page_nop_1_6
115 cheetah_copy_user_page_nop_1_6:
116         ldxa            [%g0] ASI_DCU_CONTROL_REG, %g3
117         sethi           %uhi(DCU_PE), %o2
118         sllx            %o2, 32, %o2
119         or              %g3, %o2, %o2
120         stxa            %o2, [%g0] ASI_DCU_CONTROL_REG  ! Enable P-cache
121         membar          #Sync
122
123         sethi           %hi((PAGE_SIZE/64)-7), %o2      ! A0 Group
124         prefetch        [%o1 + 0x000], #one_read        ! MS
125         or              %o2, %lo((PAGE_SIZE/64)-7), %o2 ! A1 Group
126         prefetch        [%o1 + 0x040], #one_read        ! MS
127         prefetch        [%o1 + 0x080], #one_read        ! MS Group
128         prefetch        [%o1 + 0x0c0], #one_read        ! MS Group
129         ldd             [%o1 + 0x000], %f0              ! MS Group
130         prefetch        [%o1 + 0x100], #one_read        ! MS Group
131         ldd             [%o1 + 0x008], %f2              ! AX
132         prefetch        [%o1 + 0x140], #one_read        ! MS Group
133         ldd             [%o1 + 0x010], %f4              ! AX
134         prefetch        [%o1 + 0x180], #one_read        ! MS Group
135         fmovd           %f0, %f32                       ! FGA Group
136         ldd             [%o1 + 0x018], %f6              ! AX
137         fmovd           %f2, %f34                       ! FGA Group
138         ldd             [%o1 + 0x020], %f8              ! MS
139         fmovd           %f4, %f36                       ! FGA Group
140         ldd             [%o1 + 0x028], %f10             ! AX
141         membar          #StoreStore                     ! MS
142         fmovd           %f6, %f38                       ! FGA Group
143         ldd             [%o1 + 0x030], %f12             ! MS
144         fmovd           %f8, %f40                       ! FGA Group
145         ldd             [%o1 + 0x038], %f14             ! AX
146         fmovd           %f10, %f42                      ! FGA Group
147         ldd             [%o1 + 0x040], %f16             ! MS
148 1:      ldd             [%o1 + 0x048], %f2              ! AX (Group)
149         fmovd           %f12, %f44                      ! FGA
150         ldd             [%o1 + 0x050], %f4              ! MS
151         fmovd           %f14, %f46                      ! FGA Group
152         stda            %f32, [%o0] ASI_BLK_P           ! MS
153         ldd             [%o1 + 0x058], %f6              ! AX
154         fmovd           %f16, %f32                      ! FGA Group (8-cycle stall)
155         ldd             [%o1 + 0x060], %f8              ! MS
156         fmovd           %f2, %f34                       ! FGA Group
157         ldd             [%o1 + 0x068], %f10             ! AX
158         fmovd           %f4, %f36                       ! FGA Group
159         ldd             [%o1 + 0x070], %f12             ! MS
160         fmovd           %f6, %f38                       ! FGA Group
161         ldd             [%o1 + 0x078], %f14             ! AX
162         fmovd           %f8, %f40                       ! FGA Group
163         ldd             [%o1 + 0x080], %f16             ! AX
164         prefetch        [%o1 + 0x180], #one_read        ! MS
165         fmovd           %f10, %f42                      ! FGA Group
166         subcc           %o2, 1, %o2                     ! A0
167         add             %o0, 0x40, %o0                  ! A1
168         bne,pt          %xcc, 1b                        ! BR
169          add            %o1, 0x40, %o1                  ! A0 Group
170
171         mov             5, %o2                          ! A0 Group
172 1:      ldd             [%o1 + 0x048], %f2              ! AX
173         fmovd           %f12, %f44                      ! FGA
174         ldd             [%o1 + 0x050], %f4              ! MS
175         fmovd           %f14, %f46                      ! FGA Group
176         stda            %f32, [%o0] ASI_BLK_P           ! MS
177         ldd             [%o1 + 0x058], %f6              ! AX
178         fmovd           %f16, %f32                      ! FGA Group (8-cycle stall)
179         ldd             [%o1 + 0x060], %f8              ! MS
180         fmovd           %f2, %f34                       ! FGA Group
181         ldd             [%o1 + 0x068], %f10             ! AX
182         fmovd           %f4, %f36                       ! FGA Group
183         ldd             [%o1 + 0x070], %f12             ! MS
184         fmovd           %f6, %f38                       ! FGA Group
185         ldd             [%o1 + 0x078], %f14             ! AX
186         fmovd           %f8, %f40                       ! FGA Group
187         ldd             [%o1 + 0x080], %f16             ! MS
188         fmovd           %f10, %f42                      ! FGA Group
189         subcc           %o2, 1, %o2                     ! A0
190         add             %o0, 0x40, %o0                  ! A1
191         bne,pt          %xcc, 1b                        ! BR
192          add            %o1, 0x40, %o1                  ! A0 Group
193
194         ldd             [%o1 + 0x048], %f2              ! AX
195         fmovd           %f12, %f44                      ! FGA
196         ldd             [%o1 + 0x050], %f4              ! MS
197         fmovd           %f14, %f46                      ! FGA Group
198         stda            %f32, [%o0] ASI_BLK_P           ! MS
199         ldd             [%o1 + 0x058], %f6              ! AX
200         fmovd           %f16, %f32                      ! FGA Group (8-cycle stall)
201         ldd             [%o1 + 0x060], %f8              ! MS
202         fmovd           %f2, %f34                       ! FGA Group
203         ldd             [%o1 + 0x068], %f10             ! AX
204         fmovd           %f4, %f36                       ! FGA Group
205         ldd             [%o1 + 0x070], %f12             ! MS
206         fmovd           %f6, %f38                       ! FGA Group
207         add             %o0, 0x40, %o0                  ! A0
208         ldd             [%o1 + 0x078], %f14             ! AX
209         fmovd           %f8, %f40                       ! FGA Group
210         fmovd           %f10, %f42                      ! FGA Group
211         fmovd           %f12, %f44                      ! FGA Group
212         fmovd           %f14, %f46                      ! FGA Group
213         stda            %f32, [%o0] ASI_BLK_P           ! MS
214         .globl          cheetah_copy_user_page_nop_2_3
215 cheetah_copy_user_page_nop_2_3:
216         mov             PRIMARY_CONTEXT, %o2
217         stxa            %g0, [%o2] ASI_DMMU             ! Flush P-cache
218         stxa            %g3, [%g0] ASI_DCU_CONTROL_REG  ! Disable P-cache
219         ba,a,pt         %xcc, copy_user_page_continue
220
221 spitfire_copy_user_page:
222         ldda            [%o1] ASI_BLK_P, %f0
223         add             %o1, 0x40, %o1
224         ldda            [%o1] ASI_BLK_P, %f16
225         add             %o1, 0x40, %o1
226         sethi           %hi(PAGE_SIZE), %o2
227 1:      TOUCH(f0, f2, f4, f6, f8, f10, f12, f14)
228         ldda            [%o1] ASI_BLK_P, %f32
229         stda            %f48, [%o0] ASI_BLK_P
230         add             %o1, 0x40, %o1
231         sub             %o2, 0x40, %o2
232         add             %o0, 0x40, %o0
233         TOUCH(f16, f18, f20, f22, f24, f26, f28, f30)
234         ldda            [%o1] ASI_BLK_P, %f0
235         stda            %f48, [%o0] ASI_BLK_P
236         add             %o1, 0x40, %o1
237         sub             %o2, 0x40, %o2
238         add             %o0, 0x40, %o0
239         TOUCH(f32, f34, f36, f38, f40, f42, f44, f46)
240         ldda            [%o1] ASI_BLK_P, %f16
241         stda            %f48, [%o0] ASI_BLK_P
242         sub             %o2, 0x40, %o2
243         add             %o1, 0x40, %o1
244         cmp             %o2, PAGE_SIZE_REM
245         bne,pt          %xcc, 1b
246          add            %o0, 0x40, %o0
247 #if (PAGE_SHIFT == 16) || (PAGE_SHIFT == 22)
248         TOUCH(f0, f2, f4, f6, f8, f10, f12, f14)
249         ldda            [%o1] ASI_BLK_P, %f32
250         stda            %f48, [%o0] ASI_BLK_P
251         add             %o1, 0x40, %o1
252         sub             %o2, 0x40, %o2
253         add             %o0, 0x40, %o0
254         TOUCH(f16, f18, f20, f22, f24, f26, f28, f30)
255         ldda            [%o1] ASI_BLK_P, %f0
256         stda            %f48, [%o0] ASI_BLK_P
257         add             %o1, 0x40, %o1
258         sub             %o2, 0x40, %o2
259         add             %o0, 0x40, %o0
260         membar          #Sync
261         stda            %f32, [%o0] ASI_BLK_P
262         add             %o0, 0x40, %o0
263         stda            %f0, [%o0] ASI_BLK_P
264 #else
265         membar          #Sync
266         stda            %f0, [%o0] ASI_BLK_P
267         add             %o0, 0x40, %o0
268         stda            %f16, [%o0] ASI_BLK_P
269 #endif
270 copy_user_page_continue:
271         membar          #Sync
272         VISExit
273
274         mov             TLB_TAG_ACCESS, %o2
275         stxa            %g5, [%o2] ASI_DMMU
276         stxa            %g7, [%o3] ASI_DTLB_DATA_ACCESS
277         membar          #Sync
278         sub             %o3, (TLBTEMP_ENTSZ), %o3
279         stxa            %o4, [%o2] ASI_DMMU
280         stxa            %o5, [%o3] ASI_DTLB_DATA_ACCESS
281         membar          #Sync
282         rdpr            %pstate, %g3
283         jmpl            %o7 + 0x8, %g0
284          wrpr           %g3, PSTATE_IE, %pstate
285
286 copy_page_using_blkcommit:
287         membar          #LoadStore | #StoreStore | #StoreLoad
288         ldda            [%o1] ASI_BLK_P, %f0
289         add             %o1, 0x40, %o1
290         ldda            [%o1] ASI_BLK_P, %f16
291         add             %o1, 0x40, %o1
292         sethi           %hi(PAGE_SIZE), %o2
293 1:      TOUCH(f0, f2, f4, f6, f8, f10, f12, f14)
294         ldda            [%o1] ASI_BLK_P, %f32
295         stda            %f48, [%o0] ASI_BLK_COMMIT_P
296         add             %o1, 0x40, %o1
297         sub             %o2, 0x40, %o2
298         add             %o0, 0x40, %o0
299         TOUCH(f16, f18, f20, f22, f24, f26, f28, f30)
300         ldda            [%o1] ASI_BLK_P, %f0
301         stda            %f48, [%o0] ASI_BLK_COMMIT_P
302         add             %o1, 0x40, %o1
303         sub             %o2, 0x40, %o2
304         add             %o0, 0x40, %o0
305         TOUCH(f32, f34, f36, f38, f40, f42, f44, f46)
306         ldda            [%o1] ASI_BLK_P, %f16
307         stda            %f48, [%o0] ASI_BLK_COMMIT_P
308         sub             %o2, 0x40, %o2
309         add             %o1, 0x40, %o1
310         cmp             %o2, PAGE_SIZE_REM
311         bne,pt          %xcc, 1b
312          add            %o0, 0x40, %o0
313 #if (PAGE_SHIFT == 16) || (PAGE_SHIFT == 22)
314         TOUCH(f0, f2, f4, f6, f8, f10, f12, f14)
315         ldda            [%o1] ASI_BLK_P, %f32
316         stda            %f48, [%o0] ASI_BLK_COMMIT_P
317         add             %o1, 0x40, %o1
318         sub             %o2, 0x40, %o2
319         add             %o0, 0x40, %o0
320         TOUCH(f16, f18, f20, f22, f24, f26, f28, f30)
321         ldda            [%o1] ASI_BLK_P, %f0
322         stda            %f48, [%o0] ASI_BLK_COMMIT_P
323         add             %o1, 0x40, %o1
324         sub             %o2, 0x40, %o2
325         add             %o0, 0x40, %o0
326         membar          #Sync
327         stda            %f32, [%o0] ASI_BLK_COMMIT_P
328         add             %o0, 0x40, %o0
329         ba,pt           %xcc, copy_user_page_continue
330          stda           %f0, [%o0] ASI_BLK_COMMIT_P
331 #else
332         membar          #Sync
333         stda            %f0, [%o0] ASI_BLK_COMMIT_P
334         add             %o0, 0x40, %o0
335         ba,pt           %xcc, copy_user_page_continue
336          stda           %f16, [%o0] ASI_BLK_COMMIT_P
337 #endif
338
339         .align          32
340         .globl          _clear_page
341         .type           _clear_page,@function
342 _clear_page:    /* %o0=dest */
343         VISEntryHalf
344         ba,pt           %xcc, clear_page_common
345          clr            %o4
346
347         .align          32
348         .globl          clear_user_page
349         .type           clear_user_page,@function
350 clear_user_page:        /* %o0=dest, %o1=vaddr */
351         VISEntryHalf
352         sethi           %hi(PAGE_SIZE), %g3
353         sub             %o0, %g4, %g1
354         and             %o1, %g3, %o0
355         mov             TLB_TAG_ACCESS, %o2
356         sethi           %uhi(_PAGE_VALID | _PAGE_SZBITS), %g3
357         sethi           %hi(TLBTEMP_BASE), %o3
358         sllx            %g3, 32, %g3
359         or              %g3, (_PAGE_CP | _PAGE_CV | _PAGE_P | _PAGE_L | _PAGE_W), %g3
360         or              %g1, %g3, %g1
361         add             %o0, %o3, %o0
362 #define FIX_INSN_2      0x96102068 /* mov (13 << 3), %o3 */
363 cheetah_patch_2:
364         mov             TLBTEMP_ENT2, %o3
365         rdpr            %pstate, %g3
366         wrpr            %g3, PSTATE_IE, %pstate
367
368         /* Spitfire Errata #32 workaround */
369         mov             PRIMARY_CONTEXT, %g5
370         stxa            %g0, [%g5] ASI_DMMU
371         membar          #Sync
372
373         ldxa            [%o3] ASI_DTLB_TAG_READ, %g5
374
375         /* Spitfire Errata #32 workaround */
376         mov             PRIMARY_CONTEXT, %g7
377         stxa            %g0, [%g7] ASI_DMMU
378         membar          #Sync
379
380         ldxa            [%o3] ASI_DTLB_DATA_ACCESS, %g0
381         ldxa            [%o3] ASI_DTLB_DATA_ACCESS, %g7
382         stxa            %o0, [%o2] ASI_DMMU
383         stxa            %g1, [%o3] ASI_DTLB_DATA_ACCESS
384         membar          #Sync
385
386         mov             1, %o4
387
388 clear_page_common:
389         membar          #StoreLoad | #StoreStore | #LoadStore   ! LSU   Group
390         fzero           %f0                             ! FPA   Group
391         sethi           %hi(PAGE_SIZE/256), %o1         ! IEU0
392         fzero           %f2                             ! FPA   Group
393         or              %o1, %lo(PAGE_SIZE/256), %o1    ! IEU0
394         faddd           %f0, %f2, %f4                   ! FPA   Group
395         fmuld           %f0, %f2, %f6                   ! FPM
396         faddd           %f0, %f2, %f8                   ! FPA   Group
397         fmuld           %f0, %f2, %f10                  ! FPM
398
399         faddd           %f0, %f2, %f12                  ! FPA   Group
400         fmuld           %f0, %f2, %f14                  ! FPM
401 1:      stda            %f0, [%o0 + %g0] ASI_BLK_P      ! Store Group
402         add             %o0, 0x40, %o0                  ! IEU0
403         stda            %f0, [%o0 + %g0] ASI_BLK_P      ! Store Group
404         add             %o0, 0x40, %o0                  ! IEU0
405         stda            %f0, [%o0 + %g0] ASI_BLK_P      ! Store Group
406
407         add             %o0, 0x40, %o0                  ! IEU0  Group
408         stda            %f0, [%o0 + %g0] ASI_BLK_P      ! Store Group
409         subcc           %o1, 1, %o1                     ! IEU1
410         bne,pt          %icc, 1b                        ! CTI
411          add            %o0, 0x40, %o0                  ! IEU0  Group
412         membar          #Sync                           ! LSU   Group
413         VISExitHalf
414
415         brnz,pt         %o4, 1f
416          nop
417
418         retl
419          nop
420
421 1:
422         stxa            %g5, [%o2] ASI_DMMU
423         stxa            %g7, [%o3] ASI_DTLB_DATA_ACCESS
424         membar          #Sync
425         jmpl            %o7 + 0x8, %g0
426          wrpr           %g3, 0x0, %pstate
427
428         .globl          cheetah_patch_pgcopyops
429 cheetah_patch_pgcopyops:
430         sethi           %hi(FIX_INSN_1), %g1
431         or              %g1, %lo(FIX_INSN_1), %g1
432         sethi           %hi(cheetah_patch_1), %g2
433         or              %g2, %lo(cheetah_patch_1), %g2
434         stw             %g1, [%g2]
435         flush           %g2
436         sethi           %hi(FIX_INSN_2), %g1
437         or              %g1, %lo(FIX_INSN_2), %g1
438         sethi           %hi(cheetah_patch_2), %g2
439         or              %g2, %lo(cheetah_patch_2), %g2
440         stw             %g1, [%g2]
441         flush           %g2
442         retl
443          nop
444
445 #undef FIX_INSN1
446 #undef FIX_INSN2
447 #undef PAGE_SIZE_REM