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 /* Get return address */ 41 ldr lr, =save_boot_params_ret 42 43/* Copy valid attached kernel to address KERNEL_ADDRESS */ 44 45copy_kernel_start: 46 adr r0, relocaddr /* r0 - address of section relocaddr */ 47 ldr r1, relocaddr /* r1 - address of relocaddr after relocation */ 48 cmp r0, r1 49 50 /* r4 - calculated offset */ 51 subhi r4, r0, r1 52 sublo r4, r1, r0 53 54 /* r0 - start of kernel before */ 55 ldr r0, startaddr 56 addhi r0, r0, r4 57 sublo r0, r0, r4 58 ldr r1, kernoffs 59 add r0, r0, r1 60 61 /* r3 - start of kernel after */ 62 ldr r3, kernaddr 63 64 /* r2 - end of kernel after */ 65 ldr r1, kernsize 66 add r2, r3, r1 67 68 /* r1 - end of kernel before */ 69 add r1, r0, r1 70 71 /* remove header in target kernel */ 72 mov r5, #0 73 str r5, [r3] 74 75 /* check for valid kernel uImage */ 76 ldr r4, [r0] /* r4 - 4 bytes header of kernel */ 77 ldr r5, ih_magic /* r5 - IH_MAGIC */ 78 cmp r4, r5 79 bne copy_kernel_end /* skip if invalid image */ 80 81copy_kernel_loop: 82 ldmdb r1!, {r3 - r10} 83 stmdb r2!, {r3 - r10} 84 cmp r1, r0 85 bhi copy_kernel_loop 86 87copy_kernel_end: 88 mov r5, #0 89 str r5, [r0] /* remove 4 bytes header of kernel */ 90 91 92/* Fix u-boot code */ 93 94fix_start: 95 adr r0, relocaddr /* r0 - address of section relocaddr */ 96 ldr r1, relocaddr /* r1 - address of relocaddr after relocation */ 97 cmp r0, r1 98 99 beq copy_uboot_end /* skip if u-boot is on correct address */ 100 101 /* r5 - calculated offset */ 102 subhi r5, r0, r1 103 sublo r5, r1, r0 104 105 /* r6 - maximal u-boot size */ 106 ldr r6, imagesize 107 108 /* fix return address */ 109 subhi lr, lr, r5 110 addlo lr, lr, r5 111 112 /* r1 - start of u-boot after */ 113 ldr r1, startaddr 114 115 /* r0 - start of u-boot before */ 116 addhi r0, r1, r5 117 sublo r0, r1, r5 118 119 /* check if we need to move uboot copy code before calling it */ 120 cmp r5, r6 121 bhi copy_uboot_start /* now coping u-boot code directly is safe */ 122 123 124copy_code_start: 125 /* r0 - start of u-boot before */ 126 /* r1 - start of u-boot after */ 127 /* r6 - maximal u-boot size */ 128 129 /* r7 - maximal kernel size */ 130 ldr r7, kernsize 131 132 /* r4 - end of kernel before */ 133 add r4, r0, r6 134 add r4, r4, r7 135 136 /* r5 - end of u-boot after */ 137 ldr r5, startaddr 138 add r5, r5, r6 139 140 /* r2 - start of loop code after */ 141 cmp r4, r5 /* higher address (r4 or r5) */ 142 movhs r2, r4 143 movlo r2, r5 144 145 /* r3 - end of loop code before */ 146 adr r3, end 147 148 /* r4 - end of loop code after */ 149 adr r4, copy_uboot_start 150 sub r4, r3, r4 151 add r4, r2, r4 152 153copy_code_loop: 154 ldmdb r3!, {r7 - r10} 155 stmdb r4!, {r7 - r10} 156 cmp r4, r2 157 bhi copy_code_loop 158 159copy_code_end: 160 mov pc, r2 161 162 163/* Copy u-boot to address CONFIG_SYS_TEXT_BASE */ 164 165copy_uboot_start: 166 /* r0 - start of u-boot before */ 167 /* r1 - start of u-boot after */ 168 /* r6 - maximal u-boot size */ 169 170 /* r2 - end of u-boot after */ 171 add r2, r1, r6 172 173 /* condition for copying from left to right */ 174 cmp r0, r1 175 addlo r1, r0, r6 /* r1 - end of u-boot before */ 176 blo copy_uboot_loop_right 177 178copy_uboot_loop_left: 179 ldmia r0!, {r3 - r10} 180 stmia r1!, {r3 - r10} 181 cmp r1, r2 182 blo copy_uboot_loop_left 183 b copy_uboot_end 184 185copy_uboot_loop_right: 186 ldmdb r1!, {r3 - r10} 187 stmdb r2!, {r3 - r10} 188 cmp r1, r0 189 bhi copy_uboot_loop_right 190 191copy_uboot_end: 192 bx lr 193 194end: 195