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