blob: 9d4ea1b3f90e68d2670b914bd2f4e82180970f9a [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:
Simon Glass47197fe2015-02-07 10:47:28 -070040 /* Get return address */
41 ldr lr, =save_boot_params_ret
Pali Rohár248ef0a2012-10-29 07:54:01 +000042
43/* Copy valid attached kernel to address KERNEL_ADDRESS */
44
45copy_kernel_start:
46 adr r0, relocaddr /* r0 - address of section relocaddr */
47 ldr r1, relocaddr /* r1 - address of relocaddr after relocation */
48 cmp r0, r1
49
50 /* r4 - calculated offset */
51 subhi r4, r0, r1
52 sublo r4, r1, r0
53
54 /* r0 - start of kernel before */
55 ldr r0, startaddr
56 addhi r0, r0, r4
57 sublo r0, r0, r4
58 ldr r1, kernoffs
59 add r0, r0, r1
60
61 /* r3 - start of kernel after */
62 ldr r3, kernaddr
63
64 /* r2 - end of kernel after */
65 ldr r1, kernsize
66 add r2, r3, r1
67
68 /* r1 - end of kernel before */
69 add r1, r0, r1
70
71 /* remove header in target kernel */
72 mov r5, #0
73 str r5, [r3]
74
75 /* check for valid kernel uImage */
76 ldr r4, [r0] /* r4 - 4 bytes header of kernel */
77 ldr r5, ih_magic /* r5 - IH_MAGIC */
78 cmp r4, r5
79 bne copy_kernel_end /* skip if invalid image */
80
81copy_kernel_loop:
82 ldmdb r1!, {r3 - r10}
83 stmdb r2!, {r3 - r10}
84 cmp r1, r0
85 bhi copy_kernel_loop
86
87copy_kernel_end:
88 mov r5, #0
89 str r5, [r0] /* remove 4 bytes header of kernel */
90
91
92/* Fix u-boot code */
93
94fix_start:
95 adr r0, relocaddr /* r0 - address of section relocaddr */
96 ldr r1, relocaddr /* r1 - address of relocaddr after relocation */
97 cmp r0, r1
98
99 beq copy_uboot_end /* skip if u-boot is on correct address */
100
101 /* r5 - calculated offset */
102 subhi r5, r0, r1
103 sublo r5, r1, r0
104
105 /* r6 - maximal u-boot size */
106 ldr r6, imagesize
107
108 /* fix return address */
109 subhi lr, lr, r5
110 addlo lr, lr, r5
111
112 /* r1 - start of u-boot after */
113 ldr r1, startaddr
114
115 /* r0 - start of u-boot before */
116 addhi r0, r1, r5
117 sublo r0, r1, r5
118
119 /* check if we need to move uboot copy code before calling it */
120 cmp r5, r6
121 bhi copy_uboot_start /* now coping u-boot code directly is safe */
122
123
124copy_code_start:
125 /* r0 - start of u-boot before */
126 /* r1 - start of u-boot after */
127 /* r6 - maximal u-boot size */
128
129 /* r7 - maximal kernel size */
130 ldr r7, kernsize
131
132 /* r4 - end of kernel before */
133 add r4, r0, r6
134 add r4, r4, r7
135
136 /* r5 - end of u-boot after */
137 ldr r5, startaddr
138 add r5, r5, r6
139
140 /* r2 - start of loop code after */
141 cmp r4, r5 /* higher address (r4 or r5) */
142 movhs r2, r4
143 movlo r2, r5
144
145 /* r3 - end of loop code before */
146 adr r3, end
147
148 /* r4 - end of loop code after */
149 adr r4, copy_uboot_start
150 sub r4, r3, r4
151 add r4, r2, r4
152
153copy_code_loop:
154 ldmdb r3!, {r7 - r10}
155 stmdb r4!, {r7 - r10}
156 cmp r4, r2
157 bhi copy_code_loop
158
159copy_code_end:
160 mov pc, r2
161
162
163/* Copy u-boot to address CONFIG_SYS_TEXT_BASE */
164
165copy_uboot_start:
166 /* r0 - start of u-boot before */
167 /* r1 - start of u-boot after */
168 /* r6 - maximal u-boot size */
169
170 /* r2 - end of u-boot after */
171 add r2, r1, r6
172
173 /* condition for copying from left to right */
174 cmp r0, r1
175 addlo r1, r0, r6 /* r1 - end of u-boot before */
176 blo copy_uboot_loop_right
177
178copy_uboot_loop_left:
179 ldmia r0!, {r3 - r10}
180 stmia r1!, {r3 - r10}
181 cmp r1, r2
182 blo copy_uboot_loop_left
183 b copy_uboot_end
184
185copy_uboot_loop_right:
186 ldmdb r1!, {r3 - r10}
187 stmdb r2!, {r3 - r10}
188 cmp r1, r0
189 bhi copy_uboot_loop_right
190
191copy_uboot_end:
192 bx lr
193
194end: