diff options
Diffstat (limited to 'firmware/target/arm/imx31/crt0.S')
-rw-r--r-- | firmware/target/arm/imx31/crt0.S | 400 |
1 files changed, 400 insertions, 0 deletions
diff --git a/firmware/target/arm/imx31/crt0.S b/firmware/target/arm/imx31/crt0.S new file mode 100644 index 0000000000..2be2510bbd --- /dev/null +++ b/firmware/target/arm/imx31/crt0.S | |||
@@ -0,0 +1,400 @@ | |||
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 | b newstart | ||
27 | .space 4*16 | ||
28 | |||
29 | |||
30 | /* Arm bootloader and startup code based on startup.s from the iPodLinux loader | ||
31 | * | ||
32 | * Copyright (c) 2003, Daniel Palffy (dpalffy (at) rainstorm.org) | ||
33 | * Copyright (c) 2005, Bernard Leach <leachbj@bouncycastle.org> | ||
34 | * | ||
35 | */ | ||
36 | |||
37 | newstart: | ||
38 | msr cpsr, #0xd3 /* enter supervisor mode, disable IRQ */ | ||
39 | |||
40 | #if !defined(BOOTLOADER) | ||
41 | #if !defined(DEBUG) | ||
42 | /* Copy exception handler code to address 0 */ | ||
43 | ldr r2, =_vectorsstart | ||
44 | ldr r3, =_vectorsend | ||
45 | ldr r4, =_vectorscopy | ||
46 | 1: | ||
47 | cmp r3, r2 | ||
48 | ldrhi r5, [r4], #4 | ||
49 | strhi r5, [r2], #4 | ||
50 | bhi 1b | ||
51 | #else | ||
52 | ldr r1, =vectors | ||
53 | ldr r0, =irq_handler | ||
54 | str r0, [r1, #24] | ||
55 | ldr r0, =fiq_handler | ||
56 | str r0, [r1, #28] | ||
57 | #endif | ||
58 | |||
59 | /* Zero out IBSS */ | ||
60 | ldr r2, =_iedata | ||
61 | ldr r3, =_iend | ||
62 | mov r4, #0 | ||
63 | 1: | ||
64 | cmp r3, r2 | ||
65 | strhi r4, [r2], #4 | ||
66 | bhi 1b | ||
67 | |||
68 | /* Copy the IRAM */ | ||
69 | ldr r2, =_iramcopy | ||
70 | ldr r3, =_iramstart | ||
71 | ldr r4, =_iramend | ||
72 | 1: | ||
73 | cmp r4, r3 | ||
74 | ldrhi r5, [r2], #4 | ||
75 | strhi r5, [r3], #4 | ||
76 | bhi 1b | ||
77 | #endif /* !BOOTLOADER */ | ||
78 | |||
79 | /* Initialise bss section to zero */ | ||
80 | ldr r2, =_edata | ||
81 | ldr r3, =_end | ||
82 | mov r4, #0 | ||
83 | 1: | ||
84 | cmp r3, r2 | ||
85 | strhi r4, [r2], #4 | ||
86 | bhi 1b | ||
87 | |||
88 | /* Set up some stack and munge it with 0xdeadbeef */ | ||
89 | ldr sp, =stackend | ||
90 | mov r3, sp | ||
91 | ldr r2, =stackbegin | ||
92 | ldr r4, =0xdeadbeef | ||
93 | 1: | ||
94 | cmp r3, r2 | ||
95 | strhi r4, [r2], #4 | ||
96 | bhi 1b | ||
97 | |||
98 | #ifdef BOOTLOADER | ||
99 | /* Code for ARM bootloader targets other than iPod go here */ | ||
100 | |||
101 | mov r0, #0 | ||
102 | mcr 15, 0, r0, c7, c7, 0 /* invalidate I cache and D cache */ | ||
103 | mcr 15, 0, r0, c8, c7, 0 /* invalidate TLBs */ | ||
104 | mcr 15, 0, r0, c7, c10, 4 /* Drain the write buffer */ | ||
105 | |||
106 | /* Also setup the Peripheral Port Remap register inside the core */ | ||
107 | ldr r0, =0x40000015 /* start from AIPS 2GB region */ | ||
108 | mcr p15, 0, r0, c15, c2, 4 | ||
109 | |||
110 | /*** L2 Cache setup/invalidation/disable ***/ | ||
111 | /* Disable L2 cache first */ | ||
112 | ldr r0, =L2CC_BASE_ADDR | ||
113 | ldr r2, [r0, #L2_CACHE_CTL_REG] | ||
114 | bic r2, r2, #0x1 | ||
115 | str r2, [r0, #L2_CACHE_CTL_REG] | ||
116 | |||
117 | |||
118 | /* | ||
119 | * Configure L2 Cache: | ||
120 | * - 128k size(16k way) | ||
121 | * - 8-way associativity | ||
122 | * - 0 ws TAG/VALID/DIRTY | ||
123 | * - 4 ws DATA R/W | ||
124 | */ | ||
125 | ldr r1, [r0, #L2_CACHE_AUX_CTL_REG] | ||
126 | and r1, r1, #0xFE000000 | ||
127 | ldr r2, =0x00030024 | ||
128 | orr r1, r1, r2 | ||
129 | str r1, [r0, #L2_CACHE_AUX_CTL_REG] | ||
130 | |||
131 | /* Invalidate L2 */ | ||
132 | ldr r1, =0x000000FF | ||
133 | str r1, [r0, #L2_CACHE_INV_WAY_REG] | ||
134 | L2_loop: | ||
135 | /* Poll Invalidate By Way register */ | ||
136 | ldr r2, [r0, #L2_CACHE_INV_WAY_REG] | ||
137 | cmp r2, #0 | ||
138 | bne L2_loop | ||
139 | /*** End of L2 operations ***/ | ||
140 | /* Set up stack for IRQ mode */ | ||
141 | mov r0,#0xd2 | ||
142 | msr cpsr, r0 | ||
143 | ldr sp, =irq_stack | ||
144 | /* Set up stack for FIQ mode */ | ||
145 | mov r0,#0xd1 | ||
146 | msr cpsr, r0 | ||
147 | ldr sp, =fiq_stack | ||
148 | |||
149 | /* Let abort and undefined modes use IRQ stack */ | ||
150 | mov r0,#0xd7 | ||
151 | msr cpsr, r0 | ||
152 | ldr sp, =irq_stack | ||
153 | mov r0,#0xdb | ||
154 | msr cpsr, r0 | ||
155 | ldr sp, =irq_stack | ||
156 | /* Switch to supervisor mode */ | ||
157 | mov r0,#0xd3 | ||
158 | msr cpsr, r0 | ||
159 | ldr sp, =stackend | ||
160 | |||
161 | /*remap memory as well as exception vectors*/ | ||
162 | /*for now this will be done in bootloader, especially | ||
163 | if usb will be needed within the bootloader to load the | ||
164 | main firmware file. Interrupts will be needed for this | ||
165 | (whether they be swi or irq)*/ | ||
166 | |||
167 | /* TTB Initialisation */ | ||
168 | ldr r3, =(0x80000000+64*1024*1024-TTB_SIZE) | ||
169 | mov r1, #0 | ||
170 | ldr r2, =(0x80000000+64*1024*1024) | ||
171 | ttbloop: | ||
172 | str r1, [r3], #4 | ||
173 | cmp r3, r2 | ||
174 | bne ttbloop | ||
175 | |||
176 | /* Set TTB base address */ | ||
177 | ldr r3, =(0x80000000+64*1024*1024-TTB_SIZE) | ||
178 | mcr 15, 0 ,r3, cr2, cr0, 0 | ||
179 | /* Set all domains to manager status */ | ||
180 | mvn r3, #0 | ||
181 | mcr 15, 0, r3, cr3, cr0, 0 | ||
182 | |||
183 | /* Set page tables */ | ||
184 | |||
185 | /* Map each memory loc to itself, no cache */ | ||
186 | mov r1, #0 /* Physical address */ | ||
187 | ldr r3, =(0x80000000+64*1024*1024-TTB_SIZE) /* TTB pointer */ | ||
188 | ldr r4, =(0x80000000+64*1024*1024-TTB_SIZE+0x4000) /* End position */ | ||
189 | maploop1: | ||
190 | mov r2, r1 | ||
191 | orr r2, r2, #(1<<10) /* superuser - r/w, user - no access */ | ||
192 | //orr r2, r2, #(0<<5) /* domain 0th */ | ||
193 | orr r2, r2, #(1<<4) /* should be "1" */ | ||
194 | orr r2, r2, #(1<<1) /* Section signature */ | ||
195 | str r2, [r3], #4 | ||
196 | add r1, r1, #(1<<20) | ||
197 | cmp r3, r4 | ||
198 | bne maploop1 | ||
199 | |||
200 | /* Map 0x80000000 -> 0x0, cached */ | ||
201 | mov r1, #0x80000000 /* Physical address */ | ||
202 | ldr r3, =(0x80000000+64*1024*1024-TTB_SIZE) /* TTB pointer */ | ||
203 | ldr r4, =(0x80000000+64*1024*1024-TTB_SIZE+256) /* End position */ | ||
204 | maploop2: | ||
205 | mov r2, r1 | ||
206 | orr r2, r2, #(1<<10) /* superuser - r/w, user - no access */ | ||
207 | //orr r2, r2, #(0<<5) /* domain 0th */ | ||
208 | orr r2, r2, #(1<<4) /* should be "1" */ | ||
209 | orr r2, r2, #(1<<3) /* cache flags */ | ||
210 | orr r2, r2, #(1<<2) /* more cache stuff */ | ||
211 | orr r2, r2, #(1<<1) /* Section signature */ | ||
212 | str r2, [r3], #4 | ||
213 | add r1, r1, #(1<<20) | ||
214 | cmp r3, r4 | ||
215 | bne maploop2 | ||
216 | |||
217 | /* Enable MMU */ | ||
218 | mrc 15, 0, r3, cr1, cr0, 0 | ||
219 | tst r3, #0x4 | ||
220 | bleq clean_dcache | ||
221 | tst r3, #0x1000 | ||
222 | bleq clean_dcache | ||
223 | mov r0, #0 | ||
224 | |||
225 | mcr 15, 0, r0, cr8, cr7, 0 /* Invalidate TLB */ | ||
226 | mcr 15, 0, r0, cr7, cr7, 0 /* Invalidate icache and dcache */ | ||
227 | mrc 15, 0, r0, cr1, cr0, 0 | ||
228 | orr r0, r0, #1 /* enable mmu bit */ | ||
229 | orr r0, r0, #(1<<2) /* enable dcache */ | ||
230 | orr r0, r0, #(1<<12) /* enable icache */ | ||
231 | mcr 15, 0, r0, cr1, cr0, 0 | ||
232 | nop | ||
233 | nop | ||
234 | nop | ||
235 | nop | ||
236 | |||
237 | mov r0,#0 | ||
238 | ldr r1,=_vectorstart | ||
239 | mov r2,#0 | ||
240 | |||
241 | lp: ldr r3,[r1] | ||
242 | add r1,r1,#4 | ||
243 | str r3,[r0] | ||
244 | add r0,r0,#4 | ||
245 | add r2,r2,#1 | ||
246 | cmp r2,#16 | ||
247 | bne lp | ||
248 | bl main | ||
249 | |||
250 | .section .vectors,"aw" | ||
251 | _vectorstart: | ||
252 | ldr pc, [pc, #24] | ||
253 | ldr pc, [pc, #24] | ||
254 | ldr pc, [pc, #24] | ||
255 | ldr pc, [pc, #24] | ||
256 | ldr pc, [pc, #24] | ||
257 | ldr pc, [pc, #24] | ||
258 | ldr pc, [pc, #24] | ||
259 | ldr pc, [pc, #24] | ||
260 | |||
261 | /* Exception vectors */ | ||
262 | .global vectors | ||
263 | vectors: | ||
264 | .word start | ||
265 | .word undef_instr_handler | ||
266 | .word software_int_handler | ||
267 | .word prefetch_abort_handler | ||
268 | .word data_abort_handler | ||
269 | .word reserved_handler | ||
270 | .word irqz | ||
271 | .word fiqz | ||
272 | |||
273 | .text | ||
274 | .global irq | ||
275 | .global fiq | ||
276 | .global UIE | ||
277 | |||
278 | undef_instr_handler: | ||
279 | mov r0, lr | ||
280 | mov r1, #0 | ||
281 | b UIE | ||
282 | |||
283 | software_int_handler: | ||
284 | reserved_handler: | ||
285 | bl irq_handler | ||
286 | movs pc, lr | ||
287 | |||
288 | prefetch_abort_handler: | ||
289 | sub r0, lr, #4 | ||
290 | mov r1, #1 | ||
291 | b UIE | ||
292 | |||
293 | data_abort_handler: | ||
294 | sub r0, lr, #8 | ||
295 | mov r1, #2 | ||
296 | b UIE | ||
297 | |||
298 | /*not working....if we get here, let someone | ||
299 | know....*/ | ||
300 | irqz: bl irq_handler | ||
301 | fiqz: bl fiq_handler | ||
302 | |||
303 | UIE: | ||
304 | b UIE | ||
305 | |||
306 | /* 256 words of IRQ stack */ | ||
307 | .space 256*4 | ||
308 | irq_stack: | ||
309 | |||
310 | /* 256 words of FIQ stack */ | ||
311 | .space 256*4 | ||
312 | fiq_stack: | ||
313 | |||
314 | |||
315 | #else /* BOOTLOADER */ | ||
316 | |||
317 | /* Set up stack for IRQ mode */ | ||
318 | msr cpsr_c, #0xd2 | ||
319 | ldr sp, =irq_stack | ||
320 | /* Set up stack for FIQ mode */ | ||
321 | msr cpsr_c, #0xd1 | ||
322 | ldr sp, =fiq_stack | ||
323 | |||
324 | /* Let abort and undefined modes use IRQ stack */ | ||
325 | msr cpsr_c, #0xd7 | ||
326 | ldr sp, =irq_stack | ||
327 | msr cpsr_c, #0xdb | ||
328 | ldr sp, =irq_stack | ||
329 | /* Switch to supervisor mode */ | ||
330 | msr cpsr_c, #0xd3 | ||
331 | ldr sp, =stackend | ||
332 | bl main | ||
333 | /* main() should never return */ | ||
334 | |||
335 | /* Exception handlers. Will be copied to address 0 after memory remapping */ | ||
336 | _vectorstart: | ||
337 | .section .vectors,"aw" | ||
338 | ldr pc, [pc, #24] | ||
339 | ldr pc, [pc, #24] | ||
340 | ldr pc, [pc, #24] | ||
341 | ldr pc, [pc, #24] | ||
342 | ldr pc, [pc, #24] | ||
343 | ldr pc, [pc, #24] | ||
344 | ldr pc, [pc, #24] | ||
345 | ldr pc, [pc, #24] | ||
346 | |||
347 | /* Exception vectors */ | ||
348 | .global vectors | ||
349 | vectors: | ||
350 | .word start | ||
351 | .word undef_instr_handler | ||
352 | .word software_int_handler | ||
353 | .word prefetch_abort_handler | ||
354 | .word data_abort_handler | ||
355 | .word reserved_handler | ||
356 | .word irq_handler | ||
357 | .word fiq_handler | ||
358 | |||
359 | .text | ||
360 | |||
361 | .global irq | ||
362 | .global fiq | ||
363 | .global UIE | ||
364 | |||
365 | /* All illegal exceptions call into UIE with exception address as first | ||
366 | parameter. This is calculated differently depending on which exception | ||
367 | we're in. Second parameter is exception number, used for a string lookup | ||
368 | in UIE. | ||
369 | */ | ||
370 | undef_instr_handler: | ||
371 | mov r0, lr | ||
372 | mov r1, #0 | ||
373 | b UIE | ||
374 | |||
375 | /* We run supervisor mode most of the time, and should never see a software | ||
376 | exception being thrown. Perhaps make it illegal and call UIE? | ||
377 | */ | ||
378 | software_int_handler: | ||
379 | reserved_handler: | ||
380 | movs pc, lr | ||
381 | |||
382 | prefetch_abort_handler: | ||
383 | sub r0, lr, #4 | ||
384 | mov r1, #1 | ||
385 | b UIE | ||
386 | |||
387 | data_abort_handler: | ||
388 | sub r0, lr, #8 | ||
389 | mov r1, #2 | ||
390 | b UIE | ||
391 | |||
392 | /* 256 words of IRQ stack */ | ||
393 | .space 256*4 | ||
394 | irq_stack: | ||
395 | |||
396 | /* 256 words of FIQ stack */ | ||
397 | .space 256*4 | ||
398 | fiq_stack: | ||
399 | |||
400 | #endif /* BOOTLOADER */ | ||