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