1/* 2 * (C) Copyright 2011-2012 3 * Pali Rohár <pali.rohar@gmail.com> 4 * 5 * SPDX-License-Identifier: GPL-2.0+ 6 */ 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: 194