change console=tty0 to enable linux framebuffer console
[jz_uboot.git] / cpu / mips / start.S
blob5fcef5641441883672cd7f81625d6a38bdf9ae98
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  */
25 #include <config.h>
26 #include <version.h>
27 #include <asm/regdef.h>
28 #include <asm/mipsregs.h>
29 #include <asm/addrspace.h>
30 #include <asm/cacheops.h>
32 #ifdef CONFIG_JZ4730
33 #include <asm/jz4730.h>
34 #endif
36 #ifdef CONFIG_JZ4740
37 #include <asm/jz4740.h>
38 #endif
40 #ifdef CONFIG_JZ4750
41 #include <asm/jz4750.h>
42 #endif
44 #define RVECENT(f,n) \
45    b f; nop
46 #define XVECENT(f,bev) \
47    b f     ;           \
48    li k0,bev
50         .set noreorder
52         .globl _start
53         .text
54 _start:
55 #if defined(CONFIG_JZ4740)
56 #if !defined(CONFIG_NAND_SPL) && !defined(CONFIG_NAND_U_BOOT)
57         .word JZ4740_NORBOOT_CFG        /* fetched during NOR Boot */
58 #else
59 #if defined(CONFIG_NAND_SPL)
60         .word JZ4740_NANDBOOT_CFG       /* fetched during NAND Boot */
61 #endif
62 #endif
63 #endif /* CONFIG_JZ4740 */
64 #if defined(CONFIG_JZ4750)
65 #if !defined(CONFIG_NAND_SPL) && !defined(CONFIG_NAND_U_BOOT)
66         .word JZ4750_NORBOOT_CFG        /* fetched during NOR Boot */
67 #else
68 #if defined(CONFIG_NAND_SPL)
69         .word JZ4750_NANDBOOT_CFG       /* fetched during NAND Boot */
70 #endif
71 #endif
72 #endif /* CONFIG_JZ4750 */
73 #if !defined(CONFIG_JzRISC)
74         RVECENT(reset,0)        /* U-boot entry point */
75         RVECENT(reset,1)        /* software reboot */
76 #if defined(CONFIG_INCA_IP)
77         .word INFINEON_EBU_BOOTCFG /* EBU init code, fetched during booting */
78         .word 0x00000000           /* phase of the flash                    */
79 #elif defined(CONFIG_PURPLE)
80         .word INFINEON_EBU_BOOTCFG /* EBU init code, fetched during booting */
81         .word INFINEON_EBU_BOOTCFG /* EBU init code, fetched during booting */
82 #else
83         RVECENT(romReserved,2)
84 #endif
85         RVECENT(romReserved,3)
86         RVECENT(romReserved,4)
87         RVECENT(romReserved,5)
88         RVECENT(romReserved,6)
89         RVECENT(romReserved,7)
90         RVECENT(romReserved,8)
91         RVECENT(romReserved,9)
92         RVECENT(romReserved,10)
93         RVECENT(romReserved,11)
94         RVECENT(romReserved,12)
95         RVECENT(romReserved,13)
96         RVECENT(romReserved,14)
97         RVECENT(romReserved,15)
98         RVECENT(romReserved,16)
99         RVECENT(romReserved,17)
100         RVECENT(romReserved,18)
101         RVECENT(romReserved,19)
102         RVECENT(romReserved,20)
103         RVECENT(romReserved,21)
104         RVECENT(romReserved,22)
105         RVECENT(romReserved,23)
106         RVECENT(romReserved,24)
107         RVECENT(romReserved,25)
108         RVECENT(romReserved,26)
109         RVECENT(romReserved,27)
110         RVECENT(romReserved,28)
111         RVECENT(romReserved,29)
112         RVECENT(romReserved,30)
113         RVECENT(romReserved,31)
114         RVECENT(romReserved,32)
115         RVECENT(romReserved,33)
116         RVECENT(romReserved,34)
117         RVECENT(romReserved,35)
118         RVECENT(romReserved,36)
119         RVECENT(romReserved,37)
120         RVECENT(romReserved,38)
121         RVECENT(romReserved,39)
122         RVECENT(romReserved,40)
123         RVECENT(romReserved,41)
124         RVECENT(romReserved,42)
125         RVECENT(romReserved,43)
126         RVECENT(romReserved,44)
127         RVECENT(romReserved,45)
128         RVECENT(romReserved,46)
129         RVECENT(romReserved,47)
130         RVECENT(romReserved,48)
131         RVECENT(romReserved,49)
132         RVECENT(romReserved,50)
133         RVECENT(romReserved,51)
134         RVECENT(romReserved,52)
135         RVECENT(romReserved,53)
136         RVECENT(romReserved,54)
137         RVECENT(romReserved,55)
138         RVECENT(romReserved,56)
139         RVECENT(romReserved,57)
140         RVECENT(romReserved,58)
141         RVECENT(romReserved,59)
142         RVECENT(romReserved,60)
143         RVECENT(romReserved,61)
144         RVECENT(romReserved,62)
145         RVECENT(romReserved,63)
146         XVECENT(romExcHandle,0x200)     /* bfc00200: R4000 tlbmiss vector */
147         RVECENT(romReserved,65)
148         RVECENT(romReserved,66)
149         RVECENT(romReserved,67)
150         RVECENT(romReserved,68)
151         RVECENT(romReserved,69)
152         RVECENT(romReserved,70)
153         RVECENT(romReserved,71)
154         RVECENT(romReserved,72)
155         RVECENT(romReserved,73)
156         RVECENT(romReserved,74)
157         RVECENT(romReserved,75)
158         RVECENT(romReserved,76)
159         RVECENT(romReserved,77)
160         RVECENT(romReserved,78)
161         RVECENT(romReserved,79)
162         XVECENT(romExcHandle,0x280)     /* bfc00280: R4000 xtlbmiss vector */
163         RVECENT(romReserved,81)
164         RVECENT(romReserved,82)
165         RVECENT(romReserved,83)
166         RVECENT(romReserved,84)
167         RVECENT(romReserved,85)
168         RVECENT(romReserved,86)
169         RVECENT(romReserved,87)
170         RVECENT(romReserved,88)
171         RVECENT(romReserved,89)
172         RVECENT(romReserved,90)
173         RVECENT(romReserved,91)
174         RVECENT(romReserved,92)
175         RVECENT(romReserved,93)
176         RVECENT(romReserved,94)
177         RVECENT(romReserved,95)
178         XVECENT(romExcHandle,0x300)     /* bfc00300: R4000 cache vector */
179         RVECENT(romReserved,97)
180         RVECENT(romReserved,98)
181         RVECENT(romReserved,99)
182         RVECENT(romReserved,100)
183         RVECENT(romReserved,101)
184         RVECENT(romReserved,102)
185         RVECENT(romReserved,103)
186         RVECENT(romReserved,104)
187         RVECENT(romReserved,105)
188         RVECENT(romReserved,106)
189         RVECENT(romReserved,107)
190         RVECENT(romReserved,108)
191         RVECENT(romReserved,109)
192         RVECENT(romReserved,110)
193         RVECENT(romReserved,111)
194         XVECENT(romExcHandle,0x380)     /* bfc00380: R4000 general vector */
195         RVECENT(romReserved,113)
196         RVECENT(romReserved,114)
197         RVECENT(romReserved,115)
198         RVECENT(romReserved,116)
199         RVECENT(romReserved,116)
200         RVECENT(romReserved,118)
201         RVECENT(romReserved,119)
202         RVECENT(romReserved,120)
203         RVECENT(romReserved,121)
204         RVECENT(romReserved,122)
205         RVECENT(romReserved,123)
206         RVECENT(romReserved,124)
207         RVECENT(romReserved,125)
208         RVECENT(romReserved,126)
209         RVECENT(romReserved,127)
211         /* We hope there are no more reserved vectors!
212          * 128 * 8 == 1024 == 0x400
213          * so this is address R_VEC+0x400 == 0xbfc00400
214          */
215 #ifdef CONFIG_PURPLE
216 /* 0xbfc00400 */
217         .word   0xdc870000
218         .word   0xfca70000
219         .word   0x20840008
220         .word   0x20a50008
221         .word   0x20c6ffff
222         .word   0x14c0fffa
223         .word   0x00000000
224         .word   0x03e00008
225         .word   0x00000000
226         .word   0x00000000
227 /* 0xbfc00428 */
228         .word   0xdc870000
229         .word   0xfca70000
230         .word   0x20840008
231         .word   0x20a50008
232         .word   0x20c6ffff
233         .word   0x14c0fffa
234         .word   0x00000000
235         .word   0x03e00008
236         .word   0x00000000
237         .word   0x00000000
238 #endif /* CONFIG_PURPLE */
239         .align 4
240 #endif /* CONFIG_JzRISC */
242 reset:
244 #if !defined(CONFIG_NAND_U_BOOT) || defined(CONFIG_NAND_SPL)
246 #ifdef CONFIG_JZ4730
248         /* Disable interrupts */
249         la      t0, INTC_IMR
250         li      t1, 0xffffffff
251         sw      t1, 0(t0)
253         /*
254          * Clear SCR.HGP
255          */
256         la      t0, CPM_SCR
257         lw      t1, 0(t0)
258         ori     t1, 0x8
259         xori    t1, 0x8
260         sw      t1, 0(t0)
262         /*
263          * Set usb port0 as host
264          */
265         la      t0, HARB_HAPOR
266         lw      t1, 0(t0)
267         ori     t1, HARB_HAPOR_UCHSEL
268         sw      t1, 0(t0)
270         /*
271          * Check reset status
272          */
273         la      t0, CPM_RSTR
274         lw      t1, 0(t0)
275         andi    t1, 0x4
276         bnez    t1, resume_from_hibernate
277         nop
278 #endif /* CONFIG_JZ4730 */
280 #ifndef CONFIG_NAND_SPL
281         /* Clear watch registers.
282          */
283         mtc0    zero, CP0_WATCHLO
284         mtc0    zero, CP0_WATCHHI
285 #endif
287         /* STATUS register */
288 #ifdef CONFIG_JzRISC
289         /* 
290          * CU0=UM=EXL=IE=0, BEV=ERL=1, IP2~7=1
291          */
292         li      t0, 0x0040FC04
293         mtc0    t0, CP0_STATUS
294 #else
295 #ifdef  CONFIG_TB0229
296         li      k0, ST0_CU0
297 #else
298         mfc0    k0, CP0_STATUS
299 #endif
300         li      k1, ~ST0_IE
301         and     k0, k1
302         mtc0    k0, CP0_STATUS
303 #endif
305         /* CAUSE register */
306 #ifdef CONFIG_JzRISC
307         /* IV=1, use the specical interrupt vector (0x200) */
308         li      t1, 0x00800000
309         mtc0    t1, CP0_CAUSE
310 #else
311         mtc0    zero, CP0_CAUSE
312 #endif
314 #ifndef CONFIG_JzRISC
315         /* Init Timer */
316         mtc0    zero, CP0_COUNT
317         mtc0    zero, CP0_COMPARE
318 #endif
320 #endif /* !defined(CONFIG_NAND_U_BOOT) || defined(CONFIG_NAND_SPL) */
322 #if !defined(CONFIG_NAND_SPL) && !defined(CONFIG_NAND_U_BOOT)
323         /* CONFIG0 register */
324         li      t0, CONF_CM_UNCACHED
325         mtc0    t0, CP0_CONFIG
326 #endif
328         /* Initialize GOT pointer.
329         */
330         bal     1f
331         nop
332         .word   _GLOBAL_OFFSET_TABLE_
333         1:
334         move    gp, ra
335         lw      t1, 0(ra)
336         move    gp, t1
338 #ifdef CONFIG_INCA_IP
339         /* Disable INCA-IP Watchdog.
340          */
341         la      t9, disable_incaip_wdt
342         jalr    t9
343         nop
344 #endif
346 /* JzRISC will init external memory in board_init_f,
347    which uses cache as stack and calls into C code. */
348 #ifndef CONFIG_JzRISC
349         /* Initialize any external memory.
350          */
351         la      t9, lowlevel_init
352         jalr    t9
353         nop
354 #endif
356 #if !defined(CONFIG_NAND_SPL) && !defined(CONFIG_NAND_U_BOOT)
357         /* Initialize caches...
358          */
359 #ifdef CONFIG_JzRISC
360         .set    mips32
361         mtc0    zero, CP0_TAGLO
362         mtc0    zero, CP0_TAGHI
364         li      t0, K0BASE
365         ori     t1, t0, CFG_DCACHE_SIZE
367         cache   Index_Store_Tag_D, 0(t0)
368         bne     t0, t1, 1b
369         addiu   t0, t0, CFG_CACHELINE_SIZE
371         li      t0, K0BASE
372         ori     t1, t0, CFG_ICACHE_SIZE
374         cache   Index_Store_Tag_I, 0(t0)
375         bne     t0, t1, 2b
376         addiu   t0, t0, CFG_CACHELINE_SIZE
378         /* Invalidate BTB */
379         mfc0    t0, CP0_CONFIG, 7
380         nop
381         ori     t0, 2
382         mtc0    t0, CP0_CONFIG, 7
383         nop
385         .set    mips2
386 #else
387         la      t9, mips_cache_reset
388         jalr    t9
389         nop
390 #endif
392         /* ... and enable them.
393          */
394         li      t0, CONF_CM_CACHABLE_NONCOHERENT
395         mtc0    t0, CP0_CONFIG
396         nop
398 #endif /* !defined(CONFIG_NAND_SPL) && !defined(CONFIG_NAND_U_BOOT) */
400         /* Set up temporary stack.
401          */
402 #ifndef CONFIG_JzRISC
403         li      a0, CFG_INIT_SP_OFFSET
404         la      t9, mips_cache_lock
405         jalr    t9
406         nop
407 #endif
409 #ifdef CONFIG_NAND_SPL
410         la      sp, 0x80004000
411         la      t9, nand_boot
412         j       t9
413         nop
414 #else
415         li      t0, CFG_SDRAM_BASE + CFG_INIT_SP_OFFSET
416         la      sp, 0(t0)
418         la      t9, board_init_f
419         j       t9
420         nop
424  * void relocate_code (addr_sp, gd, addr_moni)
426  * This "function" does not return, instead it continues in RAM
427  * after relocating the monitor code.
429  * a0 = addr_sp
430  * a1 = gd
431  * a2 = destination address
432  */
433         .globl  relocate_code
434         .ent    relocate_code
435 relocate_code:
436         move    sp, a0          /* Set new stack pointer                */
438         li      t0, TEXT_BASE
439         la      t3, in_ram
440         lw      t2, -12(t3)     /* t2 <-- uboot_end_data        */
441         move    t1, a2
443         /*
444          * Fix GOT pointer:
445          *
446          * New GOT-PTR = (old GOT-PTR - TEXT_BASE) + Destination Address
447          */
448         move    t6, gp
449         sub     gp, TEXT_BASE
450         add     gp, a2                  /* gp now adjusted              */
451         sub     t6, gp, t6              /* t6 <-- relocation offset     */
453         /*
454          * t0 = source address
455          * t1 = target address
456          * t2 = source end address
457          */
458         /* On the purple board we copy the code earlier in a special way
459          * in order to solve flash problems
460          */
461 #ifndef CONFIG_PURPLE
463         lw      t3, 0(t0)
464         sw      t3, 0(t1)
465         addu    t0, 4
466         ble     t0, t2, 1b
467         addu    t1, 4                   /* delay slot                   */
468 #endif
470         /* If caches were enabled, we would have to flush them here.
471          */
472 #ifdef CONFIG_JzRISC
473         /* flush d-cache */
474         .set    mips32
475         li      t0, KSEG0
476         addi    t1, t0, CFG_DCACHE_SIZE
478         cache   Index_Writeback_Inv_D, 0(t0)
479         bne     t0, t1, 2b
480         addi    t0, CFG_CACHELINE_SIZE
482         sync
484         /* flush i-cache */
485         li      t0, KSEG0
486         addi    t1, t0, CFG_ICACHE_SIZE
488         cache   Index_Invalidate_I, 0(t0)
489         bne     t0, t1, 3b
490         addi    t0, CFG_CACHELINE_SIZE
492         /* Invalidate BTB */
493         mfc0    t0, CP0_CONFIG, 7
494         nop
495         ori     t0, 2
496         mtc0    t0, CP0_CONFIG, 7
497         nop
499         .set    mips0
500 #endif
502         /* Jump to where we've relocated ourselves.
503          */
504         addi    t0, a2, in_ram - _start
505         j       t0
506         nop
508         .word   uboot_end_data
509         .word   uboot_end
510         .word   num_got_entries
512 in_ram:
513         /* Now we want to update GOT.
514          */
515         lw      t3, -4(t0)      /* t3 <-- num_got_entries       */
516         addi    t4, gp, 8       /* Skipping first two entries.  */
517         li      t2, 2
519         lw      t1, 0(t4)
520         beqz    t1, 2f
521         add     t1, t6
522         sw      t1, 0(t4)
524         addi    t2, 1
525         blt     t2, t3, 1b
526         addi    t4, 4           /* delay slot                   */
528         /* Clear BSS.
529          */
530         lw      t1, -12(t0)     /* t1 <-- uboot_end_data        */
531         lw      t2, -8(t0)      /* t2 <-- uboot_end             */
532         add     t1, t6          /* adjust pointers              */
533         add     t2, t6
535         sub     t1, 4
536 1:      addi    t1, 4
537         bltl    t1, t2, 1b
538         sw      zero, 0(t1)     /* delay slot                   */
540         move    a0, a1
541         la      t9, board_init_r
542         j       t9
543         move    a1, a2          /* delay slot                   */
545         .end    relocate_code
547 #endif /* CONFIG_NAND_SPL */
549 #if !defined(CONFIG_JzRISC)
550         /* Exception handlers.
551          */
552 romReserved:
553         b romReserved
555 romExcHandle:
556         b romExcHandle
557 #endif
559 #ifdef CONFIG_JZ4730
561 /* These are the runtime values, modify them according to your platform. */
562 #define PLCR1_VAL     0x1b000520
563 #define CFCR_VAL      0x0c526220
565 #define DMCR_VAL0     0x042a3211
566 #define DMCR_VAL1     0x05aa3211 /*(DMCR_VAL0|EMC_DMCR_RFSH|EMC_DMCR_MRSET)*/
568 #define RTCOR_VAL     0x10
569 #define RTCSR_VAL     0x83
571         /*
572          * cpu was reset from hibernate mode
573          */
574 resume_from_hibernate:
575         /*
576          * Init PLL
577          */
578         la      t0, 0xB0000000  /* CFCR */
579         li      t1, CFCR_VAL
580         sw      t1, 0(t0)
582         la      t0, 0xB0000010  /* PLCR1 */
583         li      t1, PLCR1_VAL
584         sw      t1, 0(t0)
585         nop;nop;nop;nop
587         /* Init caches */
588         .set    mips32
589         mtc0    zero, CP0_TAGLO
590         mtc0    zero, CP0_TAGHI
592         li      t0, K0BASE
593         ori     t1, t0, CFG_DCACHE_SIZE
595         cache   Index_Store_Tag_D, 0(t0)
596         cache   Index_Store_Tag_I, 0(t0)
597         bne     t0, t1, 1b
598         addiu   t0, t0, CFG_CACHELINE_SIZE
600         /*
601          * Init SDRAM
602          */
603         la      t0, 0xB0010070  /* GPALR2 */
604         lw      t1, 0(t0)
605         li      t2, 0x3FFFFFFF
606         and     t1, t2
607         li      t2, 0x40000000
608         or      t1, t2
609         sw      t1, 0(t0)
611         la      t0, 0xB0010074  /* GPAUR2 */
612         lw      t1, 0(t0)
613         li      t2, 0xFFFF0000
614         and     t1, t2
615         li      t2, 0x00005555
616         or      t1, t2
617         sw      t1, 0(t0)
619         la      t0, 0xB3010000  /* EMC base address */
621         li      t1, DMCR_VAL0   /* DMCR */
622         sw      t1, 0x80(t0)
624         li      t1, RTCOR_VAL
625         sh      t1, 0x8c(t0)    /* RTCOR */
627         li      t1, RTCSR_VAL
628         sh      t1, 0x84(t0)    /* RTCSR */
630         /* precharge all chip-selects */
631         ori     t1, t0, 0xa088
632         sb      $0, 0(t1)
633         ori     t1, t0, 0xb088
634         sb      $0, 0(t1)
636         /* delay about 200us */
637         li      t1, 0x20000
639         bnez    t1, 1b
640         sub     t1, 1
642         la      t1, DMCR_VAL1   /* DMCR */
643         sw      t1, 0x80(t0)
645         /* write sdram mode register for each chip-select */
646         ori     t1, t0, 0xa088
647         sb      $0, 0(t1)
648         ori     t1, t0, 0xb088
649         sb      $0, 0(t1)
651         /*
652          * jump to resume entry point
653          */
654         la      t0, CPM_SPR
655         lw      t1, 0(t0)
656         li      t0, 0x80000000
657         or      t0, t1
659         j       t0
660         nop
662 #endif /* CONFIG_JZ4730 */