Rename cache coherency functions.
[maemo-rb.git] / firmware / target / arm / mmu-arm.S
blob5693ca587bb6bfbae9015a74e5d846ef5a2783b3
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 */
26 #if CONFIG_CPU == TCC7801 || CONFIG_CPU == AT91SAM9260
27 /* MMU present but unused */
28 #define HAVE_TEST_AND_CLEAN_CACHE
30 #elif CONFIG_CPU == DM320 || CONFIG_CPU == AS3525v2
31 #define USE_MMU
32 #define HAVE_TEST_AND_CLEAN_CACHE
34 #elif CONFIG_CPU == AS3525
35 #define USE_MMU
36 #define CACHE_SIZE 8
38 #elif CONFIG_CPU == S3C2440
39 #define USE_MMU
40 #define CACHE_SIZE 16
42 #elif CONFIG_CPU == S5L8700 || CONFIG_CPU == S5L8701
43 /* MMU not present */
44 #define CACHE_SIZE 4
46 #else
47 #error Cache settings unknown for this CPU !
49 #endif /* CPU specific configuration */
51 @ Index format: 31:26 = index, N:5 = segment, remainder = SBZ
52 @ assume 64-way set associative separate I/D caches
53 @ CACHE_SIZE = N (kB) = N*2^10 B
54 @ number of lines = N*2^(10-CACHEALIGN_BITS)
55 @ Index bits = 6
56 @ Segment loops = N*2^(10-CACHEALIGN_BITS-6) = N*2^(4-CACHEALIGN_BITS)
57 @ Segment loops = N/2^(CACHEALIGN_BITS - 4)
58 @ Segment loops = N/(1<<(CACHEALIGN_BITS - 4))
60 #ifdef CACHE_SIZE
62 #if CACHEALIGN_BITS == 4
63 #define INDEX_STEPS CACHE_SIZE
64 #elif CACHEALIGN_BITS == 5
65 #define INDEX_STEPS (CACHE_SIZE/2)
66 #endif /* CACHEALIGN_BITS */
68 @ assume 64-way set associative separate I/D caches (log2(64) == 6)
69 @ Index format: 31:26 = index, M:N = segment, remainder = SBZ
70 @ Segment bits = log2(cache size in bytes / cache line size in byte) - Index bits (== 6)
71 @ N = CACHEALIGN_BITS
73 #endif /* CACHE_SIZE */
76 #ifdef USE_MMU
78 /** MMU setup **/
81  * void ttb_init(void);
82  */
83     .section    .text, "ax", %progbits
84     .align      2
85     .global     ttb_init
86     .type       ttb_init, %function
87 ttb_init:
88     ldr     r0, =TTB_BASE_ADDR      @
89     mvn     r1, #0                  @
90     mcr     p15, 0, r0, c2, c0, 0   @ Set the TTB base address
91     mcr     p15, 0, r1, c3, c0, 0   @ Set all domains to manager status
92     bx      lr                      @
93     .size   ttb_init, .-ttb_init
96  * void map_section(unsigned int pa, unsigned int va, int mb, int flags);
97  */
98     .section    .text, "ax", %progbits
99     .align      2
100     .global     map_section
101     .type       map_section, %function
102 map_section:
103     @ align to 1MB
104     @ pa &= (-1 << 20);
105     mov     r0, r0, lsr #20
106     mov     r0, r0, lsl #20
108     @ pa |= (flags | 0x412);
109     @ bit breakdown:
110     @  10:  superuser - r/w, user - no access
111     @  4:   should be "1"
112     @  3,2: Cache flags (flags (r3))
113     @  1:   Section signature
114     orr     r0, r0, r3
115     orr     r0, r0, #0x410
116     orr     r0, r0, #0x2
118     @ unsigned int* ttbPtr = TTB_BASE + (va >> 20);
119     @ sections are 1MB size
120     mov     r1, r1, lsr #20
121     ldr     r3, =TTB_BASE_ADDR
122     add     r1, r3, r1, lsl #0x2
124     @ Add MB to pa, flags are already present in pa, but addition
125     @ should not effect them
126     @
127     @ for( ; mb>0; mb--, pa += (1 << 20))
128     @ {
129     @     *(ttbPtr++) = pa;
130     @ }
131     cmp    r2, #0
132     bxle   lr
133     mov    r3, #0x0
134 1:  @ loop
135     str    r0, [r1], #4
136     add    r0, r0, #0x100000
137     add    r3, r3, #0x1
138     cmp    r2, r3
139     bne    1b @ loop
140     bx     lr
141     .size   map_section, .-map_section
144  * void enable_mmu(void);
145  */
146     .section    .text, "ax", %progbits
147     .align      2
148     .global     enable_mmu
149     .type       enable_mmu, %function
150 enable_mmu:
151     mov     r0, #0                  @
152     mcr     p15, 0, r0, c8, c7, 0   @ invalidate TLB
153     mcr     p15, 0, r0, c7, c7,0    @ invalidate both i and dcache
154     mrc     p15, 0, r0, c1, c0, 0   @
155     orr     r0, r0, #1              @ enable mmu bit, i and dcache
156     orr     r0, r0, #1<<2           @ enable dcache
157     orr     r0, r0, #1<<12          @ enable icache
158     mcr     p15, 0, r0, c1, c0, 0   @
159     nop                             @
160     nop                             @
161     nop                             @
162     nop                             @
163     bx      lr                      @
164     .size   enable_mmu, .-enable_mmu
165     .ltorg
167 #endif  /* USE_MMU */
171 /** Cache coherency **/
174  * Write DCache back to RAM for the given range and remove cache lines
175  * from DCache afterwards
176  * void commit_discard_dcache_range(const void *base, unsigned int size);
177  */
178     .section   .text, "ax", %progbits
179     .align      2
180     .global     commit_discard_dcache_range
181     .type       commit_discard_dcache_range, %function
182     .global     invalidate_dcache_range @ Alias, deprecated
184     @ MVA format: 31:5 = Modified virtual address, 4:0 = SBZ
185 commit_discard_dcache_range:
186 invalidate_dcache_range:
187     add     r1, r0, r1              @ size -> end
188     cmp     r1, r0                  @ end <= start?
189     bxls    lr                      @
190     bic     r0, r0, #31             @ Align start to cache line (down)
191 1:  @ inv_start                     @
192     mcr     p15, 0, r0, c7, c14, 1  @ Clean and invalidate line by MVA
193     add     r0, r0, #32             @
194     cmp     r1, r0                  @
195     mcrhi   p15, 0, r0, c7, c14, 1  @ Clean and invalidate line by MVA
196     addhi   r0, r0, #32             @
197     cmphi   r1, r0                  @
198     mcrhi   p15, 0, r0, c7, c14, 1  @ Clean and invalidate line by MVA
199     addhi   r0, r0, #32             @
200     cmphi   r1, r0                  @
201     mcrhi   p15, 0, r0, c7, c14, 1  @ Clean and invalidate line by MVA
202     addhi   r0, r0, #32             @
203     cmphi   r1, r0                  @
204     mcrhi   p15, 0, r0, c7, c14, 1  @ Clean and invalidate line by MVA
205     addhi   r0, r0, #32             @
206     cmphi   r1, r0                  @
207     mcrhi   p15, 0, r0, c7, c14, 1  @ Clean and invalidate line by MVA
208     addhi   r0, r0, #32             @
209     cmphi   r1, r0                  @
210     mcrhi   p15, 0, r0, c7, c14, 1  @ Clean and invalidate line by MVA
211     addhi   r0, r0, #32             @
212     cmphi   r1, r0                  @
213     mcrhi   p15, 0, r0, c7, c14, 1  @ Clean and invalidate line by MVA
214     addhi   r0, r0, #32             @
215     cmphi   r1, r0                  @
216     bhi     1b @ inv_start          @
217     mov     r0, #0                  @
218     mcr     p15, 0, r0, c7, c10, 4  @ Drain write buffer
219     bx      lr                      @
220     .size   commit_discard_dcache_range, .-commit_discard_dcache_range
223  * Write DCache back to RAM for the given range
224  * void commit_dcache_range(const void *base, unsigned int size);
225  */
226     .section   .text, "ax", %progbits
227     .align      2
228     .global     commit_dcache_range
229     .type       commit_dcache_range, %function
230     .global     clean_dcache_range  @ Alias, deprecated
232     @ MVA format: 31:5 = Modified virtual address, 4:0 = SBZ
233 commit_dcache_range:
234 clean_dcache_range:
235     add     r1, r0, r1              @ size -> end
236     cmp     r1, r0                  @ end <= start?
237     bxls    lr                      @
238     bic     r0, r0, #31             @ Align start to cache line (down)
239 1:  @ clean_start                   @
240     mcr     p15, 0, r0, c7, c10, 1  @ Clean line by MVA
241     add     r0, r0, #32             @
242     cmp     r1, r0                  @
243     mcrhi   p15, 0, r0, c7, c10, 1  @ Clean line by MVA
244     addhi   r0, r0, #32             @
245     cmphi   r1, r0                  @
246     mcrhi   p15, 0, r0, c7, c10, 1  @ Clean line by MVA
247     addhi   r0, r0, #32             @
248     cmphi   r1, r0                  @
249     mcrhi   p15, 0, r0, c7, c10, 1  @ Clean line by MVA
250     addhi   r0, r0, #32             @
251     cmphi   r1, r0                  @
252     mcrhi   p15, 0, r0, c7, c10, 1  @ Clean line by MVA
253     addhi   r0, r0, #32             @
254     cmphi   r1, r0                  @
255     mcrhi   p15, 0, r0, c7, c10, 1  @ Clean line by MVA
256     addhi   r0, r0, #32             @
257     cmphi   r1, r0                  @
258     mcrhi   p15, 0, r0, c7, c10, 1  @ Clean line by MVA
259     addhi   r0, r0, #32             @
260     cmphi   r1, r0                  @
261     mcrhi   p15, 0, r0, c7, c10, 1  @ Clean line by MVA
262     addhi   r0, r0, #32             @
263     cmphi   r1, r0                  @
264     bhi     1b @clean_start         @
265     mov     r0, #0                  @
266     mcr     p15, 0, r0, c7, c10, 4  @ Drain write buffer
267     bx      lr                      @
268     .size   commit_dcache_range, .-commit_dcache_range
271  * Remove cache lines for the given range from DCache
272  * will *NOT* do write back except for buffer edges not on a line boundary
273  * void discard_dcache_range(const void *base, unsigned int size);
274  */
275     .section   .text, "ax", %progbits
276     .align      2
277     .global     discard_dcache_range
278     .type       discard_dcache_range, %function
279     .global     dump_dcache_range   @ Alias, deprecated
281     @ MVA format: 31:5 = Modified virtual address, 4:0 = SBZ
282 discard_dcache_range:
283 dump_dcache_range:
284     add     r1, r0, r1              @ size -> end
285     cmp     r1, r0                  @ end <= start?
286     bxls    lr                      @
287     tst     r0, #31                 @ Check first line for bits set
288     bicne   r0, r0, #31             @ Clear low five bits (down)
289     mcrne   p15, 0, r0, c7, c14, 1  @ Clean and invalidate line by MVA
290                                     @ if not cache aligned
291     addne   r0, r0, #32             @ Move to the next cache line
292                                     @
293     tst     r1, #31                 @ Check last line for bits set
294     bicne   r1, r1, #31             @ Clear low five bits (down)
295     mcrne   p15, 0, r1, c7, c14, 1  @ Clean and invalidate line by MVA
296                                     @ if not cache aligned
297     cmp     r1, r0                  @ end <= start now?
298 1:  @ discard_start                    @
299     mcrhi   p15, 0, r0, c7, c6, 1   @ Invalidate line by MVA
300     addhi   r0, r0, #32             @
301     cmphi   r1, r0                  @
302     mcrhi   p15, 0, r0, c7, c6, 1   @ Invalidate line by MVA
303     addhi   r0, r0, #32             @
304     cmphi   r1, r0                  @
305     mcrhi   p15, 0, r0, c7, c6, 1   @ Invalidate line by MVA
306     addhi   r0, r0, #32             @
307     cmphi   r1, r0                  @
308     mcrhi   p15, 0, r0, c7, c6, 1   @ Invalidate line by MVA
309     addhi   r0, r0, #32             @
310     cmphi   r1, r0                  @
311     mcrhi   p15, 0, r0, c7, c6, 1   @ Invalidate line by MVA
312     addhi   r0, r0, #32             @
313     cmphi   r1, r0                  @
314     mcrhi   p15, 0, r0, c7, c6, 1   @ Invalidate line by MVA
315     addhi   r0, r0, #32             @
316     cmphi   r1, r0                  @
317     mcrhi   p15, 0, r0, c7, c6, 1   @ Invalidate line by MVA
318     addhi   r0, r0, #32             @
319     cmphi   r1, r0                  @
320     mcrhi   p15, 0, r0, c7, c6, 1   @ Invalidate line by MVA
321     addhi   r0, r0, #32             @
322     cmphi   r1, r0                  @
323     bhi     1b @ discard_start      @
324     mov     r0, #0                  @
325     mcr     p15, 0, r0, c7, c10, 4  @ Drain write buffer
326     bx      lr                      @
327     .size   discard_dcache_range, .-discard_dcache_range
330  * Write entire DCache back to RAM
331  * void commit_dcache(void);
332  */
333     .section   .text, "ax", %progbits
334     .align      2
335     .global     commit_dcache
336     .type       commit_dcache, %function
337     .global     cpucache_commit     @ Alias
338     .global     clean_dcache        @ Alias, deprecated
339     .global     cpucache_flush      @ Alias, deprecated
341 commit_dcache:
342 cpucache_commit:
343 clean_dcache:
344 cpucache_flush:
345 #ifdef HAVE_TEST_AND_CLEAN_CACHE
346     mrc     p15, 0, r15, c7, c10, 3 @ test and clean dcache
347     bne     commit_dcache
348     mov     r1, #0
349 #else
350     mov     r1, #0x00000000         @
351 1:  @ commit_start                   @
352     mcr     p15, 0, r1, c7, c10, 2  @ Clean entry by index
353     add     r0, r1, #(1<<CACHEALIGN_BITS)
354     mcr     p15, 0, r0, c7, c10, 2  @ Clean entry by index
355 .rept INDEX_STEPS - 2 /* 2 steps already executed */
356     add     r0, r0, #(1<<CACHEALIGN_BITS)
357     mcr     p15, 0, r0, c7, c10, 2  @ Clean entry by index
358 .endr
359     adds    r1, r1, #0x04000000     @ will wrap to zero at loop end
360     bne     1b @ commit_start        @
361 #endif /* HAVE_TEST_AND_CLEAN_CACHE */
362     mcr     p15, 0, r1, c7, c10, 4  @ Drain write buffer
363     bx      lr                      @
364     .size   commit_dcache, .-commit_dcache
367  * Commit and discard entire DCache, will do writeback
368  * void commit_discard_dcache(void);
369  */
370     .section   .icode, "ax", %progbits
371     .align      2
372     .global     commit_discard_dcache
373     .type       commit_discard_dcache, %function
374     .global     invalidate_dcache   @ Alias, deprecated
376 commit_discard_dcache:
377 invalidate_dcache:
378 #ifdef HAVE_TEST_AND_CLEAN_CACHE
379     mrc     p15, 0, r15, c7, c14, 3 @ test, clean and invalidate dcache
380     bne     commit_discard_dcache
381     mov     r1, #0
382 #else
383     mov     r1, #0x00000000         @
384 1:  @ inv_start                     @
385     mcr     p15, 0, r1, c7, c14, 2  @ Clean and invalidate entry by index
386     add     r0, r1, #(1<<CACHEALIGN_BITS)
387     mcr     p15, 0, r0, c7, c14, 2  @ Clean and invalidate entry by index
388 .rept INDEX_STEPS - 2 /* 2 steps already executed */
389     add     r0, r0, #(1<<CACHEALIGN_BITS)
390     mcr     p15, 0, r0, c7, c14, 2  @ Clean and invalidate entry by index
391 .endr
392     adds    r1, r1, #0x04000000     @ will wrap to zero at loop end
393     bne     1b @ inv_start          @
394 #endif /* HAVE_TEST_AND_CLEAN_CACHE */
395     mcr     p15, 0, r1, c7, c10, 4  @ Drain write buffer
396     bx      lr                      @
397     .size   commit_discard_dcache, .-commit_discard_dcache
400  * Discards the entire ICache, and commit+discards the entire DCache
401  * void commit_discard_idcache(void);
402  */
403     .section   .icode, "ax", %progbits
404     .align      2
405     .global     commit_discard_idcache
406     .type       commit_discard_idcache, %function
407     .global     cpucache_commit_discard @ Alias
408     .global     invalidate_idcache      @ Alias, deprecated
409     .global     cpucache_invalidate     @ Alias, deprecated
411 commit_discard_idcache:
412 cpucache_commit_discard:
413 invalidate_idcache:
414 cpucache_invalidate:
415     mov     r2, lr                  @ save lr to r1, call uses r0 only
416     bl      commit_discard_dcache   @ commit and discard entire DCache
417     mcr     p15, 0, r1, c7, c5, 0   @ Invalidate ICache (r1=0 from call)
418     bx      r2
419     .size   commit_discard_idcache, .-commit_discard_idcache