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
247