1*ed407be5SPali Rohár/*
2*ed407be5SPali Rohár * (C) Copyright 2011-2012
3*ed407be5SPali Rohár * Pali Rohár <pali.rohar@gmail.com>
4*ed407be5SPali Rohár *
5*ed407be5SPali Rohár * See file CREDITS for list of people who contributed to this
6*ed407be5SPali Rohár * project.
7*ed407be5SPali Rohár *
8*ed407be5SPali Rohár * This program is free software; you can redistribute it and/or
9*ed407be5SPali Rohár * modify it under the terms of the GNU General Public License as
10*ed407be5SPali Rohár * published by the Free Software Foundation; either version 2 of
11*ed407be5SPali Rohár * the License, or (at your option) any later version.
12*ed407be5SPali Rohár *
13*ed407be5SPali Rohár * This program is distributed in the hope that it will be useful,
14*ed407be5SPali Rohár * but WITHOUT ANY WARRANTY; without even the implied warranty of
15*ed407be5SPali Rohár * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16*ed407be5SPali Rohár * GNU General Public License for more details.
17*ed407be5SPali Rohár *
18*ed407be5SPali Rohár * You should have received a copy of the GNU General Public License
19*ed407be5SPali Rohár * along with this program; if not, write to the Free Software
20*ed407be5SPali Rohár * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
21*ed407be5SPali Rohár * MA 02111-1307 USA
22*ed407be5SPali Rohár */
23*ed407be5SPali Rohár
24*ed407be5SPali Rohár#include <config.h>
25*ed407be5SPali Rohár
26*ed407be5SPali Rohárrelocaddr:		/* address of this relocaddr section after coping */
27*ed407be5SPali Rohár	.word .		/* address of section (calculated at compile time) */
28*ed407be5SPali Rohár
29*ed407be5SPali Rohárstartaddr:		/* address of u-boot after copying */
30*ed407be5SPali Rohár	.word CONFIG_SYS_TEXT_BASE
31*ed407be5SPali Rohár
32*ed407be5SPali Rohárkernaddr:		/* address of kernel after copying */
33*ed407be5SPali Rohár	.word KERNEL_ADDRESS
34*ed407be5SPali Rohár
35*ed407be5SPali Rohárkernsize:		/* maximal size of kernel image */
36*ed407be5SPali Rohár	.word KERNEL_MAXSIZE
37*ed407be5SPali Rohár
38*ed407be5SPali Rohárkernoffs:		/* offset of kernel image in loaded u-boot */
39*ed407be5SPali Rohár	.word KERNEL_OFFSET
40*ed407be5SPali Rohár
41*ed407be5SPali Rohárimagesize:		/* maximal size of image */
42*ed407be5SPali Rohár	.word IMAGE_MAXSIZE
43*ed407be5SPali Rohár
44*ed407be5SPali Rohárih_magic:		/* IH_MAGIC in big endian from include/image.h */
45*ed407be5SPali Rohár	.word 0x56190527
46*ed407be5SPali Rohár
47*ed407be5SPali Rohár/*
48*ed407be5SPali Rohár * Routine: save_boot_params (called after reset from start.S)
49*ed407be5SPali Rohár * Description: Copy attached kernel to address KERNEL_ADDRESS
50*ed407be5SPali Rohár *              Copy u-boot to address CONFIG_SYS_TEXT_BASE
51*ed407be5SPali Rohár *              Return to copied u-boot address
52*ed407be5SPali Rohár */
53*ed407be5SPali Rohár
54*ed407be5SPali Rohár.global save_boot_params
55*ed407be5SPali Rohársave_boot_params:
56*ed407be5SPali Rohár
57*ed407be5SPali Rohár
58*ed407be5SPali Rohár/* Copy valid attached kernel to address KERNEL_ADDRESS */
59*ed407be5SPali Rohár
60*ed407be5SPali Rohárcopy_kernel_start:
61*ed407be5SPali Rohár	adr	r0, relocaddr	/* r0 - address of section relocaddr */
62*ed407be5SPali Rohár	ldr	r1, relocaddr	/* r1 - address of relocaddr after relocation */
63*ed407be5SPali Rohár	cmp	r0, r1
64*ed407be5SPali Rohár
65*ed407be5SPali Rohár	/* r4 - calculated offset */
66*ed407be5SPali Rohár	subhi	r4, r0, r1
67*ed407be5SPali Rohár	sublo	r4, r1, r0
68*ed407be5SPali Rohár
69*ed407be5SPali Rohár	/* r0 - start of kernel before */
70*ed407be5SPali Rohár	ldr	r0, startaddr
71*ed407be5SPali Rohár	addhi	r0, r0, r4
72*ed407be5SPali Rohár	sublo	r0, r0, r4
73*ed407be5SPali Rohár	ldr	r1, kernoffs
74*ed407be5SPali Rohár	add	r0, r0, r1
75*ed407be5SPali Rohár
76*ed407be5SPali Rohár	/* r3 - start of kernel after */
77*ed407be5SPali Rohár	ldr	r3, kernaddr
78*ed407be5SPali Rohár
79*ed407be5SPali Rohár	/* r2 - end of kernel after */
80*ed407be5SPali Rohár	ldr	r1, kernsize
81*ed407be5SPali Rohár	add	r2, r3, r1
82*ed407be5SPali Rohár
83*ed407be5SPali Rohár	/* r1 - end of kernel before */
84*ed407be5SPali Rohár	add	r1, r0, r1
85*ed407be5SPali Rohár
86*ed407be5SPali Rohár	/* remove header in target kernel */
87*ed407be5SPali Rohár	mov	r5, #0
88*ed407be5SPali Rohár	str	r5, [r3]
89*ed407be5SPali Rohár
90*ed407be5SPali Rohár	/* check for valid kernel uImage */
91*ed407be5SPali Rohár	ldr	r4, [r0]	/* r4 - 4 bytes header of kernel */
92*ed407be5SPali Rohár	ldr	r5, ih_magic	/* r5 - IH_MAGIC */
93*ed407be5SPali Rohár	cmp	r4, r5
94*ed407be5SPali Rohár	bne	copy_kernel_end	/* skip if invalid image */
95*ed407be5SPali Rohár
96*ed407be5SPali Rohárcopy_kernel_loop:
97*ed407be5SPali Rohár	ldmdb	r1!, {r3 - r10}
98*ed407be5SPali Rohár	stmdb	r2!, {r3 - r10}
99*ed407be5SPali Rohár	cmp	r1, r0
100*ed407be5SPali Rohár	bhi	copy_kernel_loop
101*ed407be5SPali Rohár
102*ed407be5SPali Rohárcopy_kernel_end:
103*ed407be5SPali Rohár	mov	r5, #0
104*ed407be5SPali Rohár	str	r5, [r0]	/* remove 4 bytes header of kernel */
105*ed407be5SPali Rohár
106*ed407be5SPali Rohár
107*ed407be5SPali Rohár/* Fix u-boot code */
108*ed407be5SPali Rohár
109*ed407be5SPali Rohárfix_start:
110*ed407be5SPali Rohár	adr	r0, relocaddr	/* r0 - address of section relocaddr */
111*ed407be5SPali Rohár	ldr	r1, relocaddr	/* r1 - address of relocaddr after relocation */
112*ed407be5SPali Rohár	cmp	r0, r1
113*ed407be5SPali Rohár
114*ed407be5SPali Rohár	beq	copy_uboot_end	/* skip if u-boot is on correct address */
115*ed407be5SPali Rohár
116*ed407be5SPali Rohár	/* r5 - calculated offset */
117*ed407be5SPali Rohár	subhi	r5, r0, r1
118*ed407be5SPali Rohár	sublo	r5, r1, r0
119*ed407be5SPali Rohár
120*ed407be5SPali Rohár	/* r6 - maximal u-boot size */
121*ed407be5SPali Rohár	ldr	r6, imagesize
122*ed407be5SPali Rohár
123*ed407be5SPali Rohár	/* fix return address */
124*ed407be5SPali Rohár	subhi	lr, lr, r5
125*ed407be5SPali Rohár	addlo	lr, lr, r5
126*ed407be5SPali Rohár
127*ed407be5SPali Rohár	/* r1 - start of u-boot after */
128*ed407be5SPali Rohár	ldr	r1, startaddr
129*ed407be5SPali Rohár
130*ed407be5SPali Rohár	/* r0 - start of u-boot before */
131*ed407be5SPali Rohár	addhi	r0, r1, r5
132*ed407be5SPali Rohár	sublo	r0, r1, r5
133*ed407be5SPali Rohár
134*ed407be5SPali Rohár	/* check if we need to move uboot copy code before calling it */
135*ed407be5SPali Rohár	cmp	r5, r6
136*ed407be5SPali Rohár	bhi	copy_uboot_start /* now coping u-boot code directly is safe */
137*ed407be5SPali Rohár
138*ed407be5SPali Rohár
139*ed407be5SPali Rohárcopy_code_start:
140*ed407be5SPali Rohár	/* r0 - start of u-boot before */
141*ed407be5SPali Rohár	/* r1 - start of u-boot after */
142*ed407be5SPali Rohár	/* r6 - maximal u-boot size */
143*ed407be5SPali Rohár
144*ed407be5SPali Rohár	/* r7 - maximal kernel size */
145*ed407be5SPali Rohár	ldr	r7, kernsize
146*ed407be5SPali Rohár
147*ed407be5SPali Rohár	/* r4 - end of kernel before */
148*ed407be5SPali Rohár	add	r4, r0, r6
149*ed407be5SPali Rohár	add	r4, r4, r7
150*ed407be5SPali Rohár
151*ed407be5SPali Rohár	/* r5 - end of u-boot after */
152*ed407be5SPali Rohár	ldr	r5, startaddr
153*ed407be5SPali Rohár	add	r5, r5, r6
154*ed407be5SPali Rohár
155*ed407be5SPali Rohár	/* r2 - start of loop code after */
156*ed407be5SPali Rohár	cmp	r4, r5		/* higher address (r4 or r5) */
157*ed407be5SPali Rohár	movhs	r2, r4
158*ed407be5SPali Rohár	movlo	r2, r5
159*ed407be5SPali Rohár
160*ed407be5SPali Rohár	/* r3 - end of loop code before */
161*ed407be5SPali Rohár	adr	r3, end
162*ed407be5SPali Rohár
163*ed407be5SPali Rohár	/* r4 - end of loop code after */
164*ed407be5SPali Rohár	adr	r4, copy_uboot_start
165*ed407be5SPali Rohár	sub	r4, r3, r4
166*ed407be5SPali Rohár	add	r4, r2, r4
167*ed407be5SPali Rohár
168*ed407be5SPali Rohárcopy_code_loop:
169*ed407be5SPali Rohár	ldmdb	r3!, {r7 - r10}
170*ed407be5SPali Rohár	stmdb	r4!, {r7 - r10}
171*ed407be5SPali Rohár	cmp	r4, r2
172*ed407be5SPali Rohár	bhi	copy_code_loop
173*ed407be5SPali Rohár
174*ed407be5SPali Rohárcopy_code_end:
175*ed407be5SPali Rohár	mov	pc, r2
176*ed407be5SPali Rohár
177*ed407be5SPali Rohár
178*ed407be5SPali Rohár/* Copy u-boot to address CONFIG_SYS_TEXT_BASE */
179*ed407be5SPali Rohár
180*ed407be5SPali Rohárcopy_uboot_start:
181*ed407be5SPali Rohár	/* r0 - start of u-boot before */
182*ed407be5SPali Rohár	/* r1 - start of u-boot after */
183*ed407be5SPali Rohár	/* r6 - maximal u-boot size */
184*ed407be5SPali Rohár
185*ed407be5SPali Rohár	/* r2 - end of u-boot after */
186*ed407be5SPali Rohár	add	r2, r1, r6
187*ed407be5SPali Rohár
188*ed407be5SPali Rohár	/* condition for copying from left to right */
189*ed407be5SPali Rohár	cmp	r0, r1
190*ed407be5SPali Rohár	addlo	r1, r0, r6	/* r1 - end of u-boot before */
191*ed407be5SPali Rohár	blo	copy_uboot_loop_right
192*ed407be5SPali Rohár
193*ed407be5SPali Rohárcopy_uboot_loop_left:
194*ed407be5SPali Rohár	ldmia	r0!, {r3 - r10}
195*ed407be5SPali Rohár	stmia	r1!, {r3 - r10}
196*ed407be5SPali Rohár	cmp	r1, r2
197*ed407be5SPali Rohár	blo	copy_uboot_loop_left
198*ed407be5SPali Rohár	b	copy_uboot_end
199*ed407be5SPali Rohár
200*ed407be5SPali Rohárcopy_uboot_loop_right:
201*ed407be5SPali Rohár	ldmdb	r1!, {r3 - r10}
202*ed407be5SPali Rohár	stmdb	r2!, {r3 - r10}
203*ed407be5SPali Rohár	cmp	r1, r0
204*ed407be5SPali Rohár	bhi	copy_uboot_loop_right
205*ed407be5SPali Rohár
206*ed407be5SPali Rohárcopy_uboot_end:
207*ed407be5SPali Rohár	bx	lr
208*ed407be5SPali Rohár
209*ed407be5SPali Rohárend:
210