Linux kernel mirror (for testing)
git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel
os
linux
1/* SPDX-License-Identifier: GPL-2.0 */
2#include <asm/core.h>
3#include <asm/regs.h>
4#include <asm/asmmacro.h>
5#include <asm/cacheasm.h>
6#include <asm/processor.h>
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 abi_entry(32) # we do not intend to return
41 _call0 _start
42__start_a0:
43 .align 4
44
45 .section .text, "ax"
46 .literal_position
47 .begin literal_prefix .text
48
49 /* put literals in here! */
50
51 .globl _start
52_start:
53
54 /* 'reset' window registers */
55
56 movi a4, 1
57 wsr a4, ps
58 rsync
59#if XCHAL_HAVE_WINDOWED
60 rsr a5, windowbase
61 ssl a5
62 sll a4, a4
63 wsr a4, windowstart
64 rsync
65#endif
66 movi a4, KERNEL_PS_WOE_MASK
67 wsr a4, ps
68 rsync
69
70KABI_C0 mov abi_saved0, abi_arg0
71
72 /* copy the loader to its address
73 * Note: The loader itself is a very small piece, so we assume we
74 * don't partially overlap. We also assume (even more important)
75 * that the kernel image is out of the way. Usually, when the
76 * load address of this image is not at an arbitrary address,
77 * but aligned to some 10K's we shouldn't overlap.
78 */
79
80 /* Note: The assembler cannot relax "addi a0, a0, ..." to an
81 l32r, so we load to a4 first. */
82
83 # addi a4, a0, __start - __start_a0
84 # mov a0, a4
85
86 movi a4, __start
87 movi a5, __start_a0
88 add a4, a0, a4
89 sub a0, a4, a5
90
91 movi a4, __start
92 movi a5, __reloc_end
93
94 # a0: address where this code has been loaded
95 # a4: compiled address of __start
96 # a5: compiled end address
97
98 mov.n a7, a0
99 mov.n a8, a4
100
1011:
102 l32i a10, a7, 0
103 l32i a11, a7, 4
104 s32i a10, a8, 0
105 s32i a11, a8, 4
106 l32i a10, a7, 8
107 l32i a11, a7, 12
108 s32i a10, a8, 8
109 s32i a11, a8, 12
110 addi a8, a8, 16
111 addi a7, a7, 16
112 blt a8, a5, 1b
113
114
115 /* We have to flush and invalidate the caches here before we jump. */
116
117#if XCHAL_DCACHE_IS_WRITEBACK
118
119 ___flush_dcache_all a5 a6
120
121#endif
122
123 ___invalidate_icache_all a5 a6
124 isync
125
126 movi a11, _reloc
127 jx a11
128
129 .globl _reloc
130_reloc:
131
132 /* RedBoot is now at the end of the memory, so we don't have
133 * to copy the parameter list. Keep the code around; in case
134 * we need it again. */
135#if 0
136 # a0: load address
137 # a2: start address of parameter list
138 # a3: length of parameter list
139 # a4: __start
140
141 /* copy the parameter list out of the way */
142
143 movi a6, _param_start
144 add a3, a2, a3
1452:
146 l32i a8, a2, 0
147 s32i a8, a6, 0
148 addi a2, a2, 4
149 addi a6, a6, 4
150 blt a2, a3, 2b
151#endif
152
153 /* clear BSS section */
154 movi a6, __bss_start
155 movi a7, __bss_end
156 movi.n a5, 0
1573:
158 s32i a5, a6, 0
159 addi a6, a6, 4
160 blt a6, a7, 3b
161
162 movi a5, -16
163 movi a1, _stack + STACK_SIZE
164 and a1, a1, a5
165
166 /* Uncompress the kernel */
167
168 # a0: load address
169 # a2: boot parameter
170 # a4: __start
171
172 movi a3, __image_load
173 sub a4, a3, a4
174 add abi_arg2, a0, a4
175
176 # a1 Stack
177 # a8(a4) Load address of the image
178
179 movi abi_arg0, _image_start
180 movi abi_arg4, _image_end
181 movi abi_arg1, 0x1000000
182 sub abi_tmp0, abi_arg4, abi_arg0
183 movi abi_arg3, complen
184 s32i abi_tmp0, abi_arg3, 0
185
186 movi a0, 0
187
188 # abi_arg0 destination
189 # abi_arg1 maximum size of destination
190 # abi_arg2 source
191 # abi_arg3 ptr to length
192
193 .extern gunzip
194 movi abi_tmp0, gunzip
195 beqz abi_tmp0, 1f
196
197 abi_callx abi_tmp0
198
199 j 2f
200
201
202 # abi_arg0 destination start
203 # abi_arg1 maximum size of destination
204 # abi_arg2 source start
205 # abi_arg3 ptr to length
206 # abi_arg4 destination end
207
2081:
209 l32i abi_tmp0, abi_arg2, 0
210 l32i abi_tmp1, abi_arg2, 4
211 s32i abi_tmp0, abi_arg0, 0
212 s32i abi_tmp1, abi_arg0, 4
213 l32i abi_tmp0, abi_arg2, 8
214 l32i abi_tmp1, abi_arg2, 12
215 s32i abi_tmp0, abi_arg0, 8
216 s32i abi_tmp1, abi_arg0, 12
217 addi abi_arg0, abi_arg0, 16
218 addi abi_arg2, abi_arg2, 16
219 blt abi_arg0, abi_arg4, 1b
220
221
222 /* jump to the kernel */
2232:
224#if XCHAL_DCACHE_IS_WRITEBACK
225
226 ___flush_dcache_all a5 a6
227
228#endif
229
230 ___invalidate_icache_all a5 a6
231
232 isync
233
234 # a2 Boot parameter list
235
236KABI_C0 mov abi_arg0, abi_saved0
237 movi a0, _image_start
238 jx a0
239
240 .align 16
241 .data
242 .globl avail_ram
243avail_ram:
244 .long _heap
245 .globl end_avail
246end_avail:
247 .long _heap + HEAP_SIZE
248
249 .comm _stack, STACK_SIZE
250 .comm _heap, HEAP_SIZE
251
252 .globl end_avail
253 .comm complen, 4
254
255 .end literal_prefix