Home | History | Annotate | Download | only in rx51
      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