This commit was manufactured by cvs2svn to create branch 'vserver'.
[linux-2.6.git] / arch / sparc64 / lib / NGpage.S
1 /* NGpage.S: Niagara optimize clear and copy page.
2  *
3  * Copyright (C) 2006 (davem@davemloft.net)
4  */
5
6 #include <asm/asi.h>
7 #include <asm/page.h>
8
9         .text
10         .align  32
11
12         /* This is heavily simplified from the sun4u variants
13          * because Niagara does not have any D-cache aliasing issues
14          * and also we don't need to use the FPU in order to implement
15          * an optimal page copy/clear.
16          */
17
18 NGcopy_user_page:       /* %o0=dest, %o1=src, %o2=vaddr */
19         prefetch        [%o1 + 0x00], #one_read
20         mov             8, %g1
21         mov             16, %g2
22         mov             24, %g3
23         set             PAGE_SIZE, %g7
24
25 1:      ldda            [%o1 + %g0] ASI_BLK_INIT_QUAD_LDD_P, %o2
26         ldda            [%o1 + %g2] ASI_BLK_INIT_QUAD_LDD_P, %o4
27         prefetch        [%o1 + 0x40], #one_read
28         add             %o1, 32, %o1
29         stxa            %o2, [%o0 + %g0] ASI_BLK_INIT_QUAD_LDD_P
30         stxa            %o3, [%o0 + %g1] ASI_BLK_INIT_QUAD_LDD_P
31         ldda            [%o1 + %g0] ASI_BLK_INIT_QUAD_LDD_P, %o2
32         stxa            %o4, [%o0 + %g2] ASI_BLK_INIT_QUAD_LDD_P
33         stxa            %o5, [%o0 + %g3] ASI_BLK_INIT_QUAD_LDD_P
34         ldda            [%o1 + %g2] ASI_BLK_INIT_QUAD_LDD_P, %o4
35         add             %o1, 32, %o1
36         add             %o0, 32, %o0
37         stxa            %o2, [%o0 + %g0] ASI_BLK_INIT_QUAD_LDD_P
38         stxa            %o3, [%o0 + %g1] ASI_BLK_INIT_QUAD_LDD_P
39         stxa            %o4, [%o0 + %g2] ASI_BLK_INIT_QUAD_LDD_P
40         stxa            %o5, [%o0 + %g3] ASI_BLK_INIT_QUAD_LDD_P
41         subcc           %g7, 64, %g7
42         bne,pt          %xcc, 1b
43          add            %o0, 32, %o0
44         retl
45          nop
46
47 NGclear_page:           /* %o0=dest */
48 NGclear_user_page:      /* %o0=dest, %o1=vaddr */
49         mov             8, %g1
50         mov             16, %g2
51         mov             24, %g3
52         set             PAGE_SIZE, %g7
53
54 1:      stxa            %g0, [%o0 + %g0] ASI_BLK_INIT_QUAD_LDD_P
55         stxa            %g0, [%o0 + %g1] ASI_BLK_INIT_QUAD_LDD_P
56         stxa            %g0, [%o0 + %g2] ASI_BLK_INIT_QUAD_LDD_P
57         stxa            %g0, [%o0 + %g3] ASI_BLK_INIT_QUAD_LDD_P
58         add             %o0, 32, %o0
59         stxa            %g0, [%o0 + %g0] ASI_BLK_INIT_QUAD_LDD_P
60         stxa            %g0, [%o0 + %g1] ASI_BLK_INIT_QUAD_LDD_P
61         stxa            %g0, [%o0 + %g2] ASI_BLK_INIT_QUAD_LDD_P
62         stxa            %g0, [%o0 + %g3] ASI_BLK_INIT_QUAD_LDD_P
63         subcc           %g7, 64, %g7
64         bne,pt          %xcc, 1b
65          add            %o0, 32, %o0
66         retl
67          nop
68
69 #define BRANCH_ALWAYS   0x10680000
70 #define NOP             0x01000000
71 #define NG_DO_PATCH(OLD, NEW)   \
72         sethi   %hi(NEW), %g1; \
73         or      %g1, %lo(NEW), %g1; \
74         sethi   %hi(OLD), %g2; \
75         or      %g2, %lo(OLD), %g2; \
76         sub     %g1, %g2, %g1; \
77         sethi   %hi(BRANCH_ALWAYS), %g3; \
78         sll     %g1, 11, %g1; \
79         srl     %g1, 11 + 2, %g1; \
80         or      %g3, %lo(BRANCH_ALWAYS), %g3; \
81         or      %g3, %g1, %g3; \
82         stw     %g3, [%g2]; \
83         sethi   %hi(NOP), %g3; \
84         or      %g3, %lo(NOP), %g3; \
85         stw     %g3, [%g2 + 0x4]; \
86         flush   %g2;
87
88         .globl  niagara_patch_pageops
89         .type   niagara_patch_pageops,#function
90 niagara_patch_pageops:
91         NG_DO_PATCH(copy_user_page, NGcopy_user_page)
92         NG_DO_PATCH(_clear_page, NGclear_page)
93         NG_DO_PATCH(clear_user_page, NGclear_user_page)
94         retl
95          nop
96         .size   niagara_patch_pageops,.-niagara_patch_pageops