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