blob: ae58a61f0e660263014356c524baae0769dd98d3 [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/* $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 */
24ENTRY(clear_page_slow)
25 mov r4,r5
26 mov.w .Llimit,r0
27 add r0,r5
28 mov #0,r0
29 !
301:
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
56ENTRY(__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
810: 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)
961: movca.l r0, @r2
97#else
981: mov.l r0, @r2
99#endif
100 add #4, r2
1012: mov.l r0, @r2
102 add #4, r2
1033: mov.l r0, @r2
104 add #4, r2
1054: mov.l r0, @r2
106 add #4, r2
1075: mov.l r0, @r2
108 add #4, r2
1096: mov.l r0, @r2
110 add #4, r2
1117: mov.l r0, @r2
112 add #4, r2
1138: 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
1279: 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 */
170ENTRY(__clear_user_page)
171 mov.w .L4096,r0
172 mov r4,r6
173 add r0,r6
174 mov #0,r0
175 !
1761: 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
197ENTRY(__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
2071: .long 2f
2082:
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
227ENTRY(__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
2361:
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
2572: .long 0xffffc000
2583: .long empty_zero_page
2594: .long 0x10000000 ! BL bit
260
261/* __flush_cache_4096_all(unsigned long addr) */
262ENTRY(__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
2711:
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
2922: .long 0xffffc000
2933: .long empty_zero_page
2944: .long 0x10000000 ! BL bit
295#endif