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