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