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