[MIPS] Remove useless instructions for initializing $gp.
[platform/kernel/u-boot.git] / cpu / mips / start.S
1 /*
2  *  Startup Code for MIPS32 CPU-core
3  *
4  *  Copyright (c) 2003  Wolfgang Denk <wd@denx.de>
5  *
6  * See file CREDITS for list of people who contributed to this
7  * project.
8  *
9  * This program is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU General Public License as
11  * published by the Free Software Foundation; either version 2 of
12  * the License, or (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
22  * MA 02111-1307 USA
23  */
24
25 #include <config.h>
26 #include <version.h>
27 #include <asm/regdef.h>
28 #include <asm/mipsregs.h>
29
30 #define RVECENT(f,n) \
31    b f; nop
32 #define XVECENT(f,bev) \
33    b f     ;           \
34    li k0,bev
35
36         .set noreorder
37
38         .globl _start
39         .text
40 _start:
41         RVECENT(reset,0)        /* U-boot entry point */
42         RVECENT(reset,1)        /* software reboot */
43 #if defined(CONFIG_INCA_IP)
44         .word INFINEON_EBU_BOOTCFG /* EBU init code, fetched during booting */
45         .word 0x00000000           /* phase of the flash                    */
46 #elif defined(CONFIG_PURPLE)
47         .word INFINEON_EBU_BOOTCFG /* EBU init code, fetched during booting */
48         .word INFINEON_EBU_BOOTCFG /* EBU init code, fetched during booting */
49 #else
50         RVECENT(romReserved,2)
51 #endif
52         RVECENT(romReserved,3)
53         RVECENT(romReserved,4)
54         RVECENT(romReserved,5)
55         RVECENT(romReserved,6)
56         RVECENT(romReserved,7)
57         RVECENT(romReserved,8)
58         RVECENT(romReserved,9)
59         RVECENT(romReserved,10)
60         RVECENT(romReserved,11)
61         RVECENT(romReserved,12)
62         RVECENT(romReserved,13)
63         RVECENT(romReserved,14)
64         RVECENT(romReserved,15)
65         RVECENT(romReserved,16)
66         RVECENT(romReserved,17)
67         RVECENT(romReserved,18)
68         RVECENT(romReserved,19)
69         RVECENT(romReserved,20)
70         RVECENT(romReserved,21)
71         RVECENT(romReserved,22)
72         RVECENT(romReserved,23)
73         RVECENT(romReserved,24)
74         RVECENT(romReserved,25)
75         RVECENT(romReserved,26)
76         RVECENT(romReserved,27)
77         RVECENT(romReserved,28)
78         RVECENT(romReserved,29)
79         RVECENT(romReserved,30)
80         RVECENT(romReserved,31)
81         RVECENT(romReserved,32)
82         RVECENT(romReserved,33)
83         RVECENT(romReserved,34)
84         RVECENT(romReserved,35)
85         RVECENT(romReserved,36)
86         RVECENT(romReserved,37)
87         RVECENT(romReserved,38)
88         RVECENT(romReserved,39)
89         RVECENT(romReserved,40)
90         RVECENT(romReserved,41)
91         RVECENT(romReserved,42)
92         RVECENT(romReserved,43)
93         RVECENT(romReserved,44)
94         RVECENT(romReserved,45)
95         RVECENT(romReserved,46)
96         RVECENT(romReserved,47)
97         RVECENT(romReserved,48)
98         RVECENT(romReserved,49)
99         RVECENT(romReserved,50)
100         RVECENT(romReserved,51)
101         RVECENT(romReserved,52)
102         RVECENT(romReserved,53)
103         RVECENT(romReserved,54)
104         RVECENT(romReserved,55)
105         RVECENT(romReserved,56)
106         RVECENT(romReserved,57)
107         RVECENT(romReserved,58)
108         RVECENT(romReserved,59)
109         RVECENT(romReserved,60)
110         RVECENT(romReserved,61)
111         RVECENT(romReserved,62)
112         RVECENT(romReserved,63)
113         XVECENT(romExcHandle,0x200)     /* bfc00200: R4000 tlbmiss vector */
114         RVECENT(romReserved,65)
115         RVECENT(romReserved,66)
116         RVECENT(romReserved,67)
117         RVECENT(romReserved,68)
118         RVECENT(romReserved,69)
119         RVECENT(romReserved,70)
120         RVECENT(romReserved,71)
121         RVECENT(romReserved,72)
122         RVECENT(romReserved,73)
123         RVECENT(romReserved,74)
124         RVECENT(romReserved,75)
125         RVECENT(romReserved,76)
126         RVECENT(romReserved,77)
127         RVECENT(romReserved,78)
128         RVECENT(romReserved,79)
129         XVECENT(romExcHandle,0x280)     /* bfc00280: R4000 xtlbmiss vector */
130         RVECENT(romReserved,81)
131         RVECENT(romReserved,82)
132         RVECENT(romReserved,83)
133         RVECENT(romReserved,84)
134         RVECENT(romReserved,85)
135         RVECENT(romReserved,86)
136         RVECENT(romReserved,87)
137         RVECENT(romReserved,88)
138         RVECENT(romReserved,89)
139         RVECENT(romReserved,90)
140         RVECENT(romReserved,91)
141         RVECENT(romReserved,92)
142         RVECENT(romReserved,93)
143         RVECENT(romReserved,94)
144         RVECENT(romReserved,95)
145         XVECENT(romExcHandle,0x300)     /* bfc00300: R4000 cache vector */
146         RVECENT(romReserved,97)
147         RVECENT(romReserved,98)
148         RVECENT(romReserved,99)
149         RVECENT(romReserved,100)
150         RVECENT(romReserved,101)
151         RVECENT(romReserved,102)
152         RVECENT(romReserved,103)
153         RVECENT(romReserved,104)
154         RVECENT(romReserved,105)
155         RVECENT(romReserved,106)
156         RVECENT(romReserved,107)
157         RVECENT(romReserved,108)
158         RVECENT(romReserved,109)
159         RVECENT(romReserved,110)
160         RVECENT(romReserved,111)
161         XVECENT(romExcHandle,0x380)     /* bfc00380: R4000 general vector */
162         RVECENT(romReserved,113)
163         RVECENT(romReserved,114)
164         RVECENT(romReserved,115)
165         RVECENT(romReserved,116)
166         RVECENT(romReserved,116)
167         RVECENT(romReserved,118)
168         RVECENT(romReserved,119)
169         RVECENT(romReserved,120)
170         RVECENT(romReserved,121)
171         RVECENT(romReserved,122)
172         RVECENT(romReserved,123)
173         RVECENT(romReserved,124)
174         RVECENT(romReserved,125)
175         RVECENT(romReserved,126)
176         RVECENT(romReserved,127)
177
178         /* We hope there are no more reserved vectors!
179          * 128 * 8 == 1024 == 0x400
180          * so this is address R_VEC+0x400 == 0xbfc00400
181          */
182 #ifdef CONFIG_PURPLE
183 /* 0xbfc00400 */
184         .word   0xdc870000
185         .word   0xfca70000
186         .word   0x20840008
187         .word   0x20a50008
188         .word   0x20c6ffff
189         .word   0x14c0fffa
190         .word   0x00000000
191         .word   0x03e00008
192         .word   0x00000000
193         .word   0x00000000
194 /* 0xbfc00428 */
195         .word   0xdc870000
196         .word   0xfca70000
197         .word   0x20840008
198         .word   0x20a50008
199         .word   0x20c6ffff
200         .word   0x14c0fffa
201         .word   0x00000000
202         .word   0x03e00008
203         .word   0x00000000
204         .word   0x00000000
205 #endif /* CONFIG_PURPLE */
206         .align 4
207 reset:
208
209         /* Clear watch registers.
210          */
211         mtc0    zero, CP0_WATCHLO
212         mtc0    zero, CP0_WATCHHI
213
214         /* STATUS register */
215 #ifdef  CONFIG_TB0229
216         li      k0, ST0_CU0
217 #else
218         mfc0    k0, CP0_STATUS
219 #endif
220         li      k1, ~ST0_IE
221         and     k0, k1
222         mtc0    k0, CP0_STATUS
223
224         /* CAUSE register */
225         mtc0    zero, CP0_CAUSE
226
227         /* Init Timer */
228         mtc0    zero, CP0_COUNT
229         mtc0    zero, CP0_COMPARE
230
231         /* CONFIG0 register */
232         li      t0, CONF_CM_UNCACHED
233         mtc0    t0, CP0_CONFIG
234
235         /* Initialize $gp.
236          */
237         bal     1f
238         nop
239         .word   _gp
240 1:
241         lw      gp, 0(ra)
242
243 #ifdef CONFIG_INCA_IP
244         /* Disable INCA-IP Watchdog.
245          */
246         la      t9, disable_incaip_wdt
247         jalr    t9
248         nop
249 #endif
250
251         /* Initialize any external memory.
252          */
253         la      t9, lowlevel_init
254         jalr    t9
255         nop
256
257         /* Initialize caches...
258          */
259         la      t9, mips_cache_reset
260         jalr    t9
261         nop
262
263         /* ... and enable them.
264          */
265         li      t0, CONF_CM_CACHABLE_NONCOHERENT
266         mtc0    t0, CP0_CONFIG
267
268         /* Set up temporary stack.
269          */
270         li      a0, CFG_INIT_SP_OFFSET
271         la      t9, mips_cache_lock
272         jalr    t9
273         nop
274
275         li      t0, CFG_SDRAM_BASE + CFG_INIT_SP_OFFSET
276         la      sp, 0(t0)
277
278         la      t9, board_init_f
279         j       t9
280         nop
281
282 /*
283  * void relocate_code (addr_sp, gd, addr_moni)
284  *
285  * This "function" does not return, instead it continues in RAM
286  * after relocating the monitor code.
287  *
288  * a0 = addr_sp
289  * a1 = gd
290  * a2 = destination address
291  */
292         .globl  relocate_code
293         .ent    relocate_code
294 relocate_code:
295         move    sp, a0          /* Set new stack pointer        */
296
297         li      t0, CFG_MONITOR_BASE
298         la      t3, in_ram
299         lw      t2, -12(t3)     /* t2 <-- uboot_end_data        */
300         move    t1, a2
301
302         /*
303          * Fix $gp:
304          *
305          * New $gp = (Old $gp - CFG_MONITOR_BASE) + Destination Address
306          */
307         move    t6, gp
308         sub     gp, CFG_MONITOR_BASE
309         add     gp, a2          /* gp now adjusted              */
310         sub     t6, gp, t6      /* t6 <-- relocation offset     */
311
312         /*
313          * t0 = source address
314          * t1 = target address
315          * t2 = source end address
316          */
317         /* On the purple board we copy the code earlier in a special way
318          * in order to solve flash problems
319          */
320 #ifndef CONFIG_PURPLE
321 1:
322         lw      t3, 0(t0)
323         sw      t3, 0(t1)
324         addu    t0, 4
325         ble     t0, t2, 1b
326         addu    t1, 4           /* delay slot                   */
327 #endif
328
329         /* If caches were enabled, we would have to flush them here.
330          */
331
332         /* Jump to where we've relocated ourselves.
333          */
334         addi    t0, a2, in_ram - _start
335         j       t0
336         nop
337
338         .gpword _GLOBAL_OFFSET_TABLE_   /* _GLOBAL_OFFSET_TABLE_ - _gp  */
339         .word   uboot_end_data
340         .word   uboot_end
341         .word   num_got_entries
342
343 in_ram:
344         /*
345          * Now we want to update GOT.
346          *
347          * GOT[0] is reserved. GOT[1] is also reserved for the dynamic object
348          * generated by GNU ld. Skip these reserved entries from relocation.
349          */
350         lw      t3, -4(t0)      /* t3 <-- num_got_entries       */
351         lw      t4, -16(t0)     /* t4 <-- (_GLOBAL_OFFSET_TABLE_ - _gp) */
352         add     t4, t4, gp      /* t4 now holds _GLOBAL_OFFSET_TABLE_   */
353         addi    t4, t4, 8       /* Skipping first two entries.  */
354         li      t2, 2
355 1:
356         lw      t1, 0(t4)
357         beqz    t1, 2f
358         add     t1, t6
359         sw      t1, 0(t4)
360 2:
361         addi    t2, 1
362         blt     t2, t3, 1b
363         addi    t4, 4           /* delay slot                   */
364
365         /* Clear BSS.
366          */
367         lw      t1, -12(t0)     /* t1 <-- uboot_end_data        */
368         lw      t2, -8(t0)      /* t2 <-- uboot_end             */
369         add     t1, t6          /* adjust pointers              */
370         add     t2, t6
371
372         sub     t1, 4
373 1:
374         addi    t1, 4
375         bltl    t1, t2, 1b
376         sw      zero, 0(t1)     /* delay slot                   */
377
378         move    a0, a1
379         la      t9, board_init_r
380         j       t9
381         move    a1, a2          /* delay slot                   */
382
383         .end    relocate_code
384
385         /* Exception handlers.
386          */
387 romReserved:
388         b       romReserved
389
390 romExcHandle:
391         b       romExcHandle