1 /* SPDX-License-Identifier: GPL-2.0+ */ 2 /* 3 * (C) Copyright 2011-2012 4 * Pali Rohr <pali.rohar (at) gmail.com> 5 */ 6 7 #include <config.h> 8 9 relocaddr: /* address of this relocaddr section after coping */ 10 .word . /* address of section (calculated at compile time) */ 11 12 startaddr: /* address of u-boot after copying */ 13 .word CONFIG_SYS_TEXT_BASE 14 15 kernaddr: /* address of kernel after copying */ 16 .word KERNEL_ADDRESS 17 18 kernsize: /* maximal size of kernel image */ 19 .word KERNEL_MAXSIZE 20 21 kernoffs: /* offset of kernel image in loaded u-boot */ 22 .word KERNEL_OFFSET 23 24 imagesize: /* maximal size of image */ 25 .word IMAGE_MAXSIZE 26 27 ih_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 38 save_boot_params: 39 /* Get return address */ 40 ldr lr, =save_boot_params_ret 41 42 /* Copy valid attached kernel to address KERNEL_ADDRESS */ 43 44 copy_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 80 copy_kernel_loop: 81 ldmdb r1!, {r3 - r10} 82 stmdb r2!, {r3 - r10} 83 cmp r1, r0 84 bhi copy_kernel_loop 85 86 copy_kernel_end: 87 mov r5, #0 88 str r5, [r0] /* remove 4 bytes header of kernel */ 89 90 91 /* Fix u-boot code */ 92 93 fix_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 /* 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 119 copy_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 148 copy_code_loop: 149 ldmdb r3!, {r7 - r10} 150 stmdb r4!, {r7 - r10} 151 cmp r4, r2 152 bhi copy_code_loop 153 154 copy_code_end: 155 mov pc, r2 156 157 158 /* Copy u-boot to address CONFIG_SYS_TEXT_BASE */ 159 160 copy_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 173 copy_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 180 copy_uboot_loop_right: 181 ldmdb r1!, {r3 - r10} 182 stmdb r2!, {r3 - r10} 183 cmp r1, r0 184 bhi copy_uboot_loop_right 185 186 copy_uboot_end: 187 bx lr 188 189 end: 190