1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
|
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id$
*
* Copyright (C) 2002 by Linus Nielsen Feltzing
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
****************************************************************************/
#include "config.h"
#include "cpu.h"
.section .init.text,"ax",%progbits
.global start
start:
/* Exception vectors */
b newstart
b undef_instr_handler
b software_int_handler
b prefetch_abort_handler
b data_abort_handler
b reserved_handler
/* These vectors are unused */
subs pc, lr, #4 @ b irq_handler
subs pc, lr, #4 @ b fiq_handler
.balign 0x40, 0x6B
/* Arm bootloader and startup code based on startup.s from the iPodLinux loader
*
* Copyright (c) 2003, Daniel Palffy (dpalffy (at) rainstorm.org)
* Copyright (c) 2005, Bernard Leach <leachbj@bouncycastle.org>
*
*/
/* Bootloader:
* Initially this code is running at VA 0x8a000000 (PA 0x82000000).
* The mapping stub is copied to IRAM (0x1fffc000), sets up the MMU and
* jumps into the final VA remapping starting at 0x02000000 (32MB).
*
* Firmware:
* This code will be running from VA 0x00000000 (PA 0x80000000) and perform
* similar steps to the bootloader code.
*/
newstart:
msr cpsr_c, #0xd3 /* enter supervisor mode, disable IRQ/FIQ */
adr r2, remap_start /* Load PC-relative labels (relocatable) */
adr r3, remap_end
ldr r5, =TTB_BASE_ADDR /* TTB pointer */
ldr r6, =IRAM_BASE_ADDR
mov r1, r6
1: /* Copy remapping stub to IRAM */
cmp r3, r2
ldrhi r4, [r2], #4
strhi r4, [r1], #4
bhi 1b
bx r6
/* Remapping stub. No absolute addresses may be used until after the
* remapping is complete. */
remap_start:
mrc p15, 0, r3, c1, c0, 0 /* perform writeback if D cache is enabled */
tst r3, #(1 << 2) /* dcache? */
tsteq r3, #(1 << 12) /* or icache? */
mov r0, #0
mcrne p15, 0, r0, c7, c10, 0 /* clean dcache */
mcrne p15, 0, r0, c7, c7, 0 /* invalidate I cache and D cache */
mcr p15, 0, r0, c8, c7, 0 /* invalidate TLBs */
mcr p15, 0, r0, c7, c10, 4 /* Drain the write buffer */
mcr p15, 0, r0, c13, c0, 0
mcr p15, 0, r0, c13, c0, 1
/* Also setup the Peripheral Port Remap register inside the core */
mov r0, #0x40000000 /* start from AIPS 2GB region */
add r0, r0, #0x15
mcr p15, 0, r0, c15, c2, 4
/*** L2 Cache setup/invalidation/disable ***/
/* Disable L2 cache first */
mov r0, #L2CC_BASE_ADDR
mov r1, #0
str r1, [r0, #L2_CACHE_CTL_REG]
/* Disble L1 caches and memory manager */
bic r3, r3, #(1 << 12) /* L1 I-cache disabled */
bic r3, r3, #((1 << 2) | /* L1 D-cache disabled */ \
(1 << 0)) /* MMU disabled */
mcr p15, 0, r3, c1, c0, 0
/*
* Configure L2 Cache:
* - 128k size(16k way)
* - 8-way associativity
* - 0 ws TAG/VALID/DIRTY
* - 4 ws DATA R/W
*/
mov r1, #0x00130000
orr r1, r1, #0x24
str r1, [r0, #L2_CACHE_AUX_CTL_REG]
/* Invalidate L2 */
mov r1, #0x000000FF
str r1, [r0, #L2_CACHE_INV_WAY_REG]
1:
/* Poll Invalidate By Way register */
ldr r1, [r0, #L2_CACHE_INV_WAY_REG]
cmp r1, #0
bne 1b
/*** End of L2 operations ***/
/* TTB Initialisation */
/* Set TTB base address */
mcr p15, 0, r5, c2, c0, 0
/* Set all domains to manager status */
mvn r0, #0
mcr p15, 0, r0, c3, c0, 0
/* Set page tables */
/* Map each memory loc to itself
* not cached, not buffered */
/* Physical address = 0x0 */
mov r1, #(1 << 10) /* superuser - r/w, user - no access */
orr r1, r1, #((0 << 5) | /* domain 0th */ \
(1 << 4) | /* should be "1" */ \
(1 << 1)) /* Section signature */
mov r2, r5
add r3, r5, #TTB_SIZE /* End position */
1:
str r1, [r2], #4
add r1, r1, #(1 << 20) /* Next MB */
cmp r2, r3
blo 1b
/* Bits 31:20 of r1 will be 0 due to wraparound in previous loop */
/* Map PA:0x80000000-0x83ffffff to VA:0x00000000-0x03f00000
* cached, buffered */
mov r2, r5 /* TTB pointer */
add r3, r5, #64*4 /* End position */
orr r1, r1, #(0x80000000 | /* Physical address */ \
(1 << 3) | /* cache flag */ \
(1 << 2)) /* buffer flag */
1:
str r1, [r2], #4
add r1, r1, #(1 << 20)
cmp r2, r3
blo 1b
/* Map TTB, FRAME and QHARRAY section PA:0x83f00000-0x83ffffff to
* VA:0x04000000-0x040fffff
* not cache, buffered */
sub r1, r1, #0x00100000
bic r1, r1, #(1 << 3) /* clear cache flag */
str r1, [r5, #64*4]
/* Enable MMU */
mov r0, #0
mcr p15, 0, r0, c8, c7, 0 /* Invalidate TLB */
mcr p15, 0, r0, c7, c7, 0 /* Invalidate icache and dcache */
/* Auxilliary control register */
mrc p15, 0, r0, c1, c0, 1
bic r0, r0, #((1 << 6) | /* Restrict cache size OFF */ \
(1 << 5) | /* Enable block tranfer cache operations */ \
(1 << 4) | /* Clean+Invalidate cache operation ON */ \
(1 << 3)) /* Round-robin micro TLB replacement */
orr r0, r0, #((1 << 2) | /* Static branch prediction ON */ \
(1 << 1) | /* Dynamic branch prediction ON */ \
(1 << 0)) /* Return stack enabled */
mcr p15, 0, r0, c1, c0, 1
/* Control register */
mrc p15, 0, r0, c1, c0, 0
bic r0, r0, #((1 << 29) | /* AF by AP disabled */ \
(1 << 28) | /* TEX remap disabled */ \
(1 << 23)) /* Sub AP bits enabled (compatible) */
bic r0, r0, #((1 << 21) | /* All performance features enabled */ \
(1 << 15)) /* Loads to PC set T bit */
bic r0, r0, #((1 << 13)) /* Low vectors */
bic r0, r0, #((1 << 1)) /* Strict alignment disabled */
orr r0, r0, #((1 << 24) | /* Vectored interrupt ON */ \
(1 << 22)) /* Unaligned access support enabled */
orr r0, r0, #((1 << 14) | /* Round-robin replacement for I/D caches */ \
(1 << 12) | /* L1 I-cache enabled */ \
(1 << 11) | /* Program flow prediction enabled */ \
(1 << 9) | /* ROM protection enabled */ \
(1 << 8)) /* MMU protection enabled */
orr r0, r0, #((1 << 2) | /* L1 D-cache enabled */ \
(1 << 0)) /* MMU enabled */
mcr p15, 0, r0, c1, c0, 0
nop
nop
nop
nop
nop
nop
nop
nop
ldr pc, L_post_remap
L_post_remap:
.word remap_end
remap_end:
#ifdef BOOTLOADER
/* Copy bootloader exception handler code to address 0 */
ldr r2, =_vectorsstart
ldr r3, =_vectorsend
ldr r4, =_vectorscopy
1:
cmp r3, r2
ldrhi r5, [r4], #4
strhi r5, [r2], #4
bhi 1b
#endif /* BOOTLOADER */
#ifdef HAVE_INIT_ATTR
/* copy init data to codec buffer */
/* must be done before bss is zeroed */
ldr r4, =_initcopy
ldr r3, =_initend
ldr r2, =_initstart
1:
cmp r3, r2
ldrhi r5, [r4], #4
strhi r5, [r2], #4
bhi 1b
#endif /* HAVE_INIT_ATTR */
/* Initialise bss and ncbss sections to zero */
ldr r2, =_edata
ldr r3, =_end
mov r4, #0
1:
cmp r3, r2
strhi r4, [r2], #4
bhi 1b
/* Set up stack for IRQ mode */
msr cpsr_c, #0xd2
ldr sp, =irq_stack
/* FIQ mode is unused, thus sp_FIQ is irrelevant for it */
/* Set up stack for SVC mode */
msr cpsr_c, #0xd3
ldr sp, =svc_stack
/* Let abort and undefined modes use irq stack */
msr cpsr_c, #0xd7
ldr sp, =irq_stack
msr cpsr_c, #0xdb
ldr sp, =irq_stack
/* Switch to sys mode */
msr cpsr_c, #0xdf
/* Set up some stack and munge it with 0xdeadbeef */
ldr sp, =stackend
ldr r2, =stackbegin
ldr r3, =0xdeadbeef
1:
cmp sp, r2
strhi r3, [r2], #4
bhi 1b
#ifndef BOOTLOADER
/* Enable access to VFP */
mrc p15, 0, r3, c1, c0, 2
orr r3, r3, #0xf00000
mcr p15, 0, r3, c1, c0, 2
/* Enable VFP */
mrc p10, 7, r3, c8, c0, 0
orr r3, r3, #1<<30
mcr p10, 7, r3, c8, c0, 0
/* Disable exceptions, enable default NaN, flush-to-zero, round toward 0 */
mrc p10, 7, r3, c1, c0, 0
orr r3, r3, #15<<22
bic r3, r3, #31<<8
mcr p10, 7, r3, c1, c0, 0
#endif
/* Make memory coherent for devices */
bl commit_discard_idcache
bl main
#ifdef BOOTLOADER
/* Exception vectors with absolute jumps for bootloader */
.section .vectors,"aw"
ldr pc, [pc, #24]
ldr pc, [pc, #24]
ldr pc, [pc, #24]
ldr pc, [pc, #24]
ldr pc, [pc, #24]
ldr pc, [pc, #24]
subs pc, lr, #4 @ ldr pc, [pc, #24]
subs pc, lr, #4 @ ldr pc, [pc, #24]
.word newstart
.word undef_instr_handler
.word software_int_handler
.word prefetch_abort_handler
.word data_abort_handler
.word reserved_handler
.word 0 @ irq_handler
.word 0 @ fiq_handler
#endif /* BOOTLOADER */
/* 256 words of IRQ stack */
.section .bss
.balign 32
.space 256*4
irq_stack:
/* 256 words of SVC stack */
.section .bss
.balign 32
.space 256*4
svc_stack:
|