Merge branch 'master' of git://git.denx.de/u-boot
[platform/kernel/u-boot.git] / board / nokia / rx51 / lowlevel_init.S
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
10 relocaddr:              /* address of this relocaddr section after coping */
11         .word .         /* address of section (calculated at compile time) */
12
13 startaddr:              /* address of u-boot after copying */
14         .word CONFIG_SYS_TEXT_BASE
15
16 kernaddr:               /* address of kernel after copying */
17         .word KERNEL_ADDRESS
18
19 kernsize:               /* maximal size of kernel image */
20         .word KERNEL_MAXSIZE
21
22 kernoffs:               /* offset of kernel image in loaded u-boot */
23         .word KERNEL_OFFSET
24
25 imagesize:              /* maximal size of image */
26         .word IMAGE_MAXSIZE
27
28 ih_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
39 save_boot_params:
40         /* Get return address */
41         ldr     lr, =save_boot_params_ret
42
43 /* Copy valid attached kernel to address KERNEL_ADDRESS */
44
45 copy_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
81 copy_kernel_loop:
82         ldmdb   r1!, {r3 - r10}
83         stmdb   r2!, {r3 - r10}
84         cmp     r1, r0
85         bhi     copy_kernel_loop
86
87 copy_kernel_end:
88         mov     r5, #0
89         str     r5, [r0]        /* remove 4 bytes header of kernel */
90
91
92 /* Fix u-boot code */
93
94 fix_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
124 copy_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
153 copy_code_loop:
154         ldmdb   r3!, {r7 - r10}
155         stmdb   r4!, {r7 - r10}
156         cmp     r4, r2
157         bhi     copy_code_loop
158
159 copy_code_end:
160         mov     pc, r2
161
162
163 /* Copy u-boot to address CONFIG_SYS_TEXT_BASE */
164
165 copy_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
178 copy_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
185 copy_uboot_loop_right:
186         ldmdb   r1!, {r3 - r10}
187         stmdb   r2!, {r3 - r10}
188         cmp     r1, r0
189         bhi     copy_uboot_loop_right
190
191 copy_uboot_end:
192         bx      lr
193
194 end: