hc
2024-08-16 a24a44ff9ca902811b99aa9663d697cf452e08ef
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
/* SPDX-License-Identifier: GPL-2.0 */
/* NGpage.S: Niagara optimize clear and copy page.
 *
 * Copyright (C) 2006 (davem@davemloft.net)
 */
 
#include <asm/asi.h>
#include <asm/page.h>
 
   .text
   .align    32
 
   /* This is heavily simplified from the sun4u variants
    * because Niagara does not have any D-cache aliasing issues
    * and also we don't need to use the FPU in order to implement
    * an optimal page copy/clear.
    */
 
NGcopy_user_page:    /* %o0=dest, %o1=src, %o2=vaddr */
   save        %sp, -192, %sp
   rd        %asi, %g3
   wr        %g0, ASI_BLK_INIT_QUAD_LDD_P, %asi
   set        PAGE_SIZE, %g7
   prefetch    [%i1 + 0x00], #one_read
   prefetch    [%i1 + 0x40], #one_read
 
1:    prefetch    [%i1 + 0x80], #one_read
   prefetch    [%i1 + 0xc0], #one_read
   ldda        [%i1 + 0x00] %asi, %o2
   ldda        [%i1 + 0x10] %asi, %o4
   ldda        [%i1 + 0x20] %asi, %l2
   ldda        [%i1 + 0x30] %asi, %l4
   stxa        %o2, [%i0 + 0x00] %asi
   stxa        %o3, [%i0 + 0x08] %asi
   stxa        %o4, [%i0 + 0x10] %asi
   stxa        %o5, [%i0 + 0x18] %asi
   stxa        %l2, [%i0 + 0x20] %asi
   stxa        %l3, [%i0 + 0x28] %asi
   stxa        %l4, [%i0 + 0x30] %asi
   stxa        %l5, [%i0 + 0x38] %asi
   ldda        [%i1 + 0x40] %asi, %o2
   ldda        [%i1 + 0x50] %asi, %o4
   ldda        [%i1 + 0x60] %asi, %l2
   ldda        [%i1 + 0x70] %asi, %l4
   stxa        %o2, [%i0 + 0x40] %asi
   stxa        %o3, [%i0 + 0x48] %asi
   stxa        %o4, [%i0 + 0x50] %asi
   stxa        %o5, [%i0 + 0x58] %asi
   stxa        %l2, [%i0 + 0x60] %asi
   stxa        %l3, [%i0 + 0x68] %asi
   stxa        %l4, [%i0 + 0x70] %asi
   stxa        %l5, [%i0 + 0x78] %asi
   add        %i1, 128, %i1
   subcc        %g7, 128, %g7
   bne,pt        %xcc, 1b
    add        %i0, 128, %i0
   wr        %g3, 0x0, %asi
   membar        #Sync
   ret
    restore
 
   .align        32
   .globl        NGclear_page
   .globl        NGclear_user_page
NGclear_page:        /* %o0=dest */
NGclear_user_page:    /* %o0=dest, %o1=vaddr */
   rd        %asi, %g3
   wr        %g0, ASI_BLK_INIT_QUAD_LDD_P, %asi
   set        PAGE_SIZE, %g7
 
1:    stxa        %g0, [%o0 + 0x00] %asi
   stxa        %g0, [%o0 + 0x08] %asi
   stxa        %g0, [%o0 + 0x10] %asi
   stxa        %g0, [%o0 + 0x18] %asi
   stxa        %g0, [%o0 + 0x20] %asi
   stxa        %g0, [%o0 + 0x28] %asi
   stxa        %g0, [%o0 + 0x30] %asi
   stxa        %g0, [%o0 + 0x38] %asi
   stxa        %g0, [%o0 + 0x40] %asi
   stxa        %g0, [%o0 + 0x48] %asi
   stxa        %g0, [%o0 + 0x50] %asi
   stxa        %g0, [%o0 + 0x58] %asi
   stxa        %g0, [%o0 + 0x60] %asi
   stxa        %g0, [%o0 + 0x68] %asi
   stxa        %g0, [%o0 + 0x70] %asi
   stxa        %g0, [%o0 + 0x78] %asi
   stxa        %g0, [%o0 + 0x80] %asi
   stxa        %g0, [%o0 + 0x88] %asi
   stxa        %g0, [%o0 + 0x90] %asi
   stxa        %g0, [%o0 + 0x98] %asi
   stxa        %g0, [%o0 + 0xa0] %asi
   stxa        %g0, [%o0 + 0xa8] %asi
   stxa        %g0, [%o0 + 0xb0] %asi
   stxa        %g0, [%o0 + 0xb8] %asi
   stxa        %g0, [%o0 + 0xc0] %asi
   stxa        %g0, [%o0 + 0xc8] %asi
   stxa        %g0, [%o0 + 0xd0] %asi
   stxa        %g0, [%o0 + 0xd8] %asi
   stxa        %g0, [%o0 + 0xe0] %asi
   stxa        %g0, [%o0 + 0xe8] %asi
   stxa        %g0, [%o0 + 0xf0] %asi
   stxa        %g0, [%o0 + 0xf8] %asi
   subcc        %g7, 256, %g7
   bne,pt        %xcc, 1b
    add        %o0, 256, %o0
   wr        %g3, 0x0, %asi
   membar        #Sync
   retl
    nop
 
#define BRANCH_ALWAYS    0x10680000
#define NOP        0x01000000
#define NG_DO_PATCH(OLD, NEW)    \
   sethi    %hi(NEW), %g1; \
   or    %g1, %lo(NEW), %g1; \
   sethi    %hi(OLD), %g2; \
   or    %g2, %lo(OLD), %g2; \
   sub    %g1, %g2, %g1; \
   sethi    %hi(BRANCH_ALWAYS), %g3; \
   sll    %g1, 11, %g1; \
   srl    %g1, 11 + 2, %g1; \
   or    %g3, %lo(BRANCH_ALWAYS), %g3; \
   or    %g3, %g1, %g3; \
   stw    %g3, [%g2]; \
   sethi    %hi(NOP), %g3; \
   or    %g3, %lo(NOP), %g3; \
   stw    %g3, [%g2 + 0x4]; \
   flush    %g2;
 
   .globl    niagara_patch_pageops
   .type    niagara_patch_pageops,#function
niagara_patch_pageops:
   NG_DO_PATCH(copy_user_page, NGcopy_user_page)
   NG_DO_PATCH(_clear_page, NGclear_page)
   NG_DO_PATCH(clear_user_page, NGclear_user_page)
   retl
    nop
   .size    niagara_patch_pageops,.-niagara_patch_pageops