summaryrefslogtreecommitdiff
path: root/firmware/target/arm/pp/crt0-pp502x-bl-usb.S
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/target/arm/pp/crt0-pp502x-bl-usb.S')
-rw-r--r--firmware/target/arm/pp/crt0-pp502x-bl-usb.S367
1 files changed, 367 insertions, 0 deletions
diff --git a/firmware/target/arm/pp/crt0-pp502x-bl-usb.S b/firmware/target/arm/pp/crt0-pp502x-bl-usb.S
new file mode 100644
index 0000000000..7b0489b2a8
--- /dev/null
+++ b/firmware/target/arm/pp/crt0-pp502x-bl-usb.S
@@ -0,0 +1,367 @@
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"
24
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
56
57/*
58 * Entry point
59 */
60 .section .init.text,"ax",%progbits
61 .global start
62start:
63 b newstart
64
65#ifdef IPOD_ARCH
66.align 8 /* starts at 0x100 */
67.global boot_table
68boot_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 */
76
77newstart:
78 msr cpsr_c, #0xd3 /* enter supervisor mode, disable IRQ/FIQ */
79 adr r4, start /* cache initial load address */
80
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
861:
87 ldr r3, [r0], #4
88 str r3, [r1], #4
89 cmp r0, r2
90 blo 1b
91 mov pc, #0x40000000
92
93start_stub_begin:
94 ldr r0, =PROC_ID
95 ldrb r0, [r0]
96 cmp r0, #0x55
97 beq cpu
98
99cop:
100 mov r0, #CACHE_OP_COMMIT_DISCARD
101 bl cache_operation
102
103 ldr r1, =COP_CTRL
104 mov r0, #SLEEP
105
106 /* sleep us (co-processor) while bootloader is copied */
107 str r0, [r1]
108 nop
109 nop
110 nop
111
112 /* branch to final physical load address */
113 ldr r2, =1f
114 and r4, r4, #0xfc000000
115 add pc, r2, r4
1161:
117 /* wait for bootloader to finish */
118 str r0, [r1]
119 nop
120 nop
121 nop
122
123 /* branch to the address returned by main() */
124 adr r0, startup_loc
125 ldr pc, [r0]
126
127cpu:
128 /* wait for COP to sleep */
129 ldr r1, =COP_STATUS
1301:
131 ldr r0, [r1]
132 tst r0, #COP_SLEEPING
133 beq 1b
134
135 mov r0, #CACHE_OP_COMMIT_DISCARD
136 bl cache_operation
137
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 */
1451: /* lower to higher move - copy up */
146 cmphi r2, r1
147 ldrhi r3, [r0], #4
148 strhi r3, [r1], #4
149 bhi 1b
1501: /* higher to lower move - copy down */
151 cmplo r1, r2
152 ldrlo r3, [r0, #-4]!
153 strlo r3, [r2, #-4]!
154 blo 1b
155
156 mov r0, #CACHE_OP_COMMIT
157 bl cache_operation
158
159 and r4, r4, #0xfc000000
160
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 */
168
169 /* wake the COP to jump it to the correct place */
170 ldr r1, =COP_CTRL
171 mov r0, #WAKE
172 str r0, [r1]
173
174 /* wait for COP to halt then loading may proceed */
175 ldr r1, =COP_STATUS
1761:
177 ldr r0, [r1]
178 tst r0, #COP_SLEEPING
179 beq 1b
180
181 ldr r0, =start_stub_end
182 add pc, r0, r4
183
184cache_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]
1951:
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 */
201start_stub_end:
202 /* now executing from final physical address */
203
204 /* copy the vector addresses to the table */
205 ldr r0, =INT_VECT_TBL
206 adr r1, vectorsstart
207 adr r2, vectorsend
2081:
209 cmp r2, r1
210 ldrhi r3, [r1], #4
211 strhi r3, [r0], #4
212 bhi 1b
213
214 /* Copy the IRAM */
215 ldr r0, =_iramcopy
216 ldr r1, =_iramstart
217 ldr r2, =_iramend
2181:
219 cmp r2, r1
220 ldrhi r3, [r0], #4
221 strhi r3, [r1], #4
222 bhi 1b
223
224 mov r0, #0
225
226 /* Zero out IBSS */
227 ldr r1, =_iedata
228 ldr r2, =_iend
2291:
230 cmp r2, r1
231 strhi r0, [r1], #4
232 bhi 1b
233
234 /* Initialise bss/ncbss sections to zero */
235 ldr r1, =_edata
236 ldr r2, =_end
2371:
238 cmp r2, r1
239 strhi r0, [r1], #4
240 bhi 1b
241
242 /* Set up stack for IRQ mode */
243 msr cpsr_c, #0xd2 /* IRQ/FIQ disabled */
244 ldr sp, =irq_stack
245 /* Let svc, abort and undefined modes use irq stack */
246 msr cpsr_c, #0xd3
247 ldr sp, =irq_stack
248 msr cpsr_c, #0xd7 /* IRQ/FIQ disabled */
249 ldr sp, =irq_stack
250 msr cpsr_c, #0xdb /* IRQ/FIQ disabled */
251 ldr sp, =irq_stack
252
253 /* Switch back to sys mode */
254 msr cpsr_c, #0xdf
255
256 /* Set up some stack and munge it with 0xdeadbeef */
257 ldr r0, =0xdeadbeef
258 ldr r1, =stackbegin
259 ldr sp, =stackend
2601:
261 cmp sp, r1
262 strhi r0, [r1], #4
263 bhi 1b
264
265 /* execute the loader - this will load an image to 0x10000000 */
266 ldr r0, =main
267 mov lr, pc
268 bx r0
269
270 /* store actual startup location returned by main() */
271 ldr r1, =startup_loc
272 str r0, [r1]
273
274 /* write back anything loaded + startup_loc */
275 mov r0, #CACHE_OP_COMMIT
276 bl cache_operation
277
278 mov r0, #0
279
280 /* disable memory mapper */
281 ldr r1, =MMAP_LOG
282 ldr r2, =MMAP_PHYS
283 str r0, [r1]
284 str r0, [r2]
285
286 /* bring COP back to life */
287 ldr r1, =COP_CTRL
288 mov r0, #WAKE
289 str r0, [r1]
290
291 /* after this point, r0-r3 are reserved for OF magic */
292
293#if defined(SANSA_C200) || defined(PHILIPS_HDD1630)
294 /* Magic for loading the c200 OF */
295 ldr r0, =0xb00d10ad
296 mov r1, #0x700
297 ldr r2, =0xfff0
298 mov r3, #0x7
299#endif
300
301#if defined(PHILIPS_HDD6330)
302 /* Magic for loading the HDD6XX0 OF */
303 ldr r0, =0xb00d10ad
304 mov r1, #0x800
305 ldr r2, =0xfff0
306 mov r3, #0x7
307#endif
308
309 /* branch to the address returned by main() */
310 adr r4, startup_loc
311 ldr pc, [r4]
312
313startup_loc:
314 .word 0x00000000
315
316/* exception handlers: will be copied to local vector table */
317vectorsstart:
318 .word newstart
319 .word undef_instr_handler
320 .word software_int_handler
321 .word prefetch_abort_handler
322 .word data_abort_handler
323 .word reserved_handler
324 .word irq_handler
325 .word fiq_handler
326vectorsend:
327
328 .text
329
330/* All illegal exceptions call into UIE with exception address as first
331 parameter. This is calculated differently depending on which exception
332 we're in. Second parameter is exception number, used for a string lookup
333 in UIE.
334 */
335undef_instr_handler:
336 sub r0, lr, #4
337 mov r1, #0
338 b UIE
339
340/* We run sys mode most of the time, and should never see a software
341 exception being thrown. Make it illegal and call UIE.
342 */
343software_int_handler:
344reserved_handler:
345 sub r0, lr, #4
346 mov r1, #4
347 b UIE
348
349prefetch_abort_handler:
350 sub r0, lr, #4
351 mov r1, #1
352 b UIE
353
354data_abort_handler:
355 sub r0, lr, #8
356 mov r1, #2
357 b UIE
358
359/* should never happen in the bootloader */
360fiq_handler:
361 subs pc, lr, #4
362
363/* 256 words of IRQ stack */
364 .section .bss
365 .balign 16
366 .space 256*4
367irq_stack: