1#include <variant/core.h>
2#include <asm/regs.h>
3#include <asm/asmmacro.h>
4#include <asm/cacheasm.h>
5	/*
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
54	wsr	a4, ps
55	rsync
56
57	rsr	a5, windowbase
58	ssl	a5
59	sll	a4, a4
60	wsr	a4, windowstart
61	rsync
62
63	movi	a4, 0x00040000
64	wsr	a4, ps
65	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
78	# 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
86	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
113
114	___flush_dcache_all a5 a6
115
116#endif
117
118	___invalidate_icache_all a5 a6
119	isync
120
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
220
221	___flush_dcache_all a5 a6
222
223#endif
224
225	___invalidate_icache_all a5 a6
226
227	isync
228
229	# a2  Boot parameter list
230
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
250