http://www.usr.com/support/gpl/USR9107_release1.1.tar.gz
[bcm963xx.git] / kernel / linux / arch / sh / mm / clear_page.S
1 /* $Id: clear_page.S,v 1.13 2003/08/25 17:03:10 lethal Exp $
2  *
3  * __clear_user_page, __clear_user, clear_page implementation of SuperH
4  *
5  * Copyright (C) 2001  Kaz Kojima
6  * Copyright (C) 2001, 2002  Niibe Yutaka
7  *
8  */
9 #include <linux/config.h>
10 #include <linux/linkage.h>
11
12 /*
13  * clear_page_slow
14  * @to: P1 address
15  *
16  * void clear_page_slow(void *to)
17  */
18
19 /*
20  * r0 --- scratch
21  * r4 --- to
22  * r5 --- to + 4096
23  */
24 ENTRY(clear_page_slow)
25         mov     r4,r5
26         mov.w   .Llimit,r0
27         add     r0,r5
28         mov     #0,r0
29         !
30 1:
31 #if defined(CONFIG_CPU_SH3)
32         mov.l   r0,@r4
33 #elif defined(CONFIG_CPU_SH4)
34         movca.l r0,@r4
35         mov     r4,r1
36 #endif
37         add     #32,r4
38         mov.l   r0,@-r4
39         mov.l   r0,@-r4
40         mov.l   r0,@-r4
41         mov.l   r0,@-r4
42         mov.l   r0,@-r4
43         mov.l   r0,@-r4
44         mov.l   r0,@-r4
45 #if defined(CONFIG_CPU_SH4)
46         ocbwb   @r1
47 #endif
48         cmp/eq  r5,r4
49         bf/s    1b
50          add    #28,r4
51         !
52         rts
53          nop
54 .Llimit:        .word   (4096-28)
55
56 ENTRY(__clear_user)
57         !
58         mov     #0, r0
59         mov     #0xe0, r1       ! 0xffffffe0
60         !
61         ! r4..(r4+31)&~32          -------- not aligned [ Area 0 ]
62         ! (r4+31)&~32..(r4+r5)&~32 -------- aligned     [ Area 1 ]
63         ! (r4+r5)&~32..r4+r5       -------- not aligned [ Area 2 ]
64         !
65         ! Clear area 0
66         mov     r4, r2
67         !
68         tst     r1, r5          ! length < 32
69         bt      .Larea2         ! skip to remainder
70         !
71         add     #31, r2
72         and     r1, r2
73         cmp/eq  r4, r2
74         bt      .Larea1
75         mov     r2, r3
76         sub     r4, r3
77         mov     r3, r7
78         mov     r4, r2
79         !
80 .L0:    dt      r3
81 0:      mov.b   r0, @r2
82         bf/s    .L0
83          add    #1, r2
84         !
85         sub     r7, r5
86         mov     r2, r4
87 .Larea1:
88         mov     r4, r3
89         add     r5, r3
90         and     r1, r3
91         cmp/hi  r2, r3
92         bf      .Larea2
93         !
94         ! Clear area 1
95 #if defined(CONFIG_CPU_SH4)
96 1:      movca.l r0, @r2
97 #else
98 1:      mov.l   r0, @r2
99 #endif
100         add     #4, r2
101 2:      mov.l   r0, @r2
102         add     #4, r2
103 3:      mov.l   r0, @r2
104         add     #4, r2
105 4:      mov.l   r0, @r2
106         add     #4, r2
107 5:      mov.l   r0, @r2
108         add     #4, r2
109 6:      mov.l   r0, @r2
110         add     #4, r2
111 7:      mov.l   r0, @r2
112         add     #4, r2
113 8:      mov.l   r0, @r2
114         add     #4, r2
115         cmp/hi  r2, r3
116         bt/s    1b
117          nop
118         !
119         ! Clear area 2
120 .Larea2:
121         mov     r4, r3
122         add     r5, r3
123         cmp/hs  r3, r2
124         bt/s    .Ldone
125          sub    r2, r3
126 .L2:    dt      r3
127 9:      mov.b   r0, @r2
128         bf/s    .L2
129          add    #1, r2
130         !
131 .Ldone: rts
132          mov    #0, r0  ! return 0 as normal return
133
134         ! return the number of bytes remained
135 .Lbad_clear_user:
136         mov     r4, r0
137         add     r5, r0
138         rts
139          sub    r2, r0
140
141 .section __ex_table,"a"
142         .align 2
143         .long   0b, .Lbad_clear_user
144         .long   1b, .Lbad_clear_user
145         .long   2b, .Lbad_clear_user
146         .long   3b, .Lbad_clear_user
147         .long   4b, .Lbad_clear_user
148         .long   5b, .Lbad_clear_user
149         .long   6b, .Lbad_clear_user
150         .long   7b, .Lbad_clear_user
151         .long   8b, .Lbad_clear_user
152         .long   9b, .Lbad_clear_user
153 .previous
154
155 #if defined(CONFIG_CPU_SH4)
156 /*
157  * __clear_user_page
158  * @to: P3 address (with same color)
159  * @orig_to: P1 address
160  *
161  * void __clear_user_page(void *to, void *orig_to)
162  */
163
164 /*
165  * r0 --- scratch 
166  * r4 --- to
167  * r5 --- orig_to
168  * r6 --- to + 4096
169  */
170 ENTRY(__clear_user_page)
171         mov.w   .L4096,r0
172         mov     r4,r6
173         add     r0,r6
174         mov     #0,r0
175         !
176 1:      ocbi    @r5
177         add     #32,r5
178         movca.l r0,@r4
179         mov     r4,r1
180         add     #32,r4
181         mov.l   r0,@-r4
182         mov.l   r0,@-r4
183         mov.l   r0,@-r4
184         mov.l   r0,@-r4
185         mov.l   r0,@-r4
186         mov.l   r0,@-r4
187         mov.l   r0,@-r4
188         add     #28,r4
189         cmp/eq  r6,r4
190         bf/s    1b
191          ocbwb  @r1
192         !
193         rts
194          nop
195 .L4096: .word   4096
196
197 ENTRY(__flush_cache_4096)
198         mov.l   1f,r3
199         add     r6,r3
200         mov     r4,r0
201         mov     #64,r2
202         shll    r2
203         mov     #64,r6
204         jmp     @r3
205          mov    #96,r7
206         .align  2
207 1:      .long   2f
208 2:
209         .rept   32
210         mov.l   r5,@r0
211         mov.l   r5,@(32,r0)
212         mov.l   r5,@(r0,r6)
213         mov.l   r5,@(r0,r7)
214         add     r2,r5
215         add     r2,r0
216         .endr
217         nop
218         nop
219         nop
220         nop
221         nop
222         nop
223         nop
224         rts
225          nop
226
227 ENTRY(__flush_dcache_all)
228         mov.l   2f,r0
229         mov.l   3f,r4
230         and     r0,r4           ! r4 = (unsigned long)&empty_zero_page[0] & ~0xffffc000
231         stc     sr,r1           ! save SR
232         mov.l   4f,r2
233         or      r1,r2
234         mov     #32,r3
235         shll2   r3
236 1:
237         ldc     r2,sr           ! set BL bit
238         movca.l r0,@r4
239         ocbi    @r4
240         add     #32,r4
241         movca.l r0,@r4
242         ocbi    @r4
243         add     #32,r4
244         movca.l r0,@r4
245         ocbi    @r4
246         add     #32,r4
247         movca.l r0,@r4
248         ocbi    @r4
249         ldc     r1,sr           ! restore SR
250         dt      r3
251         bf/s    1b
252          add    #32,r4
253
254         rts
255          nop
256         .align  2
257 2:      .long   0xffffc000
258 3:      .long   empty_zero_page
259 4:      .long   0x10000000      ! BL bit
260
261 /* __flush_cache_4096_all(unsigned long addr) */
262 ENTRY(__flush_cache_4096_all)
263         mov.l   2f,r0
264         mov.l   3f,r2
265         and     r0,r2
266         or      r2,r4           ! r4 = addr | (unsigned long)&empty_zero_page[0] & ~0x3fff
267         stc     sr,r1           ! save SR
268         mov.l   4f,r2
269         or      r1,r2
270         mov     #32,r3
271 1:
272         ldc     r2,sr           ! set BL bit
273         movca.l r0,@r4
274         ocbi    @r4
275         add     #32,r4
276         movca.l r0,@r4
277         ocbi    @r4
278         add     #32,r4
279         movca.l r0,@r4
280         ocbi    @r4
281         add     #32,r4
282         movca.l r0,@r4
283         ocbi    @r4
284         ldc     r1,sr           ! restore SR
285         dt      r3
286         bf/s    1b
287          add    #32,r4
288
289         rts
290          nop
291         .align  2
292 2:      .long   0xffffc000
293 3:      .long   empty_zero_page
294 4:      .long   0x10000000      ! BL bit
295 #endif