]> git.sur5r.net Git - u-boot/blob - cpu/mips/start.S
[MIPS] Initialize CP0 Cause before setting up CP0 Status register
[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         /* WP(Watch Pending), SW0/1 should be cleared. */
215         mtc0    zero, CP0_CAUSE
216
217         /* STATUS register */
218 #ifdef  CONFIG_TB0229
219         li      k0, ST0_CU0
220 #else
221         mfc0    k0, CP0_STATUS
222 #endif
223         li      k1, ~ST0_IE
224         and     k0, k1
225         mtc0    k0, CP0_STATUS
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         /* Initialize any external memory.
244          */
245         la      t9, lowlevel_init
246         jalr    t9
247         nop
248
249         /* Initialize caches...
250          */
251         la      t9, mips_cache_reset
252         jalr    t9
253         nop
254
255         /* ... and enable them.
256          */
257         li      t0, CONF_CM_CACHABLE_NONCOHERENT
258         mtc0    t0, CP0_CONFIG
259
260         /* Set up temporary stack.
261          */
262 #ifdef CFG_INIT_RAM_LOCK_MIPS
263         li      a0, CFG_INIT_SP_OFFSET
264         la      t9, mips_cache_lock
265         jalr    t9
266         nop
267 #endif
268
269         li      t0, CFG_SDRAM_BASE + CFG_INIT_SP_OFFSET
270         la      sp, 0(t0)
271
272         la      t9, board_init_f
273         j       t9
274         nop
275
276 /*
277  * void relocate_code (addr_sp, gd, addr_moni)
278  *
279  * This "function" does not return, instead it continues in RAM
280  * after relocating the monitor code.
281  *
282  * a0 = addr_sp
283  * a1 = gd
284  * a2 = destination address
285  */
286         .globl  relocate_code
287         .ent    relocate_code
288 relocate_code:
289         move    sp, a0          /* Set new stack pointer        */
290
291         li      t0, CFG_MONITOR_BASE
292         la      t3, in_ram
293         lw      t2, -12(t3)     /* t2 <-- uboot_end_data        */
294         move    t1, a2
295
296         /*
297          * Fix $gp:
298          *
299          * New $gp = (Old $gp - CFG_MONITOR_BASE) + Destination Address
300          */
301         move    t6, gp
302         sub     gp, CFG_MONITOR_BASE
303         add     gp, a2          /* gp now adjusted              */
304         sub     t6, gp, t6      /* t6 <-- relocation offset     */
305
306         /*
307          * t0 = source address
308          * t1 = target address
309          * t2 = source end address
310          */
311         /* On the purple board we copy the code earlier in a special way
312          * in order to solve flash problems
313          */
314 #ifndef CONFIG_PURPLE
315 1:
316         lw      t3, 0(t0)
317         sw      t3, 0(t1)
318         addu    t0, 4
319         ble     t0, t2, 1b
320         addu    t1, 4           /* delay slot                   */
321 #endif
322
323         /* If caches were enabled, we would have to flush them here.
324          */
325
326         /* Jump to where we've relocated ourselves.
327          */
328         addi    t0, a2, in_ram - _start
329         j       t0
330         nop
331
332         .gpword _GLOBAL_OFFSET_TABLE_   /* _GLOBAL_OFFSET_TABLE_ - _gp  */
333         .word   uboot_end_data
334         .word   uboot_end
335         .word   num_got_entries
336
337 in_ram:
338         /*
339          * Now we want to update GOT.
340          *
341          * GOT[0] is reserved. GOT[1] is also reserved for the dynamic object
342          * generated by GNU ld. Skip these reserved entries from relocation.
343          */
344         lw      t3, -4(t0)      /* t3 <-- num_got_entries       */
345         lw      t4, -16(t0)     /* t4 <-- (_GLOBAL_OFFSET_TABLE_ - _gp) */
346         add     t4, t4, gp      /* t4 now holds _GLOBAL_OFFSET_TABLE_   */
347         addi    t4, t4, 8       /* Skipping first two entries.  */
348         li      t2, 2
349 1:
350         lw      t1, 0(t4)
351         beqz    t1, 2f
352         add     t1, t6
353         sw      t1, 0(t4)
354 2:
355         addi    t2, 1
356         blt     t2, t3, 1b
357         addi    t4, 4           /* delay slot                   */
358
359         /* Clear BSS.
360          */
361         lw      t1, -12(t0)     /* t1 <-- uboot_end_data        */
362         lw      t2, -8(t0)      /* t2 <-- uboot_end             */
363         add     t1, t6          /* adjust pointers              */
364         add     t2, t6
365
366         sub     t1, 4
367 1:
368         addi    t1, 4
369         bltl    t1, t2, 1b
370         sw      zero, 0(t1)     /* delay slot                   */
371
372         move    a0, a1
373         la      t9, board_init_r
374         j       t9
375         move    a1, a2          /* delay slot                   */
376
377         .end    relocate_code
378
379         /* Exception handlers.
380          */
381 romReserved:
382         b       romReserved
383
384 romExcHandle:
385         b       romExcHandle