1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
8 * $Id: crt0.S 18776 2008-10-11 18:32:17Z gevaerts $
10 * Copyright (C) 2008 by Marcoen Hirschberg
11 * Copyright (C) 2008 by Denes Balatoni
12 * Copyright (C) 2010 by Marcin Bukat
14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License
16 * as published by the Free Software Foundation; either version 2
17 * of the License, or (at your option) any later version.
19 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
20 * KIND, either express or implied.
22 ****************************************************************************/
27 .section .intvect,"ax",%progbits
30 /* Exception vectors */
33 ldr pc, =undef_instr_handler
34 ldr pc, =software_int_handler
35 ldr pc, =prefetch_abort_handler
36 ldr pc, =data_abort_handler
37 ldr pc, =reserved_handler
43 .section .init.text,"ax",%progbits
45 msr cpsr_c, #0xd3 /* enter supervisor mode, disable IRQ/FIQ */
50 /* setup ARM core freq = 200MHz */
51 /* AHB bus freq (HCLK) = 100MHz */
52 /* APB bus freq (PCLK) = 50MHz */
53 ldr r1, [r0,#0x14] /* SCU_DIVCON1 */
54 orr r1, #9 /* ARM slow mode, HCLK:PCLK = 2:1 */
57 ldr r1,=0x01970c70 /* (1<<24) | (1<<23) | (23<<16) | (199<<4) */
62 ldr r1, [r0,#0x2c] /* SCU_STATUS */
63 tst r1, #1 /* ARM pll lock */
68 ldr r1, [r0,#0x14] /* SCU_DIVCON1 */
69 bic r1, #5 /* leave ARM slow mode, ARMclk:HCLK = 2:1 */
72 #if defined(BOOTLOADER)
73 /* remap iram to 0x00000000 */
80 ldr r0, =0xefff0000 /* cache controler base address */
82 strh r1, [r0] /* global cache disable */
84 /* setup uncached regions */
87 str r1, [r0,#0x10] /* MemMapA BUS0IP, 32MB */
88 str r1, [r0,#0x14] /* MemMapB BUS0IP, 32MB */
91 str r1, [r0,#0x18] /* MemMapC DSPMEM, 32MB */
92 mov r1, #0xee000000 /* 0xefff0000 & 0xfe000000 */
94 str r1, [r0,#0x1c] /* MemMapD cache controller, 32MB */
96 mov r1, #2 /* invalidate way opcode */
97 str r1, [r0,#4] /* invalidate way0 */
101 bne 1b /* wait for invalidate to complete */
103 orr r1, r1, #0x80000000
104 str r1, [r0,#4] /* invalidate way1 */
108 bne 1b /* wait for invalidate to complete */
111 orr r1, r1, #0x80000000
112 str r1, [r0] /* global cache enable */
115 /* Copy interrupt vectors to iram */
116 ldr r2, =_intvectstart
118 ldr r4, =_intvectcopy
125 /* Initialise bss section to zero */
135 /* Copy icode and data to ram */
145 /* Initialise ibss section to zero */
155 /* Set up some stack and munge it with 0xdeadbeef */
164 /* Set up stack for IRQ mode */
166 ldr sp, =_irqstackend
168 /* Set up stack for FIQ mode */
170 ldr sp, =_fiqstackend
172 /* Let abort and undefined modes use IRQ stack */
174 ldr sp, =_irqstackend
176 ldr sp, =_irqstackend
178 /* Switch back to supervisor mode */
186 /* All illegal exceptions call into UIE with exception address as first
187 * parameter. This is calculated differently depending on which exception
188 * we're in. Second parameter is exception number, used for a string lookup
195 /* We run supervisor mode most of the time, and should never see a software
196 * exception being thrown. Perhaps make it illegal and call UIE? */
197 software_int_handler:
201 prefetch_abort_handler: