Initial maemo platform support
[maemo-rb.git] / firmware / target / arm / crt0-pp502x-bl-usb.S
blobc8b7fb4ee8c966f1eebd807e9cd2ecb64dd23d30
1 /***************************************************************************
2  *             __________               __   ___.
3  *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
4  *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
5  *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
6  *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
7  *                     \/            \/     \/    \/            \/
8  * $Id$
9  *
10  * Copyright (C) 2002 by Linus Nielsen Feltzing
11  * Copyright (C) 2010 by Michael Sevakis
12  *
13  * This program is free software; you can redistribute it and/or
14  * modify it under the terms of the GNU General Public License
15  * as published by the Free Software Foundation; either version 2
16  * of the License, or (at your option) any later version.
17  *
18  * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19  * KIND, either express or implied.
20  *
21  ****************************************************************************/
22 #include "config.h"
23 #include "cpu.h"
25 /* PortalPlayer bootloader and startup code based on startup.s from the iPodLinux 
26  * loader
27  *
28  * Copyright (c) 2003, Daniel Palffy (dpalffy (at) rainstorm.org)
29  * Copyright (c) 2005, Bernard Leach <leachbj@bouncycastle.org>
30  *
31  */
32     .equ    PROC_ID,     0x60000000
33     .equ    CPU_IDIS,    0x60004028
34     .equ    CPU_CTRL,    0x60007000
35     .equ    CPU_STATUS,  0x60007000
36     .equ    COP_IDIS,    0x60004038
37     .equ    COP_CTRL,    0x60007004
38     .equ    COP_STATUS,  0x60007004
39     .equ    CPU_SLEEPING,0x80000000
40     .equ    COP_SLEEPING,0x80000000
41     .equ    SLEEP,       0x80000000
42     .equ    WAKE,        0x00000000
43     .equ    MMAP_LOG,    0xf000f000 /* MMAP0 */
44     .equ    MMAP_PHYS,   0xf000f004
45     .equ    INT_VECT_TBL,0x6000f100
46     .equ    CACHE_CTRL,  0x6000c000
47     .equ    CACHE_ENAB,  0x1
48     .equ    CACHE_OP_COMMIT_DISCARD, 0x1
49     .equ    CACHE_OP_COMMIT        , 0x0
50 #if MEMORYSIZE > 32
51     .equ    MMAP_MASK,   0x00003c00
52 #else
53     .equ    MMAP_MASK,   0x00003e00
54 #endif
55     .equ    MMAP_FLAGS,  0x00000f84
58  * Entry point
59  */
60     .section .init.text,"ax",%progbits
61     .global  start
62 start:
63     b       newstart
65 #ifdef IPOD_ARCH
66 .align 8    /* starts at 0x100 */
67 .global boot_table
68 boot_table:
69     /* here comes the boot table, don't move its offset - preceding
70        code+data must stay <= 256 bytes */
71     .space  400
72 #else /* !IPOD_ARCH */
73     /* (more than enough) space for exception vectors and mi4 magic */
74     .space  68*4
75 #endif /* IPOD_ARCH */
77 newstart:
78     msr     cpsr_c, #0xd3 /* enter supervisor mode, disable IRQ/FIQ */
79     adr     r4, start     /* cache initial load address */
81     /* Copy startup stub to IRAM since we need to both move the bootloader's
82      * location, which could overlap itself, and setup the memory mapper. */
83     adr     r0, start_stub_begin
84     mov     r1, #0x40000000
85     adr     r2, start_stub_end
87     ldr     r3, [r0], #4
88     str     r3, [r1], #4
89     cmp     r0, r2
90     blo     1b
91     mov     pc, #0x40000000
93 start_stub_begin:
94     ldr     r0, =PROC_ID
95     ldrb    r0, [r0]
96     cmp     r0, #0x55
97     beq     cpu
99 cop:
100     mov     r0, #CACHE_OP_COMMIT_DISCARD
101     bl      cache_operation
103     ldr     r1, =COP_CTRL
104     mov     r0, #SLEEP
106     /* sleep us (co-processor) while bootloader is copied */
107     str     r0, [r1]
108     nop
109     nop
110     nop
112     /* branch to final physical load address */
113     ldr     r2, =1f
114     and     r4, r4, #0xfc000000
115     add     pc, r2, r4
117     /* wait for bootloader to finish */
118     str     r0, [r1]
119     nop
120     nop
121     nop
123     /* branch to the address returned by main() */
124     adr     r0, startup_loc
125     ldr     pc, [r0]
127 cpu:
128     /* wait for COP to sleep */
129     ldr     r1, =COP_STATUS
131     ldr     r0, [r1]
132     tst     r0, #COP_SLEEPING
133     beq     1b
135     mov     r0, #CACHE_OP_COMMIT_DISCARD
136     bl      cache_operation
138     /* move bootloader to the correct load address if needed */
139     ldr     r1, =_loadaddress
140     cmp     r4, r1
141     ldrne   r2, =_loadaddressend
142     movne   r0, r4
143     sublo   r3, r2, r1 /* size */
144     addlo   r0, r0, r3 /* initial load end addr */
145 1: /* lower to higher move - copy up */
146     cmphi   r2, r1
147     ldrhi   r3, [r0], #4
148     strhi   r3, [r1], #4
149     bhi     1b
150 1: /* higher to lower move - copy down */
151     cmplo   r1, r2
152     ldrlo   r3, [r0, #-4]!
153     strlo   r3, [r2, #-4]!
154     blo     1b
156     mov     r0, #CACHE_OP_COMMIT
157     bl      cache_operation
159     and     r4, r4, #0xfc000000
161     ldr     r0, =MMAP_FLAGS
162     orr     r0, r0, r4 /* adjust for execute address */
163     ldr     r1, =MMAP_MASK
164     ldr     r2, =MMAP_LOG
165     ldr     r3, =MMAP_PHYS
166     str     r1, [r2] /* MMAP_LOG = MMAP_MASK */
167     str     r0, [r3] /* MMAP_PHYS = MMAP_FLAGS | SDRAM base addr */
169     /* wake the COP to jump it to the correct place */
170     ldr     r1, =COP_CTRL
171     mov     r0, #WAKE
172     str     r0, [r1]
174     /* wait for COP to halt then loading may proceed */
175     ldr     r1, =COP_STATUS
177     ldr     r0, [r1]
178     tst     r0, #COP_SLEEPING
179     beq     1b
181     ldr     r0, =start_stub_end
182     add     pc, r0, r4
184 cache_operation: /* (bool commit_discard) */
185     ldr     r2, =CACHE_CTRL
186     ldr     r1, [r2]
187     tst     r1, #CACHE_ENAB
188     bxeq    lr
189     cmp     r0, #CACHE_OP_COMMIT
190     ldr     r0, =0xf000f044
191     ldr     r1, [r0]
192     orrne   r1, r1, #0x6
193     orreq   r1, r1, #0x2
194     str     r1, [r0]
196     ldr     r1, [r2]
197     tst     r1, #0x8000
198     bne     1b
199     bx      lr
200     .ltorg /* constants used in stub come with us to IRAM */
201 start_stub_end:
202     /* now executing from final physical address */
204     /* copy the vector addresses to the table */
205     ldr     r0, =INT_VECT_TBL
206     adr     r1, vectorsstart
207     adr     r2, vectorsend
209     cmp     r2, r1
210     ldrhi   r3, [r1], #4
211     strhi   r3, [r0], #4
212     bhi     1b
214     /* Copy the IRAM */
215     ldr     r0, =_iramcopy
216     ldr     r1, =_iramstart
217     ldr     r2, =_iramend
219     cmp     r2, r1
220     ldrhi   r3, [r0], #4
221     strhi   r3, [r1], #4
222     bhi     1b
224     mov     r0, #0
226     /* Zero out IBSS */
227     ldr     r1, =_iedata
228     ldr     r2, =_iend
230     cmp     r2, r1
231     strhi   r0, [r1], #4
232     bhi     1b
234     /* Initialise bss/ncbss sections to zero */
235     ldr     r1, =_edata
236     ldr     r2, =_end
238     cmp     r2, r1
239     strhi   r0, [r1], #4
240     bhi     1b
242     /* Set up some stack and munge it with 0xdeadbeef */
243     ldr     r0, =0xdeadbeef
244     ldr     r1, =stackbegin
245     ldr     sp, =stackend
247     cmp     sp, r1
248     strhi   r0, [r1], #4
249     bhi     1b
251     /* Set up stack for IRQ mode */ 
252     msr     cpsr_c, #0xd2 /* IRQ/FIQ disabled */
253     ldr     sp, =irq_stack
254     /* Let abort and undefined modes use IRQ stack */
255     msr     cpsr_c, #0xd7 /* IRQ/FIQ disabled */
256     ldr     sp, =irq_stack
257     msr     cpsr_c, #0xdb /* IRQ/FIQ disabled */
258     ldr     sp, =irq_stack
260     /* Switch back to supervisor mode */
261     msr     cpsr_c, #0xd3
263     /* execute the loader - this will load an image to 0x10000000 */
264     ldr     r0, =main
265     mov     lr, pc
266     bx      r0
268     /* store actual startup location returned by main() */
269     ldr     r1, =startup_loc
270     str     r0, [r1]
272     /* write back anything loaded + startup_loc */
273     mov     r0, #CACHE_OP_COMMIT
274     bl      cache_operation
276     mov     r0, #0
278     /* disable memory mapper */
279     ldr     r1, =MMAP_LOG
280     ldr     r2, =MMAP_PHYS
281     str     r0, [r1]
282     str     r0, [r2]
284     /* bring COP back to life */
285     ldr     r1, =COP_CTRL
286     mov     r0, #WAKE
287     str     r0, [r1]
289     /* after this point, r0-r3 are reserved for OF magic */
291 #if defined(SANSA_C200) || defined(PHILIPS_HDD1630)
292     /* Magic for loading the c200 OF */
293     ldr     r0, =0xb00d10ad
294     mov     r1, #0x700
295     ldr     r2, =0xfff0
296     mov     r3, #0x7
297 #endif
299 #if defined(PHILIPS_HDD6330)
300     /* Magic for loading the HDD6XX0 OF */
301     ldr     r0, =0xb00d10ad
302     mov     r1, #0x800
303     ldr     r2, =0xfff0
304     mov     r3, #0x7
305 #endif
307     /* branch to the address returned by main() */
308     adr     r4, startup_loc
309     ldr     pc, [r4]
311 startup_loc:
312     .word   0x00000000
314 /* exception handlers: will be copied to local vector table */
315 vectorsstart:
316     .word   newstart 
317     .word   undef_instr_handler
318     .word   software_int_handler
319     .word   prefetch_abort_handler
320     .word   data_abort_handler
321     .word   reserved_handler
322     .word   irq_handler
323     .word   fiq_handler
324 vectorsend:
326     .text
328 /* All illegal exceptions call into UIE with exception address as first
329    parameter. This is calculated differently depending on which exception
330    we're in. Second parameter is exception number, used for a string lookup
331    in UIE.
332  */
333 undef_instr_handler:
334     sub     r0, lr, #4
335     mov     r1, #0
336     b       UIE
338 /* We run supervisor mode most of the time, and should never see a software
339    exception being thrown. Perhaps make it illegal and call UIE?
340  */
341 software_int_handler:
342 reserved_handler:
343     movs    pc, lr
344 prefetch_abort_handler:
345     sub     r0, lr, #4
346     mov     r1, #1
347     b       UIE
349 data_abort_handler:
350     sub     r0, lr, #8 
351     mov     r1, #2
352     b       UIE
354 /* should never happen in the bootloader */
355 fiq_handler:
356     subs    pc, lr, #4
358 /* 256 words of IRQ stack */
359     .section .bss
360     .balign 16
361     .space  256*4
362 irq_stack: