Clean the DCache just before going to main because areas were written by init code...
[kugel-rb.git] / firmware / target / arm / imx31 / crt0.S
blobef2d7f40b93431a42b38cfbe1076a2a2e6b4791d
1 /***************************************************************************
2  *             __________               __   ___.
3  *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
4  *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
5  *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
6  *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
7  *                     \/            \/     \/    \/            \/
8  * $Id$
9  *
10  * Copyright (C) 2002 by Linus Nielsen Feltzing
11  *
12  * This program is free software; you can redistribute it and/or
13  * modify it under the terms of the GNU General Public License
14  * as published by the Free Software Foundation; either version 2
15  * of the License, or (at your option) any later version.
16  *
17  * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18  * KIND, either express or implied.
19  *
20  ****************************************************************************/
21 #include "config.h"
22 #include "cpu.h"
24     .section .init.text,"ax",%progbits
26     .global    start
27 start:
28     /* Exception vectors */
29     b       newstart
30     b       undef_instr_handler
31     b       software_int_handler
32     b       prefetch_abort_handler
33     b       data_abort_handler
34     b       reserved_handler
35     subs    pc, lr, #4              @ b       irq_handler
36     b       fiq_handler
37     .balign 0x40, 0x6B
39 /* Arm bootloader and startup code based on startup.s from the iPodLinux loader
40  *
41  * Copyright (c) 2003, Daniel Palffy (dpalffy (at) rainstorm.org)
42  * Copyright (c) 2005, Bernard Leach <leachbj@bouncycastle.org>
43  *
44  */
46 /* Bootloader:
47  * Initially this code is running at VA 0x8a000000 (PA 0x82000000).
48  * The mapping stub is copied to IRAM (0x1fffc000), sets up the MMU and
49  * jumps into the final VA remapping starting at 0x02000000 (32MB).
50  *
51  * Firmware:
52  * This code will be running from VA 0x00000000 (PA 0x80000000) and perform
53  * similar steps to the bootloader code.
54  */
55 newstart:
56     msr     cpsr_c, #0xd3 /* enter supervisor mode, disable IRQ/FIQ */
58     adr     r2, remap_start    /* Load PC-relative labels (relocatable) */
59     adr     r3, remap_end
60     ldr     r5, =TTB_BASE_ADDR /* TTB pointer */
61     ldr     r6, =IRAM_BASE_ADDR
62     mov     r1, r6
64 1:  /* Copy remapping stub to IRAM */
65     cmp     r3, r2
66     ldrhi   r4, [r2], #4
67     strhi   r4, [r1], #4
68     bhi     1b
70     mov     pc, r6
72     /* Remapping stub. No absolute addresses may be used until after the
73      * remapping is complete. */
74 remap_start:
75     mrc     p15, 0, r3, c1, c0, 0  /* perform writeback if D cache is enabled */
76     tst     r3, #(1 <<  2)         /* dcache? */
77     tsteq   r3, #(1 << 12)         /* or icache? */
78     mov     r0, #0
79     mcrne   p15, 0, r0, c7, c10, 0 /* clean dcache */
80     mcrne   p15, 0, r0, c7, c7, 0  /* invalidate I cache and D cache */
81     mcr     p15, 0, r0, c8, c7, 0  /* invalidate TLBs */
82     mcr     p15, 0, r0, c7, c10, 4 /* Drain the write buffer */
83     
84     mcr     p15, 0, r0, c13, c0, 0
85     mcr     p15, 0, r0, c13, c0, 1
87     /* Also setup the Peripheral Port Remap register inside the core */
88     mov     r0, #0x40000000        /* start from AIPS 2GB region */
89     add     r0, r0, #0x15
90     mcr     p15, 0, r0, c15, c2, 4
92     /*** L2 Cache setup/invalidation/disable ***/
93     /* Disable L2 cache first */
94     mov     r0, #L2CC_BASE_ADDR
95     mov     r1, #0
96     str     r1, [r0, #L2_CACHE_CTL_REG]
98     /* Disble L1 caches and memory manager */
99     bic     r3, r3, #(1 << 12)    /* L1 I-cache disabled */
100     bic     r3, r3, #((1 << 2) |  /* L1 D-cache disabled */ \
101                       (1 << 0))   /* MMU disabled */
102     mcr     p15, 0, r3, c1, c0, 0
103     
104     /*
105      * Configure L2 Cache:
106      * - 128k size(16k way)
107      * - 8-way associativity
108      * - 0 ws TAG/VALID/DIRTY
109      * - 4 ws DATA R/W
110      */
111     mov     r1, #0x00130000
112     orr     r1, r1, #0x24
113     str     r1, [r0, #L2_CACHE_AUX_CTL_REG]
115     /* Invalidate L2 */
116     mov     r1, #0x000000FF
117     str     r1, [r0, #L2_CACHE_INV_WAY_REG]
119     /* Poll Invalidate By Way register */
120     ldr     r1, [r0, #L2_CACHE_INV_WAY_REG]
121     cmp     r1, #0
122     bne     1b
124     /*** End of L2 operations ***/
126     /* TTB Initialisation */
128     /* Set TTB base address */
129     mcr     p15, 0, r5, c2, c0, 0
131     /* Set all domains to manager status */
132     mvn     r0, #0
133     mcr     p15, 0, r0, c3, c0, 0
135     /* Set page tables */
137     /* Map each memory loc to itself
138      * not cached, not buffered */
139                                    /* Physical address = 0x0 */
140     mov     r1,      #(1 << 10)    /* superuser - r/w, user - no access */
141     orr     r1, r1, #((0 <<  5)  | /* domain 0th */ \
142                       (1 <<  4)  | /* should be "1" */ \
143                       (1 <<  1))   /* Section signature */
144     mov     r2, r5
145     add     r3, r5, #TTB_SIZE   /* End position */
147     str     r1, [r2], #4
148     add     r1, r1, #(1 << 20)  /* Next MB */
149     cmp     r2, r3
150     blo     1b
152     /* Bits 31:20 of r1 will be 0 due to wraparound in previous loop */
154     /* Map PA:0x80000000-0x83ffffff to VA:0x00000000-0x03f00000
155      * cached, buffered */
156     mov     r2, r5                 /* TTB pointer */
157     add     r3, r5, #64*4          /* End position */
158     orr     r1, r1, #(0x80000000 | /* Physical address */ \
159                       (1 << 3) |   /* cache flag */ \
160                       (1 << 2))    /* buffer flag */
162     str     r1, [r2], #4
163     add     r1, r1, #(1 << 20)
164     cmp     r2, r3
165     blo     1b
167     /* Map TTB, FRAME and QHARRAY section PA:0x83f00000-0x83ffffff to
168      * VA:0x04000000-0x040fffff
169      * not cache, buffered */
170     sub     r1, r1, #0x00100000
171     bic     r1, r1, #(1 << 3)     /* clear cache flag */
172     str     r1, [r5, #64*4]
174     /* Enable MMU */
175     mov     r0, #0
176     mcr     p15, 0, r0, c8, c7, 0 /* Invalidate TLB */
177     mcr     p15, 0, r0, c7, c7, 0 /* Invalidate icache and dcache */
178     
179     /* Auxilliary control register */
180     mrc     p15, 0, r0, c1, c0, 1
181     bic     r0, r0, #((1 << 6) | /* Restrict cache size OFF */ \
182                       (1 << 5) | /* Enable block tranfer cache operations */ \
183                       (1 << 4) | /* Clean+Invalidate cache operation ON */ \
184                       (1 << 3))  /* Round-robin micro TLB replacement */
185     orr     r0, r0, #((1 << 2) | /* Static branch prediction ON */ \
186                       (1 << 1) | /* Dynamic branch prediction ON */ \
187                       (1 << 0))  /* Return stack enabled */
188     mcr     p15, 0, r0, c1, c0, 1
190     /* Control register */
191     mrc     p15, 0, r0, c1, c0, 0
192     bic     r0, r0, #((1 << 29) | /* AF by AP disabled */ \
193                       (1 << 28) | /* TEX remap disabled */ \
194                       (1 << 23))  /* Sub AP bits enabled (compatible) */
195     bic     r0, r0, #((1 << 21) | /* All performance features enabled */ \
196                       (1 << 15))  /* Loads to PC set T bit */
197     bic     r0, r0, #((1 << 13))  /* Low vectors */
198     bic     r0, r0, #((1 <<  1))  /* Strict alignment disabled */
199     orr     r0, r0, #((1 << 24) | /* Vectored interrupt ON */ \
200                       (1 << 22))  /* Unaligned access support enabled */
201     orr     r0, r0, #((1 << 14) | /* Round-robin replacement for I/D caches */ \
202                       (1 << 12) | /* L1 I-cache enabled */ \
203                       (1 << 11) | /* Program flow prediction enabled */ \
204                       (1 <<  9) | /* ROM protection enabled */ \
205                       (1 <<  8))  /* MMU protection enabled */
206     orr     r0, r0, #((1 <<  2) | /* L1 D-cache enabled */ \
207                       (1 <<  0))  /* MMU enabled */
208     mcr     p15, 0, r0, c1, c0, 0
209     nop
210     nop
211     nop
212     nop
213     nop
214     nop
215     nop
216     nop
217     ldr     pc, L_post_remap
218 L_post_remap:
219     .word remap_end
220 remap_end:
222 #ifdef BOOTLOADER
223     /* Copy bootloader exception handler code to address 0 */
224     ldr     r2, =_vectorsstart
225     ldr     r3, =_vectorsend
226     ldr     r4, =_vectorscopy
228     cmp     r3, r2
229     ldrhi   r5, [r4], #4
230     strhi   r5, [r2], #4
231     bhi     1b
232 #endif /* BOOTLOADER */
234 #ifndef BOOTLOADER
235     /* Copy discardable SDMA code - loaded in the stack section
236      * and so must be done first. Destination is the plugin buffer
237      * which is safe when SDMA init takes place just after kernel
238      * init. */
239     ldr     r4, =_sdmacodecopy
240     ldr     r3, =_sdmacodeend
241     ldr     r2, =_sdmacodestart
243     cmp     r3, r2
244     ldrhi   r5, [r4], #4
245     strhi   r5, [r2], #4
246     bhi     1b
247 #endif /* BOOTLOADER */
249     /* Initialise bss and ncbss sections to zero */
250     ldr     r2, =_edata
251     ldr     r3, =_end
252     mov     r4, #0
254     cmp     r3, r2
255     strhi   r4, [r2], #4
256     bhi     1b
257     
258     /* Set up some stack and munge it with 0xdeadbeef */
259     ldr     sp, =stackend
260     ldr     r2, =stackbegin
261     ldr     r3, =0xdeadbeef
263     cmp     sp, r2
264     strhi   r3, [r2], #4
265     bhi     1b
266     
267     /* Set up stack for IRQ mode */ 
268     msr     cpsr_c, #0xd2
269     ldr     sp, =irq_stack
271     /* Set up stack for FIQ mode */ 
272     msr     cpsr_c, #0xd1
273     ldr     sp, =fiq_stack
275     /* Let abort and undefined modes use IRQ stack */
276     msr     cpsr_c, #0xd7
277     ldr     sp, =irq_stack
278     msr     cpsr_c, #0xdb
279     ldr     sp, =irq_stack
281     /* Switch back to supervisor mode */
282     msr     cpsr_c, #0xd3
284 #ifndef BOOTLOADER
285     /* Enable access to VFP */
286     mrc     p15, 0, r3, c1, c0, 2
287     orr     r3, r3, #0xf00000
288     mcr     p15, 0, r3, c1, c0, 2
289     
290     /* Enable VFP */
291     mrc     p10, 7, r3, c8, c0, 0
292     orr     r3, r3, #1<<30
293     mcr     p10, 7, r3, c8, c0, 0
295     /* Disable exceptions, enable default NaN, flush-to-zero, round toward 0 */
296     mrc     p10, 7, r3, c1, c0, 0
297     orr     r3, r3, #15<<22
298     bic     r3, r3, #31<<8
299     mcr     p10, 7, r3, c1, c0, 0
300 #endif
302     /* Make memory coherent for devices */
303     bl      clean_dcache
305     bl      main
307 #ifdef BOOTLOADER
308     /* Exception vectors with absolute jumps for bootloader */
309     .section .vectors,"aw"
310     ldr     pc, [pc, #24]
311     ldr     pc, [pc, #24]
312     ldr     pc, [pc, #24]
313     ldr     pc, [pc, #24]
314     ldr     pc, [pc, #24]
315     ldr     pc, [pc, #24]
316     subs    pc, lr, #4          @ ldr     pc, [pc, #24]
317     ldr     pc, [pc, #24]
318     .word   newstart
319     .word   undef_instr_handler
320     .word   software_int_handler
321     .word   prefetch_abort_handler
322     .word   data_abort_handler
323     .word   reserved_handler
324     .word   0                   @ irq_handler
325     .word   fiq_handler
326 #endif /* BOOTLOADER */
328     .text
330 /* All illegal exceptions call into UIE with exception address as first
331  * parameter. This is calculated differently depending on which exception
332  * we're in. Second parameter is exception number, used for a string lookup
333  * in UIE. */
334 undef_instr_handler:
335     sub    r0, lr, #4
336     mov    r1, #0
337     b      UIE
339 /* We run supervisor mode most of the time, and should never see a software
340  * exception being thrown. Perhaps make it illegal and call UIE? */
341 software_int_handler:
342 reserved_handler:
343     movs   pc, lr
345 prefetch_abort_handler:
346     sub    r0, lr, #4
347     mov    r1, #1
348     b      UIE
350 data_abort_handler:
351     sub    r0, lr, #8 
352     mov    r1, #2
353     b      UIE
355 /* 256 words of IRQ stack */
356     .space 256*4
357 irq_stack:
359 /* 256 words of FIQ stack */
360     .space 256*4
361 fiq_stack: