rockbox/firmware/target/arm/imx31/crt0.S
Daniel Stenberg 2acc0ac542 Updated our source code header to explicitly mention that we are GPL v2 or
later. We still need to hunt down snippets used that are not. 1324 modified
files...
http://www.rockbox.org/mail/archive/rockbox-dev-archive-2008-06/0060.shtml


git-svn-id: svn://svn.rockbox.org/rockbox/trunk@17847 a1c6a512-1295-4272-9138-f99709370657
2008-06-28 18:10:04 +00:00

346 lines
10 KiB
ArmAsm

/***************************************************************************
* __________ __ ___.
* 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
b irq_handler
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>
*
*/
/* Initially this code is running at VA 0x8a000000 (PA 0x82000000).
* The mapping stub is copied to IRAM (0x1fffc000) and jumps to the final
* VA remapping starting at 0x01f00000 because the 1MB section containing
* the framebuffer at PA 0x81000000 is skipped in the remapping giving 63MB
* of contiguous RAM for the firmware. The TTB is placed at the end of said
* section.
*
* For now this will be done in bootloader, especially if usb will be needed
* within the bootloader to load the main firmware file. Interrupts will be
* needed for this (whether they be swi or irq).
*/
newstart:
msr cpsr_c, #0xd3 /* enter supervisor mode, disable IRQ/FIQ */
#ifdef BOOTLOADER
adr r2, remap_start /* Load PC-relative labels */
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
mov pc, 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 */
mov r2, r5
add r3, r5, #TTB_SIZE
mov r1, #0
1:
str r1, [r2], #4
cmp r2, r3
blo 1b
/* 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, no cache */
/* 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
sub r1, r1, #TTB_SIZE/4*(1 << 20) /* Back up */
/* Map 0x80000000 -> 0x0, cached */
mov r2, r5 /* TTB pointer */
add r3, r5, #63*4 /* End position */
orr r1, r1, #0x80000000 /* Physical address */
orr r1, r1, #((1 << 3) | /* cache flag */ \
(1 << 2)) /* buffer flag */
1:
str r1, [r2], #4
add r1, r1, #(1 << 20)
and r4, r1, #0x0ff00000
cmp r4, #0x00100000 /* Skip framebuffer */
addeq r1, r1, #(1 << 20)
cmp r2, r3
blo 1b
/* Map device section 0x80100000 to 0x03f00000 - buffered, not cached */
bic r1, r1, #0x0ff00000
orr r1, r1, #0x00100000
bic r1, r1, #(1 << 3)
add r2, r5, #63*4
str r1, [r2]
/* 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:
#endif /* BOOTLOADER */
#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 */
/* Initialise bss section to zero */
ldr r2, =_edata
ldr r3, =_end
mov r4, #0
1:
cmp r3, r2
strhi r4, [r2], #4
bhi 1b
/* Initialise the device bss section to zero */
ldr r2, =_devbssdata
ldr r3, =_devbssend
mov r4, #0
1:
cmp r3, r2
strhi r4, [r2], #4
bhi 1b
/* 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
/* Set up stack for IRQ mode */
msr cpsr_c, #0xd2
ldr sp, =irq_stack
/* Set up stack for FIQ mode */
msr cpsr_c, #0xd1
ldr sp, =fiq_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 back to supervisor mode */
msr cpsr_c, #0xd3
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]
ldr pc, [pc, #24]
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 irq_handler
.word fiq_handler
#endif /* BOOTLOADER */
.text
/* All illegal exceptions call into UIE with exception address as first
* parameter. This is calculated differently depending on which exception
* we're in. Second parameter is exception number, used for a string lookup
* in UIE. */
undef_instr_handler:
mov r0, lr
mov r1, #0
b UIE
/* We run supervisor mode most of the time, and should never see a software
* exception being thrown. Perhaps make it illegal and call UIE? */
software_int_handler:
reserved_handler:
movs pc, lr
prefetch_abort_handler:
sub r0, lr, #4
mov r1, #1
b UIE
data_abort_handler:
sub r0, lr, #8
mov r1, #2
b UIE
/* 256 words of IRQ stack */
.space 256*4
irq_stack:
/* 256 words of FIQ stack */
.space 256*4
fiq_stack: