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