sh: Fix up 64kB page size selection on SH-5.
[linux-2.6] / arch / sh / mm / clear_page.S
1 /*
2  * __clear_user_page, __clear_user, clear_page implementation of SuperH
3  *
4  * Copyright (C) 2001  Kaz Kojima
5  * Copyright (C) 2001, 2002  Niibe Yutaka
6  * Copyright (C) 2006  Paul Mundt
7  */
8 #include <linux/linkage.h>
9 #include <asm/page.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 + PAGE_SIZE
22  */
23 ENTRY(clear_page_slow)
24         mov     r4,r5
25         mov.l   .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:        .long   (PAGE_SIZE-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