1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * Copyright (C) 2002 by Linus Nielsen Feltzing
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.
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
18 ****************************************************************************/
22 .section .init.text,"ax",%progbits
27 /* PortalPlayer bootloader and startup code based on startup.s from the iPodLinux
30 * Copyright (c) 2003, Daniel Palffy (dpalffy (at) rainstorm.org)
31 * Copyright (c) 2005, Bernard Leach <leachbj@bouncycastle.org>
34 #if CONFIG_CPU == PP5002
35 .equ PROC_ID, 0xc4000000
36 .equ CPU_ICLR, 0xcf001028
37 .equ CPU_CTRL, 0xcf004054
38 .equ COP_ICLR, 0xcf001038
39 .equ COP_CTRL, 0xcf004058
40 .equ CPU_STATUS, 0xcf004050
41 .equ COP_STATUS, 0xcf004050
42 .equ IIS_CONFIG, 0xc0002500
43 .equ SLEEP, 0x000000ca
45 .equ CPUSLEEPING, 0x00008000
46 .equ COPSLEEPING, 0x00004000
47 .equ CACHE_CTRL, 0xcf004024
48 .equ MMAP_LOG, 0xf000f000 /* MMAP0 */
49 .equ MMAP_PHYS, 0xf000f004
51 .equ MMAP_MASK, 0x00003c00
53 .equ MMAP_MASK, 0x00003e00
55 .equ MMAP_FLAGS, 0x00003f84
57 .equ PROC_ID, 0x60000000
58 .equ CPU_ICLR, 0x60004028
59 .equ CPU_CTRL, 0x60007000
60 .equ CPU_STATUS, 0x60007000
61 .equ COP_ICLR, 0x60004038
62 .equ COP_CTRL, 0x60007004
63 .equ COP_STATUS, 0x60007004
64 .equ IIS_CONFIG, 0x70002800
65 .equ SLEEP, 0x80000000
67 .equ CPUSLEEPING, 0x80000000
68 .equ COPSLEEPING, 0x80000000
69 .equ CACHE_CTRL, 0x6000c000
70 .equ MMAP_LOG, 0xf000f000 /* MMAP0 */
71 .equ MMAP_PHYS, 0xf000f004
73 .equ MMAP_MASK, 0x00003c00
75 .equ MMAP_MASK, 0x00003e00
77 .equ MMAP_FLAGS, 0x00000f84
80 msr cpsr_c, #0xd3 /* enter supervisor mode, disable IRQ/FIQ */
83 .space 64*4 /* (more than enough) space for exception vectors and mi4 magic */
86 /* Find out which processor we are - r0 should be preserved for the
87 * duration of the init to avoid constant reloading of the processor ID.
88 * For each stage, CPU proceeds first, then COP.
93 /* We need to remap memory from wherever SDRAM is mapped natively, to
94 base address 0, so we can put our exception vectors there. We don't
95 want to do this remapping while executing from SDRAM, so we copy the
96 remapping code to IRAM, then execute from there. Hence, the following
97 code is compiled for address 0, but is currently executing at either
98 0x28000000 or 0x10000000, depending on chipset version. Do not use any
99 absolute addresses until remapping has been done. */
101 /* Cores are stepped though the init in turn: CPU then COP. The the remap
102 stage is completed by each core in turn and then the COP waits for the
103 CPU to finish initializing its kernel where the CPU will wake the COP
104 and wait for the COP to finish. This ensures no threading activity
105 starts until it is safe. */
108 /* mask all interrupt sources before setting anything up */
114 /* put us (co-processor) to sleep and wait for CPU to remap */
122 /* wait for co-processor to sleep then CPU can begin its remapping */
123 ldreq r2, =COP_STATUS
126 tsteq r1, #COPSLEEPING
129 /* disable cache and local interrupt vectors - it is really not desireable
130 to have them enabled here */
139 and r6, pc, #0xff000000 /* adjust for execute address */
143 /* copy the code to 0x40000000 */
151 orr r4, r4, r6 /* adjust for execute address */
153 ldr r2, =MMAP_MASK /* ldr is more flexible */
168 /* Wakeup co-processor to let it do remappings */
170 /* Sleep us (co-processor) and wait for CPU to do kernel initialization */
177 /* Jump to co-processor init */
181 /* Wait for COP to go to sleep before proceeding */
188 /* Copy exception handler code to address 0 */
189 ldr r2, =_vectorsstart
191 ldr r4, =_vectorscopy
217 /* Initialise bss section to zero */
226 /* Load stack munge value */
229 /* Set up some stack and munge it with 0xdeadbeef */
238 /* Set up idle stack and munge it with 0xdeadbeef */
239 ldr r2, =cpu_idlestackbegin
240 ldr r3, =cpu_idlestackend
247 /* Set up stack for IRQ mode */
248 msr cpsr_c, #0x92 /* IRQ disabled, FIQ enabled */
250 /* Set up stack for FIQ mode */
251 msr cpsr_c, #0xd1 /* IRQ/FIQ disabled */
253 /* We'll load the banked FIQ mode registers with useful values here.
254 These values will be used in the FIQ handler in pcm-pp.c */
257 ldr r11, =dma_play_data
259 /* Let abort and undefined modes use IRQ stack */
260 msr cpsr_c, #0xd7 /* IRQ/FIQ disabled */
262 msr cpsr_c, #0xdb /* IRQ/FIQ disabled */
265 /* Switch back to supervisor mode */
268 /* Delay waking the COP until thread initialization is complete unless dual-core
269 support is not enabled in which case the cop_main function does not perform
270 any kernel or thread initialization. It's just a trivial sleep loop. */
278 /* main() should never return */
282 /* Wait for CPU to go to sleep at the end of its kernel init */
290 /* Set up idle stack for COP and munge it with 0xdeadbeef */
291 ldr sp, =cop_idlestackend
292 ldr r2, =cop_idlestackbegin
299 /* Set up stack for IRQ mode */
300 msr cpsr_c, #0x92 /* IRQ disabled, FIQ enabled */
301 ldr sp, =cop_irq_stack
302 /* Set up stack for FIQ mode */
303 msr cpsr_c, #0xd1 /* IRQ/FIQ disabled */
304 ldr sp, =cop_fiq_stack
306 /* Let abort and undefined modes use IRQ stack */
307 msr cpsr_c, #0xd7 /* IRQ/FIQ disabled */
308 ldr sp, =cop_irq_stack
309 msr cpsr_c, #0xdb /* IRQ/FIQ disabled */
310 ldr sp, =cop_irq_stack
312 /* Switch back to supervisor mode */
315 /* Run cop_main() in apps/main.c */
318 /* Exception handlers. Will be copied to address 0 after memory remapping */
319 .section .vectors,"aw"
329 /* Exception vectors */
333 .word undef_instr_handler
334 .word software_int_handler
335 .word prefetch_abort_handler
336 .word data_abort_handler
337 .word reserved_handler
348 /* All illegal exceptions call into UIE with exception address as first
349 parameter. This is calculated differently depending on which exception
350 we're in. Second parameter is exception number, used for a string lookup
358 /* We run supervisor mode most of the time, and should never see a software
359 exception being thrown. Perhaps make it illegal and call UIE?
361 software_int_handler:
364 prefetch_abort_handler:
376 stmfd sp!, {r0-r3, r12, lr}
378 ldmfd sp!, {r0-r3, r12, lr}
387 /* Align stacks to cache line boundary */
390 /* 256 words of IRQ stack */
394 /* 256 words of COP IRQ stack */
398 /* 256 words of FIQ stack */
402 /* We'll need this soon - just reserve the symbol */
404 /* 256 words of COP FIQ stack */