1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * Copyright (C) 2002 by Linus Nielsen Feltzing
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.
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
20 ****************************************************************************/
24 .section .init.text,"ax",%progbits
29 /* PortalPlayer bootloader and startup code based on startup.s from the iPodLinux
32 * Copyright (c) 2003, Daniel Palffy (dpalffy (at) rainstorm.org)
33 * Copyright (c) 2005, Bernard Leach <leachbj@bouncycastle.org>
36 #if CONFIG_CPU == PP5002
37 .equ PROC_ID, 0xc4000000
38 .equ CPU_ICLR, 0xcf001028
39 .equ CPU_CTRL, 0xcf004054
40 .equ COP_ICLR, 0xcf001038
41 .equ COP_CTRL, 0xcf004058
42 .equ CPU_STATUS, 0xcf004050
43 .equ COP_STATUS, 0xcf004050
44 .equ SLEEP, 0x000000ca
46 .equ CPUSLEEPING, 0x00008000
47 .equ COPSLEEPING, 0x00004000
48 .equ CACHE_CTRL, 0xcf004024
49 .equ MMAP_LOG, 0xf000f000 /* MMAP0 */
50 .equ MMAP_PHYS, 0xf000f004
52 .equ MMAP_MASK, 0x00003c00
54 .equ MMAP_MASK, 0x00003e00
56 .equ MMAP_FLAGS, 0x00003f84
58 .equ PROC_ID, 0x60000000
59 .equ CPU_ICLR, 0x60004028
60 .equ CPU_CTRL, 0x60007000
61 .equ CPU_STATUS, 0x60007000
62 .equ COP_ICLR, 0x60004038
63 .equ COP_CTRL, 0x60007004
64 .equ COP_STATUS, 0x60007004
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 6*4 /* pad to offset 0x20 */
85 .ascii "Rockbox" /* signature for bootloader checking osos */
86 .byte 1 /* osos boot version, only 1 exists for now */
88 .space 56*4 /* (more than enough) space for exception vectors and mi4 magic */
91 /* Find out which processor we are - r0 should be preserved for the
92 * duration of the init to avoid constant reloading of the processor ID.
93 * For each stage, CPU proceeds first, then COP.
98 /* We need to remap memory from wherever SDRAM is mapped natively, to
99 base address 0, so we can put our exception vectors there. We don't
100 want to do this remapping while executing from SDRAM, so we copy the
101 remapping code to IRAM, then execute from there. Hence, the following
102 code is compiled for address 0, but is currently executing at either
103 0x28000000 or 0x10000000, depending on chipset version. Do not use any
104 absolute addresses until remapping has been done. */
106 /* Cores are stepped though the init in turn: CPU then COP. The the remap
107 stage is completed by each core in turn and then the COP waits for the
108 CPU to finish initializing its kernel where the CPU will wake the COP
109 and wait for the COP to finish. This ensures no threading activity
110 starts until it is safe. */
113 /* mask all interrupt sources before setting anything up */
119 /* put us (co-processor) to sleep and wait for CPU to remap */
127 /* wait for co-processor to sleep then CPU can begin its remapping */
128 ldreq r2, =COP_STATUS
131 tsteq r1, #COPSLEEPING
134 /* disable cache and local interrupt vectors - it is really not desireable
135 to have them enabled here */
144 and r6, pc, #0xff000000 /* adjust for execute address */
148 /* copy the code to 0x40000000 */
156 orr r4, r4, r6 /* adjust for execute address */
158 ldr r2, =MMAP_MASK /* ldr is more flexible */
173 /* Wakeup co-processor to let it do remappings */
175 /* Sleep us (co-processor) and wait for CPU to do kernel initialization */
182 /* Jump to co-processor init */
186 /* Wait for COP to go to sleep before proceeding */
193 /* Vectors and IRAM copy is done first since they are reclaimed for
194 * other uninitialized sections */
196 /* Copy exception handler code to address 0 */
197 ldr r2, =_vectorsstart
199 ldr r4, =_vectorscopy
225 /* Initialise bss section to zero */
234 /* Load stack munge value */
237 /* Set up some stack and munge it with 0xdeadbeef */
246 /* Set up idle stack and munge it with 0xdeadbeef */
247 ldr r2, =cpu_idlestackbegin
248 ldr r3, =cpu_idlestackend
255 /* Set up stack for IRQ mode */
256 msr cpsr_c, #0x92 /* IRQ disabled, FIQ enabled */
258 /* Set up stack for FIQ mode */
259 msr cpsr_c, #0xd1 /* IRQ/FIQ disabled */
261 /* Let abort and undefined modes use IRQ stack */
262 msr cpsr_c, #0xd7 /* IRQ/FIQ disabled */
264 msr cpsr_c, #0xdb /* IRQ/FIQ disabled */
267 /* Switch back to supervisor mode */
270 /* Delay waking the COP until thread initialization is complete unless dual-core
271 support is not enabled in which case the cop_main function does not perform
272 any kernel or thread initialization. It's just a trivial sleep loop. */
280 /* main() should never return */
284 /* Wait for CPU to go to sleep at the end of its kernel init */
292 /* Set up idle stack for COP and munge it with 0xdeadbeef */
293 ldr sp, =cop_idlestackend
294 ldr r2, =cop_idlestackbegin
301 /* Set up stack for IRQ mode */
302 msr cpsr_c, #0x92 /* IRQ disabled, FIQ enabled */
303 ldr sp, =cop_irq_stack
304 /* Set up stack for FIQ mode */
305 msr cpsr_c, #0xd1 /* IRQ/FIQ disabled */
306 ldr sp, =cop_fiq_stack
308 /* Let abort and undefined modes use IRQ stack */
309 msr cpsr_c, #0xd7 /* IRQ/FIQ disabled */
310 ldr sp, =cop_irq_stack
311 msr cpsr_c, #0xdb /* IRQ/FIQ disabled */
312 ldr sp, =cop_irq_stack
314 /* Switch back to supervisor mode */
317 /* Run cop_main() in apps/main.c */
320 /* Exception handlers. Will be copied to address 0 after memory remapping */
321 .section .vectors,"aw"
331 /* Exception vectors */
335 .word undef_instr_handler
336 .word software_int_handler
337 .word prefetch_abort_handler
338 .word data_abort_handler
339 .word reserved_handler
345 /* All illegal exceptions call into UIE with exception address as first
346 parameter. This is calculated differently depending on which exception
347 we're in. Second parameter is exception number, used for a string lookup
355 /* We run supervisor mode most of the time, and should never see a software
356 exception being thrown. Perhaps make it illegal and call UIE?
358 software_int_handler:
361 prefetch_abort_handler:
371 /* Align stacks to cache line boundary */
374 /* 256 words of IRQ stack */
378 /* 256 words of COP IRQ stack */
382 /* 256 words of FIQ stack */
386 /* We'll need this soon - just reserve the symbol */
388 /* 256 words of COP FIQ stack */