1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * Copyright (C) 2002 by Linus Nielsen Feltzing
11 * Copyright (C) 2010 by Michael Sevakis
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.
18 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19 * KIND, either express or implied.
21 ****************************************************************************/
25 /* PortalPlayer bootloader and startup code based on startup.s from the iPodLinux
28 * Copyright (c) 2003, Daniel Palffy (dpalffy (at) rainstorm.org)
29 * Copyright (c) 2005, Bernard Leach <leachbj@bouncycastle.org>
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
43 .equ MMAP_LOG, 0xf000f000 /* MMAP0 */
44 .equ MMAP_PHYS, 0xf000f004
45 .equ INT_VECT_TBL,0x6000f100
46 .equ CACHE_CTRL, 0x6000c000
48 .equ CACHE_OP_COMMIT_DISCARD, 0x1
49 .equ CACHE_OP_COMMIT , 0x0
51 .equ MMAP_MASK, 0x00003c00
53 .equ MMAP_MASK, 0x00003e00
55 .equ MMAP_FLAGS, 0x00000f84
60 .section .init.text,"ax",%progbits
66 .align 8 /* starts at 0x100 */
69 /* here comes the boot table, don't move its offset - preceding
70 code+data must stay <= 256 bytes */
72 #else /* !IPOD_ARCH */
73 /* (more than enough) space for exception vectors and mi4 magic */
75 #endif /* IPOD_ARCH */
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
85 adr r2, start_stub_end
100 mov r0, #CACHE_OP_COMMIT_DISCARD
106 /* sleep us (co-processor) while bootloader is copied */
112 /* branch to final physical load address */
114 and r4, r4, #0xfc000000
117 /* wait for bootloader to finish */
123 /* branch to the address returned by main() */
128 /* wait for COP to sleep */
132 tst r0, #COP_SLEEPING
135 mov r0, #CACHE_OP_COMMIT_DISCARD
138 /* move bootloader to the correct load address if needed */
139 ldr r1, =_loadaddress
141 ldrne r2, =_loadaddressend
143 sublo r3, r2, r1 /* size */
144 addlo r0, r0, r3 /* initial load end addr */
145 1: /* lower to higher move - copy up */
150 1: /* higher to lower move - copy down */
156 mov r0, #CACHE_OP_COMMIT
159 and r4, r4, #0xfc000000
162 orr r0, r0, r4 /* adjust for execute address */
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 */
174 /* wait for COP to halt then loading may proceed */
178 tst r0, #COP_SLEEPING
181 ldr r0, =start_stub_end
184 cache_operation: /* (bool commit_discard) */
189 cmp r0, #CACHE_OP_COMMIT
200 .ltorg /* constants used in stub come with us to IRAM */
202 /* now executing from final physical address */
204 /* copy the vector addresses to the table */
205 ldr r0, =INT_VECT_TBL
234 /* Initialise bss/ncbss sections to zero */
242 /* Set up some stack and munge it with 0xdeadbeef */
251 /* Set up stack for IRQ mode */
252 msr cpsr_c, #0xd2 /* IRQ/FIQ disabled */
254 /* Let abort and undefined modes use IRQ stack */
255 msr cpsr_c, #0xd7 /* IRQ/FIQ disabled */
257 msr cpsr_c, #0xdb /* IRQ/FIQ disabled */
260 /* Switch back to supervisor mode */
263 /* execute the loader - this will load an image to 0x10000000 */
268 /* store actual startup location returned by main() */
272 /* write back anything loaded + startup_loc */
273 mov r0, #CACHE_OP_COMMIT
278 /* disable memory mapper */
284 /* bring COP back to life */
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 */
299 #if defined(PHILIPS_HDD6330)
300 /* Magic for loading the HDD6XX0 OF */
307 /* branch to the address returned by main() */
314 /* exception handlers: will be copied to local vector table */
317 .word undef_instr_handler
318 .word software_int_handler
319 .word prefetch_abort_handler
320 .word data_abort_handler
321 .word reserved_handler
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
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?
341 software_int_handler:
344 prefetch_abort_handler:
354 /* should never happen in the bootloader */
358 /* 256 words of IRQ stack */