Merge branch 'release' of git://git.kernel.org/pub/scm/linux/kernel/git/lenb/linux...
[linux-2.6] / arch / arm / mm / proc-xsc3.S
1 /*
2  * linux/arch/arm/mm/proc-xsc3.S
3  *
4  * Original Author: Matthew Gilbert
5  * Current Maintainer: Lennert Buytenhek <buytenh@wantstofly.org>
6  *
7  * Copyright 2004 (C) Intel Corp.
8  * Copyright 2005 (c) MontaVista Software, Inc.
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License version 2 as
12  * published by the Free Software Foundation.
13  *
14  * MMU functions for the Intel XScale3 Core (XSC3).  The XSC3 core is an
15  * extension to Intel's original XScale core that adds the following
16  * features:
17  *
18  * - ARMv6 Supersections
19  * - Low Locality Reference pages (replaces mini-cache)
20  * - 36-bit addressing
21  * - L2 cache
22  * - Cache-coherency if chipset supports it
23  *
24  * Based on orignal XScale code by Nicolas Pitre
25  */
26
27 #include <linux/linkage.h>
28 #include <linux/init.h>
29 #include <asm/assembler.h>
30 #include <asm/elf.h>
31 #include <asm/hardware.h>
32 #include <asm/pgtable.h>
33 #include <asm/pgtable-hwdef.h>
34 #include <asm/page.h>
35 #include <asm/ptrace.h>
36 #include "proc-macros.S"
37
38 /*
39  * This is the maximum size of an area which will be flushed.  If the
40  * area is larger than this, then we flush the whole cache.
41  */
42 #define MAX_AREA_SIZE   32768
43
44 /*
45  * The cache line size of the I and D cache.
46  */
47 #define CACHELINESIZE   32
48
49 /*
50  * The size of the data cache.
51  */
52 #define CACHESIZE       32768
53
54 /*
55  * Run with L2 enabled.
56  */
57 #define L2_CACHE_ENABLE 1
58
59 /*
60  * This macro is used to wait for a CP15 write and is needed
61  * when we have to ensure that the last operation to the co-pro
62  * was completed before continuing with operation.
63  */
64         .macro  cpwait_ret, lr, rd
65         mrc     p15, 0, \rd, c2, c0, 0          @ arbitrary read of cp15
66         sub     pc, \lr, \rd, LSR #32           @ wait for completion and
67                                                 @ flush instruction pipeline
68         .endm
69
70 /*
71  * This macro cleans & invalidates the entire xsc3 dcache by set & way.
72  */
73
74         .macro  clean_d_cache rd, rs
75         mov     \rd, #0x1f00
76         orr     \rd, \rd, #0x00e0
77 1:      mcr     p15, 0, \rd, c7, c14, 2         @ clean/inv set/way
78         adds    \rd, \rd, #0x40000000
79         bcc     1b
80         subs    \rd, \rd, #0x20
81         bpl     1b
82         .endm
83
84         .text
85
86 /*
87  * cpu_xsc3_proc_init()
88  *
89  * Nothing too exciting at the moment
90  */
91 ENTRY(cpu_xsc3_proc_init)
92         mov     pc, lr
93
94 /*
95  * cpu_xsc3_proc_fin()
96  */
97 ENTRY(cpu_xsc3_proc_fin)
98         str     lr, [sp, #-4]!
99         mov     r0, #PSR_F_BIT|PSR_I_BIT|SVC_MODE
100         msr     cpsr_c, r0
101         bl      xsc3_flush_kern_cache_all       @ clean caches
102         mrc     p15, 0, r0, c1, c0, 0           @ ctrl register
103         bic     r0, r0, #0x1800                 @ ...IZ...........
104         bic     r0, r0, #0x0006                 @ .............CA.
105         mcr     p15, 0, r0, c1, c0, 0           @ disable caches
106         ldr     pc, [sp], #4
107
108 /*
109  * cpu_xsc3_reset(loc)
110  *
111  * Perform a soft reset of the system.  Put the CPU into the
112  * same state as it would be if it had been reset, and branch
113  * to what would be the reset vector.
114  *
115  * loc: location to jump to for soft reset
116  */
117         .align  5
118 ENTRY(cpu_xsc3_reset)
119         mov     r1, #PSR_F_BIT|PSR_I_BIT|SVC_MODE
120         msr     cpsr_c, r1                      @ reset CPSR
121         mrc     p15, 0, r1, c1, c0, 0           @ ctrl register
122         bic     r1, r1, #0x0086                 @ ........B....CA.
123         bic     r1, r1, #0x3900                 @ ..VIZ..S........
124         mcr     p15, 0, r1, c1, c0, 0           @ ctrl register
125         mcr     p15, 0, ip, c7, c7, 0           @ invalidate I,D caches & BTB
126         bic     r1, r1, #0x0001                 @ ...............M
127         mcr     p15, 0, r1, c1, c0, 0           @ ctrl register
128         @ CAUTION: MMU turned off from this point.  We count on the pipeline
129         @ already containing those two last instructions to survive.
130         mcr     p15, 0, ip, c8, c7, 0           @ invalidate I & D TLBs
131         mov     pc, r0
132
133 /*
134  * cpu_xsc3_do_idle()
135  *
136  * Cause the processor to idle
137  *
138  * For now we do nothing but go to idle mode for every case
139  *
140  * XScale supports clock switching, but using idle mode support
141  * allows external hardware to react to system state changes.
142
143  MMG: Come back to this one.
144  */
145         .align  5
146
147 ENTRY(cpu_xsc3_do_idle)
148         mov     r0, #1
149         mcr     p14, 0, r0, c7, c0, 0           @ Go to IDLE
150         mov     pc, lr
151
152 /* ================================= CACHE ================================ */
153
154 /*
155  *      flush_user_cache_all()
156  *
157  *      Invalidate all cache entries in a particular address
158  *      space.
159  */
160 ENTRY(xsc3_flush_user_cache_all)
161         /* FALLTHROUGH */
162
163 /*
164  *      flush_kern_cache_all()
165  *
166  *      Clean and invalidate the entire cache.
167  */
168 ENTRY(xsc3_flush_kern_cache_all)
169         mov     r2, #VM_EXEC
170         mov     ip, #0
171 __flush_whole_cache:
172         clean_d_cache r0, r1
173         tst     r2, #VM_EXEC
174         mcrne   p15, 0, ip, c7, c5, 0           @ Invalidate I cache & BTB
175         mcrne   p15, 0, ip, c7, c10, 4          @ Drain Write Buffer
176         mcrne   p15, 0, ip, c7, c5, 4           @ Prefetch Flush
177         mov     pc, lr
178
179 /*
180  *      flush_user_cache_range(start, end, vm_flags)
181  *
182  *      Invalidate a range of cache entries in the specified
183  *      address space.
184  *
185  *      - start - start address (may not be aligned)
186  *      - end   - end address (exclusive, may not be aligned)
187  *      - vma   - vma_area_struct describing address space
188  */
189         .align  5
190 ENTRY(xsc3_flush_user_cache_range)
191         mov     ip, #0
192         sub     r3, r1, r0                      @ calculate total size
193         cmp     r3, #MAX_AREA_SIZE
194         bhs     __flush_whole_cache
195
196 1:      tst     r2, #VM_EXEC
197         mcrne   p15, 0, r0, c7, c5, 1           @ Invalidate I cache line
198         mcr     p15, 0, r0, c7, c14, 1          @ Clean/invalidate D cache line
199         add     r0, r0, #CACHELINESIZE
200         cmp     r0, r1
201         blo     1b
202         tst     r2, #VM_EXEC
203         mcrne   p15, 0, ip, c7, c5, 6           @ Invalidate BTB
204         mcrne   p15, 0, ip, c7, c10, 4          @ Drain Write Buffer
205         mcrne   p15, 0, ip, c7, c5, 4           @ Prefetch Flush
206         mov     pc, lr
207
208 /*
209  *      coherent_kern_range(start, end)
210  *
211  *      Ensure coherency between the Icache and the Dcache in the
212  *      region described by start.  If you have non-snooping
213  *      Harvard caches, you need to implement this function.
214  *
215  *      - start  - virtual start address
216  *      - end    - virtual end address
217  *
218  *      Note: single I-cache line invalidation isn't used here since
219  *      it also trashes the mini I-cache used by JTAG debuggers.
220  */
221 ENTRY(xsc3_coherent_kern_range)
222 /* FALLTHROUGH */
223 ENTRY(xsc3_coherent_user_range)
224         bic     r0, r0, #CACHELINESIZE - 1
225 1:      mcr     p15, 0, r0, c7, c10, 1          @ clean D entry
226         add     r0, r0, #CACHELINESIZE
227         cmp     r0, r1
228         blo     1b
229         mov     r0, #0
230         mcr     p15, 0, r0, c7, c5, 0           @ Invalidate I cache & BTB
231         mcr     p15, 0, r0, c7, c10, 4          @ Drain Write Buffer
232         mcr     p15, 0, r0, c7, c5, 4           @ Prefetch Flush
233         mov     pc, lr
234
235 /*
236  *      flush_kern_dcache_page(void *page)
237  *
238  *      Ensure no D cache aliasing occurs, either with itself or
239  *      the I cache
240  *
241  *      - addr  - page aligned address
242  */
243 ENTRY(xsc3_flush_kern_dcache_page)
244         add     r1, r0, #PAGE_SZ
245 1:      mcr     p15, 0, r0, c7, c14, 1          @ Clean/Invalidate D Cache line
246         add     r0, r0, #CACHELINESIZE
247         cmp     r0, r1
248         blo     1b
249         mov     r0, #0
250         mcr     p15, 0, r0, c7, c5, 0           @ Invalidate I cache & BTB
251         mcr     p15, 0, r0, c7, c10, 4          @ Drain Write Buffer
252         mcr     p15, 0, r0, c7, c5, 4           @ Prefetch Flush
253         mov     pc, lr
254
255 /*
256  *      dma_inv_range(start, end)
257  *
258  *      Invalidate (discard) the specified virtual address range.
259  *      May not write back any entries.  If 'start' or 'end'
260  *      are not cache line aligned, those lines must be written
261  *      back.
262  *
263  *      - start  - virtual start address
264  *      - end    - virtual end address
265  */
266 ENTRY(xsc3_dma_inv_range)
267         tst     r0, #CACHELINESIZE - 1
268         bic     r0, r0, #CACHELINESIZE - 1
269         mcrne   p15, 0, r0, c7, c10, 1          @ clean L1 D entry
270         mcrne   p15, 1, r0, c7, c11, 1          @ clean L2 D entry
271         tst     r1, #CACHELINESIZE - 1
272         mcrne   p15, 0, r1, c7, c10, 1          @ clean L1 D entry
273         mcrne   p15, 1, r1, c7, c11, 1          @ clean L2 D entry
274 1:      mcr     p15, 0, r0, c7, c6, 1           @ invalidate L1 D entry
275         mcr     p15, 1, r0, c7, c7, 1           @ Invalidate L2 D cache line
276         add     r0, r0, #CACHELINESIZE
277         cmp     r0, r1
278         blo     1b
279         mcr     p15, 0, r0, c7, c10, 4          @ Drain Write Buffer
280         mov     pc, lr
281
282 /*
283  *      dma_clean_range(start, end)
284  *
285  *      Clean the specified virtual address range.
286  *
287  *      - start  - virtual start address
288  *      - end    - virtual end address
289  */
290 ENTRY(xsc3_dma_clean_range)
291         bic     r0, r0, #CACHELINESIZE - 1
292 1:      mcr     p15, 0, r0, c7, c10, 1          @ clean L1 D entry
293         mcr     p15, 1, r0, c7, c11, 1          @ clean L2 D entry
294         add     r0, r0, #CACHELINESIZE
295         cmp     r0, r1
296         blo     1b
297         mcr     p15, 0, r0, c7, c10, 4          @ Drain Write Buffer
298         mov     pc, lr
299
300 /*
301  *      dma_flush_range(start, end)
302  *
303  *      Clean and invalidate the specified virtual address range.
304  *
305  *      - start  - virtual start address
306  *      - end    - virtual end address
307  */
308 ENTRY(xsc3_dma_flush_range)
309         bic     r0, r0, #CACHELINESIZE - 1
310 1:      mcr     p15, 0, r0, c7, c14, 1  @ Clean/invalidate L1 D cache line
311         mcr     p15, 1, r0, c7, c11, 1  @ Clean L2 D cache line
312         mcr     p15, 1, r0, c7, c7, 1   @ Invalidate L2 D cache line
313         add     r0, r0, #CACHELINESIZE
314         cmp     r0, r1
315         blo     1b
316         mcr     p15, 0, r0, c7, c10, 4          @ Drain Write Buffer
317         mov     pc, lr
318
319 ENTRY(xsc3_cache_fns)
320         .long   xsc3_flush_kern_cache_all
321         .long   xsc3_flush_user_cache_all
322         .long   xsc3_flush_user_cache_range
323         .long   xsc3_coherent_kern_range
324         .long   xsc3_coherent_user_range
325         .long   xsc3_flush_kern_dcache_page
326         .long   xsc3_dma_inv_range
327         .long   xsc3_dma_clean_range
328         .long   xsc3_dma_flush_range
329
330 ENTRY(cpu_xsc3_dcache_clean_area)
331 1:      mcr     p15, 0, r0, c7, c10, 1          @ clean D entry
332         add     r0, r0, #CACHELINESIZE
333         subs    r1, r1, #CACHELINESIZE
334         bhi     1b
335         mov     pc, lr
336
337 /* =============================== PageTable ============================== */
338
339 /*
340  * cpu_xsc3_switch_mm(pgd)
341  *
342  * Set the translation base pointer to be as described by pgd.
343  *
344  * pgd: new page tables
345  */
346         .align  5
347 ENTRY(cpu_xsc3_switch_mm)
348         clean_d_cache r1, r2
349         mcr     p15, 0, ip, c7, c5, 0           @ Invalidate I cache & BTB
350         mcr     p15, 0, ip, c7, c10, 4          @ Drain Write Buffer
351         mcr     p15, 0, ip, c7, c5, 4           @ Prefetch Flush
352 #ifdef L2_CACHE_ENABLE
353         orr     r0, r0, #0x18                   @ cache the page table in L2
354 #endif
355         mcr     p15, 0, r0, c2, c0, 0           @ load page table pointer
356         mcr     p15, 0, ip, c8, c7, 0           @ invalidate I & D TLBs
357         cpwait_ret lr, ip
358
359 /*
360  * cpu_xsc3_set_pte_ext(ptep, pte, ext)
361  *
362  * Set a PTE and flush it out
363  *
364  */
365         .align  5
366 ENTRY(cpu_xsc3_set_pte_ext)
367         str     r1, [r0], #-2048                @ linux version
368
369         bic     r2, r1, #0xff0                  @ Keep C, B bits
370         orr     r2, r2, #PTE_TYPE_EXT           @ extended page
371         tst     r1, #L_PTE_SHARED               @ Shared?
372         orrne   r2, r2, #0x200
373
374         eor     r3, r1, #L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_WRITE | L_PTE_DIRTY
375
376         tst     r3, #L_PTE_USER                 @ User?
377         orrne   r2, r2, #PTE_EXT_AP_URO_SRW     @ yes -> user r/o, system r/w
378
379         tst     r3, #L_PTE_WRITE | L_PTE_DIRTY  @ Write and Dirty?
380         orreq   r2, r2, #PTE_EXT_AP_UNO_SRW     @ yes -> user n/a, system r/w
381                                                 @ combined with user -> user r/w
382
383 #if L2_CACHE_ENABLE
384         @ If its cacheable it needs to be in L2 also.
385         eor     ip, r1, #L_PTE_CACHEABLE
386         tst     ip, #L_PTE_CACHEABLE
387         orreq   r2, r2, #PTE_EXT_TEX(0x5)
388 #endif
389
390         tst     r3, #L_PTE_PRESENT | L_PTE_YOUNG        @ Present and Young?
391         movne   r2, #0                          @ no -> fault
392
393         str     r2, [r0]                        @ hardware version
394         mov     ip, #0
395         mcr     p15, 0, r0, c7, c10, 1          @ Clean D cache line mcr
396         mcr     p15, 0, ip, c7, c10, 4          @ Drain Write Buffer
397         mov     pc, lr
398
399         .ltorg
400
401         .align
402
403         __INIT
404
405         .type   __xsc3_setup, #function
406 __xsc3_setup:
407         mov     r0, #PSR_F_BIT|PSR_I_BIT|SVC_MODE
408         msr     cpsr_c, r0
409         mcr     p15, 0, ip, c7, c7, 0           @ invalidate I, D caches & BTB
410         mcr     p15, 0, ip, c7, c10, 4          @ Drain Write Buffer
411         mcr     p15, 0, ip, c7, c5, 4           @ Prefetch Flush
412         mcr     p15, 0, ip, c8, c7, 0           @ invalidate I, D TLBs
413 #if L2_CACHE_ENABLE
414         orr     r4, r4, #0x18                   @ cache the page table in L2
415 #endif
416         mcr     p15, 0, r4, c2, c0, 0           @ load page table pointer
417         mov     r0, #1                          @ Allow access to CP0 and CP13
418         orr     r0, r0, #1 << 13                @ Its undefined whether this
419         mcr     p15, 0, r0, c15, c1, 0          @ affects USR or SVC modes
420         mrc     p15, 0, r0, c1, c0, 1           @ get auxiliary control reg
421         and     r0, r0, #2                      @ preserve bit P bit setting
422 #if L2_CACHE_ENABLE
423         orr     r0, r0, #(1 << 10)              @ enable L2 for LLR cache
424 #endif
425         mcr     p15, 0, r0, c1, c0, 1           @ set auxiliary control reg
426
427         adr     r5, xsc3_crval
428         ldmia   r5, {r5, r6}
429         mrc     p15, 0, r0, c1, c0, 0           @ get control register
430         bic     r0, r0, r5                      @ .... .... .... ..A.
431         orr     r0, r0, r6                      @ .... .... .... .C.M
432         orr     r0, r0, #0x00000800             @ ..VI Z..S .... ....
433 #if L2_CACHE_ENABLE
434         orr     r0, r0, #0x04000000             @ L2 enable
435 #endif
436         mov     pc, lr
437
438         .size   __xsc3_setup, . - __xsc3_setup
439
440         .type   xsc3_crval, #object
441 xsc3_crval:
442         crval   clear=0x04003b02, mmuset=0x00003105, ucset=0x00001100
443
444         __INITDATA
445
446 /*
447  * Purpose : Function pointers used to access above functions - all calls
448  *           come through these
449  */
450
451         .type   xsc3_processor_functions, #object
452 ENTRY(xsc3_processor_functions)
453         .word   v5t_early_abort
454         .word   cpu_xsc3_proc_init
455         .word   cpu_xsc3_proc_fin
456         .word   cpu_xsc3_reset
457         .word   cpu_xsc3_do_idle
458         .word   cpu_xsc3_dcache_clean_area
459         .word   cpu_xsc3_switch_mm
460         .word   cpu_xsc3_set_pte_ext
461         .size   xsc3_processor_functions, . - xsc3_processor_functions
462
463         .section ".rodata"
464
465         .type   cpu_arch_name, #object
466 cpu_arch_name:
467         .asciz  "armv5te"
468         .size   cpu_arch_name, . - cpu_arch_name
469
470         .type   cpu_elf_name, #object
471 cpu_elf_name:
472         .asciz  "v5"
473         .size   cpu_elf_name, . - cpu_elf_name
474
475         .type   cpu_xsc3_name, #object
476 cpu_xsc3_name:
477         .asciz  "XScale-Core3"
478         .size   cpu_xsc3_name, . - cpu_xsc3_name
479
480         .align
481
482         .section ".proc.info.init", #alloc, #execinstr
483
484         .type   __xsc3_proc_info,#object
485 __xsc3_proc_info:
486         .long   0x69056000
487         .long   0xffffe000
488         .long   PMD_TYPE_SECT | \
489                 PMD_SECT_BUFFERABLE | \
490                 PMD_SECT_CACHEABLE | \
491                 PMD_SECT_AP_WRITE | \
492                 PMD_SECT_AP_READ
493         .long   PMD_TYPE_SECT | \
494                 PMD_SECT_AP_WRITE | \
495                 PMD_SECT_AP_READ
496         b       __xsc3_setup
497         .long   cpu_arch_name
498         .long   cpu_elf_name
499         .long   HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP
500         .long   cpu_xsc3_name
501         .long   xsc3_processor_functions
502         .long   v4wbi_tlb_fns
503         .long   xsc3_mc_user_fns
504         .long   xsc3_cache_fns
505         .size   __xsc3_proc_info, . - __xsc3_proc_info