summaryrefslogtreecommitdiff
path: root/firmware/target/arm/pp/crt0-pp.S
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/target/arm/pp/crt0-pp.S')
-rw-r--r--firmware/target/arm/pp/crt0-pp.S430
1 files changed, 430 insertions, 0 deletions
diff --git a/firmware/target/arm/pp/crt0-pp.S b/firmware/target/arm/pp/crt0-pp.S
new file mode 100644
index 0000000000..5a9835a71f
--- /dev/null
+++ b/firmware/target/arm/pp/crt0-pp.S
@@ -0,0 +1,430 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2002 by Linus Nielsen Feltzing
11 *
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.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21#include "config.h"
22#include "cpu.h"
23
24 .section .init.text,"ax",%progbits
25
26 .global start
27start:
28
29/* PortalPlayer bootloader and startup code based on startup.s from the iPodLinux
30 * loader
31 *
32 * Copyright (c) 2003, Daniel Palffy (dpalffy (at) rainstorm.org)
33 * Copyright (c) 2005, Bernard Leach <leachbj@bouncycastle.org>
34 *
35 */
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
45 .equ WAKE, 0x000000ce
46 .equ CPUSLEEPING, 0x00008000
47 .equ COPSLEEPING, 0x00004000
48 .equ CACHE_CTRL, 0xcf004024
49 .equ MMAP_LOG, 0xf000f000 /* MMAP0 */
50 .equ MMAP_PHYS, 0xf000f004
51#if MEMORYSIZE > 32
52 .equ MMAP_MASK, 0x00003c00
53#else
54 .equ MMAP_MASK, 0x00003e00
55#endif
56 .equ MMAP_FLAGS, 0x00003f84
57#else
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
66 .equ WAKE, 0x00000000
67 .equ CPUSLEEPING, 0x80000000
68 .equ COPSLEEPING, 0x80000000
69 .equ CACHE_CTRL, 0x6000c000
70 .equ MMAP_LOG, 0xf000f000 /* MMAP0 */
71 .equ MMAP_PHYS, 0xf000f004
72#if MEMORYSIZE > 32
73 .equ MMAP_MASK, 0x00003c00
74#else
75 .equ MMAP_MASK, 0x00003e00
76#endif
77 .equ MMAP_FLAGS, 0x00000f84
78#endif
79
80 msr cpsr_c, #0xd3 /* enter supervisor mode, disable IRQ/FIQ */
81 b pad_skip
82
83.space 6*4 /* pad to offset 0x20 */
84
85 .ascii "Rockbox" /* signature for bootloader checking osos */
86 .byte 1 /* osos boot version, only 1 exists for now */
87
88.space 56*4 /* (more than enough) space for exception vectors and mi4 magic */
89
90pad_skip:
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.
94 */
95 ldr r0, =PROC_ID
96 ldrb r0, [r0]
97
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. */
105
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. */
111 cmp r0, #0x55
112
113 /* mask all interrupt sources before setting anything up */
114 ldreq r2, =CPU_ICLR
115 ldrne r2, =COP_ICLR
116 mvn r1, #0
117 str r1, [r2]
118
119 /* put us (co-processor) to sleep and wait for CPU to remap */
120 ldrne r2, =COP_CTRL
121 movne r1, #SLEEP
122 strne r1, [r2]
123 nop
124 nop
125 nop
126
127 /* wait for co-processor to sleep then CPU can begin its remapping */
128 ldreq r2, =COP_STATUS
1291:
130 ldreq r1, [r2]
131 tsteq r1, #COPSLEEPING
132 beq 1b
133
134 /* disable cache and local interrupt vectors - it is really not desireable
135 to have them enabled here */
136 ldr r2, =CACHE_CTRL
137 mov r1, #0
138 str r1, [r2]
139
140#if defined(IPOD_VIDEO)
141 /* detect 32mb vs 64mb model */
142 /* we do this here because after SDRAM is remapped, we already assumed */
143 /* its size to be whatever we were compiled for. */
144
145 mov r2, #0x12000000
146 mov r3, #64
147 strb r3, [r2, #-1] /* first write 64 to last byte of first 32MB bank */
148
149 mov r2, #0x14000000
150 mov r3, #32
151 strb r3, [r2, #-1] /* now write 32 to last byte of second 32MB bank */
152
153 /* now the last word of the first 32MB bank tells you the RAM size */
154 /* since on a 32MB model both writes will touch the same actual location */
155 /* this is read later on in boot */
156#endif
157
158 mov r2, #0x40000000
159 ldr r3, =remap_start
160 ldr r4, =remap_end
161
162 and r6, pc, #0xff000000 /* adjust for execute address */
163 orr r3, r3, r6
164 orr r4, r4, r6
165
166 /* copy the code to 0x40000000 */
1671:
168 ldr r5, [r3], #4
169 str r5, [r2], #4
170 cmp r3, r4
171 blo 1b
172
173 ldr r4, =MMAP_FLAGS
174 orr r4, r4, r6 /* adjust for execute address */
175 ldr r3, =MMAP_PHYS
176 ldr r2, =MMAP_MASK /* ldr is more flexible */
177 ldr r1, =MMAP_LOG
178 mov pc, #0x40000000
179
180remap_start:
181 str r2, [r1]
182 str r4, [r3]
183 ldr r1, L_post_remap
184 bx r1
185L_post_remap:
186 .word remap_end
187remap_end:
188
189 cmp r0, #0x55
190 ldr r4, =COP_CTRL
191 /* Wakeup co-processor to let it do remappings */
192 moveq r3, #WAKE
193 /* Sleep us (co-processor) and wait for CPU to do kernel initialization */
194 movne r3, #SLEEP
195 str r3, [r4]
196 nop
197 nop
198 nop
199
200 /* Jump to co-processor init */
201 ldrne pc, =cop_init
202
203cpu_init:
204 /* Wait for COP to go to sleep before proceeding */
205 ldr r4, =COP_STATUS
2061:
207 ldr r3, [r4]
208 tst r3, #COPSLEEPING
209 beq 1b
210
211 /* Vectors and IRAM copy is done first since they are reclaimed for
212 * other uninitialized sections */
213
214 /* Copy exception handler code to address 0 */
215 ldr r2, =_vectorsstart
216 ldr r3, =_vectorsend
217 ldr r4, =_vectorscopy
2181:
219 cmp r3, r2
220 ldrhi r5, [r4], #4
221 strhi r5, [r2], #4
222 bhi 1b
223
224 /* Copy the IRAM */
225 ldr r2, =_iramcopy
226 ldr r3, =_iramstart
227 ldr r4, =_iramend
2281:
229 cmp r4, r3
230 ldrhi r5, [r2], #4
231 strhi r5, [r3], #4
232 bhi 1b
233
234#ifdef HAVE_INIT_ATTR
235 /* copy init code to codec buffer */
236 ldr r2, =_initstart
237 ldr r3, =_initend
238 ldr r4, =_initcopy
239
2401:
241 cmp r3, r2
242 ldrhi r5, [r4], #4
243 strhi r5, [r2], #4
244 bhi 1b
245#endif
246
247 /* Zero out IBSS */
248 ldr r2, =_iedata
249 ldr r3, =_iend
250 mov r4, #0
2511:
252 cmp r3, r2
253 strhi r4, [r2], #4
254 bhi 1b
255
256 /* Initialise bss section to zero */
257 ldr r2, =_edata
258 ldr r3, =_end
259 mov r4, #0
2601:
261 cmp r3, r2
262 strhi r4, [r2], #4
263 bhi 1b
264
265 /* Load stack munge value */
266 ldr r4, =0xdeadbeef
267
268#if NUM_CORES > 1
269 /* Set up idle stack and munge it with 0xdeadbeef */
270 ldr r2, =cpu_idlestackbegin
271 ldr r3, =cpu_idlestackend
2721:
273 cmp r3, r2
274 strhi r4, [r2], #4
275 bhi 1b
276#endif
277
278 /* Set up stack for IRQ mode */
279 msr cpsr_c, #0x92 /* IRQ disabled, FIQ enabled */
280 ldr sp, =irq_stack
281 /* Set up stack for FIQ mode */
282 msr cpsr_c, #0xd1 /* IRQ/FIQ disabled */
283 ldr sp, =fiq_stack
284
285 /* Let svc, abort and undefined modes use irq stack */
286 msr cpsr_c, #0xd3 /* IRQ/FIQ disabled */
287 ldr sp, =irq_stack
288 msr cpsr_c, #0xd7 /* IRQ/FIQ disabled */
289 ldr sp, =irq_stack
290 msr cpsr_c, #0xdb /* IRQ/FIQ disabled */
291 ldr sp, =irq_stack
292
293 /* Switch to sys mode */
294 msr cpsr_c, #0xdf
295
296 /* Set up some stack and munge it with 0xdeadbeef */
297 ldr r2, =stackbegin
298 ldr sp, =stackend
2991:
300 cmp sp, r2
301 strhi r4, [r2], #4
302 bhi 1b
303
304 /* Delay waking the COP until thread initialization is complete unless dual-core
305 support is not enabled in which case the cop_main function does not perform
306 any kernel or thread initialization. It's just a trivial sleep loop. */
307#if NUM_CORES == 1
308 ldr r4, =COP_CTRL
309 mov r3, #WAKE
310 str r3, [r4]
311#endif
312
313 ldr pc, =main
314 /* main() should never return */
315
316cop_init:
317#if NUM_CORES > 1
318 /* Wait for CPU to go to sleep at the end of its kernel init */
319 ldr r4, =CPU_STATUS
3201:
321 ldr r3, [r4]
322 tst r3, #CPUSLEEPING
323 beq 1b
324#endif
325
326 /* Set up stack for IRQ mode */
327 msr cpsr_c, #0x92 /* IRQ disabled, FIQ enabled */
328 ldr sp, =cop_irq_stack
329 /* Set up stack for FIQ mode */
330 msr cpsr_c, #0xd1 /* IRQ/FIQ disabled */
331 ldr sp, =cop_fiq_stack
332
333 /* Let svc, abort and undefined modes use irq stack */
334 msr cpsr_c, #0xd3 /* IRQ/FIQ disabled */
335 ldr sp, =cop_irq_stack
336 msr cpsr_c, #0xd7 /* IRQ/FIQ disabled */
337 ldr sp, =cop_irq_stack
338 msr cpsr_c, #0xdb /* IRQ/FIQ disabled */
339 ldr sp, =cop_irq_stack
340
341 /* Switch to sys mode */
342 msr cpsr_c, #0xdf
343
344 /* Set up idle stack for COP and munge it with 0xdeadbeef */
345 ldr sp, =cop_idlestackend
346 ldr r2, =cop_idlestackbegin
347 ldr r4, =0xdeadbeef
3482:
349 cmp sp, r2
350 strhi r4, [r2], #4
351 bhi 2b
352
353 /* Run cop_main() in apps/main.c */
354 ldr pc, =cop_main
355
356/* Exception handlers. Will be copied to address 0 after memory remapping */
357 .section .vectors,"aw"
358 ldr pc, [pc, #24]
359 ldr pc, [pc, #24]
360 ldr pc, [pc, #24]
361 ldr pc, [pc, #24]
362 ldr pc, [pc, #24]
363 ldr pc, [pc, #24]
364 ldr pc, [pc, #24]
365 ldr pc, [pc, #24]
366
367 /* Exception vectors */
368 .global vectors
369vectors:
370 .word start
371 .word undef_instr_handler
372 .word software_int_handler
373 .word prefetch_abort_handler
374 .word data_abort_handler
375 .word reserved_handler
376 .word irq_handler
377 .word fiq_handler
378
379 .text
380
381/* All illegal exceptions call into UIE with exception address as first
382 parameter. This is calculated differently depending on which exception
383 we're in. Second parameter is exception number, used for a string lookup
384 in UIE.
385 */
386undef_instr_handler:
387 sub r0, lr, #4
388 mov r1, #0
389 b UIE
390
391/* We run sys mode most of the time, and should never see a software
392 exception being thrown. Make it illegal and call UIE.
393 */
394software_int_handler:
395reserved_handler:
396 sub r0, lr, #4
397 mov r1, #4
398 b UIE
399
400prefetch_abort_handler:
401 sub r0, lr, #4
402 mov r1, #1
403 b UIE
404
405data_abort_handler:
406 sub r0, lr, #8
407 mov r1, #2
408 b UIE
409
410/* Align stacks to cache line boundary */
411 .balign 32
412
413/* 256 words of IRQ stack */
414 .space 256*4
415irq_stack:
416
417/* 256 words of COP IRQ stack */
418 .space 256*4
419cop_irq_stack:
420
421/* 256 words of FIQ stack */
422 .space 256*4
423fiq_stack:
424
425/* We'll need this soon - just reserve the symbol */
426#if 0
427/* 256 words of COP FIQ stack */
428 .space 256*4
429#endif
430cop_fiq_stack: