code style scripts/checkpatch.pl (linux-3.9-rc1) formatting
[linux-2.6.32.60-moxart.git] / arch / arm / boot / compressed / head.S
blob4885d95185d5bc23961f47f99ce4f8ead946f599
1 /*
2  *  linux/arch/arm/boot/compressed/head.S
3  *
4  *  Copyright (C) 1996-2002 Russell King
5  *  Copyright (C) 2004 Hyok S. Choi (MPU support)
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License version 2 as
9  * published by the Free Software Foundation.
10  */
11 #include <linux/linkage.h>
12 #include <asm/mach-types.h>
15  * Debugging stuff
16  *
17  * Note that these macros must not contain any code which is not
18  * 100% relocatable.  Any attempt to do so will result in a crash.
19  * Please select one of the following when turning on debugging.
20  */
21 #ifdef DEBUG
23 #if defined(CONFIG_DEBUG_ICEDCC)
25 #ifdef CONFIG_CPU_V6
26                 .macro  loadsp, rb
27                 .endm
28                 .macro  writeb, ch, rb
29                 mcr     p14, 0, \ch, c0, c5, 0
30                 .endm
31 #elif defined(CONFIG_CPU_XSCALE)
32                 .macro  loadsp, rb
33                 .endm
34                 .macro  writeb, ch, rb
35                 mcr     p14, 0, \ch, c8, c0, 0
36                 .endm
37 #else
38                 .macro  loadsp, rb
39                 .endm
40                 .macro  writeb, ch, rb
41                 mcr     p14, 0, \ch, c1, c0, 0
42                 .endm
43 #endif
45 #else
47 #include <mach/debug-macro.S>
49                 .macro  writeb, ch, rb
50                 senduart \ch, \rb
51                 .endm
53 #if defined(CONFIG_ARCH_SA1100)
54                 .macro  loadsp, rb
55                 mov     \rb, #0x80000000        @ physical base address
56 #ifdef CONFIG_DEBUG_LL_SER3
57                 add     \rb, \rb, #0x00050000   @ Ser3
58 #else
59                 add     \rb, \rb, #0x00010000   @ Ser1
60 #endif
61                 .endm
62 #elif defined(CONFIG_ARCH_S3C2410)
63                 .macro loadsp, rb
64                 mov     \rb, #0x50000000
65                 add     \rb, \rb, #0x4000 * CONFIG_S3C_LOWLEVEL_UART_PORT
66                 .endm
67 #else
68                 .macro  loadsp, rb
69                 addruart \rb
70                 .endm
71 #endif
72 #endif
73 #endif
75                 .macro  kputc,val
76                 mov     r0, \val
77                 bl      putc
78                 .endm
80                 .macro  kphex,val,len
81                 mov     r0, \val
82                 mov     r1, #\len
83                 bl      phex
84                 .endm
86                 .macro  debug_reloc_start
87 #ifdef DEBUG
88                 kputc   #'\n'
89                 kphex   r6, 8           /* processor id */
90                 kputc   #':'
91                 kphex   r7, 8           /* architecture id */
92 #ifdef CONFIG_CPU_CP15
93                 kputc   #':'
94                 mrc     p15, 0, r0, c1, c0
95                 kphex   r0, 8           /* control reg */
96 #endif
97                 kputc   #'\n'
98                 kphex   r5, 8           /* decompressed kernel start */
99                 kputc   #'-'
100                 kphex   r9, 8           /* decompressed kernel end  */
101                 kputc   #'>'
102                 kphex   r4, 8           /* kernel execution address */
103                 kputc   #'\n'
104 #endif
105                 .endm
107                 .macro  debug_reloc_end
108 #ifdef DEBUG
109                 kphex   r5, 8           /* end of kernel */
110                 kputc   #'\n'
111                 mov     r0, r4
112                 bl      memdump         /* dump 256 bytes at start of kernel */
113 #endif
114                 .endm
116                 .section ".start", #alloc, #execinstr
118  * sort out different calling conventions
119  */
120                 .align
121 start:
122                 .type   start,#function
123                 .rept   8
124                 mov     r0, r0
125                 .endr
127                 b       1f
128                 .word   0x016f2818              @ Magic numbers to help the loader
129                 .word   start                   @ absolute load/run zImage address
130                 .word   _edata                  @ zImage end address
131 #ifdef CONFIG_ARCH_MOXART
132 1:              ldr r1, =MACH_TYPE_MOXART
133                 mov     r7, r1                  @ save architecture ID
134 #else
135 1:              mov r7, r1
136 #endif
137                 mov     r8, r2                  @ save atags pointer
139 #ifndef __ARM_ARCH_2__
140                 /*
141                  * Booting from Angel - need to enter SVC mode and disable
142                  * FIQs/IRQs (numeric definitions from angel arm.h source).
143                  * We only do this if we were in user mode on entry.
144                  */
145                 mrs     r2, cpsr                @ get current mode
146                 tst     r2, #3                  @ not user?
147                 bne     not_angel
148                 mov     r0, #0x17               @ angel_SWIreason_EnterSVC
149  ARM(           swi     0x123456        )       @ angel_SWI_ARM
150  THUMB(         svc     0xab            )       @ angel_SWI_THUMB
151 not_angel:
152                 mrs     r2, cpsr                @ turn off interrupts to
153                 orr     r2, r2, #0xc0           @ prevent angel from running
154                 msr     cpsr_c, r2
155 #else
156                 teqp    pc, #0x0c000003         @ turn off interrupts
157 #endif
159                 /*
160                  * Note that some cache flushing and other stuff may
161                  * be needed here - is there an Angel SWI call for this?
162                  */
164                 /*
165                  * some architecture specific code can be inserted
166                  * by the linker here, but it should preserve r7, r8, and r9.
167                  */
169                 .text
170                 adr     r0, LC0
171  ARM(           ldmia   r0, {r1, r2, r3, r4, r5, r6, r11, ip, sp})
172  THUMB(         ldmia   r0, {r1, r2, r3, r4, r5, r6, r11, ip}   )
173  THUMB(         ldr     sp, [r0, #32]                           )
174                 subs    r0, r0, r1              @ calculate the delta offset
176                                                 @ if delta is zero, we are
177                 beq     not_relocated           @ running at the address we
178                                                 @ were linked at.
180                 /*
181                  * We're running at a different address.  We need to fix
182                  * up various pointers:
183                  *   r5 - zImage base address (_start)
184                  *   r6 - size of decompressed image
185                  *   r11 - GOT start
186                  *   ip - GOT end
187                  */
188                 add     r5, r5, r0
189                 add     r11, r11, r0
190                 add     ip, ip, r0
192 #ifndef CONFIG_ZBOOT_ROM
193                 /*
194                  * If we're running fully PIC === CONFIG_ZBOOT_ROM = n,
195                  * we need to fix up pointers into the BSS region.
196                  *   r2 - BSS start
197                  *   r3 - BSS end
198                  *   sp - stack pointer
199                  */
200                 add     r2, r2, r0
201                 add     r3, r3, r0
202                 add     sp, sp, r0
204                 /*
205                  * Relocate all entries in the GOT table.
206                  */
207 1:              ldr     r1, [r11, #0]           @ relocate entries in the GOT
208                 add     r1, r1, r0              @ table.  This fixes up the
209                 str     r1, [r11], #4           @ C references.
210                 cmp     r11, ip
211                 blo     1b
212 #else
214                 /*
215                  * Relocate entries in the GOT table.  We only relocate
216                  * the entries that are outside the (relocated) BSS region.
217                  */
218 1:              ldr     r1, [r11, #0]           @ relocate entries in the GOT
219                 cmp     r1, r2                  @ entry < bss_start ||
220                 cmphs   r3, r1                  @ _end < entry
221                 addlo   r1, r1, r0              @ table.  This fixes up the
222                 str     r1, [r11], #4           @ C references.
223                 cmp     r11, ip
224                 blo     1b
225 #endif
227 not_relocated:  mov     r0, #0
228 1:              str     r0, [r2], #4            @ clear bss
229                 str     r0, [r2], #4
230                 str     r0, [r2], #4
231                 str     r0, [r2], #4
232                 cmp     r2, r3
233                 blo     1b
235                 /*
236                  * The C runtime environment should now be setup
237                  * sufficiently.  Turn the cache on, set up some
238                  * pointers, and start decompressing.
239                  */
240                 bl      cache_on
242                 mov     r1, sp                  @ malloc space above stack
243                 add     r2, sp, #0x10000        @ 64k max
246  * Check to see if we will overwrite ourselves.
247  *   r4 = final kernel address
248  *   r5 = start of this image
249  *   r6 = size of decompressed image
250  *   r2 = end of malloc space (and therefore this image)
251  * We basically want:
252  *   r4 >= r2 -> OK
253  *   r4 + image length <= r5 -> OK
254  */
255                 cmp     r4, r2
256                 bhs     wont_overwrite
257                 add     r0, r4, r6
258                 cmp     r0, r5
259                 bls     wont_overwrite
261                 mov     r5, r2                  @ decompress after malloc space
262                 mov     r0, r5
263                 mov     r3, r7
264                 bl      decompress_kernel
266                 add     r0, r0, #127 + 128      @ alignment + stack
267                 bic     r0, r0, #127            @ align the kernel length
269  * r0     = decompressed kernel length
270  * r1-r3  = unused
271  * r4     = kernel execution address
272  * r5     = decompressed kernel start
273  * r7     = architecture ID
274  * r8     = atags pointer
275  * r9-r12,r14 = corrupted
276  */
277                 add     r1, r5, r0              @ end of decompressed kernel
278                 adr     r2, reloc_start
279                 ldr     r3, LC1
280                 add     r3, r2, r3
281 1:              ldmia   r2!, {r9 - r12, r14}    @ copy relocation code
282                 stmia   r1!, {r9 - r12, r14}
283                 ldmia   r2!, {r9 - r12, r14}
284                 stmia   r1!, {r9 - r12, r14}
285                 cmp     r2, r3
286                 blo     1b
287                 mov     sp, r1
288                 add     sp, sp, #128            @ relocate the stack
290                 bl      cache_clean_flush
291  ARM(           add     pc, r5, r0              ) @ call relocation code
292  THUMB(         add     r12, r5, r0             )
293  THUMB(         mov     pc, r12                 ) @ call relocation code
296  * We're not in danger of overwriting ourselves.  Do this the simple way.
298  * r4     = kernel execution address
299  * r7     = architecture ID
300  */
301 wont_overwrite: mov     r0, r4
302                 mov     r3, r7
303                 bl      decompress_kernel
304                 b       call_kernel
306                 .align  2
307                 .type   LC0, #object
308 LC0:            .word   LC0                     @ r1
309                 .word   __bss_start             @ r2
310                 .word   _end                    @ r3
311                 .word   zreladdr                @ r4
312                 .word   _start                  @ r5
313                 .word   _image_size             @ r6
314                 .word   _got_start              @ r11
315                 .word   _got_end                @ ip
316                 .word   user_stack+4096         @ sp
317 LC1:            .word   reloc_end - reloc_start
318                 .size   LC0, . - LC0
320 #ifdef CONFIG_ARCH_RPC
321                 .globl  params
322 params:         ldr     r0, =params_phys
323                 mov     pc, lr
324                 .ltorg
325                 .align
326 #endif
329  * Turn on the cache.  We need to setup some page tables so that we
330  * can have both the I and D caches on.
332  * We place the page tables 16k down from the kernel execution address,
333  * and we hope that nothing else is using it.  If we're using it, we
334  * will go pop!
336  * On entry,
337  *  r4 = kernel execution address
338  *  r7 = architecture number
339  *  r8 = atags pointer
340  *  r9 = run-time address of "start"  (???)
341  * On exit,
342  *  r1, r2, r3, r9, r10, r12 corrupted
343  * This routine must preserve:
344  *  r4, r5, r6, r7, r8
345  */
346                 .align  5
347 cache_on:       mov     r3, #8                  @ cache_on function
348                 b       call_cache_fn
351  * Initialize the highest priority protection region, PR7
352  * to cover all 32bit address and cacheable and bufferable.
353  */
354 __armv4_mpu_cache_on:
355                 mov     r0, #0x3f               @ 4G, the whole
356                 mcr     p15, 0, r0, c6, c7, 0   @ PR7 Area Setting
357                 mcr     p15, 0, r0, c6, c7, 1
359                 mov     r0, #0x80               @ PR7
360                 mcr     p15, 0, r0, c2, c0, 0   @ D-cache on
361                 mcr     p15, 0, r0, c2, c0, 1   @ I-cache on
362                 mcr     p15, 0, r0, c3, c0, 0   @ write-buffer on
364                 mov     r0, #0xc000
365                 mcr     p15, 0, r0, c5, c0, 1   @ I-access permission
366                 mcr     p15, 0, r0, c5, c0, 0   @ D-access permission
368                 mov     r0, #0
369                 mcr     p15, 0, r0, c7, c10, 4  @ drain write buffer
370                 mcr     p15, 0, r0, c7, c5, 0   @ flush(inval) I-Cache
371                 mcr     p15, 0, r0, c7, c6, 0   @ flush(inval) D-Cache
372                 mrc     p15, 0, r0, c1, c0, 0   @ read control reg
373                                                 @ ...I .... ..D. WC.M
374                 orr     r0, r0, #0x002d         @ .... .... ..1. 11.1
375                 orr     r0, r0, #0x1000         @ ...1 .... .... ....
377                 mcr     p15, 0, r0, c1, c0, 0   @ write control reg
379                 mov     r0, #0
380                 mcr     p15, 0, r0, c7, c5, 0   @ flush(inval) I-Cache
381                 mcr     p15, 0, r0, c7, c6, 0   @ flush(inval) D-Cache
382                 mov     pc, lr
384 __armv3_mpu_cache_on:
385                 mov     r0, #0x3f               @ 4G, the whole
386                 mcr     p15, 0, r0, c6, c7, 0   @ PR7 Area Setting
388                 mov     r0, #0x80               @ PR7
389                 mcr     p15, 0, r0, c2, c0, 0   @ cache on
390                 mcr     p15, 0, r0, c3, c0, 0   @ write-buffer on
392                 mov     r0, #0xc000
393                 mcr     p15, 0, r0, c5, c0, 0   @ access permission
395                 mov     r0, #0
396                 mcr     p15, 0, r0, c7, c0, 0   @ invalidate whole cache v3
397                 mrc     p15, 0, r0, c1, c0, 0   @ read control reg
398                                                 @ .... .... .... WC.M
399                 orr     r0, r0, #0x000d         @ .... .... .... 11.1
400                 mov     r0, #0
401                 mcr     p15, 0, r0, c1, c0, 0   @ write control reg
403                 mcr     p15, 0, r0, c7, c0, 0   @ invalidate whole cache v3
404                 mov     pc, lr
406 __setup_mmu:    sub     r3, r4, #16384          @ Page directory size
407                 bic     r3, r3, #0xff           @ Align the pointer
408                 bic     r3, r3, #0x3f00
410  * Initialise the page tables, turning on the cacheable and bufferable
411  * bits for the RAM area only.
412  */
413                 mov     r0, r3
414                 mov     r9, r0, lsr #18
415                 mov     r9, r9, lsl #18         @ start of RAM
416                 add     r10, r9, #0x10000000    @ a reasonable RAM size
417                 mov     r1, #0x12
418                 orr     r1, r1, #3 << 10
419                 add     r2, r3, #16384
420 1:              cmp     r1, r9                  @ if virt > start of RAM
421                 orrhs   r1, r1, #0x0c           @ set cacheable, bufferable
422                 cmp     r1, r10                 @ if virt > end of RAM
423                 bichs   r1, r1, #0x0c           @ clear cacheable, bufferable
424                 str     r1, [r0], #4            @ 1:1 mapping
425                 add     r1, r1, #1048576
426                 teq     r0, r2
427                 bne     1b
429  * If ever we are running from Flash, then we surely want the cache
430  * to be enabled also for our execution instance...  We map 2MB of it
431  * so there is no map overlap problem for up to 1 MB compressed kernel.
432  * If the execution is in RAM then we would only be duplicating the above.
433  */
434                 mov     r1, #0x1e
435                 orr     r1, r1, #3 << 10
436                 mov     r2, pc, lsr #20
437                 orr     r1, r1, r2, lsl #20
438                 add     r0, r3, r2, lsl #2
439                 str     r1, [r0], #4
440                 add     r1, r1, #1048576
441                 str     r1, [r0]
442                 mov     pc, lr
443 ENDPROC(__setup_mmu)
445 __armv4_mmu_cache_on:
446                 mov     r12, lr
447 #ifdef CONFIG_MMU
448                 bl      __setup_mmu
449                 mov     r0, #0
450                 mcr     p15, 0, r0, c7, c10, 4  @ drain write buffer
451                 mcr     p15, 0, r0, c8, c7, 0   @ flush I,D TLBs
452                 mrc     p15, 0, r0, c1, c0, 0   @ read control reg
453                 orr     r0, r0, #0x5000         @ I-cache enable, RR cache replacement
454                 orr     r0, r0, #0x0030
455 #ifdef CONFIG_CPU_ENDIAN_BE8
456                 orr     r0, r0, #1 << 25        @ big-endian page tables
457 #endif
458                 bl      __common_mmu_cache_on
459                 mov     r0, #0
460                 mcr     p15, 0, r0, c8, c7, 0   @ flush I,D TLBs
461 #endif
462                 mov     pc, r12
464 __armv7_mmu_cache_on:
465                 mov     r12, lr
466 #ifdef CONFIG_MMU
467                 mrc     p15, 0, r11, c0, c1, 4  @ read ID_MMFR0
468                 tst     r11, #0xf               @ VMSA
469                 blne    __setup_mmu
470                 mov     r0, #0
471                 mcr     p15, 0, r0, c7, c10, 4  @ drain write buffer
472                 tst     r11, #0xf               @ VMSA
473                 mcrne   p15, 0, r0, c8, c7, 0   @ flush I,D TLBs
474 #endif
475                 mrc     p15, 0, r0, c1, c0, 0   @ read control reg
476                 orr     r0, r0, #0x5000         @ I-cache enable, RR cache replacement
477                 orr     r0, r0, #0x003c         @ write buffer
478 #ifdef CONFIG_MMU
479 #ifdef CONFIG_CPU_ENDIAN_BE8
480                 orr     r0, r0, #1 << 25        @ big-endian page tables
481 #endif
482                 orrne   r0, r0, #1              @ MMU enabled
483                 movne   r1, #-1
484                 mcrne   p15, 0, r3, c2, c0, 0   @ load page table pointer
485                 mcrne   p15, 0, r1, c3, c0, 0   @ load domain access control
486 #endif
487                 mcr     p15, 0, r0, c1, c0, 0   @ load control register
488                 mrc     p15, 0, r0, c1, c0, 0   @ and read it back
489                 mov     r0, #0
490                 mcr     p15, 0, r0, c7, c5, 4   @ ISB
491                 mov     pc, r12
493 __fa526_cache_on:
494                 mov     r12, lr
495                 bl      __setup_mmu
496                 mov     r0, #0
497                 mcr     p15, 0, r0, c7, c7, 0   @ Invalidate whole cache
498                 mcr     p15, 0, r0, c7, c10, 4  @ drain write buffer
499                 mcr     p15, 0, r0, c8, c7, 0   @ flush UTLB
500                 mrc     p15, 0, r0, c1, c0, 0   @ read control reg
501                 orr     r0, r0, #0x1000         @ I-cache enable
502                 bl      __common_mmu_cache_on
503                 mov     r0, #0
504                 mcr     p15, 0, r0, c8, c7, 0   @ flush UTLB
505                 mov     pc, r12
507 __arm6_mmu_cache_on:
508                 mov     r12, lr
509                 bl      __setup_mmu
510                 mov     r0, #0
511                 mcr     p15, 0, r0, c7, c0, 0   @ invalidate whole cache v3
512                 mcr     p15, 0, r0, c5, c0, 0   @ invalidate whole TLB v3
513                 mov     r0, #0x30
514                 bl      __common_mmu_cache_on
515                 mov     r0, #0
516                 mcr     p15, 0, r0, c5, c0, 0   @ invalidate whole TLB v3
517                 mov     pc, r12
519 __common_mmu_cache_on:
520 #ifndef CONFIG_THUMB2_KERNEL
521 #ifndef DEBUG
522                 orr     r0, r0, #0x000d         @ Write buffer, mmu
523 #endif
524                 mov     r1, #-1
525                 mcr     p15, 0, r3, c2, c0, 0   @ load page table pointer
526                 mcr     p15, 0, r1, c3, c0, 0   @ load domain access control
527                 b       1f
528                 .align  5                       @ cache line aligned
529 1:              mcr     p15, 0, r0, c1, c0, 0   @ load control register
530                 mrc     p15, 0, r0, c1, c0, 0   @ and read it back to
531                 sub     pc, lr, r0, lsr #32     @ properly flush pipeline
532 #endif
535  * All code following this line is relocatable.  It is relocated by
536  * the above code to the end of the decompressed kernel image and
537  * executed there.  During this time, we have no stacks.
539  * r0     = decompressed kernel length
540  * r1-r3  = unused
541  * r4     = kernel execution address
542  * r5     = decompressed kernel start
543  * r7     = architecture ID
544  * r8     = atags pointer
545  * r9-r12,r14 = corrupted
546  */
547                 .align  5
548 reloc_start:    add     r9, r5, r0
549                 sub     r9, r9, #128            @ do not copy the stack
550                 debug_reloc_start
551                 mov     r1, r4
553                 .rept   4
554                 ldmia   r5!, {r0, r2, r3, r10 - r12, r14}       @ relocate kernel
555                 stmia   r1!, {r0, r2, r3, r10 - r12, r14}
556                 .endr
558                 cmp     r5, r9
559                 blo     1b
560                 mov     sp, r1
561                 add     sp, sp, #128            @ relocate the stack
562                 debug_reloc_end
564 call_kernel:    bl      cache_clean_flush
565                 bl      cache_off
566                 mov     r0, #0                  @ must be zero
567                 mov     r1, r7                  @ restore architecture number
568                 mov     r2, r8                  @ restore atags pointer
569                 mov     pc, r4                  @ call kernel
572  * Here follow the relocatable cache support functions for the
573  * various processors.  This is a generic hook for locating an
574  * entry and jumping to an instruction at the specified offset
575  * from the start of the block.  Please note this is all position
576  * independent code.
578  *  r1  = corrupted
579  *  r2  = corrupted
580  *  r3  = block offset
581  *  r9  = corrupted
582  *  r12 = corrupted
583  */
585 call_cache_fn:  adr     r12, proc_types
586 #ifdef CONFIG_CPU_CP15
587                 mrc     p15, 0, r9, c0, c0      @ get processor ID
588 #else
589                 ldr     r9, =CONFIG_PROCESSOR_ID
590 #endif
591 1:              ldr     r1, [r12, #0]           @ get value
592                 ldr     r2, [r12, #4]           @ get mask
593                 eor     r1, r1, r9              @ (real ^ match)
594                 tst     r1, r2                  @       & mask
595  ARM(           addeq   pc, r12, r3             ) @ call cache function
596  THUMB(         addeq   r12, r3                 )
597  THUMB(         moveq   pc, r12                 ) @ call cache function
598                 add     r12, r12, #4*5
599                 b       1b
602  * Table for cache operations.  This is basically:
603  *   - CPU ID match
604  *   - CPU ID mask
605  *   - 'cache on' method instruction
606  *   - 'cache off' method instruction
607  *   - 'cache flush' method instruction
609  * We match an entry using: ((real_id ^ match) & mask) == 0
611  * Writethrough caches generally only need 'on' and 'off'
612  * methods.  Writeback caches _must_ have the flush method
613  * defined.
614  */
615                 .align  2
616                 .type   proc_types,#object
617 proc_types:
618                 .word   0x41560600              @ ARM6/610
619                 .word   0xffffffe0
620                 W(b)    __arm6_mmu_cache_off    @ works, but slow
621                 W(b)    __arm6_mmu_cache_off
622                 mov     pc, lr
623  THUMB(         nop                             )
624 @               b       __arm6_mmu_cache_on             @ untested
625 @               b       __arm6_mmu_cache_off
626 @               b       __armv3_mmu_cache_flush
628                 .word   0x00000000              @ old ARM ID
629                 .word   0x0000f000
630                 mov     pc, lr
631  THUMB(         nop                             )
632                 mov     pc, lr
633  THUMB(         nop                             )
634                 mov     pc, lr
635  THUMB(         nop                             )
637                 .word   0x41007000              @ ARM7/710
638                 .word   0xfff8fe00
639                 W(b)    __arm7_mmu_cache_off
640                 W(b)    __arm7_mmu_cache_off
641                 mov     pc, lr
642  THUMB(         nop                             )
644                 .word   0x41807200              @ ARM720T (writethrough)
645                 .word   0xffffff00
646                 W(b)    __armv4_mmu_cache_on
647                 W(b)    __armv4_mmu_cache_off
648                 mov     pc, lr
649  THUMB(         nop                             )
651                 .word   0x41007400              @ ARM74x
652                 .word   0xff00ff00
653                 W(b)    __armv3_mpu_cache_on
654                 W(b)    __armv3_mpu_cache_off
655                 W(b)    __armv3_mpu_cache_flush
656                 
657                 .word   0x41009400              @ ARM94x
658                 .word   0xff00ff00
659                 W(b)    __armv4_mpu_cache_on
660                 W(b)    __armv4_mpu_cache_off
661                 W(b)    __armv4_mpu_cache_flush
663                 .word   0x00007000              @ ARM7 IDs
664                 .word   0x0000f000
665                 mov     pc, lr
666  THUMB(         nop                             )
667                 mov     pc, lr
668  THUMB(         nop                             )
669                 mov     pc, lr
670  THUMB(         nop                             )
672                 @ Everything from here on will be the new ID system.
674                 .word   0x4401a100              @ sa110 / sa1100
675                 .word   0xffffffe0
676                 W(b)    __armv4_mmu_cache_on
677                 W(b)    __armv4_mmu_cache_off
678                 W(b)    __armv4_mmu_cache_flush
680                 .word   0x6901b110              @ sa1110
681                 .word   0xfffffff0
682                 W(b)    __armv4_mmu_cache_on
683                 W(b)    __armv4_mmu_cache_off
684                 W(b)    __armv4_mmu_cache_flush
686                 .word   0x56056930
687                 .word   0xff0ffff0              @ PXA935
688                 W(b)    __armv4_mmu_cache_on
689                 W(b)    __armv4_mmu_cache_off
690                 W(b)    __armv4_mmu_cache_flush
692                 .word   0x56158000              @ PXA168
693                 .word   0xfffff000
694                 W(b)    __armv4_mmu_cache_on
695                 W(b)    __armv4_mmu_cache_off
696                 W(b)    __armv5tej_mmu_cache_flush
698                 .word   0x56056930
699                 .word   0xff0ffff0              @ PXA935
700                 W(b)    __armv4_mmu_cache_on
701                 W(b)    __armv4_mmu_cache_off
702                 W(b)    __armv4_mmu_cache_flush
704                 .word   0x56050000              @ Feroceon
705                 .word   0xff0f0000
706                 W(b)    __armv4_mmu_cache_on
707                 W(b)    __armv4_mmu_cache_off
708                 W(b)    __armv5tej_mmu_cache_flush
710 #ifdef CONFIG_CPU_FEROCEON_OLD_ID
711                 /* this conflicts with the standard ARMv5TE entry */
712                 .long   0x41009260              @ Old Feroceon
713                 .long   0xff00fff0
714                 b       __armv4_mmu_cache_on
715                 b       __armv4_mmu_cache_off
716                 b       __armv5tej_mmu_cache_flush
717 #endif
719                 .word   0x66015261              @ FA526
720                 .word   0xff01fff1
721                 W(b)    __fa526_cache_on
722                 W(b)    __armv4_mmu_cache_off
723                 W(b)    __fa526_cache_flush
725                 @ These match on the architecture ID
727                 .word   0x00020000              @ ARMv4T
728                 .word   0x000f0000
729                 W(b)    __armv4_mmu_cache_on
730                 W(b)    __armv4_mmu_cache_off
731                 W(b)    __armv4_mmu_cache_flush
733                 .word   0x00050000              @ ARMv5TE
734                 .word   0x000f0000
735                 W(b)    __armv4_mmu_cache_on
736                 W(b)    __armv4_mmu_cache_off
737                 W(b)    __armv4_mmu_cache_flush
739                 .word   0x00060000              @ ARMv5TEJ
740                 .word   0x000f0000
741                 W(b)    __armv4_mmu_cache_on
742                 W(b)    __armv4_mmu_cache_off
743                 W(b)    __armv4_mmu_cache_flush
745                 .word   0x0007b000              @ ARMv6
746                 .word   0x000ff000
747                 W(b)    __armv4_mmu_cache_on
748                 W(b)    __armv4_mmu_cache_off
749                 W(b)    __armv6_mmu_cache_flush
751                 .word   0x000f0000              @ new CPU Id
752                 .word   0x000f0000
753                 W(b)    __armv7_mmu_cache_on
754                 W(b)    __armv7_mmu_cache_off
755                 W(b)    __armv7_mmu_cache_flush
757                 .word   0                       @ unrecognised type
758                 .word   0
759                 mov     pc, lr
760  THUMB(         nop                             )
761                 mov     pc, lr
762  THUMB(         nop                             )
763                 mov     pc, lr
764  THUMB(         nop                             )
766                 .size   proc_types, . - proc_types
769  * Turn off the Cache and MMU.  ARMv3 does not support
770  * reading the control register, but ARMv4 does.
772  * On exit, r0, r1, r2, r3, r9, r12 corrupted
773  * This routine must preserve: r4, r6, r7
774  */
775                 .align  5
776 cache_off:      mov     r3, #12                 @ cache_off function
777                 b       call_cache_fn
779 __armv4_mpu_cache_off:
780                 mrc     p15, 0, r0, c1, c0
781                 bic     r0, r0, #0x000d
782                 mcr     p15, 0, r0, c1, c0      @ turn MPU and cache off
783                 mov     r0, #0
784                 mcr     p15, 0, r0, c7, c10, 4  @ drain write buffer
785                 mcr     p15, 0, r0, c7, c6, 0   @ flush D-Cache
786                 mcr     p15, 0, r0, c7, c5, 0   @ flush I-Cache
787                 mov     pc, lr
789 __armv3_mpu_cache_off:
790                 mrc     p15, 0, r0, c1, c0
791                 bic     r0, r0, #0x000d
792                 mcr     p15, 0, r0, c1, c0, 0   @ turn MPU and cache off
793                 mov     r0, #0
794                 mcr     p15, 0, r0, c7, c0, 0   @ invalidate whole cache v3
795                 mov     pc, lr
797 __armv4_mmu_cache_off:
798 #ifdef CONFIG_MMU
799                 mrc     p15, 0, r0, c1, c0
800                 bic     r0, r0, #0x000d
801                 mcr     p15, 0, r0, c1, c0      @ turn MMU and cache off
802                 mov     r0, #0
803                 mcr     p15, 0, r0, c7, c7      @ invalidate whole cache v4
804                 mcr     p15, 0, r0, c8, c7      @ invalidate whole TLB v4
805 #endif
806                 mov     pc, lr
808 __armv7_mmu_cache_off:
809                 mrc     p15, 0, r0, c1, c0
810 #ifdef CONFIG_MMU
811                 bic     r0, r0, #0x000d
812 #else
813                 bic     r0, r0, #0x000c
814 #endif
815                 mcr     p15, 0, r0, c1, c0      @ turn MMU and cache off
816                 mov     r12, lr
817                 bl      __armv7_mmu_cache_flush
818                 mov     r0, #0
819 #ifdef CONFIG_MMU
820                 mcr     p15, 0, r0, c8, c7, 0   @ invalidate whole TLB
821 #endif
822                 mcr     p15, 0, r0, c7, c5, 6   @ invalidate BTC
823                 mcr     p15, 0, r0, c7, c10, 4  @ DSB
824                 mcr     p15, 0, r0, c7, c5, 4   @ ISB
825                 mov     pc, r12
827 __arm6_mmu_cache_off:
828                 mov     r0, #0x00000030         @ ARM6 control reg.
829                 b       __armv3_mmu_cache_off
831 __arm7_mmu_cache_off:
832                 mov     r0, #0x00000070         @ ARM7 control reg.
833                 b       __armv3_mmu_cache_off
835 __armv3_mmu_cache_off:
836                 mcr     p15, 0, r0, c1, c0, 0   @ turn MMU and cache off
837                 mov     r0, #0
838                 mcr     p15, 0, r0, c7, c0, 0   @ invalidate whole cache v3
839                 mcr     p15, 0, r0, c5, c0, 0   @ invalidate whole TLB v3
840                 mov     pc, lr
843  * Clean and flush the cache to maintain consistency.
845  * On exit,
846  *  r1, r2, r3, r9, r11, r12 corrupted
847  * This routine must preserve:
848  *  r0, r4, r5, r6, r7
849  */
850                 .align  5
851 cache_clean_flush:
852                 mov     r3, #16
853                 b       call_cache_fn
855 __armv4_mpu_cache_flush:
856                 mov     r2, #1
857                 mov     r3, #0
858                 mcr     p15, 0, ip, c7, c6, 0   @ invalidate D cache
859                 mov     r1, #7 << 5             @ 8 segments
860 1:              orr     r3, r1, #63 << 26       @ 64 entries
861 2:              mcr     p15, 0, r3, c7, c14, 2  @ clean & invalidate D index
862                 subs    r3, r3, #1 << 26
863                 bcs     2b                      @ entries 63 to 0
864                 subs    r1, r1, #1 << 5
865                 bcs     1b                      @ segments 7 to 0
867                 teq     r2, #0
868                 mcrne   p15, 0, ip, c7, c5, 0   @ invalidate I cache
869                 mcr     p15, 0, ip, c7, c10, 4  @ drain WB
870                 mov     pc, lr
871                 
872 __fa526_cache_flush:
873                 mov     r1, #0
874                 mcr     p15, 0, r1, c7, c14, 0  @ clean and invalidate D cache
875                 mcr     p15, 0, r1, c7, c5, 0   @ flush I cache
876                 mcr     p15, 0, r1, c7, c10, 4  @ drain WB
877                 mov     pc, lr
879 __armv6_mmu_cache_flush:
880                 mov     r1, #0
881                 mcr     p15, 0, r1, c7, c14, 0  @ clean+invalidate D
882                 mcr     p15, 0, r1, c7, c5, 0   @ invalidate I+BTB
883                 mcr     p15, 0, r1, c7, c15, 0  @ clean+invalidate unified
884                 mcr     p15, 0, r1, c7, c10, 4  @ drain WB
885                 mov     pc, lr
887 __armv7_mmu_cache_flush:
888                 mrc     p15, 0, r10, c0, c1, 5  @ read ID_MMFR1
889                 tst     r10, #0xf << 16         @ hierarchical cache (ARMv7)
890                 mov     r10, #0
891                 beq     hierarchical
892                 mcr     p15, 0, r10, c7, c14, 0 @ clean+invalidate D
893                 b       iflush
894 hierarchical:
895                 mcr     p15, 0, r10, c7, c10, 5 @ DMB
896                 stmfd   sp!, {r0-r7, r9-r11}
897                 mrc     p15, 1, r0, c0, c0, 1   @ read clidr
898                 ands    r3, r0, #0x7000000      @ extract loc from clidr
899                 mov     r3, r3, lsr #23         @ left align loc bit field
900                 beq     finished                @ if loc is 0, then no need to clean
901                 mov     r10, #0                 @ start clean at cache level 0
902 loop1:
903                 add     r2, r10, r10, lsr #1    @ work out 3x current cache level
904                 mov     r1, r0, lsr r2          @ extract cache type bits from clidr
905                 and     r1, r1, #7              @ mask of the bits for current cache only
906                 cmp     r1, #2                  @ see what cache we have at this level
907                 blt     skip                    @ skip if no cache, or just i-cache
908                 mcr     p15, 2, r10, c0, c0, 0  @ select current cache level in cssr
909                 mcr     p15, 0, r10, c7, c5, 4  @ isb to sych the new cssr&csidr
910                 mrc     p15, 1, r1, c0, c0, 0   @ read the new csidr
911                 and     r2, r1, #7              @ extract the length of the cache lines
912                 add     r2, r2, #4              @ add 4 (line length offset)
913                 ldr     r4, =0x3ff
914                 ands    r4, r4, r1, lsr #3      @ find maximum number on the way size
915                 clz     r5, r4                  @ find bit position of way size increment
916                 ldr     r7, =0x7fff
917                 ands    r7, r7, r1, lsr #13     @ extract max number of the index size
918 loop2:
919                 mov     r9, r4                  @ create working copy of max way size
920 loop3:
921  ARM(           orr     r11, r10, r9, lsl r5    ) @ factor way and cache number into r11
922  ARM(           orr     r11, r11, r7, lsl r2    ) @ factor index number into r11
923  THUMB(         lsl     r6, r9, r5              )
924  THUMB(         orr     r11, r10, r6            ) @ factor way and cache number into r11
925  THUMB(         lsl     r6, r7, r2              )
926  THUMB(         orr     r11, r11, r6            ) @ factor index number into r11
927                 mcr     p15, 0, r11, c7, c14, 2 @ clean & invalidate by set/way
928                 subs    r9, r9, #1              @ decrement the way
929                 bge     loop3
930                 subs    r7, r7, #1              @ decrement the index
931                 bge     loop2
932 skip:
933                 add     r10, r10, #2            @ increment cache number
934                 cmp     r3, r10
935                 bgt     loop1
936 finished:
937                 ldmfd   sp!, {r0-r7, r9-r11}
938                 mov     r10, #0                 @ swith back to cache level 0
939                 mcr     p15, 2, r10, c0, c0, 0  @ select current cache level in cssr
940 iflush:
941                 mcr     p15, 0, r10, c7, c10, 4 @ DSB
942                 mcr     p15, 0, r10, c7, c5, 0  @ invalidate I+BTB
943                 mcr     p15, 0, r10, c7, c10, 4 @ DSB
944                 mcr     p15, 0, r10, c7, c5, 4  @ ISB
945                 mov     pc, lr
947 __armv5tej_mmu_cache_flush:
948 1:              mrc     p15, 0, r15, c7, c14, 3 @ test,clean,invalidate D cache
949                 bne     1b
950                 mcr     p15, 0, r0, c7, c5, 0   @ flush I cache
951                 mcr     p15, 0, r0, c7, c10, 4  @ drain WB
952                 mov     pc, lr
954 __armv4_mmu_cache_flush:
955                 mov     r2, #64*1024            @ default: 32K dcache size (*2)
956                 mov     r11, #32                @ default: 32 byte line size
957                 mrc     p15, 0, r3, c0, c0, 1   @ read cache type
958                 teq     r3, r9                  @ cache ID register present?
959                 beq     no_cache_id
960                 mov     r1, r3, lsr #18
961                 and     r1, r1, #7
962                 mov     r2, #1024
963                 mov     r2, r2, lsl r1          @ base dcache size *2
964                 tst     r3, #1 << 14            @ test M bit
965                 addne   r2, r2, r2, lsr #1      @ +1/2 size if M == 1
966                 mov     r3, r3, lsr #12
967                 and     r3, r3, #3
968                 mov     r11, #8
969                 mov     r11, r11, lsl r3        @ cache line size in bytes
970 no_cache_id:
971                 mov     r1, pc
972                 bic     r1, r1, #63             @ align to longest cache line
973                 add     r2, r1, r2
975  ARM(           ldr     r3, [r1], r11           ) @ s/w flush D cache
976  THUMB(         ldr     r3, [r1]                ) @ s/w flush D cache
977  THUMB(         add     r1, r1, r11             )
978                 teq     r1, r2
979                 bne     1b
981                 mcr     p15, 0, r1, c7, c5, 0   @ flush I cache
982                 mcr     p15, 0, r1, c7, c6, 0   @ flush D cache
983                 mcr     p15, 0, r1, c7, c10, 4  @ drain WB
984                 mov     pc, lr
986 __armv3_mmu_cache_flush:
987 __armv3_mpu_cache_flush:
988                 mov     r1, #0
989                 mcr     p15, 0, r0, c7, c0, 0   @ invalidate whole cache v3
990                 mov     pc, lr
993  * Various debugging routines for printing hex characters and
994  * memory, which again must be relocatable.
995  */
996 #ifdef DEBUG
997                 .align  2
998                 .type   phexbuf,#object
999 phexbuf:        .space  12
1000                 .size   phexbuf, . - phexbuf
1002 phex:           adr     r3, phexbuf
1003                 mov     r2, #0
1004                 strb    r2, [r3, r1]
1005 1:              subs    r1, r1, #1
1006                 movmi   r0, r3
1007                 bmi     puts
1008                 and     r2, r0, #15
1009                 mov     r0, r0, lsr #4
1010                 cmp     r2, #10
1011                 addge   r2, r2, #7
1012                 add     r2, r2, #'0'
1013                 strb    r2, [r3, r1]
1014                 b       1b
1016 puts:           loadsp  r3
1017 1:              ldrb    r2, [r0], #1
1018                 teq     r2, #0
1019                 moveq   pc, lr
1020 2:              writeb  r2, r3
1021                 mov     r1, #0x00020000
1022 3:              subs    r1, r1, #1
1023                 bne     3b
1024                 teq     r2, #'\n'
1025                 moveq   r2, #'\r'
1026                 beq     2b
1027                 teq     r0, #0
1028                 bne     1b
1029                 mov     pc, lr
1030 putc:
1031                 mov     r2, r0
1032                 mov     r0, #0
1033                 loadsp  r3
1034                 b       2b
1036 memdump:        mov     r12, r0
1037                 mov     r10, lr
1038                 mov     r11, #0
1039 2:              mov     r0, r11, lsl #2
1040                 add     r0, r0, r12
1041                 mov     r1, #8
1042                 bl      phex
1043                 mov     r0, #':'
1044                 bl      putc
1045 1:              mov     r0, #' '
1046                 bl      putc
1047                 ldr     r0, [r12, r11, lsl #2]
1048                 mov     r1, #8
1049                 bl      phex
1050                 and     r0, r11, #7
1051                 teq     r0, #3
1052                 moveq   r0, #' '
1053                 bleq    putc
1054                 and     r0, r11, #7
1055                 add     r11, r11, #1
1056                 teq     r0, #7
1057                 bne     1b
1058                 mov     r0, #'\n'
1059                 bl      putc
1060                 cmp     r11, #64
1061                 blt     2b
1062                 mov     pc, r10
1063 #endif
1065                 .ltorg
1066 reloc_end:
1068                 .align
1069                 .section ".stack", "w"
1070 user_stack:     .space  4096