v2.4.8 -> v2.4.8.1
[opensuse:kernel.git] / arch / arm / boot / compressed / head.S
1 /*
2  *  linux/arch/arm/boot/compressed/head.S
3  *
4  *  Copyright (C) 1996-1999 Russell King
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 2 as
8  * published by the Free Software Foundation.
9  */
10 #include <linux/config.h>
11 #include <linux/linkage.h>
12
13 /*
14  * Debugging stuff
15  *
16  * Note that these macros must not contain any code which is not
17  * 100% relocatable.  Any attempt to do so will result in a crash.
18  * Please select one of the following when turning on debugging.
19  */
20 #ifdef DEBUG
21 #if 0 /* DC21285-type */
22                 .macro  loadsp, rb
23                 mov     \rb, #0x7c000000
24                 .endm
25                 .macro  writeb, rb
26                 strb    \rb, [r3, #0x3f8]
27                 .endm
28 #elif 0 /* RiscPC-type */
29                 .macro  loadsp, rb
30                 mov     \rb, #0x03000000
31                 orr     \rb, \rb, #0x00010000
32                 .endm
33                 .macro  writeb, rb
34                 strb    \rb, [r3, #0x3f8 << 2]
35                 .endm
36 #elif 0 /* integrator-type */
37                 .macro  loadsp, rb
38                 mov     \rb, #0x16000000
39                 .endm
40                 .macro  writeb, rb
41                 strb    \rb, [r3, #0]
42                 .endm
43 #else
44 #error no serial architecture defined
45 #endif
46 #endif
47
48                 .macro  kputc,val
49                 mov     r0, \val
50                 bl      putc
51                 .endm
52
53                 .macro  kphex,val,len
54                 mov     r0, \val
55                 mov     r1, #\len
56                 bl      phex
57                 .endm
58
59                 .macro  debug_reloc_start
60 #ifdef DEBUG
61                 kputc   #'\n'
62                 kphex   r6, 8           /* processor id */
63                 kputc   #':'
64                 kphex   r7, 8           /* architecture id */
65                 kputc   #':'
66                 mrc     p15, 0, r0, c1, c0
67                 kphex   r0, 8           /* control reg
68                 kputc   #'\n'
69                 kphex   r5, 8           /* decompressed kernel start */
70                 kputc   #'-'
71                 kphex   r8, 8           /* decompressed kernel end  */
72                 kputc   #'>'
73                 kphex   r4, 8           /* kernel execution address */
74                 kputc   #'\n'
75 #endif
76                 .endm
77
78                 .macro  debug_reloc_end
79 #ifdef DEBUG
80                 kphex   r5, 8           /* end of kernel */
81                 kputc   #'\n'
82                 mov     r0, r4
83                 bl      memdump         /* dump 256 bytes at start of kernel */
84 #endif
85                 .endm
86
87                 .section ".start", #alloc, #execinstr
88 /*
89  * sort out different calling conventions
90  */
91                 .align
92 start:
93                 .type   start,#function
94                 .rept   8
95                 mov     r0, r0
96                 .endr
97
98                 b       1f
99                 .word   0x016f2818              @ Magic numbers to help the loader
100                 .word   start                   @ absolute load/run zImage address
101                 .word   _edata                  @ zImage end address
102 1:              mov     r7, r1                  @ save architecture ID
103                 mov     r8, #0                  @ save r0
104
105 #ifndef __ARM_ARCH_2__
106                 /*
107                  * Booting from Angel - need to enter SVC mode and disable
108                  * FIQs/IRQs (numeric definitions from angel arm.h source).
109                  * We only do this if we were in user mode on entry.
110                  */
111                 mrs     r2, cpsr                @ get current mode
112                 tst     r2, #3                  @ not user?
113                 bne     not_angel
114                 mov     r0, #0x17               @ angel_SWIreason_EnterSVC
115                 swi     0x123456                @ angel_SWI_ARM
116 not_angel:
117                 mrs     r2, cpsr                @ turn off interrupts to
118                 orr     r2, r2, #0xc0           @ prevent angel from running
119                 msr     cpsr_c, r2
120 #else
121                 teqp    pc, #0x0c000003         @ turn off interrupts
122 #endif
123
124                 /*
125                  * Note that some cache flushing and other stuff may
126                  * be needed here - is there an Angel SWI call for this?
127                  */
128
129                 /*
130                  * some architecture specific code can be inserted
131                  * by the linker here, but it should preserve r7 and r8.
132                  */
133
134                 .text
135 1:              adr     r2, LC0
136                 ldmia   r2, {r2, r3, r4, r5, sp}
137
138                 mov     r0, #0
139 1:              str     r0, [r2], #4            @ clear bss
140                 str     r0, [r2], #4
141                 str     r0, [r2], #4
142                 str     r0, [r2], #4
143                 cmp     r2, r3
144                 blt     1b
145
146                 mrc     p15, 0, r6, c0, c0      @ get processor ID
147                 bl      cache_on
148
149                 mov     r1, sp                  @ malloc space above stack
150                 add     r2, sp, #0x10000        @ 64k max
151
152                 teq     r4, r5                  @ will we overwrite ourselves?
153                 moveq   r5, r2                  @ decompress after image
154                 movne   r5, r4                  @ decompress to final location
155
156                 mov     r0, r5
157                 mov     r3, r7
158                 bl      SYMBOL_NAME(decompress_kernel)
159
160                 teq     r4, r5                  @ do we need to relocate
161                 beq     call_kernel             @ the kernel?
162
163                 add     r0, r0, #127
164                 bic     r0, r0, #127            @ align the kernel length
165 /*
166  * r0     = decompressed kernel length
167  * r1-r3  = unused
168  * r4     = kernel execution address
169  * r5     = decompressed kernel start
170  * r6     = processor ID
171  * r7     = architecture ID
172  * r8-r14 = unused
173  */
174                 add     r1, r5, r0              @ end of decompressed kernel
175                 adr     r2, reloc_start
176                 adr     r3, reloc_end
177 1:              ldmia   r2!, {r8 - r13}         @ copy relocation code
178                 stmia   r1!, {r8 - r13}
179                 ldmia   r2!, {r8 - r13}
180                 stmia   r1!, {r8 - r13}
181                 cmp     r2, r3
182                 blt     1b
183
184                 bl      cache_clean_flush
185                 add     pc, r5, r0              @ call relocation code
186
187                 .type   LC0, #object
188 LC0:            .word   __bss_start
189                 .word   _end
190                 .word   _load_addr
191                 .word   _start
192                 .word   user_stack+4096
193                 .size   LC0, . - LC0
194
195 /*
196  * Turn on the cache.  We need to setup some page tables so that we
197  * can have both the I and D caches on.
198  *
199  * We place the page tables 16k down from the kernel execution address,
200  * and we hope that nothing else is using it.  If we're using it, we
201  * will go pop!
202  *
203  * On entry,
204  *  r4 = kernel execution address
205  *  r6 = processor ID
206  *  r7 = architecture number
207  *  r8 = run-time address of "start"
208  * On exit,
209  *  r0, r1, r2, r3, r8, r9 corrupted
210  * This routine must preserve:
211  *  r4, r5, r6, r7
212  */
213                 .align  5
214 cache_on:       ldr     r1, proc_sa110_type
215                 eor     r1, r1, r6
216                 movs    r1, r1, lsr #5          @ catch SA110 and SA1100
217                 beq     1f
218                 ldr     r1, proc_sa1110_type
219                 eor     r1, r1, r6
220                 movs    r1, r1, lsr #4
221                 movne   pc, lr
222 1:
223                 sub     r3, r4, #16384          @ Page directory size
224                 bic     r3, r3, #0xff           @ Align the pointer
225                 bic     r3, r3, #0x3f00
226 /*
227  * Initialise the page tables, turning on the cacheable and bufferable
228  * bits for the RAM area only.
229  */
230                 mov     r0, r3
231                 mov     r8, r0, lsr #18
232                 mov     r8, r8, lsl #18         @ start of RAM
233                 add     r9, r8, #0x10000000     @ a reasonable RAM size
234                 mov     r1, #0x12
235                 orr     r1, r1, #3 << 10
236                 add     r2, r3, #16384
237 1:              cmp     r1, r8                  @ if virt > start of RAM
238                 orrge   r1, r1, #0x0c           @ set cacheable, bufferable
239                 cmp     r1, r9                  @ if virt > end of RAM
240                 bicge   r1, r1, #0x0c           @ clear cacheable, bufferable
241                 str     r1, [r0], #4            @ 1:1 mapping
242                 add     r1, r1, #1048576
243                 teq     r0, r2
244                 bne     1b
245 /*
246  * If ever we are running from Flash, then we surely want the cache
247  * to be enabled also for our execution instance...  We map 2MB of it
248  * so there is no map overlap problem for up to 1 MB compressed kernel.
249  * If the execution is in RAM then we would only be duplicating the above.
250  */
251                 mov     r1, #0x1e
252                 orr     r1, r1, #3 << 10
253                 mov     r2, pc, lsr #20
254                 orr     r1, r1, r2, lsl #20
255                 add     r0, r3, r2, lsl #2
256                 str     r1, [r0], #4
257                 add     r1, r1, #1048576
258                 str     r1, [r0]
259
260                 mov     r0, #0
261                 mcr     p15, 0, r0, c7, c10, 4  @ drain write buffer
262                 mcr     p15, 0, r0, c8, c7      @ flush I,D TLBs
263                 mcr     p15, 0, r3, c2, c0      @ load page table pointer
264                 mov     r0, #-1
265                 mcr     p15, 0, r0, c3, c0      @ load domain access register
266                 mrc     p15, 0, r0, c1, c0
267                 orr     r0, r0, #0x1000         @ I-cache enable
268 #ifndef DEBUG
269                 orr     r0, r0, #0x003d         @ Write buffer, mmu
270 #endif
271                 mcr     p15, 0, r0, c1, c0
272                 mov     pc, lr
273
274 /*
275  * This code is relocatable.  It is relocated by the above code to the end
276  * of the kernel and executed there.  During this time, we have no stacks.
277  *
278  * r0     = decompressed kernel length
279  * r1-r3  = unused
280  * r4     = kernel execution address
281  * r5     = decompressed kernel start
282  * r6     = processor ID
283  * r7     = architecture ID
284  * r8-r14 = unused
285  */
286                 .align  5
287 reloc_start:    add     r8, r5, r0
288                 debug_reloc_start
289                 mov     r1, r4
290 1:
291                 .rept   4
292                 ldmia   r5!, {r0, r2, r3, r9 - r13}     @ relocate kernel
293                 stmia   r1!, {r0, r2, r3, r9 - r13}
294                 .endr
295
296                 cmp     r5, r8
297                 blt     1b
298                 debug_reloc_end
299
300 call_kernel:    bl      cache_clean_flush
301                 bl      cache_off
302                 mov     r0, #0
303                 mov     r1, r7                  @ restore architecture number
304                 mov     pc, r4                  @ call kernel
305
306 /*
307  * Here follow the relocatable cache support functions for
308  * the various processors.
309  */
310
311                 .type   proc_sa110_type,#object
312 proc_sa110_type:
313                 .word   0x4401a100
314                 .size   proc_sa110_type, . - proc_sa110_type
315
316                 .type   proc_sa1110_type,#object
317 proc_sa1110_type:
318                 .word   0x6901b110
319                 .size   proc_sa1110_type, . - proc_sa1110_type
320
321 /*
322  * Turn off the Cache and MMU.  ARMv3 does not support
323  * reading the control register, but ARMv4 does.
324  *
325  * On entry,  r6 = processor ID
326  * On exit,   r0, r1 corrupted
327  * This routine must preserve: r4, r6, r7
328  */
329                 .align  5
330 cache_off:
331 #ifdef CONFIG_CPU_ARM610
332                 eor     r1, r6, #0x41000000
333                 eor     r1, r1, #0x00560000
334                 bic     r1, r1, #0x0000001f
335                 teq     r1, #0x00000600
336                 mov     r0, #0x00000060         @ ARM6 control reg.
337                 beq     __armv3_cache_off
338 #endif
339 #ifdef CONFIG_CPU_ARM710
340                 eor     r1, r6, #0x41000000
341                 bic     r1, r1, #0x00070000
342                 bic     r1, r1, #0x000000ff
343                 teq     r1, #0x00007000         @ ARM7
344                 teqne   r1, #0x00007100         @ ARM710
345                 mov     r0, #0x00000070         @ ARM7 control reg.
346                 beq     __armv3_cache_off
347 #endif
348                 mrc     p15, 0, r0, c1, c0
349                 bic     r0, r0, #0x000d
350                 mcr     p15, 0, r0, c1, c0      @ turn MMU and cache off
351                 mov     r0, #0
352                 mcr     p15, 0, r0, c7, c7      @ invalidate whole cache v4
353                 mcr     p15, 0, r0, c8, c7      @ invalidate whole TLB v4
354                 mov     pc, lr
355
356 __armv3_cache_off:
357                 mcr     p15, 0, r0, c1, c0      @ turn MMU and cache off
358                 mov     r0, #0
359                 mcr     p15, 0, r0, c7, c0      @ invalidate whole cache v3
360                 mcr     p15, 0, r0, c5, c0      @ invalidate whole TLB v3
361                 mov     pc, lr
362
363 /*
364  * Clean and flush the cache to maintain consistency.
365  *
366  * On entry,
367  *  r6 = processor ID
368  * On exit,
369  *  r1, r2, r12 corrupted
370  * This routine must preserve:
371  *  r4, r6, r7
372  */
373                 .align  5
374 cache_clean_flush:
375                 ldr     r1, proc_sa110_type
376                 eor     r1, r1, r6
377                 movs    r1, r1, lsr #5          @ catch SA110 and SA1100
378                 beq     1f
379                 ldr     r1, proc_sa1110_type
380                 eor     r1, r1, r6
381                 movs    r1, r1, lsr #4
382                 movne   pc, lr
383 1:
384                 bic     r1, pc, #31
385                 add     r2, r1, #32768
386 1:              ldr     r12, [r1], #32          @ s/w flush D cache
387                 teq     r1, r2
388                 bne     1b
389
390                 mcr     p15, 0, r1, c7, c7, 0   @ flush I cache
391                 mcr     p15, 0, r1, c7, c10, 4  @ drain WB
392                 mov     pc, lr
393
394 /*
395  * Various debugging routines for printing hex characters and
396  * memory, which again must be relocatable.
397  */
398 #ifdef DEBUG
399                 .type   phexbuf,#object
400 phexbuf:        .space  12
401                 .size   phexbuf, . - phexbuf
402
403 phex:           adr     r3, phexbuf
404                 mov     r2, #0
405                 strb    r2, [r3, r1]
406 1:              subs    r1, r1, #1
407                 movmi   r0, r3
408                 bmi     puts
409                 and     r2, r0, #15
410                 mov     r0, r0, lsr #4
411                 cmp     r2, #10
412                 addge   r2, r2, #7
413                 add     r2, r2, #'0'
414                 strb    r2, [r3, r1]
415                 b       1b
416
417 puts:           loadsp  r3
418 1:              ldrb    r2, [r0], #1
419                 teq     r2, #0
420                 moveq   pc, lr
421 2:              writeb  r2
422                 mov     r1, #0x00020000
423 3:              subs    r1, r1, #1
424                 bne     3b
425                 teq     r2, #'\n'
426                 moveq   r2, #'\r'
427                 beq     2b
428                 teq     r0, #0
429                 bne     1b
430                 mov     pc, lr
431 putc:
432                 mov     r2, r0
433                 mov     r0, #0
434                 loadsp  r3
435                 b       2b
436
437 memdump:        mov     r12, r0
438                 mov     r10, lr
439                 mov     r11, #0
440 2:              mov     r0, r11, lsl #2
441                 add     r0, r0, r12
442                 mov     r1, #8
443                 bl      phex
444                 mov     r0, #':'
445                 bl      putc
446 1:              mov     r0, #' '
447                 bl      putc
448                 ldr     r0, [r12, r11, lsl #2]
449                 mov     r1, #8
450                 bl      phex
451                 and     r0, r11, #7
452                 teq     r0, #3
453                 moveq   r0, #' '
454                 bleq    putc
455                 and     r0, r11, #7
456                 add     r11, r11, #1
457                 teq     r0, #7
458                 bne     1b
459                 mov     r0, #'\n'
460                 bl      putc
461                 cmp     r11, #64
462                 blt     2b
463                 mov     pc, r10
464 #endif
465
466 reloc_end:
467
468                 .align
469                 .section        ".stack"
470 user_stack:     .space  4096