blob: 86c34dbc9cd0abdf1b5b055f6d9a7b46e082aae2 [file] [log] [blame]
Chris Zankel367b8112008-11-06 06:40:46 -08001#include <variant/core.h>
Chris Zankel173d66812006-12-10 02:18:48 -08002#include <asm/regs.h>
3#include <asm/asmmacro.h>
4#include <asm/cacheasm.h>
Chris Zankel4bedea92005-06-23 22:01:12 -07005 /*
6 * RB-Data: RedBoot data/bss
7 * P: Boot-Parameters
8 * L: Kernel-Loader
9 *
10 * The Linux-Kernel image including the loader must be loaded
11 * to a position so that the kernel and the boot parameters
12 * can fit in the space before the load address.
13 * ______________________________________________________
14 * |_RB-Data_|_P_|__________|_L_|___Linux-Kernel___|______|
15 * ^
16 * ^ Load address
17 * ______________________________________________________
18 * |___Linux-Kernel___|_P_|_L_|___________________________|
19 *
20 * The loader copies the parameter to the position that will
21 * be the end of the kernel and itself to the end of the
22 * parameter list.
23 */
24
25/* Make sure we have enough space for the 'uncompressor' */
26
27#define STACK_SIZE 32768
28#define HEAP_SIZE (131072*4)
29
30 # a2: Parameter list
31 # a3: Size of parameter list
32
33 .section .start, "ax"
34
35 .globl __start
36 /* this must be the first byte of the loader! */
37__start:
38 entry sp, 32 # we do not intend to return
39 _call0 _start
40__start_a0:
41 .align 4
42
43 .section .text, "ax"
44 .begin literal_prefix .text
45
46 /* put literals in here! */
47
48 .globl _start
49_start:
50
51 /* 'reset' window registers */
52
53 movi a4, 1
Max Filippovbc5378f2012-10-15 03:55:38 +040054 wsr a4, ps
Chris Zankel4bedea92005-06-23 22:01:12 -070055 rsync
56
Max Filippovbc5378f2012-10-15 03:55:38 +040057 rsr a5, windowbase
Chris Zankel4bedea92005-06-23 22:01:12 -070058 ssl a5
59 sll a4, a4
Max Filippovbc5378f2012-10-15 03:55:38 +040060 wsr a4, windowstart
Chris Zankel4bedea92005-06-23 22:01:12 -070061 rsync
62
63 movi a4, 0x00040000
Max Filippovbc5378f2012-10-15 03:55:38 +040064 wsr a4, ps
Chris Zankel4bedea92005-06-23 22:01:12 -070065 rsync
66
67 /* copy the loader to its address
68 * Note: The loader itself is a very small piece, so we assume we
69 * don't partially overlap. We also assume (even more important)
70 * that the kernel image is out of the way. Usually, when the
71 * load address of this image is not at an arbitrary address,
72 * but aligned to some 10K's we shouldn't overlap.
73 */
74
75 /* Note: The assembler cannot relax "addi a0, a0, ..." to an
76 l32r, so we load to a4 first. */
77
Chris Zankel173d66812006-12-10 02:18:48 -080078 # addi a4, a0, __start - __start_a0
79 # mov a0, a4
80
81 movi a4, __start
82 movi a5, __start_a0
83 add a4, a0, a4
84 sub a0, a4, a5
85
Chris Zankel4bedea92005-06-23 22:01:12 -070086 movi a4, __start
87 movi a5, __reloc_end
88
89 # a0: address where this code has been loaded
90 # a4: compiled address of __start
91 # a5: compiled end address
92
93 mov.n a7, a0
94 mov.n a8, a4
95
961:
97 l32i a10, a7, 0
98 l32i a11, a7, 4
99 s32i a10, a8, 0
100 s32i a11, a8, 4
101 l32i a10, a7, 8
102 l32i a11, a7, 12
103 s32i a10, a8, 8
104 s32i a11, a8, 12
105 addi a8, a8, 16
106 addi a7, a7, 16
107 blt a8, a5, 1b
108
109
110 /* We have to flush and invalidate the caches here before we jump. */
111
112#if XCHAL_DCACHE_IS_WRITEBACK
Chris Zankel173d66812006-12-10 02:18:48 -0800113
114 ___flush_dcache_all a5 a6
115
Chris Zankel4bedea92005-06-23 22:01:12 -0700116#endif
Chris Zankel173d66812006-12-10 02:18:48 -0800117
118 ___invalidate_icache_all a5 a6
119 isync
Chris Zankel4bedea92005-06-23 22:01:12 -0700120
121 movi a11, _reloc
122 jx a11
123
124 .globl _reloc
125_reloc:
126
127 /* RedBoot is now at the end of the memory, so we don't have
128 * to copy the parameter list. Keep the code around; in case
129 * we need it again. */
130#if 0
131 # a0: load address
132 # a2: start address of parameter list
133 # a3: length of parameter list
134 # a4: __start
135
136 /* copy the parameter list out of the way */
137
138 movi a6, _param_start
139 add a3, a2, a3
1402:
141 l32i a8, a2, 0
142 s32i a8, a6, 0
143 addi a2, a2, 4
144 addi a6, a6, 4
145 blt a2, a3, 2b
146#endif
147
148 /* clear BSS section */
149 movi a6, __bss_start
150 movi a7, __bss_end
151 movi.n a5, 0
1523:
153 s32i a5, a6, 0
154 addi a6, a6, 4
155 blt a6, a7, 3b
156
157 movi a5, -16
158 movi a1, _stack + STACK_SIZE
159 and a1, a1, a5
160
161 /* Uncompress the kernel */
162
163 # a0: load address
164 # a2: boot parameter
165 # a4: __start
166
167 movi a3, __image_load
168 sub a4, a3, a4
169 add a8, a0, a4
170
171 # a1 Stack
172 # a8(a4) Load address of the image
173
174 movi a6, _image_start
175 movi a10, _image_end
176 movi a7, 0x1000000
177 sub a11, a10, a6
178 movi a9, complen
179 s32i a11, a9, 0
180
181 movi a0, 0
182
183 # a6 destination
184 # a7 maximum size of destination
185 # a8 source
186 # a9 ptr to length
187
188 .extern gunzip
189 movi a4, gunzip
190 beqz a4, 1f
191
192 callx4 a4
193
194 j 2f
195
196
197 # a6 destination start
198 # a7 maximum size of destination
199 # a8 source start
200 # a9 ptr to length
201 # a10 destination end
202
2031:
204 l32i a9, a8, 0
205 l32i a11, a8, 4
206 s32i a9, a6, 0
207 s32i a11, a6, 4
208 l32i a9, a8, 8
209 l32i a11, a8, 12
210 s32i a9, a6, 8
211 s32i a11, a6, 12
212 addi a6, a6, 16
213 addi a8, a8, 16
214 blt a6, a10, 1b
215
216
217 /* jump to the kernel */
2182:
219#if XCHAL_DCACHE_IS_WRITEBACK
Chris Zankel173d66812006-12-10 02:18:48 -0800220
221 ___flush_dcache_all a5 a6
222
Chris Zankel4bedea92005-06-23 22:01:12 -0700223#endif
Chris Zankel173d66812006-12-10 02:18:48 -0800224
225 ___invalidate_icache_all a5 a6
226
227 isync
Chris Zankel4bedea92005-06-23 22:01:12 -0700228
Chris Zankel4bedea92005-06-23 22:01:12 -0700229 # a2 Boot parameter list
Chris Zankel4bedea92005-06-23 22:01:12 -0700230
231 movi a0, _image_start
232 jx a0
233
234 .align 16
235 .data
236 .globl avail_ram
237avail_ram:
238 .long _heap
239 .globl end_avail
240end_avail:
241 .long _heap + HEAP_SIZE
242
243 .comm _stack, STACK_SIZE
244 .comm _heap, HEAP_SIZE
245
246 .globl end_avail
247 .comm complen, 4
248
249 .end literal_prefix