blob: e144c16faea4ae00a650ffd3dd63620de04666ad [file] [log] [blame]
Dave Chapman28f6ae42007-10-28 11:08:10 +00001/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2002 by Linus Nielsen Feltzing
11 *
Daniel Stenberg2acc0ac2008-06-28 18:10:04 +000012 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
Dave Chapman28f6ae42007-10-28 11:08:10 +000016 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21
22/* Arm bootloader and startup code based on startup.s from the iPodLinux loader
23 *
24 * Copyright (c) 2003, Daniel Palffy (dpalffy (at) rainstorm.org)
25 * Copyright (c) 2005, Bernard Leach <leachbj@bouncycastle.org>
26 *
27 */
28
29#include "config.h"
30#include "cpu.h"
31
32 .section .init.text,"ax",%progbits
33
Dave Chapmanf2042982008-05-02 19:12:09 +000034 .extern irq
35 .extern fiq
36 .extern UIE
37 .extern main
38
Dave Chapman28f6ae42007-10-28 11:08:10 +000039 .global start
40
41/* Telechips firmware files start with a 32-byte header, as part of the code. */
42
43start:
44#ifdef TCCBOOT
45 /* Add -DTCCBOOT to EXTRA_DEFINES in the bootloader Makefile to
46 enable building the bootloader to be appended to the end of the
47 original firmware, dual-booting based on a key-press.
48
49 The following two values are filled in by mktccboot.
50 */
51 .word 0 /* Saved entrypoint of original firmware*/
52 .word 0 /* Location in RAM of the start of our bootloader */
53#else
Dave Chapmanf2042982008-05-02 19:12:09 +000054// ldr pc, =start_loc /* jump to the main entry point */
55 b start_loc
Dave Chapman28f6ae42007-10-28 11:08:10 +000056
57 .word 0xffff0601 /* Unknown magic */
58 .word 0x3a726556 /* "Ver:" */
59 .word 0x31373030 /* "0071" */
60 .word 0 /* First CRC32 */
61 .word 0 /* Unknown - always 0 */
62 .word 0 /* Second CRC32 */
63 .word 0 /* length of firmware file */
64
65#ifdef LOGIK_DAX
66 /* Some original firmwares have 0x40 bytes of zeroes here - we
67 don't know why, but err on the side of caution and include it
68 here. */
69 .space 0x40
70#endif
71#endif
72
73start_loc:
74
75#ifdef BOOTLOADER
Dave Chapmanf2042982008-05-02 19:12:09 +000076
77/*
78 If we are appended to the OF (i.e. dual-booting), do a simple GPIO
79 button check, and branch to the OF's entry point (saved by mktccboot)
80 if not active
81*/
82
Dave Chapman28f6ae42007-10-28 11:08:10 +000083#ifdef TCCBOOT
Dave Chapman28f6ae42007-10-28 11:08:10 +000084 mov r0, #0x80000000
Dave Chapmanf2042982008-05-02 19:12:09 +000085#ifdef LOGIK_DAX
86 ldr r0, [r0, #0x300] /* Hold button is GPIO A, pin 0x2 */
Dave Chapman28f6ae42007-10-28 11:08:10 +000087 tst r0, #0x2
Dave Chapmanf2042982008-05-02 19:12:09 +000088#elif defined(SANSA_M200)
89 ldr r0, [r0, #0x310] /* Hold button is GPIO B, pin 0x200 */
90 tst r0, #0x200
Dave Chapman28f6ae42007-10-28 11:08:10 +000091#else
92 #error No bootup key detection implemented for this target
93#endif
94
Dave Chapmanf2042982008-05-02 19:12:09 +000095 ldrne pc, [pc, #-28] /* Jump to OF if HOLD button not pressed */
96#endif /* TCCBOOT */
97
98/* We are now definitely executing the bootloader, so we relocate to the
99 linked address (see boot.lds) - 1MB from the end of DRAM.
100*/
101
102#ifdef TCCBOOT
103 ldr r0, [pc, #-28] /* mktccboot fills in the load address */
104#else
105 mov r0, #0x20000000 /* Otherwise, load address is the start of DRAM */
106#endif
107 mov r1, #0x20000000 /* Destination: 1MB from end of DRAM */
108 add r1, r1, #((MEM - 1) * 0x100000)
109
Dave Chapman28f6ae42007-10-28 11:08:10 +0000110 ldr r2, =_dataend
1111:
112 cmp r2, r1
113 ldrhi r3, [r0], #4
114 strhi r3, [r1], #4
115 bhi 1b
116
117 ldr pc, =copied_start /* jump to the relocated start_loc: */
Dave Chapman28f6ae42007-10-28 11:08:10 +0000118copied_start:
Dave Chapmanf2042982008-05-02 19:12:09 +0000119#endif /* BOOTLOADER */
Dave Chapman28f6ae42007-10-28 11:08:10 +0000120
121 /* Set up stack for IRQ mode */
122 mov r0,#0xd2
123 msr cpsr, r0
124 ldr sp, =irq_stack
Dave Chapmanf2042982008-05-02 19:12:09 +0000125
Dave Chapman28f6ae42007-10-28 11:08:10 +0000126 /* Set up stack for FIQ mode */
127 mov r0,#0xd1
128 msr cpsr, r0
129 ldr sp, =fiq_stack
130
131 /* Let abort and undefined modes use IRQ stack */
132 mov r0,#0xd7
133 msr cpsr, r0
134 ldr sp, =irq_stack
135 mov r0,#0xdb
136 msr cpsr, r0
137 ldr sp, =irq_stack
Dave Chapman28f6ae42007-10-28 11:08:10 +0000138
139 /* Switch to supervisor mode */
140 mov r0,#0xd3
141 msr cpsr, r0
142 ldr sp, =stackend
143
Dave Chapmanf2042982008-05-02 19:12:09 +0000144 /* Copy exception handler code to address 0 */
145 mov r2, #0x0
146 ldr r3, =vectors_start
147 ldr r4, =vectors_end
1481:
149 cmp r4, r3
150 ldrhi r5, [r3], #4
151 strhi r5, [r2], #4
152 bhi 1b
153
Dave Chapman28f6ae42007-10-28 11:08:10 +0000154 /* Initialise bss section to zero */
155 ldr r2, =_edata
156 ldr r3, =_end
157 mov r4, #0
1581:
159 cmp r3, r2
160 strhi r4, [r2], #4
161 bhi 1b
162
163 /* Set up some stack and munge it with 0xdeadbeef */
164 ldr sp, =stackend
165 mov r3, sp
166 ldr r2, =stackbegin
167 ldr r4, =0xdeadbeef
1681:
169 cmp r3, r2
170 strhi r4, [r2], #4
171 bhi 1b
172
173 bl main
174 /* main() should never return */
175
Dave Chapmanf2042982008-05-02 19:12:09 +0000176/* Exception handlers. Will be copied to address 0 after memory remapping */
177vectors_start:
178 ldr pc, [pc, #24]
179 ldr pc, [pc, #24]
180 ldr pc, [pc, #24]
181 ldr pc, [pc, #24]
182 ldr pc, [pc, #24]
183 ldr pc, [pc, #24]
184 ldr pc, [pc, #24]
185 ldr pc, [pc, #24]
Dave Chapman28f6ae42007-10-28 11:08:10 +0000186
Dave Chapmanf2042982008-05-02 19:12:09 +0000187 /* Exception vectors */
188 .global vectors
189vectors:
190 .word start
191 .word undef_instr_handler
192 .word software_int_handler
193 .word prefetch_abort_handler
194 .word data_abort_handler
195 .word reserved_handler
196 .word irq_handler
197 .word fiq_handler
198vectors_end:
199
200 .text
201
202/* All illegal exceptions call into UIE with exception address as first
203 parameter. This is calculated differently depending on which exception
204 we're in. Second parameter is exception number, used for a string lookup
205 in UIE.
206 */
207undef_instr_handler:
208 mov r0, lr
209 mov r1, #0
210 b UIE
211
212/* We run supervisor mode most of the time, and should never see a software
213 exception being thrown. Perhaps make it illegal and call UIE?
214 */
215software_int_handler:
216reserved_handler:
217 movs pc, lr
218
219prefetch_abort_handler:
220 sub r0, lr, #4
221 mov r1, #1
222 b UIE
223
224data_abort_handler:
225 sub r0, lr, #8
226 mov r1, #2
227 b UIE
228
229irq_handler:
230 stmfd sp!, {r0-r3, r12, lr}
231 bl irq
232 ldmfd sp!, {r0-r3, r12, lr}
233 subs pc, lr, #4
234
235/* Align stacks to cache line boundary */
236 .balign 16
237
Dave Chapman28f6ae42007-10-28 11:08:10 +0000238/* 256 words of IRQ stack */
239 .space 256*4
240irq_stack:
241
242/* 256 words of FIQ stack */
243 .space 256*4
244fiq_stack:
245