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-espd_4510b.S
blob19e8dd2cbbb8d64efe8afcb5fcffb4a7d72302b2
1 /*
2  *  linux/arch/arm/boot/compressed/head-espd_4510b.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>
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 defined(CONFIG_DEBUG_ICEDCC)
22                 .macro  loadsp, rb
23                 .endm
24                 .macro writeb, rb
25                 mcr     p14, 0, \rb, c0, c1, 0
26                 .endm
27 #else
28 #error no serial architecture defined
29 #endif
30 #endif
32                 .macro  kputc,val
33                 mov     r0, \val
34                 bl      putc
35                 .endm
37                 .macro  kphex,val,len
38                 mov     r0, \val
39                 mov     r1, #\len
40                 bl      phex
41                 .endm
43                 .macro  debug_reloc_start
44 #ifdef DEBUG
45                 kputc   #'\n'
46                 kphex   r6, 8           /* processor id */
47                 kputc   #':'
48                 kphex   r7, 8           /* architecture id */
49                 kputc   #':'
50                 mrc     p15, 0, r0, c1, c0
51                 kphex   r0, 8           /* control reg */
52                 kputc   #'\n'
53                 kphex   r5, 8           /* decompressed kernel start */
54                 kputc   #'-'
55                 kphex   r8, 8           /* decompressed kernel end  */
56                 kputc   #'>'
57                 kphex   r4, 8           /* kernel execution address */
58                 kputc   #'\n'
59 #endif
60                 .endm
62                 .macro  debug_reloc_end
63 #ifdef DEBUG
64                 kphex   r5, 8           /* end of kernel */
65                 kputc   #'\n'
66                 mov     r0, r4
67                 bl      memdump         /* dump 256 bytes at start of kernel */
68 #endif
69                 .endm
71                 .section ".start", #alloc, #execinstr
73  * sort out different calling conventions
74  */
75                 .align
76 start:
77                 .type   start,#function
78                 .rept   8
79                 mov     r0, r0
80                 .endr
82                 b       1f
83                 .word   0x016f2818              @ Magic numbers to help the loader
84                 .word   start                   @ absolute load/run zImage address
85                 .word   _edata                  @ zImage end address
86 1:              mov     r7, r1                  @ save architecture ID
87                 mov     r8, #0                  @ save r0
89 #ifndef __ARM_ARCH_2__
90                 /*
91                  * Booting from Angel - need to enter SVC mode and disable
92                  * FIQs/IRQs (numeric definitions from angel arm.h source).
93                  * We only do this if we were in user mode on entry.
94                  */
95                 mrs     r2, cpsr                @ get current mode
96                 tst     r2, #3                  @ not user?
97                 bne     not_angel
98                 mov     r0, #0x17               @ angel_SWIreason_EnterSVC
99                 swi     0x123456                @ angel_SWI_ARM
100 not_angel:
101                 mrs     r2, cpsr                @ turn off interrupts to
102                 orr     r2, r2, #0xc0           @ prevent angel from running
103                 msr     cpsr_c, r2
104 #else
105                 teqp    pc, #0x0c000003         @ turn off interrupts
106 #endif
108                 /*
109                  * Note that some cache flushing and other stuff may
110                  * be needed here - is there an Angel SWI call for this?
111                  */
113                 /*
114                  * some architecture specific code can be inserted
115                  * by the linker here, but it should preserve r7 and r8.
116                  */
118                 .text
119                 adr     r0, LC0
120                 ldmia   r0, {r1, r2, r3, r4, r5, r6, ip, sp}
121                 subs    r0, r0, r1              @ calculate the delta offset
123                                                 @ if delta is zero, we are
124                 beq     not_relocated           @ running at the address we
125                                                 @ were linked at.
127                 /*
128                  * We're running at a different address.  We need to fix
129                  * up various pointers:
130                  *   r5 - zImage base address
131                  *   r6 - GOT start
132                  *   ip - GOT end
133                  */
134                 add     r5, r5, r0
135                 add     r6, r6, r0
136                 add     ip, ip, r0
138 #ifndef CONFIG_ZBOOT_ROM
139                 /*
140                  * If we're running fully PIC === CONFIG_ZBOOT_ROM = n,
141                  * we need to fix up pointers into the BSS region.
142                  *   r2 - BSS start
143                  *   r3 - BSS end
144                  *   sp - stack pointer
145                  */
146                 add     r2, r2, r0
147                 add     r3, r3, r0
148                 add     sp, sp, r0
150                 /*
151                  * Relocate all entries in the GOT table.
152                  */
153 1:              ldr     r1, [r6, #0]            @ relocate entries in the GOT
154                 add     r1, r1, r0              @ table.  This fixes up the
155                 str     r1, [r6], #4            @ C references.
156                 cmp     r6, ip
157                 blo     1b
158 #else
160                 /*
161                  * Relocate entries in the GOT table.  We only relocate
162                  * the entries that are outside the (relocated) BSS region.
163                  */
164 1:              ldr     r1, [r6, #0]            @ relocate entries in the GOT
165                 cmp     r1, r2                  @ entry < bss_start ||
166                 cmphs   r3, r1                  @ _end < entry
167                 addlo   r1, r1, r0              @ table.  This fixes up the
168                 str     r1, [r6], #4            @ C references.
169                 cmp     r6, ip
170                 blo     1b
171 #endif
173 not_relocated:  mov     r0, #0
174 1:              str     r0, [r2], #4            @ clear bss
175                 str     r0, [r2], #4
176                 str     r0, [r2], #4
177                 str     r0, [r2], #4
178                 cmp     r2, r3
179                 blo     1b
181                 /*
182                  * Reset Ethernet BDMA (before cache on)
183                  */
184                 ldr     r3, =0x8000             @ BDMA reset
185                 ldr     r2, =0x3FF9000          @ BDMATXCON
186                 str     r3, [r2]
187                 ldr     r2, =0x3FF9004          @ BDMARXCON
188                 str     r3, [r2]
190                 /*
191                  * The C runtime environment should now be setup
192                  * sufficiently.  Turn the cache on, set up some
193                  * pointers, and start decompressing.
194                  */
195                 bl      cache_on
197                 mov     r1, sp                  @ malloc space above stack
198                 add     r2, sp, #0x10000        @ 64k max
201  * Check to see if we will overwrite ourselves.
202  *   r4 = final kernel address
203  *   r5 = start of this image
204  *   r2 = end of malloc space (and therefore this image)
205  * We basically want:
206  *   r4 >= r2 -> OK
207  *   r4 + image length <= r5 -> OK
208  */
209                 cmp     r4, r2
210                 bhs     wont_overwrite
211                 add     r0, r4, #4096*1024      @ 4MB largest kernel size
212                 cmp     r0, r5
213                 bls     wont_overwrite
215                 mov     r5, r2                  @ decompress after malloc space
216                 mov     r0, r5
217                 mov     r3, r7
218                 bl      decompress_kernel
220                 add     r0, r0, #127
221                 bic     r0, r0, #127            @ align the kernel length
223  * r0     = decompressed kernel length
224  * r1-r3  = unused
225  * r4     = kernel execution address
226  * r5     = decompressed kernel start
227  * r6     = processor ID
228  * r7     = architecture ID
229  * r8-r14 = unused
230  */
231                 add     r1, r5, r0              @ end of decompressed kernel
232                 adr     r2, reloc_start
233                 ldr     r3, LC1
234                 add     r3, r2, r3
235 1:              ldmia   r2!, {r8 - r13}         @ copy relocation code
236                 stmia   r1!, {r8 - r13}
237                 ldmia   r2!, {r8 - r13}
238                 stmia   r1!, {r8 - r13}
239                 cmp     r2, r3
240                 blo     1b
242                 bl      cache_clean_flush
243                 add     pc, r5, r0              @ call relocation code
246  * We're not in danger of overwriting ourselves.  Do this the simple way.
248  * r4     = kernel execution address
249  * r7     = architecture ID
250  */
251 wont_overwrite: mov     r0, r4
252                 mov     r3, r7
253                 bl      decompress_kernel
254                 b       call_kernel
256                 .type   LC0, #object
257 LC0:            .word   LC0                     @ r1
258                 .word   __bss_start             @ r2
259                 .word   _end                    @ r3
260                 .word   zreladdr                @ r4
261                 .word   _start                  @ r5
262                 .word   _got_start              @ r6
263                 .word   _got_end                @ ip
264                 .word   user_stack+4096         @ sp
265 LC1:            .word   reloc_end - reloc_start
266                 .size   LC0, . - LC0
269  * Turn on the cache.  We need to setup some page tables so that we
270  * can have both the I and D caches on.
272  * We place the page tables 16k down from the kernel execution address,
273  * and we hope that nothing else is using it.  If we're using it, we
274  * will go pop!
276  * On entry,
277  *  r4 = kernel execution address
278  *  r6 = processor ID
279  *  r7 = architecture number
280  *  r8 = run-time address of "start"
281  * On exit,
282  *  r1, r2, r3, r8, r9, r12 corrupted
283  * This routine must preserve:
284  *  r4, r5, r6, r7
285  */
286                 .align  5
287 cache_on:
288                 /* cache/write buffer on */
289                 ldr     r0, =0x3FF0000          @ SYSCFG
290                 ldr     r2, [r0]
291                 orr     r2, r2, #6              @ Cache and write buffer
292                 str     r2, [r0]
293                 mov     pc, lr
296  * All code following this line is relocatable.  It is relocated by
297  * the above code to the end of the decompressed kernel image and
298  * executed there.  During this time, we have no stacks.
300  * r0     = decompressed kernel length
301  * r1-r3  = unused
302  * r4     = kernel execution address
303  * r5     = decompressed kernel start
304  * r6     = processor ID
305  * r7     = architecture ID
306  * r8-r14 = unused
307  */
308                 .align  5
309 reloc_start:    add     r8, r5, r0
310                 debug_reloc_start
311                 mov     r1, r4
313                 .rept   4
314                 ldmia   r5!, {r0, r2, r3, r9 - r13}     @ relocate kernel
315                 stmia   r1!, {r0, r2, r3, r9 - r13}
316                 .endr
318                 cmp     r5, r8
319                 blo     1b
320                 debug_reloc_end
322 call_kernel:    bl      cache_clean_flush
323                 bl      cache_off
324                 mov     r0, #0
325                 mov     r1, r7                  @ restore architecture number
326                 mov     pc, r4                  @ call kernel
330  * Turn off the Cache and MMU.  ARMv3 does not support
331  * reading the control register, but ARMv4 does.
333  * On entry,  r6 = processor ID
334  * On exit,   r0, r1, r2, r3, r12 corrupted
335  * This routine must preserve: r4, r6, r7
336  */
337                 .align  5
338 cache_off:
339                 /* cache/write buffer off */
340                 ldr     r0, =0x3FF0000          @ SYSCFG
341                 ldr     r2, [r0]
342                 bic     r2, r2, #6              @ Cache and write buffer
343                 str     r2, [r0]
344                 mov     pc, lr
346  * Clean and flush the cache to maintain consistency.
348  * On entry,
349  *  r6 = processor ID
350  * On exit,
351  *  r1, r2, r3, r11, r12 corrupted
352  * This routine must preserve:
353  *  r0, r4, r5, r6, r7
354  */
355                 .align  5
356 cache_clean_flush:
358  * cf. Ch-5 of S3C4510 user's manual for
359  *     "Cache flush operation"
360  * To clear Tag RAM area.
361  */
362                 ldr     r1, =0x11000000
363                 mov     r2, #0
364                 mov     r12, #256
365 cache_flush_loop:
366                 str     r2, [r1], #4
367                 subs    r12, r12, #1
368                 bne     cache_flush_loop
369                 mov     pc, lr
372  * Various debugging routines for printing hex characters and
373  * memory, which again must be relocatable.
374  */
375 #ifdef DEBUG
376                 .type   phexbuf,#object
377 phexbuf:        .space  12
378                 .size   phexbuf, . - phexbuf
380 phex:           adr     r3, phexbuf
381                 mov     r2, #0
382                 strb    r2, [r3, r1]
383 1:              subs    r1, r1, #1
384                 movmi   r0, r3
385                 bmi     puts
386                 and     r2, r0, #15
387                 mov     r0, r0, lsr #4
388                 cmp     r2, #10
389                 addge   r2, r2, #7
390                 add     r2, r2, #'0'
391                 strb    r2, [r3, r1]
392                 b       1b
394 puts:           loadsp  r3
395 1:              ldrb    r2, [r0], #1
396                 teq     r2, #0
397                 moveq   pc, lr
398 2:              writeb  r2
399                 mov     r1, #0x00020000
400 3:              subs    r1, r1, #1
401                 bne     3b
402                 teq     r2, #'\n'
403                 moveq   r2, #'\r'
404                 beq     2b
405                 teq     r0, #0
406                 bne     1b
407                 mov     pc, lr
408 putc:
409                 mov     r2, r0
410                 mov     r0, #0
411                 loadsp  r3
412                 b       2b
414 memdump:        mov     r12, r0
415                 mov     r10, lr
416                 mov     r11, #0
417 2:              mov     r0, r11, lsl #2
418                 add     r0, r0, r12
419                 mov     r1, #8
420                 bl      phex
421                 mov     r0, #':'
422                 bl      putc
423 1:              mov     r0, #' '
424                 bl      putc
425                 ldr     r0, [r12, r11, lsl #2]
426                 mov     r1, #8
427                 bl      phex
428                 and     r0, r11, #7
429                 teq     r0, #3
430                 moveq   r0, #' '
431                 bleq    putc
432                 and     r0, r11, #7
433                 add     r11, r11, #1
434                 teq     r0, #7
435                 bne     1b
436                 mov     r0, #'\n'
437                 bl      putc
438                 cmp     r11, #64
439                 blt     2b
440                 mov     pc, r10
441 #endif
443 reloc_end:
445                 .align
446                 .section ".stack", "w"
447 user_stack:     .space  4096