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