RT-AC56 3.0.0.4.374.37 core
[tomato.git] / release / src-rt-6.x.4708 / linux / linux-2.6.36 / arch / arm / mm / proc-arm925.S
blob8acf15b9d5e6a245dac445d91c853e4008916d90
3 #include <linux/linkage.h>
4 #include <linux/init.h>
5 #include <asm/assembler.h>
6 #include <asm/hwcap.h>
7 #include <asm/pgtable-hwdef.h>
8 #include <asm/pgtable.h>
9 #include <asm/page.h>
10 #include <asm/ptrace.h>
11 #include "proc-macros.S"
14  * The size of one data cache line.
15  */
16 #define CACHE_DLINESIZE 16
19  * The number of data cache segments.
20  */
21 #define CACHE_DSEGMENTS 2
24  * The number of lines in a cache segment.
25  */
26 #define CACHE_DENTRIES  256
29  * This is the size at which it becomes more efficient to
30  * clean the whole cache, rather than using the individual
31  * cache line maintainence instructions.
32  */
33 #define CACHE_DLIMIT    8192
35         .text
37  * cpu_arm925_proc_init()
38  */
39 ENTRY(cpu_arm925_proc_init)
40         mov     pc, lr
43  * cpu_arm925_proc_fin()
44  */
45 ENTRY(cpu_arm925_proc_fin)
46         mrc     p15, 0, r0, c1, c0, 0           @ ctrl register
47         bic     r0, r0, #0x1000                 @ ...i............
48         bic     r0, r0, #0x000e                 @ ............wca.
49         mcr     p15, 0, r0, c1, c0, 0           @ disable caches
50         mov     pc, lr
53  * cpu_arm925_reset(loc)
54  *
55  * Perform a soft reset of the system.  Put the CPU into the
56  * same state as it would be if it had been reset, and branch
57  * to what would be the reset vector.
58  *
59  * loc: location to jump to for soft reset
60  */
61         .align  5
62 ENTRY(cpu_arm925_reset)
63         /* Send software reset to MPU and DSP */
64         mov     ip, #0xff000000
65         orr     ip, ip, #0x00fe0000
66         orr     ip, ip, #0x0000ce00
67         mov     r4, #1
68         strh    r4, [ip, #0x10]
70         mov     ip, #0
71         mcr     p15, 0, ip, c7, c7, 0           @ invalidate I,D caches
72         mcr     p15, 0, ip, c7, c10, 4          @ drain WB
73 #ifdef CONFIG_MMU
74         mcr     p15, 0, ip, c8, c7, 0           @ invalidate I & D TLBs
75 #endif
76         mrc     p15, 0, ip, c1, c0, 0           @ ctrl register
77         bic     ip, ip, #0x000f                 @ ............wcam
78         bic     ip, ip, #0x1100                 @ ...i...s........
79         mcr     p15, 0, ip, c1, c0, 0           @ ctrl register
80         mov     pc, r0
83  * cpu_arm925_do_idle()
84  *
85  * Called with IRQs disabled
86  */
87         .align  10
88 ENTRY(cpu_arm925_do_idle)
89         mov     r0, #0
90         mrc     p15, 0, r1, c1, c0, 0           @ Read control register
91         mcr     p15, 0, r0, c7, c10, 4          @ Drain write buffer
92         bic     r2, r1, #1 << 12
93         mcr     p15, 0, r2, c1, c0, 0           @ Disable I cache
94         mcr     p15, 0, r0, c7, c0, 4           @ Wait for interrupt
95         mcr     p15, 0, r1, c1, c0, 0           @ Restore ICache enable
96         mov     pc, lr
99  *      flush_user_cache_all()
101  *      Clean and invalidate all cache entries in a particular
102  *      address space.
103  */
104 ENTRY(arm925_flush_user_cache_all)
105         /* FALLTHROUGH */
108  *      flush_kern_cache_all()
110  *      Clean and invalidate the entire cache.
111  */
112 ENTRY(arm925_flush_kern_cache_all)
113         mov     r2, #VM_EXEC
114         mov     ip, #0
115 __flush_whole_cache:
116 #ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
117         mcr     p15, 0, ip, c7, c6, 0           @ invalidate D cache
118 #else
119         /* Flush entries in both segments at once, see NOTE1 above */
120         mov     r3, #(CACHE_DENTRIES - 1) << 4  @ 256 entries in segment
121 2:      mcr     p15, 0, r3, c7, c14, 2          @ clean+invalidate D index
122         subs    r3, r3, #1 << 4
123         bcs     2b                              @ entries 255 to 0
124 #endif
125         tst     r2, #VM_EXEC
126         mcrne   p15, 0, ip, c7, c5, 0           @ invalidate I cache
127         mcrne   p15, 0, ip, c7, c10, 4          @ drain WB
128         mov     pc, lr
131  *      flush_user_cache_range(start, end, flags)
133  *      Clean and invalidate a range of cache entries in the
134  *      specified address range.
136  *      - start - start address (inclusive)
137  *      - end   - end address (exclusive)
138  *      - flags - vm_flags describing address space
139  */
140 ENTRY(arm925_flush_user_cache_range)
141         mov     ip, #0
142         sub     r3, r1, r0                      @ calculate total size
143         cmp     r3, #CACHE_DLIMIT
144         bgt     __flush_whole_cache
145 1:      tst     r2, #VM_EXEC
146 #ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
147         mcr     p15, 0, r0, c7, c6, 1           @ invalidate D entry
148         mcrne   p15, 0, r0, c7, c5, 1           @ invalidate I entry
149         add     r0, r0, #CACHE_DLINESIZE
150         mcr     p15, 0, r0, c7, c6, 1           @ invalidate D entry
151         mcrne   p15, 0, r0, c7, c5, 1           @ invalidate I entry
152         add     r0, r0, #CACHE_DLINESIZE
153 #else
154         mcr     p15, 0, r0, c7, c14, 1          @ clean and invalidate D entry
155         mcrne   p15, 0, r0, c7, c5, 1           @ invalidate I entry
156         add     r0, r0, #CACHE_DLINESIZE
157         mcr     p15, 0, r0, c7, c14, 1          @ clean and invalidate D entry
158         mcrne   p15, 0, r0, c7, c5, 1           @ invalidate I entry
159         add     r0, r0, #CACHE_DLINESIZE
160 #endif
161         cmp     r0, r1
162         blo     1b
163         tst     r2, #VM_EXEC
164         mcrne   p15, 0, ip, c7, c10, 4          @ drain WB
165         mov     pc, lr
168  *      coherent_kern_range(start, end)
170  *      Ensure coherency between the Icache and the Dcache in the
171  *      region described by start, end.  If you have non-snooping
172  *      Harvard caches, you need to implement this function.
174  *      - start - virtual start address
175  *      - end   - virtual end address
176  */
177 ENTRY(arm925_coherent_kern_range)
178         /* FALLTHROUGH */
181  *      coherent_user_range(start, end)
183  *      Ensure coherency between the Icache and the Dcache in the
184  *      region described by start, end.  If you have non-snooping
185  *      Harvard caches, you need to implement this function.
187  *      - start - virtual start address
188  *      - end   - virtual end address
189  */
190 ENTRY(arm925_coherent_user_range)
191         bic     r0, r0, #CACHE_DLINESIZE - 1
192 1:      mcr     p15, 0, r0, c7, c10, 1          @ clean D entry
193         mcr     p15, 0, r0, c7, c5, 1           @ invalidate I entry
194         add     r0, r0, #CACHE_DLINESIZE
195         cmp     r0, r1
196         blo     1b
197         mcr     p15, 0, r0, c7, c10, 4          @ drain WB
198         mov     pc, lr
201  *      flush_kern_dcache_area(void *addr, size_t size)
203  *      Ensure no D cache aliasing occurs, either with itself or
204  *      the I cache
206  *      - addr  - kernel address
207  *      - size  - region size
208  */
209 ENTRY(arm925_flush_kern_dcache_area)
210         add     r1, r0, r1
211 1:      mcr     p15, 0, r0, c7, c14, 1          @ clean+invalidate D entry
212         add     r0, r0, #CACHE_DLINESIZE
213         cmp     r0, r1
214         blo     1b
215         mov     r0, #0
216         mcr     p15, 0, r0, c7, c5, 0           @ invalidate I cache
217         mcr     p15, 0, r0, c7, c10, 4          @ drain WB
218         mov     pc, lr
221  *      dma_inv_range(start, end)
223  *      Invalidate (discard) the specified virtual address range.
224  *      May not write back any entries.  If 'start' or 'end'
225  *      are not cache line aligned, those lines must be written
226  *      back.
228  *      - start - virtual start address
229  *      - end   - virtual end address
231  * (same as v4wb)
232  */
233 arm925_dma_inv_range:
234 #ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
235         tst     r0, #CACHE_DLINESIZE - 1
236         mcrne   p15, 0, r0, c7, c10, 1          @ clean D entry
237         tst     r1, #CACHE_DLINESIZE - 1
238         mcrne   p15, 0, r1, c7, c10, 1          @ clean D entry
239 #endif
240         bic     r0, r0, #CACHE_DLINESIZE - 1
241 1:      mcr     p15, 0, r0, c7, c6, 1           @ invalidate D entry
242         add     r0, r0, #CACHE_DLINESIZE
243         cmp     r0, r1
244         blo     1b
245         mcr     p15, 0, r0, c7, c10, 4          @ drain WB
246         mov     pc, lr
249  *      dma_clean_range(start, end)
251  *      Clean the specified virtual address range.
253  *      - start - virtual start address
254  *      - end   - virtual end address
256  * (same as v4wb)
257  */
258 arm925_dma_clean_range:
259 #ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
260         bic     r0, r0, #CACHE_DLINESIZE - 1
261 1:      mcr     p15, 0, r0, c7, c10, 1          @ clean D entry
262         add     r0, r0, #CACHE_DLINESIZE
263         cmp     r0, r1
264         blo     1b
265 #endif
266         mcr     p15, 0, r0, c7, c10, 4          @ drain WB
267         mov     pc, lr
270  *      dma_flush_range(start, end)
272  *      Clean and invalidate the specified virtual address range.
274  *      - start - virtual start address
275  *      - end   - virtual end address
276  */
277 ENTRY(arm925_dma_flush_range)
278         bic     r0, r0, #CACHE_DLINESIZE - 1
280 #ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
281         mcr     p15, 0, r0, c7, c14, 1          @ clean+invalidate D entry
282 #else
283         mcr     p15, 0, r0, c7, c6, 1           @ invalidate D entry
284 #endif
285         add     r0, r0, #CACHE_DLINESIZE
286         cmp     r0, r1
287         blo     1b
288         mcr     p15, 0, r0, c7, c10, 4          @ drain WB
289         mov     pc, lr
292  *      dma_map_area(start, size, dir)
293  *      - start - kernel virtual start address
294  *      - size  - size of region
295  *      - dir   - DMA direction
296  */
297 ENTRY(arm925_dma_map_area)
298         add     r1, r1, r0
299         cmp     r2, #DMA_TO_DEVICE
300         beq     arm925_dma_clean_range
301         bcs     arm925_dma_inv_range
302         b       arm925_dma_flush_range
303 ENDPROC(arm925_dma_map_area)
306  *      dma_unmap_area(start, size, dir)
307  *      - start - kernel virtual start address
308  *      - size  - size of region
309  *      - dir   - DMA direction
310  */
311 ENTRY(arm925_dma_unmap_area)
312         mov     pc, lr
313 ENDPROC(arm925_dma_unmap_area)
315 ENTRY(arm925_cache_fns)
316         .long   arm925_flush_kern_cache_all
317         .long   arm925_flush_user_cache_all
318         .long   arm925_flush_user_cache_range
319         .long   arm925_coherent_kern_range
320         .long   arm925_coherent_user_range
321         .long   arm925_flush_kern_dcache_area
322         .long   arm925_dma_map_area
323         .long   arm925_dma_unmap_area
324         .long   arm925_dma_flush_range
326 ENTRY(cpu_arm925_dcache_clean_area)
327 #ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
328 1:      mcr     p15, 0, r0, c7, c10, 1          @ clean D entry
329         add     r0, r0, #CACHE_DLINESIZE
330         subs    r1, r1, #CACHE_DLINESIZE
331         bhi     1b
332 #endif
333         mcr     p15, 0, r0, c7, c10, 4          @ drain WB
334         mov     pc, lr
336 /* =============================== PageTable ============================== */
339  * cpu_arm925_switch_mm(pgd)
341  * Set the translation base pointer to be as described by pgd.
343  * pgd: new page tables
344  */
345         .align  5
346 ENTRY(cpu_arm925_switch_mm)
347 #ifdef CONFIG_MMU
348         mov     ip, #0
349 #ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
350         mcr     p15, 0, ip, c7, c6, 0           @ invalidate D cache
351 #else
352         /* Flush entries in bothe segments at once, see NOTE1 above */
353         mov     r3, #(CACHE_DENTRIES - 1) << 4  @ 256 entries in segment
354 2:      mcr     p15, 0, r3, c7, c14, 2          @ clean & invalidate D index
355         subs    r3, r3, #1 << 4
356         bcs     2b                              @ entries 255 to 0
357 #endif
358         mcr     p15, 0, ip, c7, c5, 0           @ invalidate I cache
359         mcr     p15, 0, ip, c7, c10, 4          @ drain WB
360         mcr     p15, 0, r0, c2, c0, 0           @ load page table pointer
361         mcr     p15, 0, ip, c8, c7, 0           @ invalidate I & D TLBs
362 #endif
363         mov     pc, lr
366  * cpu_arm925_set_pte_ext(ptep, pte, ext)
368  * Set a PTE and flush it out
369  */
370         .align  5
371 ENTRY(cpu_arm925_set_pte_ext)
372 #ifdef CONFIG_MMU
373         armv3_set_pte_ext
374         mov     r0, r0
375 #ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
376         mcr     p15, 0, r0, c7, c10, 1          @ clean D entry
377 #endif
378         mcr     p15, 0, r0, c7, c10, 4          @ drain WB
379 #endif /* CONFIG_MMU */
380         mov     pc, lr
382         __INIT
384         .type   __arm925_setup, #function
385 __arm925_setup:
386         mov     r0, #0
387 #if defined(CONFIG_CPU_ICACHE_STREAMING_DISABLE)
388         orr     r0,r0,#1 << 7
389 #endif
391         /* Transparent on, D-cache clean & flush mode. See  NOTE2 above */
392         orr     r0,r0,#1 << 1                   @ transparent mode on
393         mcr     p15, 0, r0, c15, c1, 0          @ write TI config register
395         mov     r0, #0
396         mcr     p15, 0, r0, c7, c7              @ invalidate I,D caches on v4
397         mcr     p15, 0, r0, c7, c10, 4          @ drain write buffer on v4
398 #ifdef CONFIG_MMU
399         mcr     p15, 0, r0, c8, c7              @ invalidate I,D TLBs on v4
400 #endif
402 #ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
403         mov     r0, #4                          @ disable write-back on caches explicitly
404         mcr     p15, 7, r0, c15, c0, 0
405 #endif
407         adr     r5, arm925_crval
408         ldmia   r5, {r5, r6}
409         mrc     p15, 0, r0, c1, c0              @ get control register v4
410         bic     r0, r0, r5
411         orr     r0, r0, r6
412 #ifdef CONFIG_CPU_CACHE_ROUND_ROBIN
413         orr     r0, r0, #0x4000                 @ .1.. .... .... ....
414 #endif
415         mov     pc, lr
416         .size   __arm925_setup, . - __arm925_setup
418         /*
419          *  R
420          * .RVI ZFRS BLDP WCAM
421          * .011 0001 ..11 1101
422          * 
423          */
424         .type   arm925_crval, #object
425 arm925_crval:
426         crval   clear=0x00007f3f, mmuset=0x0000313d, ucset=0x00001130
428         __INITDATA
431  * Purpose : Function pointers used to access above functions - all calls
432  *           come through these
433  */
434         .type   arm925_processor_functions, #object
435 arm925_processor_functions:
436         .word   v4t_early_abort
437         .word   legacy_pabort
438         .word   cpu_arm925_proc_init
439         .word   cpu_arm925_proc_fin
440         .word   cpu_arm925_reset
441         .word   cpu_arm925_do_idle
442         .word   cpu_arm925_dcache_clean_area
443         .word   cpu_arm925_switch_mm
444         .word   cpu_arm925_set_pte_ext
445         .size   arm925_processor_functions, . - arm925_processor_functions
447         .section ".rodata"
449         .type   cpu_arch_name, #object
450 cpu_arch_name:
451         .asciz  "armv4t"
452         .size   cpu_arch_name, . - cpu_arch_name
454         .type   cpu_elf_name, #object
455 cpu_elf_name:
456         .asciz  "v4"
457         .size   cpu_elf_name, . - cpu_elf_name
459         .type   cpu_arm925_name, #object
460 cpu_arm925_name:
461         .asciz  "ARM925T"
462         .size   cpu_arm925_name, . - cpu_arm925_name
464         .align
466         .section ".proc.info.init", #alloc, #execinstr
468         .type   __arm925_proc_info,#object
469 __arm925_proc_info:
470         .long   0x54029250
471         .long   0xfffffff0
472         .long   PMD_TYPE_SECT | \
473                 PMD_BIT4 | \
474                 PMD_SECT_AP_WRITE | \
475                 PMD_SECT_AP_READ
476         .long   PMD_TYPE_SECT | \
477                 PMD_BIT4 | \
478                 PMD_SECT_AP_WRITE | \
479                 PMD_SECT_AP_READ
480         b       __arm925_setup
481         .long   cpu_arch_name
482         .long   cpu_elf_name
483         .long   HWCAP_SWP | HWCAP_HALF | HWCAP_THUMB
484         .long   cpu_arm925_name
485         .long   arm925_processor_functions
486         .long   v4wbi_tlb_fns
487         .long   v4wb_user_fns
488         .long   arm925_cache_fns
489         .size   __arm925_proc_info, . - __arm925_proc_info
491         .type   __arm915_proc_info,#object
492 __arm915_proc_info:
493         .long   0x54029150
494         .long   0xfffffff0
495         .long   PMD_TYPE_SECT | \
496                 PMD_BIT4 | \
497                 PMD_SECT_AP_WRITE | \
498                 PMD_SECT_AP_READ
499         .long   PMD_TYPE_SECT | \
500                 PMD_BIT4 | \
501                 PMD_SECT_AP_WRITE | \
502                 PMD_SECT_AP_READ
503         b       __arm925_setup
504         .long   cpu_arch_name
505         .long   cpu_elf_name
506         .long   HWCAP_SWP | HWCAP_HALF | HWCAP_THUMB
507         .long   cpu_arm925_name
508         .long   arm925_processor_functions
509         .long   v4wbi_tlb_fns
510         .long   v4wb_user_fns
511         .long   arm925_cache_fns
512         .size   __arm925_proc_info, . - __arm925_proc_info