1*ed407be5SPali Rohár/* 2*ed407be5SPali Rohár * (C) Copyright 2011-2012 3*ed407be5SPali Rohár * Pali Rohár <pali.rohar@gmail.com> 4*ed407be5SPali Rohár * 5*ed407be5SPali Rohár * See file CREDITS for list of people who contributed to this 6*ed407be5SPali Rohár * project. 7*ed407be5SPali Rohár * 8*ed407be5SPali Rohár * This program is free software; you can redistribute it and/or 9*ed407be5SPali Rohár * modify it under the terms of the GNU General Public License as 10*ed407be5SPali Rohár * published by the Free Software Foundation; either version 2 of 11*ed407be5SPali Rohár * the License, or (at your option) any later version. 12*ed407be5SPali Rohár * 13*ed407be5SPali Rohár * This program is distributed in the hope that it will be useful, 14*ed407be5SPali Rohár * but WITHOUT ANY WARRANTY; without even the implied warranty of 15*ed407be5SPali Rohár * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16*ed407be5SPali Rohár * GNU General Public License for more details. 17*ed407be5SPali Rohár * 18*ed407be5SPali Rohár * You should have received a copy of the GNU General Public License 19*ed407be5SPali Rohár * along with this program; if not, write to the Free Software 20*ed407be5SPali Rohár * Foundation, Inc., 59 Temple Place, Suite 330, Boston, 21*ed407be5SPali Rohár * MA 02111-1307 USA 22*ed407be5SPali Rohár */ 23*ed407be5SPali Rohár 24*ed407be5SPali Rohár#include <config.h> 25*ed407be5SPali Rohár 26*ed407be5SPali Rohárrelocaddr: /* address of this relocaddr section after coping */ 27*ed407be5SPali Rohár .word . /* address of section (calculated at compile time) */ 28*ed407be5SPali Rohár 29*ed407be5SPali Rohárstartaddr: /* address of u-boot after copying */ 30*ed407be5SPali Rohár .word CONFIG_SYS_TEXT_BASE 31*ed407be5SPali Rohár 32*ed407be5SPali Rohárkernaddr: /* address of kernel after copying */ 33*ed407be5SPali Rohár .word KERNEL_ADDRESS 34*ed407be5SPali Rohár 35*ed407be5SPali Rohárkernsize: /* maximal size of kernel image */ 36*ed407be5SPali Rohár .word KERNEL_MAXSIZE 37*ed407be5SPali Rohár 38*ed407be5SPali Rohárkernoffs: /* offset of kernel image in loaded u-boot */ 39*ed407be5SPali Rohár .word KERNEL_OFFSET 40*ed407be5SPali Rohár 41*ed407be5SPali Rohárimagesize: /* maximal size of image */ 42*ed407be5SPali Rohár .word IMAGE_MAXSIZE 43*ed407be5SPali Rohár 44*ed407be5SPali Rohárih_magic: /* IH_MAGIC in big endian from include/image.h */ 45*ed407be5SPali Rohár .word 0x56190527 46*ed407be5SPali Rohár 47*ed407be5SPali Rohár/* 48*ed407be5SPali Rohár * Routine: save_boot_params (called after reset from start.S) 49*ed407be5SPali Rohár * Description: Copy attached kernel to address KERNEL_ADDRESS 50*ed407be5SPali Rohár * Copy u-boot to address CONFIG_SYS_TEXT_BASE 51*ed407be5SPali Rohár * Return to copied u-boot address 52*ed407be5SPali Rohár */ 53*ed407be5SPali Rohár 54*ed407be5SPali Rohár.global save_boot_params 55*ed407be5SPali Rohársave_boot_params: 56*ed407be5SPali Rohár 57*ed407be5SPali Rohár 58*ed407be5SPali Rohár/* Copy valid attached kernel to address KERNEL_ADDRESS */ 59*ed407be5SPali Rohár 60*ed407be5SPali Rohárcopy_kernel_start: 61*ed407be5SPali Rohár adr r0, relocaddr /* r0 - address of section relocaddr */ 62*ed407be5SPali Rohár ldr r1, relocaddr /* r1 - address of relocaddr after relocation */ 63*ed407be5SPali Rohár cmp r0, r1 64*ed407be5SPali Rohár 65*ed407be5SPali Rohár /* r4 - calculated offset */ 66*ed407be5SPali Rohár subhi r4, r0, r1 67*ed407be5SPali Rohár sublo r4, r1, r0 68*ed407be5SPali Rohár 69*ed407be5SPali Rohár /* r0 - start of kernel before */ 70*ed407be5SPali Rohár ldr r0, startaddr 71*ed407be5SPali Rohár addhi r0, r0, r4 72*ed407be5SPali Rohár sublo r0, r0, r4 73*ed407be5SPali Rohár ldr r1, kernoffs 74*ed407be5SPali Rohár add r0, r0, r1 75*ed407be5SPali Rohár 76*ed407be5SPali Rohár /* r3 - start of kernel after */ 77*ed407be5SPali Rohár ldr r3, kernaddr 78*ed407be5SPali Rohár 79*ed407be5SPali Rohár /* r2 - end of kernel after */ 80*ed407be5SPali Rohár ldr r1, kernsize 81*ed407be5SPali Rohár add r2, r3, r1 82*ed407be5SPali Rohár 83*ed407be5SPali Rohár /* r1 - end of kernel before */ 84*ed407be5SPali Rohár add r1, r0, r1 85*ed407be5SPali Rohár 86*ed407be5SPali Rohár /* remove header in target kernel */ 87*ed407be5SPali Rohár mov r5, #0 88*ed407be5SPali Rohár str r5, [r3] 89*ed407be5SPali Rohár 90*ed407be5SPali Rohár /* check for valid kernel uImage */ 91*ed407be5SPali Rohár ldr r4, [r0] /* r4 - 4 bytes header of kernel */ 92*ed407be5SPali Rohár ldr r5, ih_magic /* r5 - IH_MAGIC */ 93*ed407be5SPali Rohár cmp r4, r5 94*ed407be5SPali Rohár bne copy_kernel_end /* skip if invalid image */ 95*ed407be5SPali Rohár 96*ed407be5SPali Rohárcopy_kernel_loop: 97*ed407be5SPali Rohár ldmdb r1!, {r3 - r10} 98*ed407be5SPali Rohár stmdb r2!, {r3 - r10} 99*ed407be5SPali Rohár cmp r1, r0 100*ed407be5SPali Rohár bhi copy_kernel_loop 101*ed407be5SPali Rohár 102*ed407be5SPali Rohárcopy_kernel_end: 103*ed407be5SPali Rohár mov r5, #0 104*ed407be5SPali Rohár str r5, [r0] /* remove 4 bytes header of kernel */ 105*ed407be5SPali Rohár 106*ed407be5SPali Rohár 107*ed407be5SPali Rohár/* Fix u-boot code */ 108*ed407be5SPali Rohár 109*ed407be5SPali Rohárfix_start: 110*ed407be5SPali Rohár adr r0, relocaddr /* r0 - address of section relocaddr */ 111*ed407be5SPali Rohár ldr r1, relocaddr /* r1 - address of relocaddr after relocation */ 112*ed407be5SPali Rohár cmp r0, r1 113*ed407be5SPali Rohár 114*ed407be5SPali Rohár beq copy_uboot_end /* skip if u-boot is on correct address */ 115*ed407be5SPali Rohár 116*ed407be5SPali Rohár /* r5 - calculated offset */ 117*ed407be5SPali Rohár subhi r5, r0, r1 118*ed407be5SPali Rohár sublo r5, r1, r0 119*ed407be5SPali Rohár 120*ed407be5SPali Rohár /* r6 - maximal u-boot size */ 121*ed407be5SPali Rohár ldr r6, imagesize 122*ed407be5SPali Rohár 123*ed407be5SPali Rohár /* fix return address */ 124*ed407be5SPali Rohár subhi lr, lr, r5 125*ed407be5SPali Rohár addlo lr, lr, r5 126*ed407be5SPali Rohár 127*ed407be5SPali Rohár /* r1 - start of u-boot after */ 128*ed407be5SPali Rohár ldr r1, startaddr 129*ed407be5SPali Rohár 130*ed407be5SPali Rohár /* r0 - start of u-boot before */ 131*ed407be5SPali Rohár addhi r0, r1, r5 132*ed407be5SPali Rohár sublo r0, r1, r5 133*ed407be5SPali Rohár 134*ed407be5SPali Rohár /* check if we need to move uboot copy code before calling it */ 135*ed407be5SPali Rohár cmp r5, r6 136*ed407be5SPali Rohár bhi copy_uboot_start /* now coping u-boot code directly is safe */ 137*ed407be5SPali Rohár 138*ed407be5SPali Rohár 139*ed407be5SPali Rohárcopy_code_start: 140*ed407be5SPali Rohár /* r0 - start of u-boot before */ 141*ed407be5SPali Rohár /* r1 - start of u-boot after */ 142*ed407be5SPali Rohár /* r6 - maximal u-boot size */ 143*ed407be5SPali Rohár 144*ed407be5SPali Rohár /* r7 - maximal kernel size */ 145*ed407be5SPali Rohár ldr r7, kernsize 146*ed407be5SPali Rohár 147*ed407be5SPali Rohár /* r4 - end of kernel before */ 148*ed407be5SPali Rohár add r4, r0, r6 149*ed407be5SPali Rohár add r4, r4, r7 150*ed407be5SPali Rohár 151*ed407be5SPali Rohár /* r5 - end of u-boot after */ 152*ed407be5SPali Rohár ldr r5, startaddr 153*ed407be5SPali Rohár add r5, r5, r6 154*ed407be5SPali Rohár 155*ed407be5SPali Rohár /* r2 - start of loop code after */ 156*ed407be5SPali Rohár cmp r4, r5 /* higher address (r4 or r5) */ 157*ed407be5SPali Rohár movhs r2, r4 158*ed407be5SPali Rohár movlo r2, r5 159*ed407be5SPali Rohár 160*ed407be5SPali Rohár /* r3 - end of loop code before */ 161*ed407be5SPali Rohár adr r3, end 162*ed407be5SPali Rohár 163*ed407be5SPali Rohár /* r4 - end of loop code after */ 164*ed407be5SPali Rohár adr r4, copy_uboot_start 165*ed407be5SPali Rohár sub r4, r3, r4 166*ed407be5SPali Rohár add r4, r2, r4 167*ed407be5SPali Rohár 168*ed407be5SPali Rohárcopy_code_loop: 169*ed407be5SPali Rohár ldmdb r3!, {r7 - r10} 170*ed407be5SPali Rohár stmdb r4!, {r7 - r10} 171*ed407be5SPali Rohár cmp r4, r2 172*ed407be5SPali Rohár bhi copy_code_loop 173*ed407be5SPali Rohár 174*ed407be5SPali Rohárcopy_code_end: 175*ed407be5SPali Rohár mov pc, r2 176*ed407be5SPali Rohár 177*ed407be5SPali Rohár 178*ed407be5SPali Rohár/* Copy u-boot to address CONFIG_SYS_TEXT_BASE */ 179*ed407be5SPali Rohár 180*ed407be5SPali Rohárcopy_uboot_start: 181*ed407be5SPali Rohár /* r0 - start of u-boot before */ 182*ed407be5SPali Rohár /* r1 - start of u-boot after */ 183*ed407be5SPali Rohár /* r6 - maximal u-boot size */ 184*ed407be5SPali Rohár 185*ed407be5SPali Rohár /* r2 - end of u-boot after */ 186*ed407be5SPali Rohár add r2, r1, r6 187*ed407be5SPali Rohár 188*ed407be5SPali Rohár /* condition for copying from left to right */ 189*ed407be5SPali Rohár cmp r0, r1 190*ed407be5SPali Rohár addlo r1, r0, r6 /* r1 - end of u-boot before */ 191*ed407be5SPali Rohár blo copy_uboot_loop_right 192*ed407be5SPali Rohár 193*ed407be5SPali Rohárcopy_uboot_loop_left: 194*ed407be5SPali Rohár ldmia r0!, {r3 - r10} 195*ed407be5SPali Rohár stmia r1!, {r3 - r10} 196*ed407be5SPali Rohár cmp r1, r2 197*ed407be5SPali Rohár blo copy_uboot_loop_left 198*ed407be5SPali Rohár b copy_uboot_end 199*ed407be5SPali Rohár 200*ed407be5SPali Rohárcopy_uboot_loop_right: 201*ed407be5SPali Rohár ldmdb r1!, {r3 - r10} 202*ed407be5SPali Rohár stmdb r2!, {r3 - r10} 203*ed407be5SPali Rohár cmp r1, r0 204*ed407be5SPali Rohár bhi copy_uboot_loop_right 205*ed407be5SPali Rohár 206*ed407be5SPali Rohárcopy_uboot_end: 207*ed407be5SPali Rohár bx lr 208*ed407be5SPali Rohár 209*ed407be5SPali Rohárend: 210