blob: 6df8e4215d0d917244467aad19d0b2ab4a379552 [file] [log] [blame]
Karl Kurbjun31ea7802007-11-11 17:58:13 +00001/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
Karl Kurbjun75103352008-04-22 04:34:25 +000010 * Copyright (C) 2008 by Karl Kurbjun
11 *
12 * Arm bootloader and startup code based on startup.s from the iPodLinux loader
13 * Copyright (c) 2003, Daniel Palffy (dpalffy (at) rainstorm.org)
14 * Copyright (c) 2005, Bernard Leach <leachbj@bouncycastle.org>
Karl Kurbjun31ea7802007-11-11 17:58:13 +000015 *
Daniel Stenberg2acc0ac2008-06-28 18:10:04 +000016 * This program is free software; you can redistribute it and/or
17 * modify it under the terms of the GNU General Public License
18 * as published by the Free Software Foundation; either version 2
19 * of the License, or (at your option) any later version.
Karl Kurbjun31ea7802007-11-11 17:58:13 +000020 *
21 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
22 * KIND, either express or implied.
23 *
24 ****************************************************************************/
25#include "config.h"
26#include "cpu.h"
27
Karl Kurbjun75103352008-04-22 04:34:25 +000028/* Exception Handlers */
29.section .vectors,"ax",%progbits
30.code 32
Karl Kurbjun31ea7802007-11-11 17:58:13 +000031
Karl Kurbjun75103352008-04-22 04:34:25 +000032.global vectors
33vectors:
34 b start
35 b undef_instr_handler
36 b software_int_handler
37 b prefetch_abort_handler
38 b data_abort_handler
39 b reserved_handler
40 b irq_handler
41 b fiq_handler
Karl Kurbjun31ea7802007-11-11 17:58:13 +000042
Karl Kurbjun75103352008-04-22 04:34:25 +000043/*
44 * Function: code_copy
45 * Variables:
46 * r0 = from
47 * r1 = to
48 * r2 = length
Karl Kurbjun31ea7802007-11-11 17:58:13 +000049 */
Karl Kurbjun31ea7802007-11-11 17:58:13 +000050
Karl Kurbjun75103352008-04-22 04:34:25 +000051.section .init.text, "ax", %progbits
52.align 0x04
53.global word_copy
54.type word_copy, %function
55word_copy:
56 sub r2, r2, #0x04
57 cmp r2, #0
58 ldrge r3, [r0], #4
59 strge r3, [r1], #4
60 bgt word_copy
61 bx lr
62.ltorg
63.size word_copy, .-word_copy
64
65/*
66 * Entry: start
67 * Variables:
68 * none
69 */
70
71.section .init.text,"ax",%progbits
72.code 32
73.align 0x04 /* Align */
74.global start
75start:
76 msr cpsr, #0xd3 /* enter supervisor mode, disable IRQ */
77
78 /* Disable the watchdog */
79 ldr r2, =0x00000000
80 mov r1, #0x53000000
81 str r2, [r1]
82
83 /* Mask all Interupts to be safe */
84 ldr r2, =0xFFFFFFFF
85 mov r1, #0x4A000000
86 str r2, [r1]
87
88 /* Submask too */
89 ldr r2, =0x00003FFF
90 str r2, [r1, #0x1C]
91
92 /* Check if loaded by the old bootloader or by the OF
93 * Be careful with code size above this as well.
94 */
95
96 /* Get the execute address (cannot be past 0x100 for this to work */
97 ldr r0, =0xffffff00
98 and r0, pc, r0
99
100 /* Calculate the length of the code needed to run/copy */
101 ldr r1, = _vectorstart
Michael Sevakis209aa8e2008-05-10 22:03:45 +0000102 ldr r2, = _initdata_end
Karl Kurbjun75103352008-04-22 04:34:25 +0000103 sub r2, r2, r1
104
105 add r3, r2, #0x30000000
106
107 /* Is there enough space to copy without overwriting? */
108 cmp r0, r3
109
110 /* There's enough space, skip copying */
111 bgt skipreset
112
113 /* Is this code running from 0x0? If so skip copy. */
114 cmplt r0, #0
115 beq skipreset
116
117 /* There's not enough space to copy without overwriting, copy to safe spot
118 * and reset
119 */
120 mov r1, #0x31000000 /* copy location */
121 bl word_copy
122
123 mov pc, #0x31000000
124
125 skipreset:
126
127 /* Initial Clock Setup */
128 mov r2, #0x7
129 mov r1, #0x4C000000
130 str r2, [r1, #0x14]
131
132 mov r2, #0x0
133 str r2, [r1, #0x18]
134
135 ldr r2, =0xFFFFFFFF
136 str r2, [r1]
137
138 ldr r2, =0x0003C042
139 str r2, [r1, #0x08]
140
141 nop
142 nop
143 nop
144 nop
145 nop
146 nop
147 nop
148 nop
149
150 ldr r2, =0x000C9042
151 str r2, [r1, #0x04]
152
153 nop
154 nop
155 nop
156 nop
157 nop
158 nop
159 nop
160 nop
161
162 /* If we want to disable extraneous clocks, uncomment, but it can
163 * freeze the device
164 */
165#if 0
166 ldr r2, =0x6030
167 mov r1, #0x4C000000
168 str r2, [r1, #0x0C]
Karl Kurbjun31ea7802007-11-11 17:58:13 +0000169#endif
170
Karl Kurbjun75103352008-04-22 04:34:25 +0000171 /* set Bus to Asynchronous mode (full speed) */
172 mov r0, #0
173 mrc p15, 0, r0, c1, c0, 0
174 ldr r1, =0xC0000000
175 orr r0, r0, r1
176 mcr p15, 0, r0, c1, c0, 0
Karl Kurbjun31ea7802007-11-11 17:58:13 +0000177
Karl Kurbjun75103352008-04-22 04:34:25 +0000178 /* Setup MISCCR */
179 ldr r2, =0x00613020
180 mov r1, #0x56000000
181 str r2, [r1, #0x80]
Karl Kurbjun31ea7802007-11-11 17:58:13 +0000182
Karl Kurbjun75103352008-04-22 04:34:25 +0000183 /* Setup some unknown outputs in GPB and GPH */
184 ldr r2, [r1, #0x10]
185 mov r3, #0x05
186 orr r2, r3, r2
187 str r2, [r1, #0x10]
188
189 ldr r2, [r1, #0x14]
190 mov r3, #0x03
191 orr r2, r3, r2
192 str r2, [r1, #0x14]
193
194 ldr r2, [r1, #0x70]
195 mov r3, #0x05
196 orr r2, r3, r2
197 str r2, [r1, #0x70]
198
199 ldr r2, [r1, #0x74]
200 mov r3, #0x03
201 orr r2, r3, r2
202 str r2, [r1, #0x74]
203
204 /* Memory setup (taken from 0x5070) */
Karl Kurbjun31ea7802007-11-11 17:58:13 +0000205
206 /* BWSCON
207 * Reserved 0
208 * Bank 0:
209 * Bus width 01 (16 bit)
210 * Bank 1:
211 * Buswidth 00 (8 bit)
212 * Disable wait 0
213 * Not using UB/LB 0
214 * Bank 2:
215 * Buswidth 10 (32 bit)
216 * Disable wait 0
217 * Not using UB/LB 0
218 * Bank 3:
219 * Buswidth 10 (32 bit)
220 * Disable wait 0
221 * Use UB/LB 1
222 * Bank 4:
223 * Buswidth 10 (32 bit)
224 * Disable wait 0
225 * Use UB/LB 1
226 * Bank 5:
227 * Buswidth 00 (8 bit)
228 * Disable wait 0
229 * Not using UB/LB 0
230 * Bank 6:
231 * Buswidth 10 (32 bit)
232 * Disable wait 0
233 * Not using UB/LB 0
234 * Bank 7:
235 * Buswidth 00 (8 bit)
236 * Disable wait 0
237 * Not using UB/LB 0
238 */
Karl Kurbjun75103352008-04-22 04:34:25 +0000239 ldr r2, =0x01055102
Karl Kurbjun31ea7802007-11-11 17:58:13 +0000240 mov r1, #0x48000000
241 str r2, [r1]
242
243 /* BANKCON0
244 * Pagemode: normal (1 data) 00
245 * Pagemode access cycle: 2 clocks 00
246 * Address hold: 2 clocks 10
247 * Chip selection hold time: 1 clock 10
248 * Access cycle: 8 clocks 101
249 * Chip select setup time: 1 clock 01
250 * Address setup time: 0 clock 00
251 */
Karl Kurbjun75103352008-04-22 04:34:25 +0000252 ldr r2, =0x00000D60
253 str r2, [r1, #0x04]
Karl Kurbjun31ea7802007-11-11 17:58:13 +0000254
255
256 /* BANKCON1
257 * Pagemode: normal (1 data) 00
258 * Pagemode access cycle: 2 clocks 00
259 * Address hold: 0 clocks 00
260 * Chip selection hold time: 0 clock 00
261 * Access cycle: 1 clocks 000
262 * Chip select setup time: 0 clocks 00
263 * Address setup time: 0 clocks 00
264 */
Karl Kurbjun75103352008-04-22 04:34:25 +0000265 ldr r2, =0x00000000
266 str r2, [r1, #0x08]
Karl Kurbjun31ea7802007-11-11 17:58:13 +0000267
268 /* BANKCON2
269 * Pagemode: normal (1 data) 00
270 * Pagemode access cycle: 2 clocks 00
271 * Address hold: 2 clocks 10
272 * Chip selection hold time: 2 clocks 10
273 * Access cycle: 14 clocks 111
274 * Chip select setup time: 4 clocks 11
275 * Address setup time: 0 clocks 00
276 */
Karl Kurbjun75103352008-04-22 04:34:25 +0000277 ldr r2, =0x00001FA0
Karl Kurbjun31ea7802007-11-11 17:58:13 +0000278 str r2, [r1, #0xC]
279
280 /* BANKCON3 */
Karl Kurbjun75103352008-04-22 04:34:25 +0000281 ldr r2, =0x00001D80
Karl Kurbjun31ea7802007-11-11 17:58:13 +0000282 str r2, [r1, #0x10]
283 /* BANKCON4 */
284 str r2, [r1, #0x14]
285
286 /* BANKCON5 */
Karl Kurbjun75103352008-04-22 04:34:25 +0000287 ldr r2, =0x00000000
Karl Kurbjun31ea7802007-11-11 17:58:13 +0000288 str r2, [r1, #0x18]
289
290 /* BANKCON6/7
291 * SCAN: 9 bit 01
292 * Trcd: 3 clocks 01
293 * Tcah: 0 clock 00
294 * Tcoh: 0 clock 00
295 * Tacc: 1 clock 000
296 * Tcos: 0 clock 00
297 * Tacs: 0 clock 00
298 * MT: Sync DRAM 11
299 */
Karl Kurbjun75103352008-04-22 04:34:25 +0000300 ldr r2, =0x00018005
Karl Kurbjun31ea7802007-11-11 17:58:13 +0000301 str r2, [r1, #0x1C]
302 /* BANKCON7 */
303 str r2, [r1, #0x20]
304
305 /* REFRESH */
Karl Kurbjun75103352008-04-22 04:34:25 +0000306 ldr r2, =0x00980501
Karl Kurbjun31ea7802007-11-11 17:58:13 +0000307 str r2, [r1, #0x24]
308
309 /* BANKSIZE
310 * BK76MAP: 32M/32M 000
311 * Reserved: 0 0 (was 1)
312 * SCLK_EN: always 1 (was 0)
313 * SCKE_EN: disable 0
314 * Reserved: 0 0
315 * BURST_EN: enabled 1
316 */
Karl Kurbjun75103352008-04-22 04:34:25 +0000317 ldr r2, =0x00000090
Karl Kurbjun31ea7802007-11-11 17:58:13 +0000318 str r2, [r1, #0x28]
319
320 /* MRSRB6 */
Karl Kurbjun75103352008-04-22 04:34:25 +0000321 ldr r2, =0x00000030
Karl Kurbjun31ea7802007-11-11 17:58:13 +0000322 str r2, [r1, #0x2C]
323 /* MRSRB7 */
324 str r2, [r1, #0x30]
325
326#if 0
Karl Kurbjun31ea7802007-11-11 17:58:13 +0000327 /* GPACON */
Karl Kurbjun75103352008-04-22 04:34:25 +0000328 mov r1, #0x56000000
329 ldr r2, =0x01FFFCFF /* 0x01FFFCFF */
330 str r2, [r1]
Karl Kurbjun31ea7802007-11-11 17:58:13 +0000331
332 /* GPADAT */
Karl Kurbjun75103352008-04-22 04:34:25 +0000333 ldr r2, =0x01FFFEFF
334 str r2, [r1, #0x04]
Karl Kurbjun31ea7802007-11-11 17:58:13 +0000335
336 /* MRSRB6 */
Karl Kurbjun75103352008-04-22 04:34:25 +0000337 mov r1, #0x48000000
338 mov r2, #0x00000000
339 str r2, [r1, #0x2C]
Karl Kurbjun31ea7802007-11-11 17:58:13 +0000340
341 /* GPADAT */
Karl Kurbjun75103352008-04-22 04:34:25 +0000342 mov r1, #0x56000000
343 ldr r2, =0x01FFFFFF
344 str r2, [r1, #0x04]
345
346 /* MRSRB6 */
347 mov r1, #0x48000000
348 mov r2, #0x00000030
349 str r2, [r1, #0x2C]
350
351 /* GPACON */
Karl Kurbjun31ea7802007-11-11 17:58:13 +0000352 mov r1, #0x56000000
Karl Kurbjun75103352008-04-22 04:34:25 +0000353 mov r2, #0x01FFFFFF
354 str r2, [r1]
Karl Kurbjun31ea7802007-11-11 17:58:13 +0000355
356 /* End of the unknown */
357#endif
358
Karl Kurbjun75103352008-04-22 04:34:25 +0000359 /* The builds have two potential load addresses, one being from flash,
360 * and the other from some "unknown" location right now the assumption
361 * is that the code is not at 0x3000000.
362 */
363 /* get the high part of our execute address (where am I) */
364 ldr r0, =0xfffff000
365 and r0, pc, r0
Karl Kurbjun31ea7802007-11-11 17:58:13 +0000366
Karl Kurbjun75103352008-04-22 04:34:25 +0000367 /* Copy code to 0x30000000 */
368 ldr r2, = _vectorstart
Michael Sevakis209aa8e2008-05-10 22:03:45 +0000369 ldr r3, = _initdata_end
Karl Kurbjun31ea7802007-11-11 17:58:13 +0000370
Karl Kurbjun75103352008-04-22 04:34:25 +0000371 sub r2, r3, r2 /* length of loader */
Karl Kurbjun31ea7802007-11-11 17:58:13 +0000372
Karl Kurbjun75103352008-04-22 04:34:25 +0000373 ldr r1, =0x30000000 /* copy location */
374
375 bl word_copy
Karl Kurbjun31ea7802007-11-11 17:58:13 +0000376
Karl Kurbjun75103352008-04-22 04:34:25 +0000377 ldr r1, =donecopy
378 ldr r2, =0x30000000
379 add r1, r1, r2
380 mov pc, r1 /* The code is located where we want it-jump*/
381
382donecopy:
383
384 /* Setup the MMU, start by disabling */
385
386 mrc p15, 0, r0, c1, c0, 0
387 bic r0, r0, #0x41 /* disable mmu and dcache */
388 bic r0, r0, #0x1000 /* disable icache */
389 mcr p15, 0, r0, c1, c0, 0
390
391 bl ttb_init
392
393 ldr r0, =0x0
394 ldr r1, =0x0
395 ldr r2, =0x1000
396 mov r3, #0
397 bl map_section
398
399 ldr r0, =0x30000000
400 ldr r1, =0x0
401 mov r2, #32
402 mov r3, #12
403 bl map_section
404
405 ldr r0, =0x31FD6800 /* FRAME */
406 mov r1, r0
407 mov r2, #1
408 mov r3, #4
409 bl map_section
410
411 bl enable_mmu
412
Karl Kurbjun75103352008-04-22 04:34:25 +0000413 /* Initialise bss section to zero */
414 ldr r2, =_edata
415 ldr r3, =_end
416 mov r4, #0
417bsszero:
418 cmp r3, r2
419 strhi r4, [r2], #4
420 bhi bsszero
421
422 /* Set up some stack and munge it with 0xdeadbeef */
423 ldr sp, =stackend
424 mov r3, sp
425 ldr r2, =stackbegin
426 ldr r4, =0xdeadbeef
427stackmunge:
428 cmp r3, r2
429 strhi r4, [r2], #4
430 bhi stackmunge
Karl Kurbjun31ea7802007-11-11 17:58:13 +0000431
432 /* Set up stack for IRQ mode */
Karl Kurbjun75103352008-04-22 04:34:25 +0000433 msr cpsr_c, #0xd2
434 ldr sp, =irq_stack
Karl Kurbjun31ea7802007-11-11 17:58:13 +0000435 /* Set up stack for FIQ mode */
Karl Kurbjun75103352008-04-22 04:34:25 +0000436 msr cpsr_c, #0xd1
437 ldr sp, =fiq_stack
Karl Kurbjun31ea7802007-11-11 17:58:13 +0000438
439 /* Let abort and undefined modes use IRQ stack */
Karl Kurbjun75103352008-04-22 04:34:25 +0000440 msr cpsr_c, #0xd7
441 ldr sp, =irq_stack
442 msr cpsr_c, #0xdb
443 ldr sp, =irq_stack
Karl Kurbjun31ea7802007-11-11 17:58:13 +0000444 /* Switch to supervisor mode */
Karl Kurbjun75103352008-04-22 04:34:25 +0000445 msr cpsr_c, #0xd3
446 ldr sp, =stackend
Karl Kurbjun31ea7802007-11-11 17:58:13 +0000447
Karl Kurbjun75103352008-04-22 04:34:25 +0000448 /* Start the main function */
449 ldr pc, =main
Karl Kurbjun31ea7802007-11-11 17:58:13 +0000450
Karl Kurbjun75103352008-04-22 04:34:25 +0000451 /* Should never get here, but let's restart in case */
452// b vectors
Karl Kurbjun31ea7802007-11-11 17:58:13 +0000453
454/* All illegal exceptions call into UIE with exception address as first
455 parameter. This is calculated differently depending on which exception
456 we're in. Second parameter is exception number, used for a string lookup
457 in UIE.
458 */
459undef_instr_handler:
460 mov r0, lr
461 mov r1, #0
462 b UIE
463
464/* We run supervisor mode most of the time, and should never see a software
465 exception being thrown. Perhaps make it illegal and call UIE?
466 */
467software_int_handler:
468reserved_handler:
469 movs pc, lr
470
471prefetch_abort_handler:
472 sub r0, lr, #4
473 mov r1, #1
474 b UIE
475
476data_abort_handler:
477 sub r0, lr, #8
478 mov r1, #2
479 b UIE
480
Karl Kurbjun75103352008-04-22 04:34:25 +0000481#if defined(BOOTLOADER)
482fiq_handler:
Karl Kurbjun31ea7802007-11-11 17:58:13 +0000483 b UIE
484#endif
485
Karl Kurbjun75103352008-04-22 04:34:25 +0000486UIE:
487 b UIE
488
489.section .text
Karl Kurbjun31ea7802007-11-11 17:58:13 +0000490/* 256 words of IRQ stack */
491 .space 256*4
492irq_stack:
493
494/* 256 words of FIQ stack */
495 .space 256*4
496fiq_stack:
497