Merge remote-tracking branch 'moduleh/module.h-split'
[linux-2.6/next.git] / arch / unicore32 / boot / compressed / head.S
blobfbd1e374c685bb97fcb2529725af7cc6670eba00
1 /*
2  * linux/arch/unicore32/boot/compressed/head.S
3  *
4  * Code specific to PKUnity SoC and UniCore ISA
5  *
6  * Copyright (C) 2001-2010 GUAN Xue-tao
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License version 2 as
10  * published by the Free Software Foundation.
11  */
12 #include <linux/linkage.h>
13 #include <mach/memory.h>
15 #define csub    cmpsub
16 #define cand    cmpand
17 #define nop8    nop; nop; nop; nop; nop; nop; nop; nop
19                 .section ".start", #alloc, #execinstr
20                 .text
21 start:
22                 .type   start,#function
24                 /* Initialize ASR, PRIV mode and INTR off */
25                 mov     r0, #0xD3
26                 mov.a   asr, r0
28                 adr     r0, LC0
29                 ldm     (r1, r2, r3, r5, r6, r7, r8), [r0]+
30                 ldw     sp, [r0+], #28
31                 sub.a   r0, r0, r1              @ calculate the delta offset
33                 /*
34                  * if delta is zero, we are running at the address
35                  * we were linked at.
36                  */
37                 beq     not_relocated
39                 /*
40                  * We're running at a different address.  We need to fix
41                  * up various pointers:
42                  *   r5 - zImage base address (_start)
43                  *   r7 - GOT start
44                  *   r8 - GOT end
45                  */
46                 add     r5, r5, r0
47                 add     r7, r7, r0
48                 add     r8, r8, r0
50                 /*
51                  * we need to fix up pointers into the BSS region.
52                  *   r2 - BSS start
53                  *   r3 - BSS end
54                  *   sp - stack pointer
55                  */
56                 add     r2, r2, r0
57                 add     r3, r3, r0
58                 add     sp, sp, r0
60                 /*
61                  * Relocate all entries in the GOT table.
62                  * This fixes up the C references.
63                  *   r7 - GOT start
64                  *   r8 - GOT end
65                  */
66 1001:           ldw     r1, [r7+], #0
67                 add     r1, r1, r0
68                 stw.w   r1, [r7]+, #4
69                 csub.a  r7, r8
70                 bub     1001b
72 not_relocated:
73                 /*
74                  * Clear BSS region.
75                  *   r2 - BSS start
76                  *   r3 - BSS end
77                  */
78                 mov     r0, #0
79 1002:           stw.w   r0, [r2]+, #4
80                 csub.a  r2, r3
81                 bub     1002b
83                 /*
84                  * Turn on the cache.
85                  */
86                 mov     r0, #0
87                 movc    p0.c5, r0, #28          @ cache invalidate all
88                 nop8
89                 movc    p0.c6, r0, #6           @ tlb invalidate all
90                 nop8
92                 mov     r0, #0x1c               @ en icache and wb dcache
93                 movc    p0.c1, r0, #0
94                 nop8
96                 /*
97                  * Set up some pointers, for starting decompressing.
98                  */
100                 mov     r1, sp                  @ malloc space above stack
101                 add     r2, sp, #0x10000        @ 64k max
103                 /*
104                  * Check to see if we will overwrite ourselves.
105                  *   r4 = final kernel address
106                  *   r5 = start of this image
107                  *   r6 = size of decompressed image
108                  *   r2 = end of malloc space (and therefore this image)
109                  * We basically want:
110                  *   r4 >= r2 -> OK
111                  *   r4 + image length <= r5 -> OK
112                  */
113                 ldw     r4, =KERNEL_IMAGE_START
114                 csub.a  r4, r2
115                 bea     wont_overwrite
116                 add     r0, r4, r6
117                 csub.a  r0, r5
118                 beb     wont_overwrite
120                 /*
121                  * If overwrite, just print error message
122                  */
123                 b       __error_overwrite
125                 /*
126                  * We're not in danger of overwriting ourselves.
127                  * Do this the simple way.
128                  */
129 wont_overwrite:
130                 /*
131                  * decompress_kernel:
132                  *   r0: output_start
133                  *   r1: free_mem_ptr_p
134                  *   r2: free_mem_ptr_end_p
135                  */
136                 mov     r0, r4
137                 b.l     decompress_kernel       @ C functions
139                 /*
140                  * Clean and flush the cache to maintain consistency.
141                  */
142                 mov     r0, #0
143                 movc    p0.c5, r0, #14          @ flush dcache
144                 nop8
145                 movc    p0.c5, r0, #20          @ icache invalidate all
146                 nop8
148                 /*
149                  * Turn off the Cache and MMU.
150                  */
151                 mov     r0, #0                  @ disable i/d cache and MMU
152                 movc    p0.c1, r0, #0
153                 nop8
155                 mov     r0, #0                  @ must be zero
156                 ldw     r4, =KERNEL_IMAGE_START
157                 mov     pc, r4                  @ call kernel
160                 .align  2
161                 .type   LC0, #object
162 LC0:            .word   LC0                     @ r1
163                 .word   __bss_start             @ r2
164                 .word   _end                    @ r3
165                 .word   _start                  @ r5
166                 .word   _image_size             @ r6
167                 .word   _got_start              @ r7
168                 .word   _got_end                @ r8
169                 .word   decompress_stack_end    @ sp
170                 .size   LC0, . - LC0
172 print_string:
173 #ifdef CONFIG_DEBUG_OCD
174 2001:           ldb.w   r1, [r0]+, #1
175                 csub.a  r1, #0
176                 bne     2002f
177                 mov     pc, lr
178 2002:
179                 movc    r2, p1.c0, #0
180                 cand.a  r2, #2
181                 bne     2002b
182                 movc    p1.c1, r1, #1
183                 csub.a  r1, #'\n'
184                 cmoveq  r1, #'\r'
185                 beq     2002b
186                 b       2001b
187 #else
188                 mov     pc, lr
189 #endif
191 __error_overwrite:
192                 adr     r0, str_error
193                 b.l     print_string
194 2001:           nop8
195                 b       2001b
196 str_error:      .asciz  "\nError: Kernel address OVERWRITE\n"
197                 .align
199                 .ltorg
201                 .align  4
202                 .section ".stack", "aw", %nobits
203 decompress_stack:       .space  4096
204 decompress_stack_end: