1/* SPDX-License-Identifier: GPL-2.0+ */ 2/* 3 * (C) Copyright 2011-2012 4 * Pali Rohár <pali@kernel.org> 5 */ 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 30z_magic: /* LINUX_ARM_ZIMAGE_MAGIC */ 31 .word 0x016f2818 32 33/* 34 * Routine: save_boot_params (called after reset from start.S) 35 * Description: Copy attached kernel to address KERNEL_ADDRESS 36 * Copy u-boot to address CONFIG_SYS_TEXT_BASE 37 * Return to copied u-boot address 38 */ 39 40.global save_boot_params 41save_boot_params: 42 /* Get return address */ 43 ldr lr, =save_boot_params_ret 44 45/* Copy valid attached kernel to address KERNEL_ADDRESS */ 46 47copy_kernel_start: 48 adr r0, relocaddr /* r0 - address of section relocaddr */ 49 ldr r1, relocaddr /* r1 - address of relocaddr after relocation */ 50 cmp r0, r1 51 52 /* r4 - calculated offset */ 53 subhi r4, r0, r1 54 sublo r4, r1, r0 55 56 /* r0 - start of kernel before */ 57 ldr r0, startaddr 58 addhi r0, r0, r4 59 sublo r0, r0, r4 60 ldr r1, kernoffs 61 add r0, r0, r1 62 63 /* r3 - start of kernel after */ 64 ldr r3, kernaddr 65 66 /* r2 - end of kernel after */ 67 ldr r1, kernsize 68 add r2, r3, r1 69 70 /* r1 - end of kernel before */ 71 add r1, r0, r1 72 73 /* remove header in target kernel */ 74 mov r5, #0 75 str r5, [r3] 76 77 /* check for valid kernel uImage */ 78 ldr r4, [r0] /* r4 - 4 bytes header of kernel */ 79 ldr r5, ih_magic /* r5 - IH_MAGIC */ 80 cmp r4, r5 81 beq copy_kernel_loop 82 83 /* check for valid kernel zImage */ 84 ldr r4, [r0, #36] /* r4 - 4 bytes header of kernel at offset 36 */ 85 ldr r5, z_magic /* r5 - LINUX_ARM_ZIMAGE_MAGIC */ 86 cmp r4, r5 87 bne copy_kernel_end /* skip if invalid image */ 88 89copy_kernel_loop: 90 ldmdb r1!, {r3 - r10} 91 stmdb r2!, {r3 - r10} 92 cmp r1, r0 93 bhi copy_kernel_loop 94 95copy_kernel_end: 96 mov r5, #0 97 str r5, [r0] /* remove 4 bytes header of kernel uImage */ 98 str r5, [r0, #36] /* remove 4 bytes header of kernel zImage */ 99 100 101/* Fix u-boot code */ 102 103fix_start: 104 adr r0, relocaddr /* r0 - address of section relocaddr */ 105 ldr r1, relocaddr /* r1 - address of relocaddr after relocation */ 106 cmp r0, r1 107 108 beq copy_uboot_end /* skip if u-boot is on correct address */ 109 110 /* r5 - calculated offset */ 111 subhi r5, r0, r1 112 sublo r5, r1, r0 113 114 /* r6 - maximal u-boot size */ 115 ldr r6, imagesize 116 117 /* r1 - start of u-boot after */ 118 ldr r1, startaddr 119 120 /* r0 - start of u-boot before */ 121 addhi r0, r1, r5 122 sublo r0, r1, r5 123 124 /* check if we need to move uboot copy code before calling it */ 125 cmp r5, r6 126 bhi copy_uboot_start /* now coping u-boot code directly is safe */ 127 128 129copy_code_start: 130 /* r0 - start of u-boot before */ 131 /* r1 - start of u-boot after */ 132 /* r6 - maximal u-boot size */ 133 134 /* r7 - maximal kernel size */ 135 ldr r7, kernsize 136 137 /* r4 - end of kernel before */ 138 add r4, r0, r6 139 add r4, r4, r7 140 141 /* r5 - end of u-boot after */ 142 ldr r5, startaddr 143 add r5, r5, r6 144 145 /* r2 - start of loop code after */ 146 cmp r4, r5 /* higher address (r4 or r5) */ 147 movhs r2, r4 148 movlo r2, r5 149 150 /* r3 - end of loop code before */ 151 adr r3, end 152 153 /* r4 - end of loop code after */ 154 adr r4, copy_uboot_start 155 sub r4, r3, r4 156 add r4, r2, r4 157 158copy_code_loop: 159 ldmdb r3!, {r7 - r10} 160 stmdb r4!, {r7 - r10} 161 cmp r4, r2 162 bhi copy_code_loop 163 164copy_code_end: 165 mov pc, r2 166 167 168/* 169 * Copy u-boot to address CONFIG_SYS_TEXT_BASE 170 * 171 * Nokia X-Loader loading secondary image to address 0x80400000 172 * NOLO loading boot image to random place, so it doesn't really 173 * matter what is set in CONFIG_SYS_TEXT_BASE. We have to copy 174 * u-boot to CONFIG_SYS_TEXT_BASE address. 175 */ 176 177copy_uboot_start: 178 /* r0 - start of u-boot before */ 179 /* r1 - start of u-boot after */ 180 /* r6 - maximal u-boot size */ 181 182 /* r2 - end of u-boot after */ 183 add r2, r1, r6 184 185 /* condition for copying from left to right */ 186 cmp r0, r1 187 addlo r1, r0, r6 /* r1 - end of u-boot before */ 188 blo copy_uboot_loop_right 189 190copy_uboot_loop_left: 191 ldmia r0!, {r3 - r10} 192 stmia r1!, {r3 - r10} 193 cmp r1, r2 194 blo copy_uboot_loop_left 195 b copy_uboot_end 196 197copy_uboot_loop_right: 198 ldmdb r1!, {r3 - r10} 199 stmdb r2!, {r3 - r10} 200 cmp r1, r0 201 bhi copy_uboot_loop_right 202 203copy_uboot_end: 204 bx lr 205 206end: 207