blob: 6871a5a74f5d2ce122eb1e048804a13ee17aadc5 [file] [log] [blame]
Tom Rini83d290c2018-05-06 17:58:06 -04001/* SPDX-License-Identifier: GPL-2.0+ */
Pali Roháred407be2012-10-29 07:54:01 +00002/*
3 * (C) Copyright 2011-2012
4 * Pali Rohár <pali.rohar@gmail.com>
Pali Roháred407be2012-10-29 07:54:01 +00005 */
6
7#include <config.h>
8
9relocaddr: /* address of this relocaddr section after coping */
10 .word . /* address of section (calculated at compile time) */
11
12startaddr: /* address of u-boot after copying */
13 .word CONFIG_SYS_TEXT_BASE
14
15kernaddr: /* address of kernel after copying */
16 .word KERNEL_ADDRESS
17
18kernsize: /* maximal size of kernel image */
19 .word KERNEL_MAXSIZE
20
21kernoffs: /* offset of kernel image in loaded u-boot */
22 .word KERNEL_OFFSET
23
24imagesize: /* maximal size of image */
25 .word IMAGE_MAXSIZE
26
27ih_magic: /* IH_MAGIC in big endian from include/image.h */
28 .word 0x56190527
29
30/*
31 * Routine: save_boot_params (called after reset from start.S)
32 * Description: Copy attached kernel to address KERNEL_ADDRESS
33 * Copy u-boot to address CONFIG_SYS_TEXT_BASE
34 * Return to copied u-boot address
35 */
36
37.global save_boot_params
38save_boot_params:
Simon Glasse11c6c22015-02-07 10:47:28 -070039 /* Get return address */
40 ldr lr, =save_boot_params_ret
Pali Roháred407be2012-10-29 07:54:01 +000041
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
Pali Roháred407be2012-10-29 07:54:01 +0000107 /* r1 - start of u-boot after */
108 ldr r1, startaddr
109
110 /* r0 - start of u-boot before */
111 addhi r0, r1, r5
112 sublo r0, r1, r5
113
114 /* check if we need to move uboot copy code before calling it */
115 cmp r5, r6
116 bhi copy_uboot_start /* now coping u-boot code directly is safe */
117
118
119copy_code_start:
120 /* r0 - start of u-boot before */
121 /* r1 - start of u-boot after */
122 /* r6 - maximal u-boot size */
123
124 /* r7 - maximal kernel size */
125 ldr r7, kernsize
126
127 /* r4 - end of kernel before */
128 add r4, r0, r6
129 add r4, r4, r7
130
131 /* r5 - end of u-boot after */
132 ldr r5, startaddr
133 add r5, r5, r6
134
135 /* r2 - start of loop code after */
136 cmp r4, r5 /* higher address (r4 or r5) */
137 movhs r2, r4
138 movlo r2, r5
139
140 /* r3 - end of loop code before */
141 adr r3, end
142
143 /* r4 - end of loop code after */
144 adr r4, copy_uboot_start
145 sub r4, r3, r4
146 add r4, r2, r4
147
148copy_code_loop:
149 ldmdb r3!, {r7 - r10}
150 stmdb r4!, {r7 - r10}
151 cmp r4, r2
152 bhi copy_code_loop
153
154copy_code_end:
155 mov pc, r2
156
157
158/* Copy u-boot to address CONFIG_SYS_TEXT_BASE */
159
160copy_uboot_start:
161 /* r0 - start of u-boot before */
162 /* r1 - start of u-boot after */
163 /* r6 - maximal u-boot size */
164
165 /* r2 - end of u-boot after */
166 add r2, r1, r6
167
168 /* condition for copying from left to right */
169 cmp r0, r1
170 addlo r1, r0, r6 /* r1 - end of u-boot before */
171 blo copy_uboot_loop_right
172
173copy_uboot_loop_left:
174 ldmia r0!, {r3 - r10}
175 stmia r1!, {r3 - r10}
176 cmp r1, r2
177 blo copy_uboot_loop_left
178 b copy_uboot_end
179
180copy_uboot_loop_right:
181 ldmdb r1!, {r3 - r10}
182 stmdb r2!, {r3 - r10}
183 cmp r1, r0
184 bhi copy_uboot_loop_right
185
186copy_uboot_end:
187 bx lr
188
189end: