1*83d290c5STom Rini/* SPDX-License-Identifier: GPL-2.0+ */
2ed407be5SPali Rohár/*
3ed407be5SPali Rohár * (C) Copyright 2011-2012
4ed407be5SPali Rohár * Pali Rohár <pali.rohar@gmail.com>
5ed407be5SPali Rohár */
6ed407be5SPali Rohár
7ed407be5SPali Rohár#include <config.h>
8ed407be5SPali Rohár
9ed407be5SPali Rohárrelocaddr:		/* address of this relocaddr section after coping */
10ed407be5SPali Rohár	.word .		/* address of section (calculated at compile time) */
11ed407be5SPali Rohár
12ed407be5SPali Rohárstartaddr:		/* address of u-boot after copying */
13ed407be5SPali Rohár	.word CONFIG_SYS_TEXT_BASE
14ed407be5SPali Rohár
15ed407be5SPali Rohárkernaddr:		/* address of kernel after copying */
16ed407be5SPali Rohár	.word KERNEL_ADDRESS
17ed407be5SPali Rohár
18ed407be5SPali Rohárkernsize:		/* maximal size of kernel image */
19ed407be5SPali Rohár	.word KERNEL_MAXSIZE
20ed407be5SPali Rohár
21ed407be5SPali Rohárkernoffs:		/* offset of kernel image in loaded u-boot */
22ed407be5SPali Rohár	.word KERNEL_OFFSET
23ed407be5SPali Rohár
24ed407be5SPali Rohárimagesize:		/* maximal size of image */
25ed407be5SPali Rohár	.word IMAGE_MAXSIZE
26ed407be5SPali Rohár
27ed407be5SPali Rohárih_magic:		/* IH_MAGIC in big endian from include/image.h */
28ed407be5SPali Rohár	.word 0x56190527
29ed407be5SPali Rohár
30ed407be5SPali Rohár/*
31ed407be5SPali Rohár * Routine: save_boot_params (called after reset from start.S)
32ed407be5SPali Rohár * Description: Copy attached kernel to address KERNEL_ADDRESS
33ed407be5SPali Rohár *              Copy u-boot to address CONFIG_SYS_TEXT_BASE
34ed407be5SPali Rohár *              Return to copied u-boot address
35ed407be5SPali Rohár */
36ed407be5SPali Rohár
37ed407be5SPali Rohár.global save_boot_params
38ed407be5SPali Rohársave_boot_params:
39e11c6c27SSimon Glass	/* Get return address */
40e11c6c27SSimon Glass	ldr	lr, =save_boot_params_ret
41ed407be5SPali Rohár
42ed407be5SPali Rohár/* Copy valid attached kernel to address KERNEL_ADDRESS */
43ed407be5SPali Rohár
44ed407be5SPali Rohárcopy_kernel_start:
45ed407be5SPali Rohár	adr	r0, relocaddr	/* r0 - address of section relocaddr */
46ed407be5SPali Rohár	ldr	r1, relocaddr	/* r1 - address of relocaddr after relocation */
47ed407be5SPali Rohár	cmp	r0, r1
48ed407be5SPali Rohár
49ed407be5SPali Rohár	/* r4 - calculated offset */
50ed407be5SPali Rohár	subhi	r4, r0, r1
51ed407be5SPali Rohár	sublo	r4, r1, r0
52ed407be5SPali Rohár
53ed407be5SPali Rohár	/* r0 - start of kernel before */
54ed407be5SPali Rohár	ldr	r0, startaddr
55ed407be5SPali Rohár	addhi	r0, r0, r4
56ed407be5SPali Rohár	sublo	r0, r0, r4
57ed407be5SPali Rohár	ldr	r1, kernoffs
58ed407be5SPali Rohár	add	r0, r0, r1
59ed407be5SPali Rohár
60ed407be5SPali Rohár	/* r3 - start of kernel after */
61ed407be5SPali Rohár	ldr	r3, kernaddr
62ed407be5SPali Rohár
63ed407be5SPali Rohár	/* r2 - end of kernel after */
64ed407be5SPali Rohár	ldr	r1, kernsize
65ed407be5SPali Rohár	add	r2, r3, r1
66ed407be5SPali Rohár
67ed407be5SPali Rohár	/* r1 - end of kernel before */
68ed407be5SPali Rohár	add	r1, r0, r1
69ed407be5SPali Rohár
70ed407be5SPali Rohár	/* remove header in target kernel */
71ed407be5SPali Rohár	mov	r5, #0
72ed407be5SPali Rohár	str	r5, [r3]
73ed407be5SPali Rohár
74ed407be5SPali Rohár	/* check for valid kernel uImage */
75ed407be5SPali Rohár	ldr	r4, [r0]	/* r4 - 4 bytes header of kernel */
76ed407be5SPali Rohár	ldr	r5, ih_magic	/* r5 - IH_MAGIC */
77ed407be5SPali Rohár	cmp	r4, r5
78ed407be5SPali Rohár	bne	copy_kernel_end	/* skip if invalid image */
79ed407be5SPali Rohár
80ed407be5SPali Rohárcopy_kernel_loop:
81ed407be5SPali Rohár	ldmdb	r1!, {r3 - r10}
82ed407be5SPali Rohár	stmdb	r2!, {r3 - r10}
83ed407be5SPali Rohár	cmp	r1, r0
84ed407be5SPali Rohár	bhi	copy_kernel_loop
85ed407be5SPali Rohár
86ed407be5SPali Rohárcopy_kernel_end:
87ed407be5SPali Rohár	mov	r5, #0
88ed407be5SPali Rohár	str	r5, [r0]	/* remove 4 bytes header of kernel */
89ed407be5SPali Rohár
90ed407be5SPali Rohár
91ed407be5SPali Rohár/* Fix u-boot code */
92ed407be5SPali Rohár
93ed407be5SPali Rohárfix_start:
94ed407be5SPali Rohár	adr	r0, relocaddr	/* r0 - address of section relocaddr */
95ed407be5SPali Rohár	ldr	r1, relocaddr	/* r1 - address of relocaddr after relocation */
96ed407be5SPali Rohár	cmp	r0, r1
97ed407be5SPali Rohár
98ed407be5SPali Rohár	beq	copy_uboot_end	/* skip if u-boot is on correct address */
99ed407be5SPali Rohár
100ed407be5SPali Rohár	/* r5 - calculated offset */
101ed407be5SPali Rohár	subhi	r5, r0, r1
102ed407be5SPali Rohár	sublo	r5, r1, r0
103ed407be5SPali Rohár
104ed407be5SPali Rohár	/* r6 - maximal u-boot size */
105ed407be5SPali Rohár	ldr	r6, imagesize
106ed407be5SPali Rohár
107ed407be5SPali Rohár	/* r1 - start of u-boot after */
108ed407be5SPali Rohár	ldr	r1, startaddr
109ed407be5SPali Rohár
110ed407be5SPali Rohár	/* r0 - start of u-boot before */
111ed407be5SPali Rohár	addhi	r0, r1, r5
112ed407be5SPali Rohár	sublo	r0, r1, r5
113ed407be5SPali Rohár
114ed407be5SPali Rohár	/* check if we need to move uboot copy code before calling it */
115ed407be5SPali Rohár	cmp	r5, r6
116ed407be5SPali Rohár	bhi	copy_uboot_start /* now coping u-boot code directly is safe */
117ed407be5SPali Rohár
118ed407be5SPali Rohár
119ed407be5SPali Rohárcopy_code_start:
120ed407be5SPali Rohár	/* r0 - start of u-boot before */
121ed407be5SPali Rohár	/* r1 - start of u-boot after */
122ed407be5SPali Rohár	/* r6 - maximal u-boot size */
123ed407be5SPali Rohár
124ed407be5SPali Rohár	/* r7 - maximal kernel size */
125ed407be5SPali Rohár	ldr	r7, kernsize
126ed407be5SPali Rohár
127ed407be5SPali Rohár	/* r4 - end of kernel before */
128ed407be5SPali Rohár	add	r4, r0, r6
129ed407be5SPali Rohár	add	r4, r4, r7
130ed407be5SPali Rohár
131ed407be5SPali Rohár	/* r5 - end of u-boot after */
132ed407be5SPali Rohár	ldr	r5, startaddr
133ed407be5SPali Rohár	add	r5, r5, r6
134ed407be5SPali Rohár
135ed407be5SPali Rohár	/* r2 - start of loop code after */
136ed407be5SPali Rohár	cmp	r4, r5		/* higher address (r4 or r5) */
137ed407be5SPali Rohár	movhs	r2, r4
138ed407be5SPali Rohár	movlo	r2, r5
139ed407be5SPali Rohár
140ed407be5SPali Rohár	/* r3 - end of loop code before */
141ed407be5SPali Rohár	adr	r3, end
142ed407be5SPali Rohár
143ed407be5SPali Rohár	/* r4 - end of loop code after */
144ed407be5SPali Rohár	adr	r4, copy_uboot_start
145ed407be5SPali Rohár	sub	r4, r3, r4
146ed407be5SPali Rohár	add	r4, r2, r4
147ed407be5SPali Rohár
148ed407be5SPali Rohárcopy_code_loop:
149ed407be5SPali Rohár	ldmdb	r3!, {r7 - r10}
150ed407be5SPali Rohár	stmdb	r4!, {r7 - r10}
151ed407be5SPali Rohár	cmp	r4, r2
152ed407be5SPali Rohár	bhi	copy_code_loop
153ed407be5SPali Rohár
154ed407be5SPali Rohárcopy_code_end:
155ed407be5SPali Rohár	mov	pc, r2
156ed407be5SPali Rohár
157ed407be5SPali Rohár
158ed407be5SPali Rohár/* Copy u-boot to address CONFIG_SYS_TEXT_BASE */
159ed407be5SPali Rohár
160ed407be5SPali Rohárcopy_uboot_start:
161ed407be5SPali Rohár	/* r0 - start of u-boot before */
162ed407be5SPali Rohár	/* r1 - start of u-boot after */
163ed407be5SPali Rohár	/* r6 - maximal u-boot size */
164ed407be5SPali Rohár
165ed407be5SPali Rohár	/* r2 - end of u-boot after */
166ed407be5SPali Rohár	add	r2, r1, r6
167ed407be5SPali Rohár
168ed407be5SPali Rohár	/* condition for copying from left to right */
169ed407be5SPali Rohár	cmp	r0, r1
170ed407be5SPali Rohár	addlo	r1, r0, r6	/* r1 - end of u-boot before */
171ed407be5SPali Rohár	blo	copy_uboot_loop_right
172ed407be5SPali Rohár
173ed407be5SPali Rohárcopy_uboot_loop_left:
174ed407be5SPali Rohár	ldmia	r0!, {r3 - r10}
175ed407be5SPali Rohár	stmia	r1!, {r3 - r10}
176ed407be5SPali Rohár	cmp	r1, r2
177ed407be5SPali Rohár	blo	copy_uboot_loop_left
178ed407be5SPali Rohár	b	copy_uboot_end
179ed407be5SPali Rohár
180ed407be5SPali Rohárcopy_uboot_loop_right:
181ed407be5SPali Rohár	ldmdb	r1!, {r3 - r10}
182ed407be5SPali Rohár	stmdb	r2!, {r3 - r10}
183ed407be5SPali Rohár	cmp	r1, r0
184ed407be5SPali Rohár	bhi	copy_uboot_loop_right
185ed407be5SPali Rohár
186ed407be5SPali Rohárcopy_uboot_end:
187ed407be5SPali Rohár	bx	lr
188ed407be5SPali Rohár
189ed407be5SPali Rohárend:
190