2 * (C) Copyright 2011-2012
3 * Pali Rohár <pali.rohar@gmail.com>
5 * See file CREDITS for list of people who contributed to this
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License as
10 * published by the Free Software Foundation; either version 2 of
11 * the License, or (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
26 relocaddr: /* address of this relocaddr section after coping */
27 .word . /* address of section (calculated at compile time) */
29 startaddr: /* address of u-boot after copying */
30 .word CONFIG_SYS_TEXT_BASE
32 kernaddr: /* address of kernel after copying */
35 kernsize: /* maximal size of kernel image */
38 kernoffs: /* offset of kernel image in loaded u-boot */
41 imagesize: /* maximal size of image */
44 ih_magic: /* IH_MAGIC in big endian from include/image.h */
48 * Routine: save_boot_params (called after reset from start.S)
49 * Description: Copy attached kernel to address KERNEL_ADDRESS
50 * Copy u-boot to address CONFIG_SYS_TEXT_BASE
51 * Return to copied u-boot address
54 .global save_boot_params
58 /* Copy valid attached kernel to address KERNEL_ADDRESS */
61 adr r0, relocaddr /* r0 - address of section relocaddr */
62 ldr r1, relocaddr /* r1 - address of relocaddr after relocation */
65 /* r4 - calculated offset */
69 /* r0 - start of kernel before */
76 /* r3 - start of kernel after */
79 /* r2 - end of kernel after */
83 /* r1 - end of kernel before */
86 /* remove header in target kernel */
90 /* check for valid kernel uImage */
91 ldr r4, [r0] /* r4 - 4 bytes header of kernel */
92 ldr r5, ih_magic /* r5 - IH_MAGIC */
94 bne copy_kernel_end /* skip if invalid image */
104 str r5, [r0] /* remove 4 bytes header of kernel */
107 /* Fix u-boot code */
110 adr r0, relocaddr /* r0 - address of section relocaddr */
111 ldr r1, relocaddr /* r1 - address of relocaddr after relocation */
114 beq copy_uboot_end /* skip if u-boot is on correct address */
116 /* r5 - calculated offset */
120 /* r6 - maximal u-boot size */
123 /* fix return address */
127 /* r1 - start of u-boot after */
130 /* r0 - start of u-boot before */
134 /* check if we need to move uboot copy code before calling it */
136 bhi copy_uboot_start /* now coping u-boot code directly is safe */
140 /* r0 - start of u-boot before */
141 /* r1 - start of u-boot after */
142 /* r6 - maximal u-boot size */
144 /* r7 - maximal kernel size */
147 /* r4 - end of kernel before */
151 /* r5 - end of u-boot after */
155 /* r2 - start of loop code after */
156 cmp r4, r5 /* higher address (r4 or r5) */
160 /* r3 - end of loop code before */
163 /* r4 - end of loop code after */
164 adr r4, copy_uboot_start
169 ldmdb r3!, {r7 - r10}
170 stmdb r4!, {r7 - r10}
178 /* Copy u-boot to address CONFIG_SYS_TEXT_BASE */
181 /* r0 - start of u-boot before */
182 /* r1 - start of u-boot after */
183 /* r6 - maximal u-boot size */
185 /* r2 - end of u-boot after */
188 /* condition for copying from left to right */
190 addlo r1, r0, r6 /* r1 - end of u-boot before */
191 blo copy_uboot_loop_right
193 copy_uboot_loop_left:
194 ldmia r0!, {r3 - r10}
195 stmia r1!, {r3 - r10}
197 blo copy_uboot_loop_left
200 copy_uboot_loop_right:
201 ldmdb r1!, {r3 - r10}
202 stmdb r2!, {r3 - r10}
204 bhi copy_uboot_loop_right