summaryrefslogtreecommitdiff
path: root/firmware/target/arm/crt0-pp.S
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/target/arm/crt0-pp.S')
-rw-r--r--firmware/target/arm/crt0-pp.S375
1 files changed, 375 insertions, 0 deletions
diff --git a/firmware/target/arm/crt0-pp.S b/firmware/target/arm/crt0-pp.S
new file mode 100644
index 0000000000..d847d9d943
--- /dev/null
+++ b/firmware/target/arm/crt0-pp.S
@@ -0,0 +1,375 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2002 by Linus Nielsen Feltzing
11 *
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.
14 *
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
17 *
18 ****************************************************************************/
19#include "config.h"
20#include "cpu.h"
21
22 .section .init.text,"ax",%progbits
23
24 .global start
25start:
26
27/* PortalPlayer bootloader and startup code based on startup.s from the iPodLinux
28 * loader
29 *
30 * Copyright (c) 2003, Daniel Palffy (dpalffy (at) rainstorm.org)
31 * Copyright (c) 2005, Bernard Leach <leachbj@bouncycastle.org>
32 *
33 */
34#if CONFIG_CPU == PP5002
35 .equ PROC_ID, 0xc4000000
36 .equ COP_CTRL, 0xcf004058
37 .equ COP_STATUS, 0xcf004050
38 .equ IIS_CONFIG, 0xc0002500
39 .equ SLEEP, 0xca
40 .equ WAKE, 0xce
41 .equ SLEEPING, 0x4000
42#else
43 .equ PROC_ID, 0x60000000
44 .equ COP_CTRL, 0x60007004
45 .equ COP_STATUS, 0x60007004
46 .equ IIS_CONFIG, 0x70002800
47 .equ SLEEP, 0x80000000
48 .equ WAKE, 0x0
49 .equ SLEEPING, 0x80000000
50#endif
51
52 msr cpsr_c, #0xd3 /* enter supervisor mode, disable IRQ */
53
54#ifndef BOOTLOADER
55 b pad_skip
56.space 50*4 /* (more than enough) space for exception vectors */
57pad_skip:
58 /* We need to remap memory from wherever SDRAM is mapped natively, to
59 base address 0, so we can put our exception vectors there. We don't
60 want to do this remapping while executing from SDRAM, so we copy the
61 remapping code to IRAM, then execute from there. Hence, the following
62 code is compiled for address 0, but is currently executing at either
63 0x28000000 or 0x10000000, depending on chipset version. Do not use any
64 absolute addresses until remapping has been done. */
65 ldr r1, =0x40000000
66 ldr r2, =remap_start
67 ldr r3, =remap_end
68
69 and r5, pc, #0xff000000 /* adjust for execute address */
70 orr r2, r2, r5
71 orr r3, r3, r5
72
73 /* copy the code to 0x40000000 */
741:
75 ldr r4, [r2], #4
76 str r4, [r1], #4
77 cmp r2, r3
78 ble 1b
79
80 ldr r3, =0x3f84 /* r3 and r1 values here are magic, don't touch */
81 orr r3, r3, r5 /* adjust for execute address */
82 ldr r2, =0xf000f014
83 mov r1, #0x3a00
84 ldr r0, =0xf000f010
85 mov pc, #0x40000000
86
87remap_start:
88 str r1, [r0]
89 str r3, [r2]
90 ldr r0, L_post_remap
91 mov pc, r0
92L_post_remap: .word remap_end
93remap_end:
94
95 /* After doing the remapping, send the COP to sleep.
96 On wakeup it will go to cop_init */
97 ldr r0, =PROC_ID
98 ldr r0, [r0]
99 and r0, r0, #0xff
100 cmp r0, #0x55
101 beq 1f
102
103 /* put us (co-processor) to sleep */
104 ldr r4, =COP_CTRL
105 mov r3, #SLEEP
106 str r3, [r4]
107
108 ldr pc, =cop_init
109
1101:
111
112#ifndef DEBUG
113 /* Copy exception handler code to address 0 */
114 ldr r2, =_vectorsstart
115 ldr r3, =_vectorsend
116 ldr r4, =_vectorscopy
1171:
118 cmp r3, r2
119 ldrhi r5, [r4], #4
120 strhi r5, [r2], #4
121 bhi 1b
122#else
123 ldr r1, =vectors
124 ldr r0, =irq_handler
125 str r0, [r1, #24]
126 ldr r0, =fiq_handler
127 str r0, [r1, #28]
128#endif
129
130#ifndef STUB
131 /* Zero out IBSS */
132 ldr r2, =_iedata
133 ldr r3, =_iend
134 mov r4, #0
1351:
136 cmp r3, r2
137 strhi r4, [r2], #4
138 bhi 1b
139
140 /* Copy the IRAM */
141 ldr r2, =_iramcopy
142 ldr r3, =_iramstart
143 ldr r4, =_iramend
1441:
145 cmp r4, r3
146 ldrhi r5, [r2], #4
147 strhi r5, [r3], #4
148 bhi 1b
149#endif /* !STUB */
150#endif /* !BOOTLOADER */
151
152 /* Initialise bss section to zero */
153 ldr r2, =_edata
154 ldr r3, =_end
155 mov r4, #0
1561:
157 cmp r3, r2
158 strhi r4, [r2], #4
159 bhi 1b
160
161 /* Set up some stack and munge it with 0xdeadbeef */
162 ldr sp, =stackend
163 mov r3, sp
164 ldr r2, =stackbegin
165 ldr r4, =0xdeadbeef
1661:
167 cmp r3, r2
168 strhi r4, [r2], #4
169 bhi 1b
170
171#ifdef BOOTLOADER
172 /* TODO: the high part of the address is probably dependent on CONFIG_CPU.
173 Since we tend to use ifdefs for each chipset target
174 anyway, we might as well just hardcode it here.
175 */
176
177 /* get the high part of our execute address */
178 ldr r0, =0xff000000
179 and r8, pc, r0 @ r8 is used later
180
181 /* Find out which processor we are */
182 mov r0, #PROC_ID
183 ldr r0, [r0]
184 and r0, r0, #0xff
185 cmp r0, #0x55
186 beq 1f
187
188 /* put us (co-processor) to sleep */
189 ldr r4, =COP_CTRL
190 mov r3, #SLEEP
191 str r3, [r4]
192 ldr pc, =cop_wake_start
193
194cop_wake_start:
195 /* jump the COP to startup */
196 ldr r0, =startup_loc
197 ldr pc, [r0]
198
1991:
200
201 /* get the high part of our execute address */
202 ldr r2, =0xffffff00
203 and r4, pc, r2
204
205 /* Copy bootloader to safe area - 0x40000000 */
206 mov r5, #0x40000000
207 ldr r6, = _dataend
208 sub r0, r6, r5 /* length of loader */
209 add r0, r4, r0 /* r0 points to start of loader */
2101:
211 cmp r5, r6
212 ldrcc r2, [r4], #4
213 strcc r2, [r5], #4
214 bcc 1b
215
216 ldr pc, =start_loc /* jump to the relocated start_loc: */
217
218start_loc:
219
220 /* execute the loader - this will load an image to 0x10000000 */
221 bl main
222
223 /* Wake up the coprocessor before executing the firmware */
224
225 /* save the startup address for the COP */
226 ldr r1, =startup_loc
227 str r0, [r1]
228
229 /* make sure COP is sleeping */
230 ldr r4, =COP_STATUS
2311:
232 ldr r3, [r4]
233 ands r3, r3, #SLEEPING
234 beq 1b
235
236 /* wake up COP */
237 ldr r4, =COP_CTRL
238 mov r3, #WAKE
239 str r3, [r4]
240
241 /* jump to start location */
242 mov pc, r0
243
244startup_loc:
245 .word 0x0
246
247.align 8 /* starts at 0x100 */
248.global boot_table
249boot_table:
250 /* here comes the boot table, don't move its offset */
251 .space 400
252
253#else /* BOOTLOADER */
254
255 /* Set up stack for IRQ mode */
256 msr cpsr_c, #0xd2
257 ldr sp, =irq_stack
258 /* Set up stack for FIQ mode */
259 msr cpsr_c, #0xd1
260 ldr sp, =fiq_stack
261 /* We'll load the banked FIQ mode registers with useful values here.
262 These values will be used in the FIQ handler in pcm_playback.c */
263 ldr r12, =IIS_CONFIG
264
265 ldr r11, =p
266
267 /* Let abort and undefined modes use IRQ stack */
268 msr cpsr_c, #0xd7
269 ldr sp, =irq_stack
270 msr cpsr_c, #0xdb
271 ldr sp, =irq_stack
272 /* Switch to supervisor mode */
273 msr cpsr_c, #0xd3
274 ldr sp, =stackend
275 bl main
276 /* main() should never return */
277
278cop_init:
279 ldr sp, =cop_stackend
280 mov r3, sp
281 ldr r2, =cop_stackbegin
282 ldr r4, =0xdeadbeef
2832:
284 cmp r3, r2
285 strhi r4, [r2], #4
286 bhi 2b
287
288 ldr sp, =cop_stackend
289 bl cop_main
290
291/* Exception handlers. Will be copied to address 0 after memory remapping */
292 .section .vectors,"aw"
293 ldr pc, [pc, #24]
294 ldr pc, [pc, #24]
295 ldr pc, [pc, #24]
296 ldr pc, [pc, #24]
297 ldr pc, [pc, #24]
298 ldr pc, [pc, #24]
299 ldr pc, [pc, #24]
300 ldr pc, [pc, #24]
301
302 /* Exception vectors */
303 .global vectors
304vectors:
305 .word start
306 .word undef_instr_handler
307 .word software_int_handler
308 .word prefetch_abort_handler
309 .word data_abort_handler
310 .word reserved_handler
311 .word irq_handler
312 .word fiq_handler
313
314 .text
315
316#ifndef STUB
317 .global irq
318 .global fiq
319 .global UIE
320#endif
321
322/* All illegal exceptions call into UIE with exception address as first
323 parameter. This is calculated differently depending on which exception
324 we're in. Second parameter is exception number, used for a string lookup
325 in UIE.
326 */
327undef_instr_handler:
328 mov r0, lr
329 mov r1, #0
330 b UIE
331
332/* We run supervisor mode most of the time, and should never see a software
333 exception being thrown. Perhaps make it illegal and call UIE?
334 */
335software_int_handler:
336reserved_handler:
337 movs pc, lr
338
339prefetch_abort_handler:
340 sub r0, lr, #4
341 mov r1, #1
342 b UIE
343
344fiq_handler:
345 @ Branch straight to FIQ handler in pcm_playback.c. This also handles the
346 @ the correct return sequence.
347 ldr pc, =fiq
348
349data_abort_handler:
350 sub r0, lr, #8
351 mov r1, #2
352 b UIE
353
354irq_handler:
355#ifndef STUB
356 stmfd sp!, {r0-r3, r12, lr}
357 bl irq
358 ldmfd sp!, {r0-r3, r12, lr}
359#endif
360 subs pc, lr, #4
361
362#ifdef STUB
363UIE:
364 b UIE
365#endif
366
367/* 256 words of IRQ stack */
368 .space 256*4
369irq_stack:
370
371/* 256 words of FIQ stack */
372 .space 256*4
373fiq_stack:
374
375#endif /* BOOTLOADER */