mmu-arm (v4/v5) : use one less instruction in invalidate_dcache/clean_dcache
[kugel-rb.git] / firmware / target / arm / mmu-arm.S
blob6b580b4524f60f74af97ceaa1386d9ce7540aaf3
1 /***************************************************************************
2  *             __________               __   ___.
3  *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
4  *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
5  *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
6  *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
7  *                     \/            \/     \/    \/            \/
8  * $Id$
9  *
10  * Copyright (C) 2006,2007 by Greg White
11  *
12  * This program is free software; you can redistribute it and/or
13  * modify it under the terms of the GNU General Public License
14  * as published by the Free Software Foundation; either version 2
15  * of the License, or (at your option) any later version.
16  *
17  * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18  * KIND, either express or implied.
19  *
20  ****************************************************************************/
21 #include "config.h"
22 #include "cpu.h"
24 /* Used by ARMv4 & ARMv5 CPUs with cp15 register and MMU */
25 /* WARNING : assume size of a data cache line == 32 bytes */
27 /** MMU setup **/
30  * void ttb_init(void);
31  */
32     .section    .text, "ax", %progbits
33     .align      2
34     .global     ttb_init
35     .type       ttb_init, %function
36 ttb_init:
37     ldr     r0, =TTB_BASE_ADDR      @
38     mvn     r1, #0                  @
39     mcr     p15, 0, r0, c2, c0, 0   @ Set the TTB base address
40     mcr     p15, 0, r1, c3, c0, 0   @ Set all domains to manager status
41     bx      lr                      @
42     .size   ttb_init, .-ttb_init
45  * void map_section(unsigned int pa, unsigned int va, int mb, int flags);
46  */
47     .section    .text, "ax", %progbits
48     .align      2
49     .global     map_section
50     .type       map_section, %function
51 map_section:
52     @ align to 1MB
53     @ pa &= (-1 << 20);
54     mov     r0, r0, lsr #20
55     mov     r0, r0, lsl #20
57     @ pa |= (flags | 0x412);
58     @ bit breakdown:
59     @  10:  superuser - r/w, user - no access
60     @  4:   should be "1"
61     @  3,2: Cache flags (flags (r3))
62     @  1:   Section signature 
63     orr     r0, r0, r3
64     orr     r0, r0, #0x410
65     orr     r0, r0, #0x2
66     
67     @ unsigned int* ttbPtr = TTB_BASE + (va >> 20);
68     @ sections are 1MB size 
69     mov     r1, r1, lsr #20
70     ldr     r3, =TTB_BASE_ADDR
71     add     r1, r3, r1, lsl #0x2 
72     
73     @ Add MB to pa, flags are already present in pa, but addition 
74     @ should not effect them
75     @
76     @ for( ; mb>0; mb--, pa += (1 << 20))
77     @ {
78     @     *(ttbPtr++) = pa;
79     @ }
80     cmp    r2, #0
81     bxle   lr
82     mov    r3, #0x0
83 1:  @ loop
84     str    r0, [r1], #4
85     add    r0, r0, #0x100000
86     add    r3, r3, #0x1
87     cmp    r2, r3
88     bne    1b @ loop
89     bx     lr
90     .size   map_section, .-map_section
93  * void enable_mmu(void);
94  */
95     .section    .text, "ax", %progbits
96     .align      2
97     .global     enable_mmu
98     .type       enable_mmu, %function
99 enable_mmu:
100     mov     r0, #0                  @
101     mcr     p15, 0, r0, c8, c7, 0   @ invalidate TLB
102     mcr     p15, 0, r0, c7, c7,0    @ invalidate both i and dcache
103     mrc     p15, 0, r0, c1, c0, 0   @
104     orr     r0, r0, #1              @ enable mmu bit, i and dcache
105     orr     r0, r0, #1<<2           @ enable dcache
106     orr     r0, r0, #1<<12          @ enable icache
107     mcr     p15, 0, r0, c1, c0, 0   @
108     nop                             @
109     nop                             @
110     nop                             @
111     nop                             @
112     bx      lr                      @
113     .size   enable_mmu, .-enable_mmu
114     .ltorg
115     
116 /** Cache coherency **/
119  * Invalidate DCache for this range
120  * will do write back
121  * void invalidate_dcache_range(const void *base, unsigned int size);
122  */
123     .section   .text, "ax", %progbits
124     .align      2
125     .global     invalidate_dcache_range
126     .type       invalidate_dcache_range, %function
127     @ MVA format: 31:5 = Modified virtual address, 4:0 = SBZ
128 invalidate_dcache_range:
129     add     r1, r0, r1              @ size -> end
130     cmp     r1, r0                  @ end <= start?
131     bxls    lr                      @
132     bic     r0, r0, #31             @ Align start to cache line (down)
133 1:  @ inv_start                     @
134     mcr     p15, 0, r0, c7, c14, 1  @ Clean and invalidate line by MVA
135     add     r0, r0, #32             @
136     cmp     r1, r0                  @
137     mcrhi   p15, 0, r0, c7, c14, 1  @ Clean and invalidate line by MVA
138     addhi   r0, r0, #32             @
139     cmphi   r1, r0                  @
140     mcrhi   p15, 0, r0, c7, c14, 1  @ Clean and invalidate line by MVA
141     addhi   r0, r0, #32             @
142     cmphi   r1, r0                  @
143     mcrhi   p15, 0, r0, c7, c14, 1  @ Clean and invalidate line by MVA
144     addhi   r0, r0, #32             @
145     cmphi   r1, r0                  @
146     mcrhi   p15, 0, r0, c7, c14, 1  @ Clean and invalidate line by MVA
147     addhi   r0, r0, #32             @
148     cmphi   r1, r0                  @
149     mcrhi   p15, 0, r0, c7, c14, 1  @ Clean and invalidate line by MVA
150     addhi   r0, r0, #32             @
151     cmphi   r1, r0                  @
152     mcrhi   p15, 0, r0, c7, c14, 1  @ Clean and invalidate line by MVA
153     addhi   r0, r0, #32             @
154     cmphi   r1, r0                  @
155     mcrhi   p15, 0, r0, c7, c14, 1  @ Clean and invalidate line by MVA
156     addhi   r0, r0, #32             @
157     cmphi   r1, r0                  @
158     bhi     1b @ inv_start          @
159     mov     r0, #0                  @
160     mcr     p15, 0, r0, c7, c10, 4  @ Drain write buffer
161     bx      lr                      @
162     .size   invalidate_dcache_range, .-invalidate_dcache_range
165  * clean DCache for this range
166  * forces DCache writeback for the specified range
167  * void clean_dcache_range(const void *base, unsigned int size);
168  */
169     .section   .text, "ax", %progbits
170     .align      2
171     .global     clean_dcache_range
172     .type       clean_dcache_range, %function
173     @ MVA format: 31:5 = Modified virtual address, 4:0 = SBZ
174 clean_dcache_range:
175     add     r1, r0, r1              @ size -> end
176     cmp     r1, r0                  @ end <= start?
177     bxls    lr                      @
178     bic     r0, r0, #31             @ Align start to cache line (down)
179 1:  @ clean_start                   @
180     mcr     p15, 0, r0, c7, c10, 1  @ Clean line by MVA
181     add     r0, r0, #32             @
182     cmp     r1, r0                  @
183     mcrhi   p15, 0, r0, c7, c10, 1  @ Clean line by MVA
184     addhi   r0, r0, #32             @
185     cmphi   r1, r0                  @
186     mcrhi   p15, 0, r0, c7, c10, 1  @ Clean line by MVA
187     addhi   r0, r0, #32             @
188     cmphi   r1, r0                  @
189     mcrhi   p15, 0, r0, c7, c10, 1  @ Clean line by MVA
190     addhi   r0, r0, #32             @
191     cmphi   r1, r0                  @
192     mcrhi   p15, 0, r0, c7, c10, 1  @ Clean line by MVA
193     addhi   r0, r0, #32             @
194     cmphi   r1, r0                  @
195     mcrhi   p15, 0, r0, c7, c10, 1  @ Clean line by MVA
196     addhi   r0, r0, #32             @
197     cmphi   r1, r0                  @
198     mcrhi   p15, 0, r0, c7, c10, 1  @ Clean line by MVA
199     addhi   r0, r0, #32             @
200     cmphi   r1, r0                  @
201     mcrhi   p15, 0, r0, c7, c10, 1  @ Clean line by MVA
202     addhi   r0, r0, #32             @
203     cmphi   r1, r0                  @
204     bhi     1b @clean_start         @
205     mov     r0, #0                  @
206     mcr     p15, 0, r0, c7, c10, 4  @ Drain write buffer
207     bx      lr                      @
208     .size   clean_dcache_range, .-clean_dcache_range
211  * Dump DCache for this range
212  * will *NOT* do write back except for buffer edges not on a line boundary
213  * void dump_dcache_range(const void *base, unsigned int size);
214  */
215     .section   .text, "ax", %progbits
216     .align      2
217     .global     dump_dcache_range
218     .type       dump_dcache_range, %function
219     @ MVA format: 31:5 = Modified virtual address, 4:0 = SBZ
220  dump_dcache_range:
221     add     r1, r0, r1              @ size -> end
222     cmp     r1, r0                  @ end <= start?
223     bxls    lr                      @
224     tst     r0, #31                 @ Check first line for bits set
225     bicne   r0, r0, #31             @ Clear low five bits (down)
226     mcrne   p15, 0, r0, c7, c14, 1  @ Clean and invalidate line by MVA
227                                     @ if not cache aligned
228     addne   r0, r0, #32             @ Move to the next cache line
229                                     @
230     tst     r1, #31                 @ Check last line for bits set
231     bicne   r1, r1, #31             @ Clear low five bits (down)
232     mcrne   p15, 0, r1, c7, c14, 1  @ Clean and invalidate line by MVA
233                                     @ if not cache aligned
234     cmp     r1, r0                  @ end <= start now?
235 1:  @ dump_start                    @
236     mcrhi   p15, 0, r0, c7, c6, 1   @ Invalidate line by MVA
237     addhi   r0, r0, #32             @
238     cmphi   r1, r0                  @
239     mcrhi   p15, 0, r0, c7, c6, 1   @ Invalidate line by MVA
240     addhi   r0, r0, #32             @
241     cmphi   r1, r0                  @
242     mcrhi   p15, 0, r0, c7, c6, 1   @ Invalidate line by MVA
243     addhi   r0, r0, #32             @
244     cmphi   r1, r0                  @
245     mcrhi   p15, 0, r0, c7, c6, 1   @ Invalidate line by MVA
246     addhi   r0, r0, #32             @
247     cmphi   r1, r0                  @
248     mcrhi   p15, 0, r0, c7, c6, 1   @ Invalidate line by MVA
249     addhi   r0, r0, #32             @
250     cmphi   r1, r0                  @
251     mcrhi   p15, 0, r0, c7, c6, 1   @ Invalidate line by MVA
252     addhi   r0, r0, #32             @
253     cmphi   r1, r0                  @
254     mcrhi   p15, 0, r0, c7, c6, 1   @ Invalidate line by MVA
255     addhi   r0, r0, #32             @
256     cmphi   r1, r0                  @
257     mcrhi   p15, 0, r0, c7, c6, 1   @ Invalidate line by MVA
258     addhi   r0, r0, #32             @
259     cmphi   r1, r0                  @
260     bhi     1b @ dump_start         @
261     mov     r0, #0                  @
262     mcr     p15, 0, r0, c7, c10, 4  @ Drain write buffer
263     bx      lr                      @
264     .size   dump_dcache_range, .-dump_dcache_range
267  * Cleans entire DCache
268  * void clean_dcache(void);
269  */
270     .section   .text, "ax", %progbits
271     .align      2
272     .global     clean_dcache
273     .type       clean_dcache, %function
274     .global     cpucache_flush      @ Alias
275 clean_dcache:
276 cpucache_flush:
277     @ Index format: 31:26 = index, 7:5 = segment, remainder = SBZ
278     mov     r1, #0x00000000         @
279 1:  @ clean_start                   @
280     mcr     p15, 0, r0, c7, c10, 2  @ Clean entry by index
281     add     r0, r1, #0x00000020     @
282     mcr     p15, 0, r0, c7, c10, 2  @ Clean entry by index
283     add     r0, r0, #0x00000020     @
284     mcr     p15, 0, r0, c7, c10, 2  @ Clean entry by index
285     add     r0, r0, #0x00000020     @
286     mcr     p15, 0, r0, c7, c10, 2  @ Clean entry by index
287     add     r0, r0, #0x00000020     @
288     mcr     p15, 0, r0, c7, c10, 2  @ Clean entry by index
289     add     r0, r0, #0x00000020     @
290     mcr     p15, 0, r0, c7, c10, 2  @ Clean entry by index
291     add     r0, r0, #0x00000020     @
292     mcr     p15, 0, r0, c7, c10, 2  @ Clean entry by index
293     add     r0, r0, #0x00000020     @
294     mcr     p15, 0, r0, c7, c10, 2  @ Clean entry by index
295     adds    r1, r1, #0x04000000     @ will wrap to zero at loop end
296     bne     1b @ clean_start        @
297     mcr     p15, 0, r1, c7, c10, 4  @ Drain write buffer
298     bx      lr                      @ 
299     .size   clean_dcache, .-clean_dcache
302  * Invalidate entire DCache
303  * will do writeback
304  * void invalidate_dcache(void);
305  */
306     .section   .text, "ax", %progbits
307     .align      2
308     .global     invalidate_dcache
309     .type       invalidate_dcache, %function
310 invalidate_dcache:
311     @ Index format: 31:26 = index, 7:5 = segment, remainder = SBZ
312     mov     r1, #0x00000000         @
313 1:  @ inv_start                     @
314     mcr     p15, 0, r0, c7, c14, 2  @ Clean and invalidate entry by index
315     add     r0, r1, #0x00000020     @
316     mcr     p15, 0, r0, c7, c14, 2  @ Clean and invalidate entry by index
317     add     r0, r0, #0x00000020     @
318     mcr     p15, 0, r0, c7, c14, 2  @ Clean and invalidate entry by index
319     add     r0, r0, #0x00000020     @
320     mcr     p15, 0, r0, c7, c14, 2  @ Clean and invalidate entry by index
321     add     r0, r0, #0x00000020     @
322     mcr     p15, 0, r0, c7, c14, 2  @ Clean and invalidate entry by index
323     add     r0, r0, #0x00000020     @
324     mcr     p15, 0, r0, c7, c14, 2  @ Clean and invalidate entry by index
325     add     r0, r0, #0x00000020     @
326     mcr     p15, 0, r0, c7, c14, 2  @ Clean and invalidate entry by index
327     add     r0, r0, #0x00000020     @
328     mcr     p15, 0, r0, c7, c14, 2  @ Clean and invalidate entry by index
329     adds    r1, r1, #0x04000000     @ will wrap to zero at loop end
330     bne     1b @ inv_start          @
331     mcr     p15, 0, r1, c7, c10, 4  @ Drain write buffer
332     bx      lr                      @
333     .size   invalidate_dcache, .-invalidate_dcache
336  * Invalidate entire ICache and DCache
337  * will do writeback
338  * void invalidate_idcache(void);
339  */
340     .section   .text, "ax", %progbits
341     .align      2
342     .global     invalidate_idcache
343     .type       invalidate_idcache, %function
344     .global     cpucache_invalidate @ Alias
345 invalidate_idcache:
346 cpucache_invalidate: 
347     mov     r2, lr                  @ save lr to r1, call uses r0 only
348     bl      invalidate_dcache       @ Clean and invalidate entire DCache
349     mcr     p15, 0, r1, c7, c5, 0   @ Invalidate ICache (r1=0 from call)
350     mov     pc, r2                  @
351     .size   invalidate_idcache, .-invalidate_idcache