diff options
Diffstat (limited to 'firmware/target/arm/tcc780x/crt0.S')
-rw-r--r-- | firmware/target/arm/tcc780x/crt0.S | 304 |
1 files changed, 304 insertions, 0 deletions
diff --git a/firmware/target/arm/tcc780x/crt0.S b/firmware/target/arm/tcc780x/crt0.S new file mode 100644 index 0000000000..6e092bcd82 --- /dev/null +++ b/firmware/target/arm/tcc780x/crt0.S | |||
@@ -0,0 +1,304 @@ | |||
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 | |||
20 | /* Arm bootloader and startup code based on startup.s from the iPodLinux loader | ||
21 | * | ||
22 | * Copyright (c) 2003, Daniel Palffy (dpalffy (at) rainstorm.org) | ||
23 | * Copyright (c) 2005, Bernard Leach <leachbj@bouncycastle.org> | ||
24 | * | ||
25 | */ | ||
26 | |||
27 | #include "config.h" | ||
28 | #include "cpu.h" | ||
29 | |||
30 | .section .init.text,"ax",%progbits | ||
31 | |||
32 | .global start | ||
33 | |||
34 | /* Telechips firmware files start with a 32-byte header, as part of the code. */ | ||
35 | |||
36 | start: | ||
37 | #ifdef TCCBOOT | ||
38 | /* Add -DTCCBOOT to EXTRA_DEFINES in the bootloader Makefile to | ||
39 | enable building the bootloader to be appended to the end of the | ||
40 | original firmware, dual-booting based on a key-press. | ||
41 | |||
42 | NB: On the D2 TCCBOOT currently only works in USB boot mode (via tcctool) | ||
43 | When flashed to the device, the OF will boot as normal - but holding a | ||
44 | key to boot Rockbox results in a blank screen and crashed player. | ||
45 | |||
46 | The following two values are filled in by mktccboot. | ||
47 | */ | ||
48 | .word 0 /* Saved entrypoint of original firmware*/ | ||
49 | .word 0 /* Location in RAM of the start of our bootloader */ | ||
50 | #else | ||
51 | ldr pc, =start_loc /* jump to the main entry point */ | ||
52 | |||
53 | .word 0xffff0601 /* Unknown magic */ | ||
54 | .word 0x3a726556 /* "Ver:" */ | ||
55 | .word 0x31373030 /* "0071" */ | ||
56 | .word 0 /* First CRC32 */ | ||
57 | .word 0 /* Unknown - always 0 */ | ||
58 | .word 0 /* Second CRC32 */ | ||
59 | .word 0 /* length of firmware file */ | ||
60 | |||
61 | #ifdef COWON_D2 | ||
62 | /* Some original firmwares have 0x40 bytes of zeroes here - we | ||
63 | don't know why, but err on the side of caution and include it | ||
64 | here. */ | ||
65 | .space 0x40 | ||
66 | #endif | ||
67 | #endif | ||
68 | |||
69 | start_loc: | ||
70 | |||
71 | #ifdef BOOTLOADER | ||
72 | #ifdef TCCBOOT | ||
73 | #ifdef COWON_D2 | ||
74 | ldr r0, =0xf005a000 | ||
75 | ldr r0, [r0, #0x40] /* Read GPIO B */ | ||
76 | tst r0, #0x4 | ||
77 | ldreq pc, [pc, #-28] /* Jump to original firmware if keypad not pressed */ | ||
78 | #else | ||
79 | #error No bootup key detection implemented for this target | ||
80 | #endif | ||
81 | |||
82 | /* Copy bootloader to safe area - 0x21000000 (DRAM) */ | ||
83 | /* TODO: Adjust this for other targets - DRAM + DRAMSIZE - 0x100000 */ | ||
84 | ldr r0, [pc, #-28] | ||
85 | mov r1, #0x22000000 | ||
86 | sub r1, r1, #0x100000 | ||
87 | ldr r2, =_dataend | ||
88 | 1: | ||
89 | cmp r2, r1 | ||
90 | ldrhi r3, [r0], #4 | ||
91 | strhi r3, [r1], #4 | ||
92 | bhi 1b | ||
93 | |||
94 | ldr pc, =copied_start /* jump to the relocated start_loc: */ | ||
95 | |||
96 | copied_start: | ||
97 | #endif | ||
98 | #else | ||
99 | /* We don't use interrupts in the bootloader */ | ||
100 | |||
101 | /* Set up stack for IRQ mode */ | ||
102 | mov r0,#0xd2 | ||
103 | msr cpsr, r0 | ||
104 | ldr sp, =irq_stack | ||
105 | /* Set up stack for FIQ mode */ | ||
106 | mov r0,#0xd1 | ||
107 | msr cpsr, r0 | ||
108 | ldr sp, =fiq_stack | ||
109 | |||
110 | /* Let abort and undefined modes use IRQ stack */ | ||
111 | mov r0,#0xd7 | ||
112 | msr cpsr, r0 | ||
113 | ldr sp, =irq_stack | ||
114 | mov r0,#0xdb | ||
115 | msr cpsr, r0 | ||
116 | ldr sp, =irq_stack | ||
117 | #endif | ||
118 | |||
119 | /* Switch to supervisor mode */ | ||
120 | mov r0,#0xd3 | ||
121 | msr cpsr, r0 | ||
122 | ldr sp, =stackend | ||
123 | |||
124 | |||
125 | #if !defined(BOOTLOADER) && !defined(STUB) | ||
126 | |||
127 | /* Copy exception handler code to address 0 */ | ||
128 | ldr r2, =_vectorsstart | ||
129 | ldr r3, =_vectorsend | ||
130 | ldr r4, =_vectorscopy | ||
131 | 1: | ||
132 | cmp r3, r2 | ||
133 | ldrhi r5, [r4], #4 | ||
134 | strhi r5, [r2], #4 | ||
135 | bhi 1b | ||
136 | |||
137 | /* Zero out IBSS */ | ||
138 | ldr r2, =_iedata | ||
139 | ldr r3, =_iend | ||
140 | mov r4, #0 | ||
141 | 1: | ||
142 | cmp r3, r2 | ||
143 | strhi r4, [r2], #4 | ||
144 | bhi 1b | ||
145 | |||
146 | /* Copy the ITCM */ | ||
147 | ldr r2, =_itcmcopy | ||
148 | ldr r3, =_itcmstart | ||
149 | ldr r4, =_itcmend | ||
150 | 1: | ||
151 | cmp r4, r3 | ||
152 | ldrhi r5, [r2], #4 | ||
153 | strhi r5, [r3], #4 | ||
154 | bhi 1b | ||
155 | |||
156 | /* Copy the DTCM */ | ||
157 | ldr r2, =_dtcmcopy | ||
158 | ldr r3, =_dtcmstart | ||
159 | ldr r4, =_dtcmend | ||
160 | 1: | ||
161 | cmp r4, r3 | ||
162 | ldrhi r5, [r2], #4 | ||
163 | strhi r5, [r3], #4 | ||
164 | bhi 1b | ||
165 | #endif /* !BOOTLOADER,!STUB */ | ||
166 | |||
167 | /* Initialise bss section to zero */ | ||
168 | ldr r2, =_edata | ||
169 | ldr r3, =_end | ||
170 | mov r4, #0 | ||
171 | 1: | ||
172 | cmp r3, r2 | ||
173 | strhi r4, [r2], #4 | ||
174 | bhi 1b | ||
175 | |||
176 | /* Set up some stack and munge it with 0xdeadbeef */ | ||
177 | ldr sp, =stackend | ||
178 | mov r3, sp | ||
179 | ldr r2, =stackbegin | ||
180 | ldr r4, =0xdeadbeef | ||
181 | 1: | ||
182 | cmp r3, r2 | ||
183 | strhi r4, [r2], #4 | ||
184 | bhi 1b | ||
185 | |||
186 | /* | ||
187 | Enable cache & TCM regions | ||
188 | TODO: This is just doing what the OF does at present. It needs to be | ||
189 | better understood and moved out to a separate MMU functions package. | ||
190 | */ | ||
191 | ldr r1, =0x1fe0c | ||
192 | mov r0, #0xf7000000 | ||
193 | str r1, [r0] | ||
194 | ldr r1, =0x2801ae24 | ||
195 | str r1, [r0,#4] | ||
196 | ldr r1, =0x13e44 | ||
197 | str r1, [r0,#8] | ||
198 | ldr r1, =0x4001ce60 | ||
199 | str r1, [r0,#0xc] | ||
200 | ldr r1, =0x6001be80 | ||
201 | str r1, [r0,#0x10] | ||
202 | ldr r1, =0x3801aea4 | ||
203 | str r1, [r0,#0x14] | ||
204 | ldr r1, =0x8001eec0 | ||
205 | str r1, [r0,#0x18] | ||
206 | ldr r1, =0x1001aee0 | ||
207 | str r1, [r0,#0x1c] | ||
208 | add r1, r0, #0x8000 /* r1 now = 0xf7008000 */ | ||
209 | ldr r0, =0xa0000011 | ||
210 | ldr r2, =0x5507d | ||
211 | mcr p15, 0, r0,c9,c1 /* data tcm region (enabled; 8kb; 0xa0000000) */ | ||
212 | mov r0, #0xd | ||
213 | mcr p15, 0, r0,c9,c1, 1 /* inst tcm region (enabled, 4kb, 0x00000000) */ | ||
214 | ldr r0, =0x55555555 | ||
215 | mcr p15, 0, r1,c2,c0 /* translation table base register = 0xf7008000 */ | ||
216 | mcr p15, 0, r0,c3,c0 /* domain access d0-d15 = 'client' */ | ||
217 | mov r0, #0 | ||
218 | mcr p15, 0, r0,c7,c5 /* invalidate icache */ | ||
219 | mcr p15, 0, r2,c1,c0 /* enable mmu, i & d caches */ | ||
220 | mcr p15, 0, r0,c7,c6 /* invalidate dcache */ | ||
221 | mcr p15, 0, r1,c8,c7 /* invalidate tlb */ | ||
222 | |||
223 | bl main | ||
224 | /* main() should never return */ | ||
225 | |||
226 | #ifndef BOOTLOADER | ||
227 | |||
228 | /* Exception handlers. Will be copied to address 0 after memory remapping */ | ||
229 | .section .vectors,"aw" | ||
230 | ldr pc, [pc, #24] | ||
231 | ldr pc, [pc, #24] | ||
232 | ldr pc, [pc, #24] | ||
233 | ldr pc, [pc, #24] | ||
234 | ldr pc, [pc, #24] | ||
235 | ldr pc, [pc, #24] | ||
236 | ldr pc, [pc, #24] | ||
237 | ldr pc, [pc, #24] | ||
238 | |||
239 | /* Exception vectors */ | ||
240 | .global vectors | ||
241 | vectors: | ||
242 | .word start | ||
243 | .word undef_instr_handler | ||
244 | .word software_int_handler | ||
245 | .word prefetch_abort_handler | ||
246 | .word data_abort_handler | ||
247 | .word reserved_handler | ||
248 | .word irq_handler | ||
249 | .word fiq_handler | ||
250 | |||
251 | .text | ||
252 | |||
253 | #if !defined(STUB) | ||
254 | .global irq | ||
255 | .global fiq | ||
256 | .global UIE | ||
257 | #endif | ||
258 | |||
259 | /* All illegal exceptions call into UIE with exception address as first | ||
260 | parameter. This is calculated differently depending on which exception | ||
261 | we're in. Second parameter is exception number, used for a string lookup | ||
262 | in UIE. | ||
263 | */ | ||
264 | undef_instr_handler: | ||
265 | mov r0, lr | ||
266 | mov r1, #0 | ||
267 | b UIE | ||
268 | |||
269 | /* We run supervisor mode most of the time, and should never see a software | ||
270 | exception being thrown. Perhaps make it illegal and call UIE? | ||
271 | */ | ||
272 | software_int_handler: | ||
273 | reserved_handler: | ||
274 | movs pc, lr | ||
275 | |||
276 | prefetch_abort_handler: | ||
277 | sub r0, lr, #4 | ||
278 | mov r1, #1 | ||
279 | b UIE | ||
280 | |||
281 | data_abort_handler: | ||
282 | sub r0, lr, #8 | ||
283 | mov r1, #2 | ||
284 | b UIE | ||
285 | |||
286 | #if defined(STUB) | ||
287 | UIE: | ||
288 | b UIE | ||
289 | #endif | ||
290 | |||
291 | /* We don't use interrupts in the bootloader */ | ||
292 | |||
293 | /* Align stacks to cache line boundary */ | ||
294 | .balign 16 | ||
295 | |||
296 | /* 256 words of IRQ stack */ | ||
297 | .space 256*4 | ||
298 | irq_stack: | ||
299 | |||
300 | /* 256 words of FIQ stack */ | ||
301 | .space 256*4 | ||
302 | fiq_stack: | ||
303 | |||
304 | #endif | ||