compile libnl with -ffunction-sections to make binaries that use genl smaller
[openwrt.git] / target / linux / ifxmips / image / u-boot / files / cpu / mips / danube / 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
26 #include <config.h>
27 #include <version.h>
28 #include <asm/regdef.h>
29 #include <asm/mipsregs.h>
30 #if defined(CONFIG_IFX_MIPS)
31 #include "ifx_start.S"
32 #endif
33
34 #define RVECENT(f,n) \
35    b f; nop
36 #define XVECENT(f,bev) \
37    b f     ;           \
38    li k0,bev
39
40         .set noreorder
41
42         .globl _start
43         .text
44 _start:
45         RVECENT(reset,0)        /* U-boot entry point */
46         RVECENT(reset,1)        /* software reboot */
47 #if defined(CONFIG_INCA_IP)
48         .word INFINEON_EBU_BOOTCFG /* EBU init code, fetched during booting */
49         .word 0x00000000           /* phase of the flash                    */
50 #elif defined(CONFIG_IFX_MIPS) && defined(IFX_EBU_BOOTCFG_DWORD)
51         IFX_EBU_BOOTCFG_DWORD
52 #elif defined(CONFIG_PURPLE)
53         .word INFINEON_EBU_BOOTCFG /* EBU init code, fetched during booting */
54         .word INFINEON_EBU_BOOTCFG /* EBU init code, fetched during booting */
55 #else
56         RVECENT(romReserved,2)
57 #endif
58         RVECENT(romReserved,3)
59         RVECENT(romReserved,4)
60         RVECENT(romReserved,5)
61         RVECENT(romReserved,6)
62         RVECENT(romReserved,7)
63         RVECENT(romReserved,8)
64         RVECENT(romReserved,9)
65         RVECENT(romReserved,10)
66         RVECENT(romReserved,11)
67         RVECENT(romReserved,12)
68         RVECENT(romReserved,13)
69         RVECENT(romReserved,14)
70         RVECENT(romReserved,15)
71         RVECENT(romReserved,16)
72         RVECENT(romReserved,17)
73         RVECENT(romReserved,18)
74         RVECENT(romReserved,19)
75         RVECENT(romReserved,20)
76         RVECENT(romReserved,21)
77         RVECENT(romReserved,22)
78         RVECENT(romReserved,23)
79         RVECENT(romReserved,24)
80         RVECENT(romReserved,25)
81         RVECENT(romReserved,26)
82         RVECENT(romReserved,27)
83         RVECENT(romReserved,28)
84         RVECENT(romReserved,29)
85         RVECENT(romReserved,30)
86         RVECENT(romReserved,31)
87         RVECENT(romReserved,32)
88         RVECENT(romReserved,33)
89         RVECENT(romReserved,34)
90         RVECENT(romReserved,35)
91         RVECENT(romReserved,36)
92         RVECENT(romReserved,37)
93         RVECENT(romReserved,38)
94         RVECENT(romReserved,39)
95         RVECENT(romReserved,40)
96         RVECENT(romReserved,41)
97         RVECENT(romReserved,42)
98         RVECENT(romReserved,43)
99         RVECENT(romReserved,44)
100         RVECENT(romReserved,45)
101         RVECENT(romReserved,46)
102         RVECENT(romReserved,47)
103         RVECENT(romReserved,48)
104         RVECENT(romReserved,49)
105         RVECENT(romReserved,50)
106         RVECENT(romReserved,51)
107         RVECENT(romReserved,52)
108         RVECENT(romReserved,53)
109         RVECENT(romReserved,54)
110         RVECENT(romReserved,55)
111         RVECENT(romReserved,56)
112         RVECENT(romReserved,57)
113         RVECENT(romReserved,58)
114         RVECENT(romReserved,59)
115         RVECENT(romReserved,60)
116         RVECENT(romReserved,61)
117         RVECENT(romReserved,62)
118         RVECENT(romReserved,63)
119         XVECENT(romExcHandle,0x200)     /* bfc00200: R4000 tlbmiss vector */
120         RVECENT(romReserved,65)
121         RVECENT(romReserved,66)
122         RVECENT(romReserved,67)
123         RVECENT(romReserved,68)
124         RVECENT(romReserved,69)
125         RVECENT(romReserved,70)
126         RVECENT(romReserved,71)
127         RVECENT(romReserved,72)
128         RVECENT(romReserved,73)
129         RVECENT(romReserved,74)
130         RVECENT(romReserved,75)
131         RVECENT(romReserved,76)
132         RVECENT(romReserved,77)
133         RVECENT(romReserved,78)
134         RVECENT(romReserved,79)
135         XVECENT(romExcHandle,0x280)     /* bfc00280: R4000 xtlbmiss vector */
136         RVECENT(romReserved,81)
137         RVECENT(romReserved,82)
138         RVECENT(romReserved,83)
139         RVECENT(romReserved,84)
140         RVECENT(romReserved,85)
141         RVECENT(romReserved,86)
142         RVECENT(romReserved,87)
143         RVECENT(romReserved,88)
144         RVECENT(romReserved,89)
145         RVECENT(romReserved,90)
146         RVECENT(romReserved,91)
147         RVECENT(romReserved,92)
148         RVECENT(romReserved,93)
149         RVECENT(romReserved,94)
150         RVECENT(romReserved,95)
151         XVECENT(romExcHandle,0x300)     /* bfc00300: R4000 cache vector */
152         RVECENT(romReserved,97)
153         RVECENT(romReserved,98)
154         RVECENT(romReserved,99)
155         RVECENT(romReserved,100)
156         RVECENT(romReserved,101)
157         RVECENT(romReserved,102)
158         RVECENT(romReserved,103)
159         RVECENT(romReserved,104)
160         RVECENT(romReserved,105)
161         RVECENT(romReserved,106)
162         RVECENT(romReserved,107)
163         RVECENT(romReserved,108)
164         RVECENT(romReserved,109)
165         RVECENT(romReserved,110)
166         RVECENT(romReserved,111)
167         XVECENT(romExcHandle,0x380)     /* bfc00380: R4000 general vector */
168         RVECENT(romReserved,113)
169         RVECENT(romReserved,114)
170         RVECENT(romReserved,115)
171         RVECENT(romReserved,116)
172         RVECENT(romReserved,116)
173         RVECENT(romReserved,118)
174         RVECENT(romReserved,119)
175         RVECENT(romReserved,120)
176         RVECENT(romReserved,121)
177         RVECENT(romReserved,122)
178         RVECENT(romReserved,123)
179         RVECENT(romReserved,124)
180         RVECENT(romReserved,125)
181         RVECENT(romReserved,126)
182         RVECENT(romReserved,127)
183
184         /* We hope there are no more reserved vectors!
185          * 128 * 8 == 1024 == 0x400
186          * so this is address R_VEC+0x400 == 0xbfc00400
187          */
188 #if defined(CONFIG_IFX_MIPS) && defined(IFX_MORE_RESERVED_VECTORS)
189         IFX_MORE_RESERVED_VECTORS
190 #else
191 #ifdef CONFIG_PURPLE
192 /* 0xbfc00400 */
193         .word   0xdc870000
194         .word   0xfca70000
195         .word   0x20840008
196         .word   0x20a50008
197         .word   0x20c6ffff
198         .word   0x14c0fffa
199         .word   0x00000000
200         .word   0x03e00008
201         .word   0x00000000
202         .word   0x00000000
203 /* 0xbfc00428 */
204         .word   0xdc870000
205         .word   0xfca70000
206         .word   0x20840008
207         .word   0x20a50008
208         .word   0x20c6ffff
209         .word   0x14c0fffa
210         .word   0x00000000
211         .word   0x03e00008
212         .word   0x00000000
213         .word   0x00000000
214 #endif /* CONFIG_PURPLE */
215 #endif /* CONFIG_IFX_MIPS */
216         .align 4
217 reset:
218 #if defined(CONFIG_IFX_MIPS) && defined(IFX_RESET_PRECHECK)
219         IFX_RESET_PRECHECK
220 #endif
221         /* Clear watch registers.
222          */
223         mtc0    zero, CP0_WATCHLO
224         mtc0    zero, CP0_WATCHHI
225
226         /* STATUS register */
227 #ifdef  CONFIG_TB0229
228         li      k0, ST0_CU0
229 #else
230         mfc0    k0, CP0_STATUS
231 #endif
232         li      k1, ~ST0_IE
233         and     k0, k1
234         mtc0    k0, CP0_STATUS
235
236         /* CAUSE register */
237         mtc0    zero, CP0_CAUSE
238
239 #if defined(CONFIG_IFX_MIPS) && defined(IFX_CPU_EXTRA_INIT)
240         IFX_CPU_EXTRA_INIT
241 #endif
242
243         /* Init Timer */
244         mtc0    zero, CP0_COUNT
245         mtc0    zero, CP0_COMPARE
246
247         /* CONFIG0 register */
248         li      t0, CONF_CM_UNCACHED
249         mtc0    t0, CP0_CONFIG
250
251         /* Initialize GOT pointer.
252         */
253         bal     1f
254         nop
255         .word   _GLOBAL_OFFSET_TABLE_
256         1:
257         move    gp, ra
258         lw      t1, 0(ra)
259         move    gp, t1
260
261 #ifdef CONFIG_INCA_IP
262         /* Disable INCA-IP Watchdog.
263          */
264         la      t9, disable_incaip_wdt
265         jalr    t9
266         nop
267 #endif
268
269         /* Initialize any external memory.
270          */
271         la      t9, lowlevel_init
272         jalr    t9
273         nop
274
275         /* Initialize caches...
276          */
277         la      t9, mips_cache_reset
278         jalr    t9
279         nop
280
281         /* ... and enable them.
282          */
283 #if defined(CONFIG_IFX_MIPS) && defined(IFX_CACHE_OPER_MODE)
284         IFX_CACHE_OPER_MODE
285 #else
286         li      t0, CONF_CM_CACHABLE_NONCOHERENT
287 #endif
288         mtc0    t0, CP0_CONFIG
289
290
291         /* Set up temporary stack.
292          */
293         li      a0, CFG_INIT_SP_OFFSET
294         la      t9, mips_cache_lock
295         jalr    t9
296         nop
297
298         li      t0, CFG_SDRAM_BASE + CFG_INIT_SP_OFFSET
299         la      sp, 0(t0)
300
301         la      t9, board_init_f
302         j       t9
303         nop
304
305 #ifdef CFG_HEAD_CODE
306 /*
307  * void jump_unconditional (addr)
308  * This function simply jumps to the location pointed by a0.
309  * a0 = target_location
310  *
311  */
312         .globl  jump_unconditional
313         .ent    jump_unconditional
314 jump_unconditional:
315         move t9, a0
316         j       t9
317         nop
318         .end    jump_unconditional
319
320 #endif
321
322 /*
323  * void relocate_code (addr_sp, gd, addr_moni)
324  *
325  * This "function" does not return, instead it continues in RAM
326  * after relocating the monitor code.
327  *
328  * a0 = addr_sp
329  * a1 = gd
330  * a2 = destination address
331  */
332         .globl  relocate_code
333         .ent    relocate_code
334 relocate_code:
335         move    sp, a0          /* Set new stack pointer                */
336
337 #ifdef CFG_HEAD_CODE
338         li      t0, CFG_HEAD_BASE
339 #else
340         li      t0, CFG_MONITOR_BASE
341 #endif
342         la      t3, in_ram
343         lw      t2, -12(t3)     /* t2 <-- uboot_end_data        */
344         move    t1, a2
345
346         /*
347          * Fix GOT pointer:
348          *
349          * New GOT-PTR = (old GOT-PTR - CFG_MONITOR_BASE) + Destination Address
350          */
351         move    t6, gp
352 #ifdef CFG_HEAD_CODE
353         sub     gp, CFG_HEAD_BASE
354 #else
355         sub     gp, CFG_MONITOR_BASE
356 #endif
357         add     gp, a2                  /* gp now adjusted              */
358         sub     t6, gp, t6              /* t6 <-- relocation offset     */
359
360         /*
361          * t0 = source address
362          * t1 = target address
363          * t2 = source end address
364          */
365         /* On the purple board we copy the code earlier in a special way
366          * in order to solve flash problems
367          */
368 #ifndef CONFIG_PURPLE
369 1:
370         lw      t3, 0(t0)
371         sw      t3, 0(t1)
372         addu    t0, 4
373         ble     t0, t2, 1b
374         addu    t1, 4                   /* delay slot                   */
375 #endif
376
377         /* If caches were enabled, we would have to flush them here.
378          */
379
380         /* Jump to where we've relocated ourselves.
381          */
382         addi    t0, a2, in_ram - _start
383         j       t0
384         nop
385
386         .word   uboot_end_data
387         .word   uboot_end
388         .word   num_got_entries
389
390 in_ram:
391         /* Now we want to update GOT.
392          */
393         lw      t3, -4(t0)      /* t3 <-- num_got_entries       */
394         addi    t4, gp, 8       /* Skipping first two entries.  */
395         li      t2, 2
396 1:
397         lw      t1, 0(t4)
398         beqz    t1, 2f
399         add     t1, t6
400         sw      t1, 0(t4)
401 2:
402         addi    t2, 1
403         blt     t2, t3, 1b
404         addi    t4, 4           /* delay slot                   */
405
406         /* Clear BSS.
407          */
408         lw      t1, -12(t0)     /* t1 <-- uboot_end_data        */
409         lw      t2, -8(t0)      /* t2 <-- uboot_end             */
410         add     t1, t6          /* adjust pointers              */
411         add     t2, t6
412
413         sub     t1, 4
414 1:      addi    t1, 4
415         bltl    t1, t2, 1b
416         sw      zero, 0(t1)     /* delay slot                   */
417
418         move    a0, a1
419         la      t9, board_init_r
420         j       t9
421         move    a1, a2          /* delay slot                   */
422
423         .end    relocate_code
424
425
426         /* Exception handlers.
427          */
428 romReserved:
429         b romReserved
430
431 romExcHandle:
432         b romExcHandle
433
434         /* Additional handlers.
435          */
436 #if defined(CONFIG_IFX_MIPS)
437 #if defined(IFX_MIPS_HANDLER_1)
438 ifx_mips_handler_1:
439         IFX_MIPS_HANDLER_1
440 #endif
441 #endif
442