Merge branch 'devel'
[linux-2.6] / arch / sparc / 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         membar          #Sync
45         retl
46          nop
47
48         .globl          NGclear_page, NGclear_user_page
49 NGclear_page:           /* %o0=dest */
50 NGclear_user_page:      /* %o0=dest, %o1=vaddr */
51         mov             8, %g1
52         mov             16, %g2
53         mov             24, %g3
54         set             PAGE_SIZE, %g7
55
56 1:      stxa            %g0, [%o0 + %g0] ASI_BLK_INIT_QUAD_LDD_P
57         stxa            %g0, [%o0 + %g1] ASI_BLK_INIT_QUAD_LDD_P
58         stxa            %g0, [%o0 + %g2] ASI_BLK_INIT_QUAD_LDD_P
59         stxa            %g0, [%o0 + %g3] ASI_BLK_INIT_QUAD_LDD_P
60         add             %o0, 32, %o0
61         stxa            %g0, [%o0 + %g0] ASI_BLK_INIT_QUAD_LDD_P
62         stxa            %g0, [%o0 + %g1] ASI_BLK_INIT_QUAD_LDD_P
63         stxa            %g0, [%o0 + %g2] ASI_BLK_INIT_QUAD_LDD_P
64         stxa            %g0, [%o0 + %g3] ASI_BLK_INIT_QUAD_LDD_P
65         subcc           %g7, 64, %g7
66         bne,pt          %xcc, 1b
67          add            %o0, 32, %o0
68         membar          #Sync
69         retl
70          nop
71
72 #define BRANCH_ALWAYS   0x10680000
73 #define NOP             0x01000000
74 #define NG_DO_PATCH(OLD, NEW)   \
75         sethi   %hi(NEW), %g1; \
76         or      %g1, %lo(NEW), %g1; \
77         sethi   %hi(OLD), %g2; \
78         or      %g2, %lo(OLD), %g2; \
79         sub     %g1, %g2, %g1; \
80         sethi   %hi(BRANCH_ALWAYS), %g3; \
81         sll     %g1, 11, %g1; \
82         srl     %g1, 11 + 2, %g1; \
83         or      %g3, %lo(BRANCH_ALWAYS), %g3; \
84         or      %g3, %g1, %g3; \
85         stw     %g3, [%g2]; \
86         sethi   %hi(NOP), %g3; \
87         or      %g3, %lo(NOP), %g3; \
88         stw     %g3, [%g2 + 0x4]; \
89         flush   %g2;
90
91         .globl  niagara_patch_pageops
92         .type   niagara_patch_pageops,#function
93 niagara_patch_pageops:
94         NG_DO_PATCH(copy_user_page, NGcopy_user_page)
95         NG_DO_PATCH(_clear_page, NGclear_page)
96         NG_DO_PATCH(clear_user_page, NGclear_user_page)
97         retl
98          nop
99         .size   niagara_patch_pageops,.-niagara_patch_pageops