aboutsummaryrefslogtreecommitdiffstats
path: root/arch/xtensa/boot/boot-redboot/bootstrap.S
diff options
context:
space:
mode:
Diffstat (limited to 'arch/xtensa/boot/boot-redboot/bootstrap.S')
-rw-r--r--arch/xtensa/boot/boot-redboot/bootstrap.S246
1 files changed, 246 insertions, 0 deletions
diff --git a/arch/xtensa/boot/boot-redboot/bootstrap.S b/arch/xtensa/boot/boot-redboot/bootstrap.S
new file mode 100644
index 000000000000..ee636b0da81c
--- /dev/null
+++ b/arch/xtensa/boot/boot-redboot/bootstrap.S
@@ -0,0 +1,246 @@
1
2#define _ASMLANGUAGE
3#include <xtensa/config/specreg.h>
4#include <xtensa/config/core.h>
5#include <xtensa/cacheasm.h>
6
7 /*
8 * RB-Data: RedBoot data/bss
9 * P: Boot-Parameters
10 * L: Kernel-Loader
11 *
12 * The Linux-Kernel image including the loader must be loaded
13 * to a position so that the kernel and the boot parameters
14 * can fit in the space before the load address.
15 * ______________________________________________________
16 * |_RB-Data_|_P_|__________|_L_|___Linux-Kernel___|______|
17 * ^
18 * ^ Load address
19 * ______________________________________________________
20 * |___Linux-Kernel___|_P_|_L_|___________________________|
21 *
22 * The loader copies the parameter to the position that will
23 * be the end of the kernel and itself to the end of the
24 * parameter list.
25 */
26
27/* Make sure we have enough space for the 'uncompressor' */
28
29#define STACK_SIZE 32768
30#define HEAP_SIZE (131072*4)
31
32 # a2: Parameter list
33 # a3: Size of parameter list
34
35 .section .start, "ax"
36
37 .globl __start
38 /* this must be the first byte of the loader! */
39__start:
40 entry sp, 32 # we do not intend to return
41 _call0 _start
42__start_a0:
43 .align 4
44
45 .section .text, "ax"
46 .begin literal_prefix .text
47
48 /* put literals in here! */
49
50 .globl _start
51_start:
52
53 /* 'reset' window registers */
54
55 movi a4, 1
56 wsr a4, PS
57 rsync
58
59 rsr a5, WINDOWBASE
60 ssl a5
61 sll a4, a4
62 wsr a4, WINDOWSTART
63 rsync
64
65 movi a4, 0x00040000
66 wsr a4, PS
67 rsync
68
69 /* copy the loader to its address
70 * Note: The loader itself is a very small piece, so we assume we
71 * don't partially overlap. We also assume (even more important)
72 * that the kernel image is out of the way. Usually, when the
73 * load address of this image is not at an arbitrary address,
74 * but aligned to some 10K's we shouldn't overlap.
75 */
76
77 /* Note: The assembler cannot relax "addi a0, a0, ..." to an
78 l32r, so we load to a4 first. */
79
80 addi a4, a0, __start - __start_a0
81 mov a0, a4
82 movi a4, __start
83 movi a5, __reloc_end
84
85 # a0: address where this code has been loaded
86 # a4: compiled address of __start
87 # a5: compiled end address
88
89 mov.n a7, a0
90 mov.n a8, a4
91
921:
93 l32i a10, a7, 0
94 l32i a11, a7, 4
95 s32i a10, a8, 0
96 s32i a11, a8, 4
97 l32i a10, a7, 8
98 l32i a11, a7, 12
99 s32i a10, a8, 8
100 s32i a11, a8, 12
101 addi a8, a8, 16
102 addi a7, a7, 16
103 blt a8, a5, 1b
104
105
106 /* We have to flush and invalidate the caches here before we jump. */
107
108#if XCHAL_DCACHE_IS_WRITEBACK
109 dcache_writeback_all a5, a6
110#endif
111 icache_invalidate_all a5, a6
112
113 movi a11, _reloc
114 jx a11
115
116 .globl _reloc
117_reloc:
118
119 /* RedBoot is now at the end of the memory, so we don't have
120 * to copy the parameter list. Keep the code around; in case
121 * we need it again. */
122#if 0
123 # a0: load address
124 # a2: start address of parameter list
125 # a3: length of parameter list
126 # a4: __start
127
128 /* copy the parameter list out of the way */
129
130 movi a6, _param_start
131 add a3, a2, a3
1322:
133 l32i a8, a2, 0
134 s32i a8, a6, 0
135 addi a2, a2, 4
136 addi a6, a6, 4
137 blt a2, a3, 2b
138#endif
139
140 /* clear BSS section */
141 movi a6, __bss_start
142 movi a7, __bss_end
143 movi.n a5, 0
1443:
145 s32i a5, a6, 0
146 addi a6, a6, 4
147 blt a6, a7, 3b
148
149 movi a5, -16
150 movi a1, _stack + STACK_SIZE
151 and a1, a1, a5
152
153 /* Uncompress the kernel */
154
155 # a0: load address
156 # a2: boot parameter
157 # a4: __start
158
159 movi a3, __image_load
160 sub a4, a3, a4
161 add a8, a0, a4
162
163 # a1 Stack
164 # a8(a4) Load address of the image
165
166 movi a6, _image_start
167 movi a10, _image_end
168 movi a7, 0x1000000
169 sub a11, a10, a6
170 movi a9, complen
171 s32i a11, a9, 0
172
173 movi a0, 0
174
175 # a6 destination
176 # a7 maximum size of destination
177 # a8 source
178 # a9 ptr to length
179
180 .extern gunzip
181 movi a4, gunzip
182 beqz a4, 1f
183
184 callx4 a4
185
186 j 2f
187
188
189 # a6 destination start
190 # a7 maximum size of destination
191 # a8 source start
192 # a9 ptr to length
193 # a10 destination end
194
1951:
196 l32i a9, a8, 0
197 l32i a11, a8, 4
198 s32i a9, a6, 0
199 s32i a11, a6, 4
200 l32i a9, a8, 8
201 l32i a11, a8, 12
202 s32i a9, a6, 8
203 s32i a11, a6, 12
204 addi a6, a6, 16
205 addi a8, a8, 16
206 blt a6, a10, 1b
207
208
209 /* jump to the kernel */
2102:
211#if XCHAL_DCACHE_IS_WRITEBACK
212 dcache_writeback_all a5, a6
213#endif
214 icache_invalidate_all a5, a6
215
216 movi a5, __start
217 movi a3, boot_initrd_start
218 movi a4, boot_initrd_end
219 sub a3, a3, a5
220 sub a4, a4, a5
221 add a3, a0, a3
222 add a4, a0, a4
223
224 # a2 Boot parameter list
225 # a3 initrd_start (virtual load address)
226 # a4 initrd_end (virtual load address)
227
228 movi a0, _image_start
229 jx a0
230
231 .align 16
232 .data
233 .globl avail_ram
234avail_ram:
235 .long _heap
236 .globl end_avail
237end_avail:
238 .long _heap + HEAP_SIZE
239
240 .comm _stack, STACK_SIZE
241 .comm _heap, HEAP_SIZE
242
243 .globl end_avail
244 .comm complen, 4
245
246 .end literal_prefix