blob: 97cdc197fdf14007d70f2aa0e39a89788f30a135 [file] [log] [blame]
Daniel Ankers41997d32006-08-31 19:45:05 +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.
Daniel Ankers41997d32006-08-31 19:45:05 +000016 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21#include "config.h"
22#include "cpu.h"
23
24 .section .init.text,"ax",%progbits
25
26 .global start
27start:
28
29/* PortalPlayer bootloader and startup code based on startup.s from the iPodLinux
30 * loader
31 *
32 * Copyright (c) 2003, Daniel Palffy (dpalffy (at) rainstorm.org)
33 * Copyright (c) 2005, Bernard Leach <leachbj@bouncycastle.org>
34 *
35 */
36#if CONFIG_CPU == PP5002
Michael Sevakisa8b388f2007-11-27 01:20:26 +000037 .equ PROC_ID, 0xc4000000
38 .equ CPU_ICLR, 0xcf001028
39 .equ CPU_CTRL, 0xcf004054
40 .equ COP_ICLR, 0xcf001038
41 .equ COP_CTRL, 0xcf004058
42 .equ CPU_STATUS, 0xcf004050
43 .equ COP_STATUS, 0xcf004050
44 .equ IIS_CONFIG, 0xc0002500
45 .equ SLEEP, 0x000000ca
46 .equ WAKE, 0x000000ce
47 .equ CPUSLEEPING, 0x00008000
48 .equ COPSLEEPING, 0x00004000
49 .equ CACHE_CTRL, 0xcf004024
50 .equ MMAP_LOG, 0xf000f000 /* MMAP0 */
51 .equ MMAP_PHYS, 0xf000f004
Michael Sevakis940e8992007-10-04 04:53:01 +000052#if MEM > 32
Michael Sevakisa8b388f2007-11-27 01:20:26 +000053 .equ MMAP_MASK, 0x00003c00
Michael Sevakis940e8992007-10-04 04:53:01 +000054#else
Michael Sevakisa8b388f2007-11-27 01:20:26 +000055 .equ MMAP_MASK, 0x00003e00
Michael Sevakis940e8992007-10-04 04:53:01 +000056#endif
Michael Sevakisa8b388f2007-11-27 01:20:26 +000057 .equ MMAP_FLAGS, 0x00003f84
Daniel Ankers41997d32006-08-31 19:45:05 +000058#else
Michael Sevakisa8b388f2007-11-27 01:20:26 +000059 .equ PROC_ID, 0x60000000
60 .equ CPU_ICLR, 0x60004028
61 .equ CPU_CTRL, 0x60007000
62 .equ CPU_STATUS, 0x60007000
63 .equ COP_ICLR, 0x60004038
64 .equ COP_CTRL, 0x60007004
65 .equ COP_STATUS, 0x60007004
66 .equ IIS_CONFIG, 0x70002800
67 .equ SLEEP, 0x80000000
68 .equ WAKE, 0x00000000
69 .equ CPUSLEEPING, 0x80000000
70 .equ COPSLEEPING, 0x80000000
71 .equ CACHE_CTRL, 0x6000c000
72 .equ MMAP_LOG, 0xf000f000 /* MMAP0 */
73 .equ MMAP_PHYS, 0xf000f004
Michael Sevakis940e8992007-10-04 04:53:01 +000074#if MEM > 32
Michael Sevakisa8b388f2007-11-27 01:20:26 +000075 .equ MMAP_MASK, 0x00003c00
Michael Sevakis940e8992007-10-04 04:53:01 +000076#else
Michael Sevakisa8b388f2007-11-27 01:20:26 +000077 .equ MMAP_MASK, 0x00003e00
Michael Sevakis940e8992007-10-04 04:53:01 +000078#endif
Michael Sevakisa8b388f2007-11-27 01:20:26 +000079 .equ MMAP_FLAGS, 0x00000f84
Daniel Ankers41997d32006-08-31 19:45:05 +000080#endif
81
Michael Sevakise1c52e72007-08-01 20:26:04 +000082 msr cpsr_c, #0xd3 /* enter supervisor mode, disable IRQ/FIQ */
Daniel Ankers41997d32006-08-31 19:45:05 +000083 b pad_skip
Daniel Ankers43e2c012006-11-22 00:49:16 +000084
Michael Sevakis7914e902007-09-28 10:20:02 +000085.space 64*4 /* (more than enough) space for exception vectors and mi4 magic */
Daniel Ankers43e2c012006-11-22 00:49:16 +000086
Daniel Ankers41997d32006-08-31 19:45:05 +000087pad_skip:
Michael Sevakis7914e902007-09-28 10:20:02 +000088 /* Find out which processor we are - r0 should be preserved for the
89 * duration of the init to avoid constant reloading of the processor ID.
90 * For each stage, CPU proceeds first, then COP.
91 */
92 ldr r0, =PROC_ID
93 ldrb r0, [r0]
94
Daniel Ankers41997d32006-08-31 19:45:05 +000095 /* We need to remap memory from wherever SDRAM is mapped natively, to
96 base address 0, so we can put our exception vectors there. We don't
97 want to do this remapping while executing from SDRAM, so we copy the
98 remapping code to IRAM, then execute from there. Hence, the following
99 code is compiled for address 0, but is currently executing at either
100 0x28000000 or 0x10000000, depending on chipset version. Do not use any
101 absolute addresses until remapping has been done. */
Daniel Ankers41997d32006-08-31 19:45:05 +0000102
Michael Sevakis7914e902007-09-28 10:20:02 +0000103 /* Cores are stepped though the init in turn: CPU then COP. The the remap
104 stage is completed by each core in turn and then the COP waits for the
105 CPU to finish initializing its kernel where the CPU will wake the COP
106 and wait for the COP to finish. This ensures no threading activity
107 starts until it is safe. */
108 cmp r0, #0x55
109
110 /* mask all interrupt sources before setting anything up */
111 ldreq r2, =CPU_ICLR
112 ldrne r2, =COP_ICLR
113 mvn r1, #0
114 str r1, [r2]
115
116 /* put us (co-processor) to sleep and wait for CPU to remap */
117 ldrne r2, =COP_CTRL
118 movne r1, #SLEEP
119 strne r1, [r2]
Michael Sevakisa8b388f2007-11-27 01:20:26 +0000120 nop
121 nop
122 nop
Michael Sevakis7914e902007-09-28 10:20:02 +0000123
124 /* wait for co-processor to sleep then CPU can begin its remapping */
125 ldreq r2, =COP_STATUS
1261:
127 ldreq r1, [r2]
Michael Sevakisa8b388f2007-11-27 01:20:26 +0000128 tsteq r1, #COPSLEEPING
Michael Sevakis7914e902007-09-28 10:20:02 +0000129 beq 1b
130
Michael Sevakis7914e902007-09-28 10:20:02 +0000131 /* disable cache and local interrupt vectors - it is really not desireable
132 to have them enabled here */
133 ldr r2, =CACHE_CTRL
134 mov r1, #0
135 str r1, [r2]
Michael Sevakis7914e902007-09-28 10:20:02 +0000136
137 mov r2, #0x40000000
138 ldr r3, =remap_start
139 ldr r4, =remap_end
140
141 and r6, pc, #0xff000000 /* adjust for execute address */
142 orr r3, r3, r6
143 orr r4, r4, r6
Daniel Ankers41997d32006-08-31 19:45:05 +0000144
145 /* copy the code to 0x40000000 */
1461:
Michael Sevakis7914e902007-09-28 10:20:02 +0000147 ldr r5, [r3], #4
148 str r5, [r2], #4
149 cmp r3, r4
150 blo 1b
Daniel Ankers41997d32006-08-31 19:45:05 +0000151
Michael Sevakis940e8992007-10-04 04:53:01 +0000152 ldr r4, =MMAP_FLAGS
Michael Sevakis7914e902007-09-28 10:20:02 +0000153 orr r4, r4, r6 /* adjust for execute address */
Michael Sevakis940e8992007-10-04 04:53:01 +0000154 ldr r3, =MMAP_PHYS
155 ldr r2, =MMAP_MASK /* ldr is more flexible */
156 ldr r1, =MMAP_LOG
Daniel Ankers41997d32006-08-31 19:45:05 +0000157 mov pc, #0x40000000
158
159remap_start:
Michael Sevakis7914e902007-09-28 10:20:02 +0000160 str r2, [r1]
161 str r4, [r3]
162 ldr r1, L_post_remap
163 mov pc, r1
164L_post_remap:
165 .word remap_end
Daniel Ankers41997d32006-08-31 19:45:05 +0000166remap_end:
167
Daniel Ankers41997d32006-08-31 19:45:05 +0000168 cmp r0, #0x55
Michael Sevakis7914e902007-09-28 10:20:02 +0000169 ldr r4, =COP_CTRL
170 /* Wakeup co-processor to let it do remappings */
171 moveq r3, #WAKE
172 /* Sleep us (co-processor) and wait for CPU to do kernel initialization */
Michael Sevakise1c52e72007-08-01 20:26:04 +0000173 movne r3, #SLEEP
Michael Sevakis7914e902007-09-28 10:20:02 +0000174 str r3, [r4]
Michael Sevakisa8b388f2007-11-27 01:20:26 +0000175 nop
176 nop
177 nop
Daniel Ankers41997d32006-08-31 19:45:05 +0000178
Michael Sevakis7914e902007-09-28 10:20:02 +0000179 /* Jump to co-processor init */
Michael Sevakise1c52e72007-08-01 20:26:04 +0000180 ldrne pc, =cop_init
Daniel Ankers41997d32006-08-31 19:45:05 +0000181
Barry Wardell2f16d4f2006-12-19 11:33:53 +0000182cpu_init:
Michael Sevakis7914e902007-09-28 10:20:02 +0000183 /* Wait for COP to go to sleep before proceeding */
Barry Wardell2f16d4f2006-12-19 11:33:53 +0000184 ldr r4, =COP_STATUS
1851:
186 ldr r3, [r4]
Michael Sevakisa8b388f2007-11-27 01:20:26 +0000187 tst r3, #COPSLEEPING
Barry Wardell2f16d4f2006-12-19 11:33:53 +0000188 beq 1b
Michael Sevakis7914e902007-09-28 10:20:02 +0000189
Daniel Ankers41997d32006-08-31 19:45:05 +0000190 /* Copy exception handler code to address 0 */
191 ldr r2, =_vectorsstart
192 ldr r3, =_vectorsend
193 ldr r4, =_vectorscopy
1941:
195 cmp r3, r2
196 ldrhi r5, [r4], #4
197 strhi r5, [r2], #4
198 bhi 1b
Daniel Ankers43e2c012006-11-22 00:49:16 +0000199
Daniel Ankers41997d32006-08-31 19:45:05 +0000200 /* Zero out IBSS */
201 ldr r2, =_iedata
202 ldr r3, =_iend
203 mov r4, #0
2041:
205 cmp r3, r2
206 strhi r4, [r2], #4
207 bhi 1b
208
209 /* Copy the IRAM */
210 ldr r2, =_iramcopy
211 ldr r3, =_iramstart
212 ldr r4, =_iramend
2131:
214 cmp r4, r3
215 ldrhi r5, [r2], #4
216 strhi r5, [r3], #4
217 bhi 1b
Daniel Ankers41997d32006-08-31 19:45:05 +0000218
219 /* Initialise bss section to zero */
220 ldr r2, =_edata
221 ldr r3, =_end
222 mov r4, #0
2231:
224 cmp r3, r2
225 strhi r4, [r2], #4
226 bhi 1b
Michael Sevakis7914e902007-09-28 10:20:02 +0000227
228 /* Load stack munge value */
Daniel Ankers41997d32006-08-31 19:45:05 +0000229 ldr r4, =0xdeadbeef
Michael Sevakis7914e902007-09-28 10:20:02 +0000230
231 /* Set up some stack and munge it with 0xdeadbeef */
232 ldr r2, =stackbegin
233 ldr sp, =stackend
2341:
235 cmp sp, r2
236 strhi r4, [r2], #4
237 bhi 1b
238
239#if NUM_CORES > 1
240 /* Set up idle stack and munge it with 0xdeadbeef */
241 ldr r2, =cpu_idlestackbegin
242 ldr r3, =cpu_idlestackend
Daniel Ankers41997d32006-08-31 19:45:05 +00002431:
244 cmp r3, r2
245 strhi r4, [r2], #4
246 bhi 1b
Michael Sevakis7914e902007-09-28 10:20:02 +0000247#endif
248
Daniel Ankers41997d32006-08-31 19:45:05 +0000249 /* Set up stack for IRQ mode */
Michael Sevakise1c52e72007-08-01 20:26:04 +0000250 msr cpsr_c, #0x92 /* IRQ disabled, FIQ enabled */
Daniel Ankers41997d32006-08-31 19:45:05 +0000251 ldr sp, =irq_stack
252 /* Set up stack for FIQ mode */
Michael Sevakise1c52e72007-08-01 20:26:04 +0000253 msr cpsr_c, #0xd1 /* IRQ/FIQ disabled */
Daniel Ankers41997d32006-08-31 19:45:05 +0000254 ldr sp, =fiq_stack
255 /* We'll load the banked FIQ mode registers with useful values here.
Michael Sevakis6077e5b2007-10-06 22:27:27 +0000256 These values will be used in the FIQ handler in pcm-pp.c */
257 ldr r10, =IIS_CONFIG
Daniel Ankers41997d32006-08-31 19:45:05 +0000258
Michael Sevakis6077e5b2007-10-06 22:27:27 +0000259 ldr r11, =dma_play_data
Daniel Ankers41997d32006-08-31 19:45:05 +0000260
261 /* Let abort and undefined modes use IRQ stack */
Michael Sevakise1c52e72007-08-01 20:26:04 +0000262 msr cpsr_c, #0xd7 /* IRQ/FIQ disabled */
Daniel Ankers41997d32006-08-31 19:45:05 +0000263 ldr sp, =irq_stack
Michael Sevakise1c52e72007-08-01 20:26:04 +0000264 msr cpsr_c, #0xdb /* IRQ/FIQ disabled */
Daniel Ankers41997d32006-08-31 19:45:05 +0000265 ldr sp, =irq_stack
Michael Sevakis4aaded52007-08-01 20:59:27 +0000266
Michael Sevakis7914e902007-09-28 10:20:02 +0000267 /* Switch back to supervisor mode */
Daniel Ankers41997d32006-08-31 19:45:05 +0000268 msr cpsr_c, #0xd3
Michael Sevakis7914e902007-09-28 10:20:02 +0000269
270 /* Delay waking the COP until thread initialization is complete unless dual-core
271 support is not enabled in which case the cop_main function does not perform
272 any kernel or thread initialization. It's just a trivial sleep loop. */
273#if NUM_CORES == 1
274 ldr r4, =COP_CTRL
275 mov r3, #WAKE
276 str r3, [r4]
277#endif
278
Daniel Ankers41997d32006-08-31 19:45:05 +0000279 bl main
280 /* main() should never return */
281
282cop_init:
Michael Sevakis7914e902007-09-28 10:20:02 +0000283#if NUM_CORES > 1
284 /* Wait for CPU to go to sleep at the end of its kernel init */
285 ldr r4, =CPU_STATUS
Barry Wardell2f16d4f2006-12-19 11:33:53 +00002861:
Michael Sevakis7914e902007-09-28 10:20:02 +0000287 ldr r3, [r4]
Michael Sevakisa8b388f2007-11-27 01:20:26 +0000288 tst r3, #CPUSLEEPING
Michael Sevakis7914e902007-09-28 10:20:02 +0000289 beq 1b
Michael Sevakisda552512007-09-29 06:17:33 +0000290#endif
Barry Wardell2f16d4f2006-12-19 11:33:53 +0000291
Michael Sevakis7914e902007-09-28 10:20:02 +0000292 /* Set up idle stack for COP and munge it with 0xdeadbeef */
Michael Sevakis7914e902007-09-28 10:20:02 +0000293 ldr sp, =cop_idlestackend
Michael Sevakisda552512007-09-29 06:17:33 +0000294 ldr r2, =cop_idlestackbegin
Daniel Ankers41997d32006-08-31 19:45:05 +0000295 ldr r4, =0xdeadbeef
2962:
Michael Sevakis7914e902007-09-28 10:20:02 +0000297 cmp sp, r2
Daniel Ankers41997d32006-08-31 19:45:05 +0000298 strhi r4, [r2], #4
299 bhi 2b
300
Daniel Ankers82f90562007-03-04 20:06:41 +0000301 /* Set up stack for IRQ mode */
Michael Sevakise1c52e72007-08-01 20:26:04 +0000302 msr cpsr_c, #0x92 /* IRQ disabled, FIQ enabled */
Daniel Ankers82f90562007-03-04 20:06:41 +0000303 ldr sp, =cop_irq_stack
304 /* Set up stack for FIQ mode */
Michael Sevakise1c52e72007-08-01 20:26:04 +0000305 msr cpsr_c, #0xd1 /* IRQ/FIQ disabled */
306 ldr sp, =cop_fiq_stack
Daniel Ankers82f90562007-03-04 20:06:41 +0000307
308 /* Let abort and undefined modes use IRQ stack */
Michael Sevakise1c52e72007-08-01 20:26:04 +0000309 msr cpsr_c, #0xd7 /* IRQ/FIQ disabled */
Daniel Ankers82f90562007-03-04 20:06:41 +0000310 ldr sp, =cop_irq_stack
Michael Sevakise1c52e72007-08-01 20:26:04 +0000311 msr cpsr_c, #0xdb /* IRQ/FIQ disabled */
Daniel Ankers82f90562007-03-04 20:06:41 +0000312 ldr sp, =cop_irq_stack
313
Michael Sevakis7914e902007-09-28 10:20:02 +0000314 /* Switch back to supervisor mode */
Michael Sevakis4aaded52007-08-01 20:59:27 +0000315 msr cpsr_c, #0xd3
Barry Wardell2f16d4f2006-12-19 11:33:53 +0000316
317 /* Run cop_main() in apps/main.c */
Daniel Ankers41997d32006-08-31 19:45:05 +0000318 bl cop_main
Michael Sevakis7914e902007-09-28 10:20:02 +0000319
Daniel Ankers41997d32006-08-31 19:45:05 +0000320/* Exception handlers. Will be copied to address 0 after memory remapping */
321 .section .vectors,"aw"
322 ldr pc, [pc, #24]
323 ldr pc, [pc, #24]
324 ldr pc, [pc, #24]
325 ldr pc, [pc, #24]
326 ldr pc, [pc, #24]
327 ldr pc, [pc, #24]
328 ldr pc, [pc, #24]
329 ldr pc, [pc, #24]
330
331 /* Exception vectors */
332 .global vectors
333vectors:
334 .word start
335 .word undef_instr_handler
336 .word software_int_handler
337 .word prefetch_abort_handler
338 .word data_abort_handler
339 .word reserved_handler
340 .word irq_handler
Michael Sevakis6077e5b2007-10-06 22:27:27 +0000341 .word fiq_handler
Daniel Ankers41997d32006-08-31 19:45:05 +0000342
343 .text
344
Daniel Ankers41997d32006-08-31 19:45:05 +0000345/* All illegal exceptions call into UIE with exception address as first
346 parameter. This is calculated differently depending on which exception
347 we're in. Second parameter is exception number, used for a string lookup
348 in UIE.
349 */
350undef_instr_handler:
351 mov r0, lr
352 mov r1, #0
353 b UIE
354
355/* We run supervisor mode most of the time, and should never see a software
356 exception being thrown. Perhaps make it illegal and call UIE?
357 */
358software_int_handler:
359reserved_handler:
360 movs pc, lr
Daniel Ankers41997d32006-08-31 19:45:05 +0000361prefetch_abort_handler:
362 sub r0, lr, #4
363 mov r1, #1
364 b UIE
365
Daniel Ankers41997d32006-08-31 19:45:05 +0000366data_abort_handler:
367 sub r0, lr, #8
368 mov r1, #2
369 b UIE
370
371irq_handler:
372#ifndef STUB
373 stmfd sp!, {r0-r3, r12, lr}
374 bl irq
375 ldmfd sp!, {r0-r3, r12, lr}
376#endif
377 subs pc, lr, #4
378
379#ifdef STUB
380UIE:
381 b UIE
382#endif
383
Michael Sevakis7914e902007-09-28 10:20:02 +0000384/* Align stacks to cache line boundary */
Michael Sevakisa8b388f2007-11-27 01:20:26 +0000385 .balign 32
Michael Sevakis7914e902007-09-28 10:20:02 +0000386
Daniel Ankers41997d32006-08-31 19:45:05 +0000387/* 256 words of IRQ stack */
388 .space 256*4
389irq_stack:
390
Daniel Ankers82f90562007-03-04 20:06:41 +0000391/* 256 words of COP IRQ stack */
392 .space 256*4
393cop_irq_stack:
394
Daniel Ankers41997d32006-08-31 19:45:05 +0000395/* 256 words of FIQ stack */
396 .space 256*4
397fiq_stack:
Michael Sevakise1c52e72007-08-01 20:26:04 +0000398
399/* We'll need this soon - just reserve the symbol */
400#if 0
401/* 256 words of COP FIQ stack */
402 .space 256*4
403#endif
404cop_fiq_stack: