FS#8961 - Anti-Aliased Fonts.
[kugel-rb.git] / firmware / target / arm / imx31 / crt0.S
blob7118c7572f1acfe4e6b7558fc616f57c9ad888fe
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     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, no cache */
138                                    /* Physical address = 0x0 */
139     mov     r1,      #(1 << 10)    /* superuser - r/w, user - no access */
140     orr     r1, r1, #((0 <<  5)  | /* domain 0th */ \
141                       (1 <<  4)  | /* should be "1" */ \
142                       (1 <<  1))   /* Section signature */
143     mov     r2, r5
144     add     r3, r5, #TTB_SIZE   /* End position */
146     str     r1, [r2], #4
147     add     r1, r1, #(1 << 20)  /* Next MB */
148     cmp     r2, r3
149     blo     1b
151     bic     r1, r1, #0x0ff00000 /* Back up */
153     /* Map 0x80000000 -> 0x0, cached */
154     mov     r2, r5               /* TTB pointer */
155     add     r3, r5, #64*4        /* End position */
156     orr     r1, r1, #0x80000000  /* Physical address */
157     orr     r1, r1, #((1 << 3) | /* cache flag */ \
158                       (1 << 2))  /* buffer flag */
160     str     r1, [r2], #4
161     add     r1, r1, #(1 << 20)
162     cmp     r2, r3
163     blo     1b
165     /* Map device section 0x83f00000 to 0x03f00000 - buffered, not cached */
166     bic     r1, r1, #0x0ff00000
167     orr     r1, r1, #0x03f00000
168     bic     r1, r1, #(1 << 3)
169     add     r2, r5, #63*4
170     str     r1, [r2]
171     
172     /* Enable MMU */
173     mov     r0, #0
174     mcr     p15, 0, r0, c8, c7, 0 /* Invalidate TLB */
175     mcr     p15, 0, r0, c7, c7, 0 /* Invalidate icache and dcache */
176     
177     /* Auxilliary control register */
178     mrc     p15, 0, r0, c1, c0, 1
179     bic     r0, r0, #((1 << 6) | /* Restrict cache size OFF */ \
180                       (1 << 5) | /* Enable block tranfer cache operations */ \
181                       (1 << 4) | /* Clean+Invalidate cache operation ON */ \
182                       (1 << 3))  /* Round-robin micro TLB replacement */
183     orr     r0, r0, #((1 << 2) | /* Static branch prediction ON */ \
184                       (1 << 1) | /* Dynamic branch prediction ON */ \
185                       (1 << 0))  /* Return stack enabled */
186     mcr     p15, 0, r0, c1, c0, 1
188     /* Control register */
189     mrc     p15, 0, r0, c1, c0, 0
190     bic     r0, r0, #((1 << 29) | /* AF by AP disabled */ \
191                       (1 << 28) | /* TEX remap disabled */ \
192                       (1 << 23))  /* Sub AP bits enabled (compatible) */
193     bic     r0, r0, #((1 << 21) | /* All performance features enabled */ \
194                       (1 << 15))  /* Loads to PC set T bit */
195     bic     r0, r0, #((1 << 13))  /* Low vectors */
196     bic     r0, r0, #((1 <<  1))  /* Strict alignment disabled */
197     orr     r0, r0, #((1 << 24) | /* Vectored interrupt ON */ \
198                       (1 << 22))  /* Unaligned access support enabled */
199     orr     r0, r0, #((1 << 14) | /* Round-robin replacement for I/D caches */ \
200                       (1 << 12) | /* L1 I-cache enabled */ \
201                       (1 << 11) | /* Program flow prediction enabled */ \
202                       (1 <<  9) | /* ROM protection enabled */ \
203                       (1 <<  8))  /* MMU protection enabled */
204     orr     r0, r0, #((1 <<  2) | /* L1 D-cache enabled */ \
205                       (1 <<  0))  /* MMU enabled */
206     mcr     p15, 0, r0, c1, c0, 0
207     nop
208     nop
209     nop
210     nop
211     nop
212     nop
213     nop
214     nop
215     ldr     pc, L_post_remap
216 L_post_remap:
217     .word remap_end
218 remap_end:
220 #ifdef BOOTLOADER
221     /* Copy bootloader exception handler code to address 0 */
222     ldr     r2, =_vectorsstart
223     ldr     r3, =_vectorsend
224     ldr     r4, =_vectorscopy
226     cmp     r3, r2
227     ldrhi   r5, [r4], #4
228     strhi   r5, [r2], #4
229     bhi     1b
230 #endif /* BOOTLOADER */
232 #ifndef BOOTLOADER
233     /* Copy discardable SDMA code - loaded in the stack section
234      * and so must be done first. Destination is the plugin buffer
235      * which is safe when SDMA init takes place just after kernel
236      * init. */
237     ldr     r4, =_sdmacodecopy
238     ldr     r3, =_sdmacodeend
239     ldr     r2, =_sdmacodestart
241     cmp     r3, r2
242     ldrhi   r5, [r4], #4
243     strhi   r5, [r2], #4
244     bhi     1b
246     /* Make buffer coherent */
247     ldr     r0, =_sdmacodestart
248     sub     r1, r3, r0
249     bl      clean_dcache_range
250 #endif /* BOOTLOADER */
252     /* Initialise bss section to zero */
253     ldr     r2, =_edata
254     ldr     r3, =_end
255     mov     r4, #0
257     cmp     r3, r2
258     strhi   r4, [r2], #4
259     bhi     1b
260     
261     /* Initialise the device bss section to zero */
262     ldr     r2, =_devbssdata
263     ldr     r3, =_devbssend
264     mov     r4, #0
266     cmp     r3, r2
267     strhi   r4, [r2], #4
268     bhi     1b
270     /* Set up some stack and munge it with 0xdeadbeef */
271     ldr     sp, =stackend
272     ldr     r2, =stackbegin
273     ldr     r3, =0xdeadbeef
275     cmp     sp, r2
276     strhi   r3, [r2], #4
277     bhi     1b
278     
279     /* Set up stack for IRQ mode */ 
280     msr     cpsr_c, #0xd2
281     ldr     sp, =irq_stack
283     /* Set up stack for FIQ mode */ 
284     msr     cpsr_c, #0xd1
285     ldr     sp, =fiq_stack
287     /* Let abort and undefined modes use IRQ stack */
288     msr     cpsr_c, #0xd7
289     ldr     sp, =irq_stack
290     msr     cpsr_c, #0xdb
291     ldr     sp, =irq_stack
293     /* Switch back to supervisor mode */
294     msr     cpsr_c, #0xd3
295     bl      main
297 #ifdef BOOTLOADER
298     /* Exception vectors with absolute jumps for bootloader */
299     .section .vectors,"aw"
300     ldr     pc, [pc, #24]
301     ldr     pc, [pc, #24]
302     ldr     pc, [pc, #24]
303     ldr     pc, [pc, #24]
304     ldr     pc, [pc, #24]
305     ldr     pc, [pc, #24]
306     ldr     pc, [pc, #24]
307     ldr     pc, [pc, #24]
308     .word   newstart
309     .word   undef_instr_handler
310     .word   software_int_handler
311     .word   prefetch_abort_handler
312     .word   data_abort_handler
313     .word   reserved_handler
314     .word   irq_handler
315     .word   fiq_handler
316 #endif /* BOOTLOADER */
318     .text
320 /* All illegal exceptions call into UIE with exception address as first
321  * parameter. This is calculated differently depending on which exception
322  * we're in. Second parameter is exception number, used for a string lookup
323  * in UIE. */
324 undef_instr_handler:
325     mov    r0, lr
326     mov    r1, #0
327     b      UIE
329 /* We run supervisor mode most of the time, and should never see a software
330  * exception being thrown. Perhaps make it illegal and call UIE? */
331 software_int_handler:
332 reserved_handler:
333     movs   pc, lr
335 prefetch_abort_handler:
336     sub    r0, lr, #4
337     mov    r1, #1
338     b      UIE
340 data_abort_handler:
341     sub    r0, lr, #8 
342     mov    r1, #2
343     b      UIE
345 /* 256 words of IRQ stack */
346     .space 256*4
347 irq_stack:
349 /* 256 words of FIQ stack */
350     .space 256*4
351 fiq_stack: