MOXA linux-2.6.x / linux-2.6.19-uc1 from UC-7110-LX-BOOTLOADER-1.9_VERSION-4.2.tgz
[linux-2.6.19-moxart.git] / arch / arm / boot / compressed / head-p2001.S
blob0926f9ae0d875816bcdc98f5e77299cea1775aa5
1 /*
2  *  linux/arch/armnommu/boot/compressed/head-p2001.S
3  *
4  *  Copyright (C) 2004 Tobias Lorenz
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/linkage.h>
13  * Debugging stuff
14  *
15  * Note that these macros must not contain any code which is not
16  * 100% relocatable.  Any attempt to do so will result in a crash.
17  * Please select one of the following when turning on debugging.
18  */
19 #ifdef DEBUG
20                 .macro  loadsp, rb
21                 mov     \rb, #0x00140000        @ Adr_UART_OLD_BASE
22                 .endm
24                 .macro  writeb, rb
25                 str     \rb, [r3, #0x00]        @ REL_Adr_Uart_TX1
26                 .endm
27 #endif
29                 .macro  kputc,val
30                 mov     r0, \val
31                 bl      putc
32                 .endm
34                 .macro  kphex,val,len
35                 mov     r0, \val
36                 mov     r1, #\len
37                 bl      phex
38                 .endm
40                 .macro  debug_reloc_start
41 #ifdef DEBUG
42                 kputc   #'\n'
43                 kphex   r6, 8           /* processor id */
44                 kputc   #':'
45                 kphex   r7, 8           /* architecture id */
46                 kputc   #'\n'
47                 kphex   r5, 8           /* decompressed kernel start */
48                 kputc   #'-'
49                 kphex   r8, 8           /* decompressed kernel end  */
50                 kputc   #'>'
51                 kphex   r4, 8           /* kernel execution address */
52                 kputc   #'\n'
53 #endif
54                 .endm
56                 .macro  debug_reloc_end
57 #ifdef DEBUG
58                 kphex   r5, 8           /* end of kernel */
59                 kputc   #'\n'
60                 mov     r0, r4
61                 bl      memdump         /* dump 256 bytes at start of kernel */
62 #endif
63                 .endm
66                 .section ".start", #alloc, #execinstr
68  * sort out different calling conventions
69  */
70                 .align
71 start:
72                 .type   start,#function
73                 .rept   8
74                 mov     r0, r0
75                 .endr
77                 b       1f
78                 .word   0x016f2818              @ Magic numbers to help the loader
79                 .word   start                   @ absolute load/run zImage address
80                 .word   _edata                  @ zImage end address
81 1:              mov     r7, r1                  @ save architecture ID
82                 mov     r8, #0                  @ save r0
84                 /*
85                  * Booting from P2001 - need to enter SVC mode and disable
86                  * FIQs/IRQs (numeric definitions from angel arm.h source).
87                  * We only do this if we were in user mode on entry.
88                  */
89                 mrs     r2, cpsr                @ get current mode
90                 orr     r2, r2, #0xc0           @ turn off interrupts
91                 msr     cpsr_c, r2
93                 /*
94                  * Note that some cache flushing and other stuff may
95                  * be needed here - is there an Angel SWI call for this?
96                  */
98                 /*
99                  * some architecture specific code can be inserted
100                  * by the linker here, but it should preserve r7 and r8.
101                  */
103                 .text
104                 adr     r0, LC0
105                 ldmia   r0, {r1, r2, r3, r4, r5, r6, ip, sp}
106                 subs    r0, r0, r1              @ calculate the delta offset
108                                                 @ if delta is zero, we're
109                 beq     not_relocated           @ running at the address we
110                                                 @ were linked at.
112                 /*
113                  * We're running at a different address.  We need to fix
114                  * up various pointers:
115                  *   r5 - zImage base address
116                  *   r6 - GOT start
117                  *   ip - GOT end
118                  */
119                 add     r5, r5, r0
120                 add     r6, r6, r0
121                 add     ip, ip, r0
123 #ifndef CONFIG_ZBOOT_ROM
124                 /*
125                  * If we're running fully PIC === CONFIG_ZBOOT_ROM = n,
126                  * we need to fix up pointers into the BSS region.
127                  *   r2 - BSS start
128                  *   r3 - BSS end
129                  *   sp - stack pointer
130                  */
131                 add     r2, r2, r0
132                 add     r3, r3, r0
133                 add     sp, sp, r0
135                 /*
136                  * Relocate all entries in the GOT table.
137                  */
138 1:              ldr     r1, [r6, #0]            @ relocate entries in the GOT
139                 add     r1, r1, r0              @ table.  This fixes up the
140                 str     r1, [r6], #4            @ C references.
141                 cmp     r6, ip
142                 blo     1b
143 #else
145                 /*
146                  * Relocate entries in the GOT table.  We only relocate
147                  * the entries that are outside the (relocated) BSS region.
148                  */
149 1:              ldr     r1, [r6, #0]            @ relocate entries in the GOT
150                 cmp     r1, r2                  @ entry < bss_start ||
151                 cmphs   r3, r1                  @ _end < entry
152                 addlo   r1, r1, r0              @ table.  This fixes up the
153                 str     r1, [r6], #4            @ C references.
154                 cmp     r6, ip
155                 blo     1b
156 #endif
158 not_relocated:  mov     r0, #0
159 1:              str     r0, [r2], #4            @ clear bss
160                 str     r0, [r2], #4
161                 str     r0, [r2], #4
162                 str     r0, [r2], #4
163                 cmp     r2, r3
164                 blo     1b
166                 /*
167                  * The C runtime environment should now be setup
168                  * sufficiently.  Set up some pointers, and start decompressing.
169                  */
170                 mov     r1, sp                  @ malloc space above stack
171                 add     r2, sp, #0x10000        @ 64k max
174  * Check to see if we will overwrite ourselves.
175  *   r4 = final kernel address
176  *   r5 = start of this image
177  *   r2 = end of malloc space (and therefore this image)
178  * We basically want:
179  *   r4 >= r2 -> OK
180  *   r4 + image length <= r5 -> OK
181  */
182                 cmp     r4, r2
183                 bhs     wont_overwrite
184                 add     r0, r4, #4096*1024      @ 4MB largest kernel size
185                 cmp     r0, r5
186                 bls     wont_overwrite
188                 mov     r5, r2                  @ decompress after malloc space
189                 mov     r0, r5
190                 mov     r3, r7
191                 bl      decompress_kernel
193                 add     r0, r0, #127
194                 bic     r0, r0, #127            @ align the kernel length
196  * r0     = decompressed kernel length
197  * r1-r3  = unused
198  * r4     = kernel execution address
199  * r5     = decompressed kernel start
200  * r6     = processor ID
201  * r7     = architecture ID
202  * r8-r14 = unused
203  */
204                 add     r1, r5, r0              @ end of decompressed kernel
205                 adr     r2, reloc_start
206                 ldr     r3, LC1
207                 add     r3, r2, r3
208 1:              ldmia   r2!, {r8 - r13}         @ copy relocation code
209                 stmia   r1!, {r8 - r13}
210                 ldmia   r2!, {r8 - r13}
211                 stmia   r1!, {r8 - r13}
212                 cmp     r2, r3
213                 blo     1b
215                 add     pc, r5, r0              @ call relocation code
218  * We're not in danger of overwriting ourselves.  Do this the simple way.
220  * r4     = kernel execution address
221  * r7     = architecture ID
222  */
223 wont_overwrite: mov     r0, r4
224                 mov     r3, r7
225                 bl      decompress_kernel
226                 b       call_kernel
228                 .type   LC0, #object
229 LC0:            .word   LC0                     @ r1
230                 .word   __bss_start             @ r2
231                 .word   _end                    @ r3
232                 .word   _load_addr              @ r4
233                 .word   _start                  @ r5
234                 .word   _got_start              @ r6
235                 .word   _got_end                @ ip
236                 .word   user_stack+4096         @ sp
237 LC1:            .word   reloc_end - reloc_start
238                 .size   LC0, . - LC0
241  * Initialise the page tables, turning on the cacheable and bufferable
242  * bits for the RAM area only.
243  */
244                 mov     r0, r3
245                 mov     r8, r0, lsr #18
246                 mov     r8, r8, lsl #18         @ start of RAM
247                 add     r9, r8, #0x10000000     @ a reasonable RAM size
248                 mov     r1, #0x12
249                 orr     r1, r1, #3 << 10
250                 add     r2, r3, #16384
251 1:              cmp     r1, r8                  @ if virt > start of RAM
252                 orrhs   r1, r1, #0x0c           @ set cacheable, bufferable
253                 cmp     r1, r9                  @ if virt > end of RAM
254                 bichs   r1, r1, #0x0c           @ clear cacheable, bufferable
255                 str     r1, [r0], #4            @ 1:1 mapping
256                 add     r1, r1, #1048576
257                 teq     r0, r2
258                 bne     1b
260  * If ever we are running from Flash, then we surely want the cache
261  * to be enabled also for our execution instance...  We map 2MB of it
262  * so there is no map overlap problem for up to 1 MB compressed kernel.
263  * If the execution is in RAM then we would only be duplicating the above.
264  */
265                 mov     r1, #0x1e
266                 orr     r1, r1, #3 << 10
267                 mov     r2, pc, lsr #20
268                 orr     r1, r1, r2, lsl #20
269                 add     r0, r3, r2, lsl #2
270                 str     r1, [r0], #4
271                 add     r1, r1, #1048576
272                 str     r1, [r0]
273                 mov     pc, lr
276  * All code following this line is relocatable.  It is relocated by
277  * the above code to the end of the decompressed kernel image and
278  * executed there.  During this time, we have no stacks.
280  * r0     = decompressed kernel length
281  * r1-r3  = unused
282  * r4     = kernel execution address
283  * r5     = decompressed kernel start
284  * r6     = processor ID
285  * r7     = architecture ID
286  * r8-r14 = unused
287  */
288                 .align  5
289 reloc_start:    add     r8, r5, r0
290                 debug_reloc_start
291                 mov     r1, r4
293                 .rept   4
294                 ldmia   r5!, {r0, r2, r3, r9 - r13}     @ relocate kernel
295                 stmia   r1!, {r0, r2, r3, r9 - r13}
296                 .endr
298                 cmp     r5, r8
299                 blo     1b
300                 debug_reloc_end
302 call_kernel:    mov     r0, #0
303                 mov     r1, r7                  @ restore architecture number
304                 mov     pc, r4                  @ call kernel
307  * Various debugging routines for printing hex characters and
308  * memory, which again must be relocatable.
309  */
310 #ifdef DEBUG
311                 .type   phexbuf,#object
312 phexbuf:        .space  12
313                 .size   phexbuf, . - phexbuf
315 phex:           adr     r3, phexbuf
316                 mov     r2, #0
317                 strb    r2, [r3, r1]
318 1:              subs    r1, r1, #1
319                 movmi   r0, r3
320                 bmi     puts
321                 and     r2, r0, #15
322                 mov     r0, r0, lsr #4
323                 cmp     r2, #10
324                 addge   r2, r2, #7
325                 add     r2, r2, #'0'
326                 strb    r2, [r3, r1]
327                 b       1b
329 puts:           loadsp  r3
330 1:              ldrb    r2, [r0], #1
331                 teq     r2, #0
332                 moveq   pc, lr
333 2:              writeb  r2
334                 mov     r1, #0x00020000
335 3:              subs    r1, r1, #1
336                 bne     3b
337                 teq     r2, #'\n'
338                 moveq   r2, #'\r'
339                 beq     2b
340                 teq     r0, #0
341                 bne     1b
342                 mov     pc, lr
343 putc:
344                 mov     r2, r0
345                 mov     r0, #0
346                 loadsp  r3
347                 b       2b
349 memdump:        mov     r12, r0
350                 mov     r10, lr
351                 mov     r11, #0
352 2:              mov     r0, r11, lsl #2
353                 add     r0, r0, r12
354                 mov     r1, #8
355                 bl      phex
356                 mov     r0, #':'
357                 bl      putc
358 1:              mov     r0, #' '
359                 bl      putc
360                 ldr     r0, [r12, r11, lsl #2]
361                 mov     r1, #8
362                 bl      phex
363                 and     r0, r11, #7
364                 teq     r0, #3
365                 moveq   r0, #' '
366                 bleq    putc
367                 and     r0, r11, #7
368                 add     r11, r11, #1
369                 teq     r0, #7
370                 bne     1b
371                 mov     r0, #'\n'
372                 bl      putc
373                 cmp     r11, #64
374                 blt     2b
375                 mov     pc, r10
376 #endif
378 reloc_end:
380                 .align
381                 .section ".stack", "w"
382 user_stack:     .space  4096