]> git.sur5r.net Git - u-boot/blob - cpu/mips/start.S
930f9b3fde1a902eb2bb631dae12a0ad854726ea
[u-boot] / 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 #ifdef CFG_INIT_RAM_LOCK_MIPS
271         li      a0, CFG_INIT_SP_OFFSET
272         la      t9, mips_cache_lock
273         jalr    t9
274         nop
275 #endif
276
277         li      t0, CFG_SDRAM_BASE + CFG_INIT_SP_OFFSET
278         la      sp, 0(t0)
279
280         la      t9, board_init_f
281         j       t9
282         nop
283
284 /*
285  * void relocate_code (addr_sp, gd, addr_moni)
286  *
287  * This "function" does not return, instead it continues in RAM
288  * after relocating the monitor code.
289  *
290  * a0 = addr_sp
291  * a1 = gd
292  * a2 = destination address
293  */
294         .globl  relocate_code
295         .ent    relocate_code
296 relocate_code:
297         move    sp, a0          /* Set new stack pointer        */
298
299         li      t0, CFG_MONITOR_BASE
300         la      t3, in_ram
301         lw      t2, -12(t3)     /* t2 <-- uboot_end_data        */
302         move    t1, a2
303
304         /*
305          * Fix $gp:
306          *
307          * New $gp = (Old $gp - CFG_MONITOR_BASE) + Destination Address
308          */
309         move    t6, gp
310         sub     gp, CFG_MONITOR_BASE
311         add     gp, a2          /* gp now adjusted              */
312         sub     t6, gp, t6      /* t6 <-- relocation offset     */
313
314         /*
315          * t0 = source address
316          * t1 = target address
317          * t2 = source end address
318          */
319         /* On the purple board we copy the code earlier in a special way
320          * in order to solve flash problems
321          */
322 #ifndef CONFIG_PURPLE
323 1:
324         lw      t3, 0(t0)
325         sw      t3, 0(t1)
326         addu    t0, 4
327         ble     t0, t2, 1b
328         addu    t1, 4           /* delay slot                   */
329 #endif
330
331         /* If caches were enabled, we would have to flush them here.
332          */
333
334         /* Jump to where we've relocated ourselves.
335          */
336         addi    t0, a2, in_ram - _start
337         j       t0
338         nop
339
340         .gpword _GLOBAL_OFFSET_TABLE_   /* _GLOBAL_OFFSET_TABLE_ - _gp  */
341         .word   uboot_end_data
342         .word   uboot_end
343         .word   num_got_entries
344
345 in_ram:
346         /*
347          * Now we want to update GOT.
348          *
349          * GOT[0] is reserved. GOT[1] is also reserved for the dynamic object
350          * generated by GNU ld. Skip these reserved entries from relocation.
351          */
352         lw      t3, -4(t0)      /* t3 <-- num_got_entries       */
353         lw      t4, -16(t0)     /* t4 <-- (_GLOBAL_OFFSET_TABLE_ - _gp) */
354         add     t4, t4, gp      /* t4 now holds _GLOBAL_OFFSET_TABLE_   */
355         addi    t4, t4, 8       /* Skipping first two entries.  */
356         li      t2, 2
357 1:
358         lw      t1, 0(t4)
359         beqz    t1, 2f
360         add     t1, t6
361         sw      t1, 0(t4)
362 2:
363         addi    t2, 1
364         blt     t2, t3, 1b
365         addi    t4, 4           /* delay slot                   */
366
367         /* Clear BSS.
368          */
369         lw      t1, -12(t0)     /* t1 <-- uboot_end_data        */
370         lw      t2, -8(t0)      /* t2 <-- uboot_end             */
371         add     t1, t6          /* adjust pointers              */
372         add     t2, t6
373
374         sub     t1, 4
375 1:
376         addi    t1, 4
377         bltl    t1, t2, 1b
378         sw      zero, 0(t1)     /* delay slot                   */
379
380         move    a0, a1
381         la      t9, board_init_r
382         j       t9
383         move    a1, a2          /* delay slot                   */
384
385         .end    relocate_code
386
387         /* Exception handlers.
388          */
389 romReserved:
390         b       romReserved
391
392 romExcHandle:
393         b       romExcHandle