Enable tick IRQs on TCC780x. The main menu is now working on the D2.
[kugel-rb.git] / firmware / target / arm / tcc780x / crt0.S
blob05a8868d512ce0e3020dd148459b3865c078db4f
1 /***************************************************************************
2  *             __________               __   ___.
3  *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
4  *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
5  *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
6  *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
7  *                     \/            \/     \/    \/            \/
8  * $Id$
9  *
10  * Copyright (C) 2002 by Linus Nielsen Feltzing
11  *
12  * All files in this archive are subject to the GNU General Public License.
13  * See the file COPYING in the source tree root for full license agreement.
14  *
15  * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16  * KIND, either express or implied.
17  *
18  ****************************************************************************/
20 /* Arm bootloader and startup code based on startup.s from the iPodLinux loader
21  *
22  * Copyright (c) 2003, Daniel Palffy (dpalffy (at) rainstorm.org)
23  * Copyright (c) 2005, Bernard Leach <leachbj@bouncycastle.org>
24  *
25  */
27 #include "config.h"
28 #include "cpu.h"
30     .section .init.text,"ax",%progbits
32     .global    start
34 /* Telechips firmware files start with a 32-byte header, as part of the code. */
36 start:
37 #ifdef TCCBOOT
38     /* Add -DTCCBOOT to EXTRA_DEFINES in the bootloader Makefile to
39        enable building the bootloader to be appended to the end of the
40        original firmware, dual-booting based on a key-press.
42        NB: On the D2 TCCBOOT currently only works in USB boot mode (via tcctool)
43        When flashed to the device, the OF will boot as normal - but holding a
44        key to boot Rockbox results in a blank screen and crashed player.
46        The following two values are filled in by mktccboot.
47      */
48     .word  0              /* Saved entrypoint of original firmware*/
49     .word  0              /* Location in RAM of the start of our bootloader */
50 #else
51     ldr    pc, =start_loc    /* jump to the main entry point  */
53     .word  0xffff0601        /* Unknown magic */
54     .word  0x3a726556        /* "Ver:" */
55     .word  0x31373030        /* "0071" */
56     .word  0                 /* First CRC32 */
57     .word  0                 /* Unknown - always 0 */
58     .word  0                 /* Second CRC32 */
59     .word  0                 /* length of firmware file */
61 #ifdef COWON_D2
62     /* Some original firmwares have 0x40 bytes of zeroes here - we
63        don't know why, but err on the side of caution and include it
64        here. */
65     .space 0x40
66 #endif
67 #endif
69 start_loc:
71 #ifdef BOOTLOADER
72 #ifdef TCCBOOT
73 #ifdef COWON_D2
74     ldr    r0, =0xf005a000
75     ldr    r0, [r0, #0x40] /* Read GPIO B */
76     tst    r0, #0x4
77     ldreq  pc, [pc, #-28]  /* Jump to original firmware if keypad not pressed */
78 #else
79     #error No bootup key detection implemented for this target
80 #endif
82     /* Copy bootloader to safe area - 0x21000000 (DRAM) */
83     /* TODO: Adjust this for other targets - DRAM + DRAMSIZE - 0x100000 */
84     ldr    r0, [pc, #-28]
85     mov    r1, #0x22000000
86     sub    r1, r1, #0x100000
87     ldr    r2, =_dataend
89     cmp    r2, r1
90     ldrhi  r3, [r0], #4
91     strhi  r3, [r1], #4
92     bhi    1b
94     ldr    pc, =copied_start   /* jump to the relocated start_loc:  */
96 copied_start:
97 #endif
98 #else
99     /* We don't use interrupts in the bootloader */
101     /* Set up stack for IRQ mode */ 
102     mov    r0,#0xd2
103     msr    cpsr, r0
104     ldr    sp, =irq_stack
105     /* Set up stack for FIQ mode */ 
106     mov    r0,#0xd1
107     msr    cpsr, r0
108     ldr    sp, =fiq_stack
110     /* Let abort and undefined modes use IRQ stack */
111     mov    r0,#0xd7
112     msr    cpsr, r0
113     ldr    sp, =irq_stack
114     mov    r0,#0xdb
115     msr    cpsr, r0
116     ldr    sp, =irq_stack
117 #endif
119     /* Switch to supervisor mode */
120     mov    r0,#0xd3
121     msr    cpsr, r0
122     ldr    sp, =stackend
124     /* Enable MMU & caches. At present this is just doing what the OF does.
125        Ensure TCMs are enabled before copying the exception vectors to 0x0. */
127     mov     r1, #0xf7000000  /* Virtual MMU Table base */
129     ldr     r0, =0x1fe0c     /* Region 0: 0x00000000-0xffffffff (4Gb) */
130     str     r0, [r1]         /* AP: 3 EN: 1 DO: 0 CACHE_ALL */
132     ldr     r0, =0x2801ae24  /* Region 1: 0x28000000-0x2fffffff (128Mb) */
133     str     r0, [r1,#4]      /* AP: 3 EN: 1 DO: 1 BUFFERED */
135     ldr     r0, =0x13e44     /* Region 2: 0x00000000-0x000fffff (1Mb) */
136     str     r0, [r1,#8]      /* AP: 3 EN: 1 DO: 2 BUFFERED */
138     ldr     r0, =0x4001ce60  /* Region 3: 0x40000000-0x5fffffff (512Mb) */
139     str     r0, [r1,#0xc]    /* AP: 3 EN: 1 DO: 3 CACHE_NONE */
141     ldr     r0, =0x6001be80  /* Region 4: 0x60000000-0x6fffffff (256Mb) */
142     str     r0, [r1,#0x10]   /* AP: 3 EN: 1 DO: 4 CACHE_NONE */
144     ldr     r0, =0x3801aea4  /* Region 5: 0x38000000-0x3fffffff (128Mb) */
145     str     r0, [r1,#0x14]   /* AP: 3 EN: 1 DO: 5 BUFFERED */
147     ldr     r0, =0x8001eec0  /* Region 6: 0x80000000-0xffffffff (2Gb) */
148     str     r0, [r1,#0x18]   /* AP: 3 EN: 1 DO: 6 CACHE_NONE */
150     ldr     r0, =0x1001aee0  /* Region 7: 0x10000000-0x17ffffff (128Mb) */
151     str     r0, [r1,#0x1c]   /* AP: 3 EN: 1 DO: 7 CACHE_NONE */
153     add     r1, r1, #0x8000
154     mcr     p15, 0, r1, c2, c0, 0  /* Set TTBR = TABBASE (Virtual TLB) */
156     ldr     r0, =0x55555555
157     mcr     p15, 0, r0, c3, c0, 0  /* Domain access d0-d15 = 'client' */
158     
159     ldr     r0, =0xa0000011
160     mcr     p15, 0, r0, c9, c1, 0  /* Data TCM: 0xA0000000-0xA00001fff (8Kb) */
161     mov     r0, #0xd
162     mcr     p15, 0, r0, c9, c1, 1  /* Instr. TCM: 0x00000000-0x00000fff (4Kb) */
164     mov     r0, #0
165     mcr     p15, 0, r0, c7, c5, 0  /* Invalidate Icache */
166     ldr     r2, =0x5507d
167     mcr     p15, 0, r2, c1, c0, 0  /* Enable MMU, I & D caches */
168     mcr     p15, 0, r0, c7, c6, 0  /* Invalidate Dcache */
169     mcr     p15, 0, r1, c8, c7, 0  /* Invalidate TLB */
171 #if !defined(BOOTLOADER) && !defined(STUB)
173     /* Copy exception handler code to address 0 */
174     ldr    r2, =_vectorsstart
175     ldr    r3, =_vectorsend
176     ldr    r4, =_vectorscopy
178     cmp    r3, r2
179     ldrhi  r5, [r4], #4
180     strhi  r5, [r2], #4
181     bhi    1b
183     /* Copy the IRAM (SRAM) */
184     ldr    r2, =_iramcopy
185     ldr    r3, =_iramstart
186     ldr    r4, =_iramend
188     cmp    r4, r3
189     ldrhi  r5, [r2], #4
190     strhi  r5, [r3], #4
191     bhi    1b
192     
193     /* Zero out IBSS */
194     ldr    r2, =_iedata
195     ldr    r3, =_iend
196     mov    r4, #0
198     cmp    r3, r2
199     strhi  r4, [r2], #4
200     bhi    1b
202     /* Copy the ITCM */
203     ldr    r2, =_itcmcopy
204     ldr    r3, =_itcmstart
205     ldr    r4, =_itcmend
207     cmp    r4, r3
208     ldrhi  r5, [r2], #4
209     strhi  r5, [r3], #4
210     bhi    1b
212     /* Copy the DTCM */
213     ldr    r2, =_dtcmcopy
214     ldr    r3, =_dtcmstart
215     ldr    r4, =_dtcmend
217     cmp    r4, r3
218     ldrhi  r5, [r2], #4
219     strhi  r5, [r3], #4
220     bhi    1b
221 #endif /* !BOOTLOADER,!STUB */
223     /* Initialise bss section to zero */
224     ldr    r2, =_edata
225     ldr    r3, =_end
226     mov    r4, #0
228     cmp    r3, r2
229     strhi  r4, [r2], #4
230     bhi    1b
232     /* Set up some stack and munge it with 0xdeadbeef */
233     ldr    sp, =stackend
234     mov    r3, sp
235     ldr    r2, =stackbegin
236     ldr    r4, =0xdeadbeef
238     cmp    r3, r2
239     strhi  r4, [r2], #4
240     bhi    1b
242     bl     main
243     /* main() should never return */
245 #ifndef BOOTLOADER
247 /* Exception handlers. Will be copied to address 0 after memory remapping */
248     .section .vectors,"aw"
249     ldr    pc, [pc, #24]
250     ldr    pc, [pc, #24]
251     ldr    pc, [pc, #24]
252     ldr    pc, [pc, #24]
253     ldr    pc, [pc, #24]
254     ldr    pc, [pc, #24]
255     ldr    pc, [pc, #24]
256     ldr    pc, [pc, #24]
258     /* Exception vectors */
259     .global vectors
260 vectors:
261     .word  start
262     .word  undef_instr_handler
263     .word  software_int_handler
264     .word  prefetch_abort_handler
265     .word  data_abort_handler
266     .word  reserved_handler
267     .word  irq_handler
268     .word  fiq_handler
270     .text
272 #if !defined(STUB)
273     .global irq
274     .global fiq
275     .global UIE
276 #endif
278 /* All illegal exceptions call into UIE with exception address as first
279    parameter. This is calculated differently depending on which exception
280    we're in. Second parameter is exception number, used for a string lookup
281    in UIE.
282  */
283 undef_instr_handler:
284     mov    r0, lr
285     mov    r1, #0
286     b      UIE
288 /* We run supervisor mode most of the time, and should never see a software
289    exception being thrown. Perhaps make it illegal and call UIE?
290  */
291 software_int_handler:
292 reserved_handler:
293     movs   pc, lr
295 prefetch_abort_handler:
296     sub    r0, lr, #4
297     mov    r1, #1
298     b      UIE
300 data_abort_handler:
301     sub    r0, lr, #8
302     mov    r1, #2
303     b      UIE
305 #if defined(STUB)
306 UIE:
307     b UIE
308 #endif
310     /* We don't use interrupts in the bootloader */
312 /* Align stacks to cache line boundary */
313     .balign 16
314     
315 /* 256 words of IRQ stack */
316     .space 256*4
317 irq_stack:
319 /* 256 words of FIQ stack */
320     .space 256*4
321 fiq_stack:
323 #endif