diff options
Diffstat (limited to 'firmware/target/arm/crt0.S')
-rw-r--r-- | firmware/target/arm/crt0.S | 232 |
1 files changed, 232 insertions, 0 deletions
diff --git a/firmware/target/arm/crt0.S b/firmware/target/arm/crt0.S new file mode 100644 index 0000000000..82b7c31f92 --- /dev/null +++ b/firmware/target/arm/crt0.S | |||
@@ -0,0 +1,232 @@ | |||
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 | ||
25 | start: | ||
26 | |||
27 | /* Arm bootloader and startup code based on startup.s from the iPodLinux loader | ||
28 | * | ||
29 | * Copyright (c) 2003, Daniel Palffy (dpalffy (at) rainstorm.org) | ||
30 | * Copyright (c) 2005, Bernard Leach <leachbj@bouncycastle.org> | ||
31 | * | ||
32 | */ | ||
33 | |||
34 | msr cpsr_c, #0xd3 /* enter supervisor mode, disable IRQ */ | ||
35 | |||
36 | #ifndef BOOTLOADER | ||
37 | #if CONFIG_CPU == PNX0101 | ||
38 | |||
39 | #ifndef DEBUG | ||
40 | ldr r0, =0x80105000 | ||
41 | mov r1, #1 | ||
42 | str r1, [r0, #4] | ||
43 | mov r1, #0 | ||
44 | str r1, [r0, #4] | ||
45 | 1: ldr r1, [r0] | ||
46 | cmp r1, #0 | ||
47 | bne 1b | ||
48 | mov r1, #0x74 | ||
49 | str r1, [r0, #8] | ||
50 | mov r1, #2 | ||
51 | str r1, [r0, #0x18] | ||
52 | mov r1, #0x120 | ||
53 | str r1, [r0, #0x30] | ||
54 | mov r1, #6 | ||
55 | str r1, [r0, #4] | ||
56 | ldr r0, =1f | ||
57 | mov r15, r0 | ||
58 | 1: | ||
59 | #endif /* !DEBUG */ | ||
60 | #endif /* chipset specific */ | ||
61 | |||
62 | #ifndef DEBUG | ||
63 | /* Copy exception handler code to address 0 */ | ||
64 | ldr r2, =_vectorsstart | ||
65 | ldr r3, =_vectorsend | ||
66 | ldr r4, =_vectorscopy | ||
67 | 1: | ||
68 | cmp r3, r2 | ||
69 | ldrhi r5, [r4], #4 | ||
70 | strhi r5, [r2], #4 | ||
71 | bhi 1b | ||
72 | #else | ||
73 | ldr r1, =vectors | ||
74 | ldr r0, =irq_handler | ||
75 | str r0, [r1, #24] | ||
76 | ldr r0, =fiq_handler | ||
77 | str r0, [r1, #28] | ||
78 | #endif | ||
79 | |||
80 | #ifndef STUB | ||
81 | /* Zero out IBSS */ | ||
82 | ldr r2, =_iedata | ||
83 | ldr r3, =_iend | ||
84 | mov r4, #0 | ||
85 | 1: | ||
86 | cmp r3, r2 | ||
87 | strhi r4, [r2], #4 | ||
88 | bhi 1b | ||
89 | |||
90 | /* Copy the IRAM */ | ||
91 | ldr r2, =_iramcopy | ||
92 | ldr r3, =_iramstart | ||
93 | ldr r4, =_iramend | ||
94 | 1: | ||
95 | cmp r4, r3 | ||
96 | ldrhi r5, [r2], #4 | ||
97 | strhi r5, [r3], #4 | ||
98 | bhi 1b | ||
99 | #endif /* !STUB */ | ||
100 | #endif /* !BOOTLOADER */ | ||
101 | |||
102 | /* Initialise bss section to zero */ | ||
103 | ldr r2, =_edata | ||
104 | ldr r3, =_end | ||
105 | mov r4, #0 | ||
106 | 1: | ||
107 | cmp r3, r2 | ||
108 | strhi r4, [r2], #4 | ||
109 | bhi 1b | ||
110 | |||
111 | /* Set up some stack and munge it with 0xdeadbeef */ | ||
112 | ldr sp, =stackend | ||
113 | mov r3, sp | ||
114 | ldr r2, =stackbegin | ||
115 | ldr r4, =0xdeadbeef | ||
116 | 1: | ||
117 | cmp r3, r2 | ||
118 | strhi r4, [r2], #4 | ||
119 | bhi 1b | ||
120 | |||
121 | #ifdef BOOTLOADER | ||
122 | /* Code for ARM bootloader targets other than iPod go here */ | ||
123 | |||
124 | #if CONFIG_CPU == S3C2440 | ||
125 | bl main | ||
126 | #endif | ||
127 | |||
128 | #else /* BOOTLOADER */ | ||
129 | |||
130 | /* Set up stack for IRQ mode */ | ||
131 | msr cpsr_c, #0xd2 | ||
132 | ldr sp, =irq_stack | ||
133 | /* Set up stack for FIQ mode */ | ||
134 | msr cpsr_c, #0xd1 | ||
135 | ldr sp, =fiq_stack | ||
136 | |||
137 | /* Let abort and undefined modes use IRQ stack */ | ||
138 | msr cpsr_c, #0xd7 | ||
139 | ldr sp, =irq_stack | ||
140 | msr cpsr_c, #0xdb | ||
141 | ldr sp, =irq_stack | ||
142 | /* Switch to supervisor mode */ | ||
143 | msr cpsr_c, #0xd3 | ||
144 | ldr sp, =stackend | ||
145 | bl main | ||
146 | /* main() should never return */ | ||
147 | |||
148 | /* Exception handlers. Will be copied to address 0 after memory remapping */ | ||
149 | .section .vectors,"aw" | ||
150 | ldr pc, [pc, #24] | ||
151 | ldr pc, [pc, #24] | ||
152 | ldr pc, [pc, #24] | ||
153 | ldr pc, [pc, #24] | ||
154 | ldr pc, [pc, #24] | ||
155 | ldr pc, [pc, #24] | ||
156 | ldr pc, [pc, #24] | ||
157 | ldr pc, [pc, #24] | ||
158 | |||
159 | /* Exception vectors */ | ||
160 | .global vectors | ||
161 | vectors: | ||
162 | .word start | ||
163 | .word undef_instr_handler | ||
164 | .word software_int_handler | ||
165 | .word prefetch_abort_handler | ||
166 | .word data_abort_handler | ||
167 | .word reserved_handler | ||
168 | .word irq_handler | ||
169 | .word fiq_handler | ||
170 | |||
171 | .text | ||
172 | |||
173 | #ifndef STUB | ||
174 | .global irq | ||
175 | .global fiq | ||
176 | .global UIE | ||
177 | #endif | ||
178 | |||
179 | /* All illegal exceptions call into UIE with exception address as first | ||
180 | parameter. This is calculated differently depending on which exception | ||
181 | we're in. Second parameter is exception number, used for a string lookup | ||
182 | in UIE. | ||
183 | */ | ||
184 | undef_instr_handler: | ||
185 | mov r0, lr | ||
186 | mov r1, #0 | ||
187 | b UIE | ||
188 | |||
189 | /* We run supervisor mode most of the time, and should never see a software | ||
190 | exception being thrown. Perhaps make it illegal and call UIE? | ||
191 | */ | ||
192 | software_int_handler: | ||
193 | reserved_handler: | ||
194 | movs pc, lr | ||
195 | |||
196 | prefetch_abort_handler: | ||
197 | sub r0, lr, #4 | ||
198 | mov r1, #1 | ||
199 | b UIE | ||
200 | |||
201 | fiq_handler: | ||
202 | @ Branch straight to FIQ handler in pcm_playback.c. This also handles the | ||
203 | @ the correct return sequence. | ||
204 | ldr pc, =fiq | ||
205 | |||
206 | data_abort_handler: | ||
207 | sub r0, lr, #8 | ||
208 | mov r1, #2 | ||
209 | b UIE | ||
210 | |||
211 | irq_handler: | ||
212 | #ifndef STUB | ||
213 | stmfd sp!, {r0-r3, r12, lr} | ||
214 | bl irq | ||
215 | ldmfd sp!, {r0-r3, r12, lr} | ||
216 | #endif | ||
217 | subs pc, lr, #4 | ||
218 | |||
219 | #ifdef STUB | ||
220 | UIE: | ||
221 | b UIE | ||
222 | #endif | ||
223 | |||
224 | /* 256 words of IRQ stack */ | ||
225 | .space 256*4 | ||
226 | irq_stack: | ||
227 | |||
228 | /* 256 words of FIQ stack */ | ||
229 | .space 256*4 | ||
230 | fiq_stack: | ||
231 | |||
232 | #endif /* BOOTLOADER */ | ||