Merge master.kernel.org:/pub/scm/linux/kernel/git/kyle/parisc-2.6
[sfrench/cifs-2.6.git] / arch / arm / mm / proc-arm1026.S
1 /*
2  *  linux/arch/arm/mm/proc-arm1026.S: MMU functions for ARM1026EJ-S
3  *
4  *  Copyright (C) 2000 ARM Limited
5  *  Copyright (C) 2000 Deep Blue Solutions Ltd.
6  *  hacked for non-paged-MM by Hyok S. Choi, 2003.
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version.
12  *
13  *
14  * These are the low level assembler for performing cache and TLB
15  * functions on the ARM1026EJ-S.
16  */
17 #include <linux/linkage.h>
18 #include <linux/config.h>
19 #include <linux/init.h>
20 #include <asm/assembler.h>
21 #include <asm/asm-offsets.h>
22 #include <asm/pgtable-hwdef.h>
23 #include <asm/pgtable.h>
24 #include <asm/procinfo.h>
25 #include <asm/ptrace.h>
26
27 /*
28  * This is the maximum size of an area which will be invalidated
29  * using the single invalidate entry instructions.  Anything larger
30  * than this, and we go for the whole cache.
31  *
32  * This value should be chosen such that we choose the cheapest
33  * alternative.
34  */
35 #define MAX_AREA_SIZE   32768
36
37 /*
38  * The size of one data cache line.
39  */
40 #define CACHE_DLINESIZE 32
41
42 /*
43  * The number of data cache segments.
44  */
45 #define CACHE_DSEGMENTS 16
46
47 /*
48  * The number of lines in a cache segment.
49  */
50 #define CACHE_DENTRIES  64
51
52 /*
53  * This is the size at which it becomes more efficient to
54  * clean the whole cache, rather than using the individual
55  * cache line maintainence instructions.
56  */
57 #define CACHE_DLIMIT    32768
58
59         .text
60 /*
61  * cpu_arm1026_proc_init()
62  */
63 ENTRY(cpu_arm1026_proc_init)
64         mov     pc, lr
65
66 /*
67  * cpu_arm1026_proc_fin()
68  */
69 ENTRY(cpu_arm1026_proc_fin)
70         stmfd   sp!, {lr}
71         mov     ip, #PSR_F_BIT | PSR_I_BIT | SVC_MODE
72         msr     cpsr_c, ip
73         bl      arm1026_flush_kern_cache_all
74         mrc     p15, 0, r0, c1, c0, 0           @ ctrl register
75         bic     r0, r0, #0x1000                 @ ...i............
76         bic     r0, r0, #0x000e                 @ ............wca.
77         mcr     p15, 0, r0, c1, c0, 0           @ disable caches
78         ldmfd   sp!, {pc}
79
80 /*
81  * cpu_arm1026_reset(loc)
82  *
83  * Perform a soft reset of the system.  Put the CPU into the
84  * same state as it would be if it had been reset, and branch
85  * to what would be the reset vector.
86  *
87  * loc: location to jump to for soft reset
88  */
89         .align  5
90 ENTRY(cpu_arm1026_reset)
91         mov     ip, #0
92         mcr     p15, 0, ip, c7, c7, 0           @ invalidate I,D caches
93         mcr     p15, 0, ip, c7, c10, 4          @ drain WB
94 #ifdef CONFIG_MMU
95         mcr     p15, 0, ip, c8, c7, 0           @ invalidate I & D TLBs
96 #endif
97         mrc     p15, 0, ip, c1, c0, 0           @ ctrl register
98         bic     ip, ip, #0x000f                 @ ............wcam
99         bic     ip, ip, #0x1100                 @ ...i...s........
100         mcr     p15, 0, ip, c1, c0, 0           @ ctrl register
101         mov     pc, r0
102
103 /*
104  * cpu_arm1026_do_idle()
105  */
106         .align  5
107 ENTRY(cpu_arm1026_do_idle)
108         mcr     p15, 0, r0, c7, c0, 4           @ Wait for interrupt
109         mov     pc, lr
110
111 /* ================================= CACHE ================================ */
112
113         .align  5
114 /*
115  *      flush_user_cache_all()
116  *
117  *      Invalidate all cache entries in a particular address
118  *      space.
119  */
120 ENTRY(arm1026_flush_user_cache_all)
121         /* FALLTHROUGH */
122 /*
123  *      flush_kern_cache_all()
124  *
125  *      Clean and invalidate the entire cache.
126  */
127 ENTRY(arm1026_flush_kern_cache_all)
128         mov     r2, #VM_EXEC
129         mov     ip, #0
130 __flush_whole_cache:
131 #ifndef CONFIG_CPU_DCACHE_DISABLE
132 1:      mrc     p15, 0, r15, c7, c14, 3         @ test, clean, invalidate
133         bne     1b
134 #endif
135         tst     r2, #VM_EXEC
136 #ifndef CONFIG_CPU_ICACHE_DISABLE
137         mcrne   p15, 0, ip, c7, c5, 0           @ invalidate I cache
138 #endif
139         mcrne   p15, 0, ip, c7, c10, 4          @ drain WB
140         mov     pc, lr
141
142 /*
143  *      flush_user_cache_range(start, end, flags)
144  *
145  *      Invalidate a range of cache entries in the specified
146  *      address space.
147  *
148  *      - start - start address (inclusive)
149  *      - end   - end address (exclusive)
150  *      - flags - vm_flags for this space
151  */
152 ENTRY(arm1026_flush_user_cache_range)
153         mov     ip, #0
154         sub     r3, r1, r0                      @ calculate total size
155         cmp     r3, #CACHE_DLIMIT
156         bhs     __flush_whole_cache
157
158 #ifndef CONFIG_CPU_DCACHE_DISABLE
159 1:      mcr     p15, 0, r0, c7, c14, 1          @ clean+invalidate D entry
160         add     r0, r0, #CACHE_DLINESIZE
161         cmp     r0, r1
162         blo     1b
163 #endif
164         tst     r2, #VM_EXEC
165 #ifndef CONFIG_CPU_ICACHE_DISABLE
166         mcrne   p15, 0, ip, c7, c5, 0           @ invalidate I cache
167 #endif
168         mcrne   p15, 0, ip, c7, c10, 4          @ drain WB
169         mov     pc, lr
170
171 /*
172  *      coherent_kern_range(start, end)
173  *
174  *      Ensure coherency between the Icache and the Dcache in the
175  *      region described by start.  If you have non-snooping
176  *      Harvard caches, you need to implement this function.
177  *
178  *      - start - virtual start address
179  *      - end   - virtual end address
180  */
181 ENTRY(arm1026_coherent_kern_range)
182         /* FALLTHROUGH */
183 /*
184  *      coherent_user_range(start, end)
185  *
186  *      Ensure coherency between the Icache and the Dcache in the
187  *      region described by start.  If you have non-snooping
188  *      Harvard caches, you need to implement this function.
189  *
190  *      - start - virtual start address
191  *      - end   - virtual end address
192  */
193 ENTRY(arm1026_coherent_user_range)
194         mov     ip, #0
195         bic     r0, r0, #CACHE_DLINESIZE - 1
196 1:
197 #ifndef CONFIG_CPU_DCACHE_DISABLE
198         mcr     p15, 0, r0, c7, c10, 1          @ clean D entry
199 #endif
200 #ifndef CONFIG_CPU_ICACHE_DISABLE
201         mcr     p15, 0, r0, c7, c5, 1           @ invalidate I entry
202 #endif
203         add     r0, r0, #CACHE_DLINESIZE
204         cmp     r0, r1
205         blo     1b
206         mcr     p15, 0, ip, c7, c10, 4          @ drain WB
207         mov     pc, lr
208
209 /*
210  *      flush_kern_dcache_page(void *page)
211  *
212  *      Ensure no D cache aliasing occurs, either with itself or
213  *      the I cache
214  *
215  *      - page  - page aligned address
216  */
217 ENTRY(arm1026_flush_kern_dcache_page)
218         mov     ip, #0
219 #ifndef CONFIG_CPU_DCACHE_DISABLE
220         add     r1, r0, #PAGE_SZ
221 1:      mcr     p15, 0, r0, c7, c14, 1          @ clean+invalidate D entry
222         add     r0, r0, #CACHE_DLINESIZE
223         cmp     r0, r1
224         blo     1b
225 #endif
226         mcr     p15, 0, ip, c7, c10, 4          @ drain WB
227         mov     pc, lr
228
229 /*
230  *      dma_inv_range(start, end)
231  *
232  *      Invalidate (discard) the specified virtual address range.
233  *      May not write back any entries.  If 'start' or 'end'
234  *      are not cache line aligned, those lines must be written
235  *      back.
236  *
237  *      - start - virtual start address
238  *      - end   - virtual end address
239  *
240  * (same as v4wb)
241  */
242 ENTRY(arm1026_dma_inv_range)
243         mov     ip, #0
244 #ifndef CONFIG_CPU_DCACHE_DISABLE
245         tst     r0, #CACHE_DLINESIZE - 1
246         bic     r0, r0, #CACHE_DLINESIZE - 1
247         mcrne   p15, 0, r0, c7, c10, 1          @ clean D entry
248         tst     r1, #CACHE_DLINESIZE - 1
249         mcrne   p15, 0, r1, c7, c10, 1          @ clean D entry
250 1:      mcr     p15, 0, r0, c7, c6, 1           @ invalidate D entry
251         add     r0, r0, #CACHE_DLINESIZE
252         cmp     r0, r1
253         blo     1b
254 #endif
255         mcr     p15, 0, ip, c7, c10, 4          @ drain WB
256         mov     pc, lr
257
258 /*
259  *      dma_clean_range(start, end)
260  *
261  *      Clean the specified virtual address range.
262  *
263  *      - start - virtual start address
264  *      - end   - virtual end address
265  *
266  * (same as v4wb)
267  */
268 ENTRY(arm1026_dma_clean_range)
269         mov     ip, #0
270 #ifndef CONFIG_CPU_DCACHE_DISABLE
271         bic     r0, r0, #CACHE_DLINESIZE - 1
272 1:      mcr     p15, 0, r0, c7, c10, 1          @ clean D entry
273         add     r0, r0, #CACHE_DLINESIZE
274         cmp     r0, r1
275         blo     1b
276 #endif
277         mcr     p15, 0, ip, c7, c10, 4          @ drain WB
278         mov     pc, lr
279
280 /*
281  *      dma_flush_range(start, end)
282  *
283  *      Clean and invalidate the specified virtual address range.
284  *
285  *      - start - virtual start address
286  *      - end   - virtual end address
287  */
288 ENTRY(arm1026_dma_flush_range)
289         mov     ip, #0
290 #ifndef CONFIG_CPU_DCACHE_DISABLE
291         bic     r0, r0, #CACHE_DLINESIZE - 1
292 1:      mcr     p15, 0, r0, c7, c14, 1          @ clean+invalidate D entry
293         add     r0, r0, #CACHE_DLINESIZE
294         cmp     r0, r1
295         blo     1b
296 #endif
297         mcr     p15, 0, ip, c7, c10, 4          @ drain WB
298         mov     pc, lr
299
300 ENTRY(arm1026_cache_fns)
301         .long   arm1026_flush_kern_cache_all
302         .long   arm1026_flush_user_cache_all
303         .long   arm1026_flush_user_cache_range
304         .long   arm1026_coherent_kern_range
305         .long   arm1026_coherent_user_range
306         .long   arm1026_flush_kern_dcache_page
307         .long   arm1026_dma_inv_range
308         .long   arm1026_dma_clean_range
309         .long   arm1026_dma_flush_range
310
311         .align  5
312 ENTRY(cpu_arm1026_dcache_clean_area)
313 #ifndef CONFIG_CPU_DCACHE_DISABLE
314         mov     ip, #0
315 1:      mcr     p15, 0, r0, c7, c10, 1          @ clean D entry
316         add     r0, r0, #CACHE_DLINESIZE
317         subs    r1, r1, #CACHE_DLINESIZE
318         bhi     1b
319 #endif
320         mov     pc, lr
321
322 /* =============================== PageTable ============================== */
323
324 /*
325  * cpu_arm1026_switch_mm(pgd)
326  *
327  * Set the translation base pointer to be as described by pgd.
328  *
329  * pgd: new page tables
330  */
331         .align  5
332 ENTRY(cpu_arm1026_switch_mm)
333 #ifdef CONFIG_MMU
334         mov     r1, #0
335 #ifndef CONFIG_CPU_DCACHE_DISABLE
336 1:      mrc     p15, 0, r15, c7, c14, 3         @ test, clean, invalidate
337         bne     1b
338 #endif
339 #ifndef CONFIG_CPU_ICACHE_DISABLE
340         mcr     p15, 0, r1, c7, c5, 0           @ invalidate I cache
341 #endif
342         mcr     p15, 0, r1, c7, c10, 4          @ drain WB
343         mcr     p15, 0, r0, c2, c0, 0           @ load page table pointer
344         mcr     p15, 0, r1, c8, c7, 0           @ invalidate I & D TLBs
345 #endif
346         mov     pc, lr
347         
348 /*
349  * cpu_arm1026_set_pte(ptep, pte)
350  *
351  * Set a PTE and flush it out
352  */
353         .align  5
354 ENTRY(cpu_arm1026_set_pte)
355 #ifdef CONFIG_MMU
356         str     r1, [r0], #-2048                @ linux version
357
358         eor     r1, r1, #L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_WRITE | L_PTE_DIRTY
359
360         bic     r2, r1, #PTE_SMALL_AP_MASK
361         bic     r2, r2, #PTE_TYPE_MASK
362         orr     r2, r2, #PTE_TYPE_SMALL
363
364         tst     r1, #L_PTE_USER                 @ User?
365         orrne   r2, r2, #PTE_SMALL_AP_URO_SRW
366
367         tst     r1, #L_PTE_WRITE | L_PTE_DIRTY  @ Write and Dirty?
368         orreq   r2, r2, #PTE_SMALL_AP_UNO_SRW
369
370         tst     r1, #L_PTE_PRESENT | L_PTE_YOUNG        @ Present and Young?
371         movne   r2, #0
372
373 #ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
374         eor     r3, r1, #0x0a                   @ C & small page?
375         tst     r3, #0x0b
376         biceq   r2, r2, #4
377 #endif
378         str     r2, [r0]                        @ hardware version
379         mov     r0, r0
380 #ifndef CONFIG_CPU_DCACHE_DISABLE
381         mcr     p15, 0, r0, c7, c10, 1          @ clean D entry
382 #endif
383 #endif /* CONFIG_MMU */
384         mov     pc, lr
385
386
387         __INIT
388
389         .type   __arm1026_setup, #function
390 __arm1026_setup:
391         mov     r0, #0
392         mcr     p15, 0, r0, c7, c7              @ invalidate I,D caches on v4
393         mcr     p15, 0, r0, c7, c10, 4          @ drain write buffer on v4
394 #ifdef CONFIG_MMU
395         mcr     p15, 0, r0, c8, c7              @ invalidate I,D TLBs on v4
396         mcr     p15, 0, r4, c2, c0              @ load page table pointer
397 #endif
398 #ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
399         mov     r0, #4                          @ explicitly disable writeback
400         mcr     p15, 7, r0, c15, c0, 0
401 #endif
402         mrc     p15, 0, r0, c1, c0              @ get control register v4
403         ldr     r5, arm1026_cr1_clear
404         bic     r0, r0, r5
405         ldr     r5, arm1026_cr1_set
406         orr     r0, r0, r5
407 #ifdef CONFIG_CPU_CACHE_ROUND_ROBIN
408         orr     r0, r0, #0x4000                 @ .R.. .... .... ....
409 #endif
410         mov     pc, lr
411         .size   __arm1026_setup, . - __arm1026_setup
412
413         /*
414          *  R
415          * .RVI ZFRS BLDP WCAM
416          * .011 1001 ..11 0101
417          * 
418          */
419         .type   arm1026_cr1_clear, #object
420         .type   arm1026_cr1_set, #object
421 arm1026_cr1_clear:
422         .word   0x7f3f
423 arm1026_cr1_set:
424         .word   0x3935
425
426         __INITDATA
427
428 /*
429  * Purpose : Function pointers used to access above functions - all calls
430  *           come through these
431  */
432         .type   arm1026_processor_functions, #object
433 arm1026_processor_functions:
434         .word   v5t_early_abort
435         .word   cpu_arm1026_proc_init
436         .word   cpu_arm1026_proc_fin
437         .word   cpu_arm1026_reset
438         .word   cpu_arm1026_do_idle
439         .word   cpu_arm1026_dcache_clean_area
440         .word   cpu_arm1026_switch_mm
441         .word   cpu_arm1026_set_pte
442         .size   arm1026_processor_functions, . - arm1026_processor_functions
443
444         .section .rodata
445
446         .type   cpu_arch_name, #object
447 cpu_arch_name:
448         .asciz  "armv5tej"
449         .size   cpu_arch_name, . - cpu_arch_name
450
451         .type   cpu_elf_name, #object
452 cpu_elf_name:
453         .asciz  "v5"
454         .size   cpu_elf_name, . - cpu_elf_name
455         .align
456
457         .type   cpu_arm1026_name, #object
458 cpu_arm1026_name:
459         .ascii  "ARM1026EJ-S"
460 #ifndef CONFIG_CPU_ICACHE_DISABLE
461         .ascii  "i"
462 #endif
463 #ifndef CONFIG_CPU_DCACHE_DISABLE
464         .ascii  "d"
465 #ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
466         .ascii  "(wt)"
467 #else
468         .ascii  "(wb)"
469 #endif
470 #endif
471 #ifndef CONFIG_CPU_BPREDICT_DISABLE
472         .ascii  "B"
473 #endif
474 #ifdef CONFIG_CPU_CACHE_ROUND_ROBIN
475         .ascii  "RR"
476 #endif
477         .ascii  "\0"
478         .size   cpu_arm1026_name, . - cpu_arm1026_name
479
480         .align
481
482         .section ".proc.info.init", #alloc, #execinstr
483
484         .type   __arm1026_proc_info,#object
485 __arm1026_proc_info:
486         .long   0x4106a260                      @ ARM 1026EJ-S (v5TEJ)
487         .long   0xff0ffff0
488         .long   PMD_TYPE_SECT | \
489                 PMD_BIT4 | \
490                 PMD_SECT_AP_WRITE | \
491                 PMD_SECT_AP_READ
492         b       __arm1026_setup
493         .long   cpu_arch_name
494         .long   cpu_elf_name
495         .long   HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP|HWCAP_JAVA
496         .long   cpu_arm1026_name
497         .long   arm1026_processor_functions
498         .long   v4wbi_tlb_fns
499         .long   v4wb_user_fns
500         .long   arm1026_cache_fns
501         .size   __arm1026_proc_info, . - __arm1026_proc_info