DM320: Re-write of crt0.S and update to app linker script.

git-svn-id: svn://svn.rockbox.org/rockbox/trunk@29224 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
Karl Kurbjun 2011-02-06 20:10:45 +00:00
parent 02dbde7097
commit 9241210050
2 changed files with 384 additions and 173 deletions

View file

@ -7,12 +7,7 @@
* \/ \/ \/ \/ \/
* $Id$
*
* Copyright (C) 2002 by Linus Nielsen Feltzing
*
* 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>
* Copyright (C) 2010 by Karl Kurbjun
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -26,25 +21,83 @@
#include "config.h"
#include "cpu.h"
.section .init.text,"ax",%progbits
#define CACHE_NONE 0
#define CACHE_ALL 0x0C
#define BUFFERED 0x04
.global start
start:
msr cpsr, #0xd3 /* enter supervisor mode, disable IRQ/FIQ */
#define LONG_VECTORS 1
#ifndef CREATIVE_ZVx
/* Copy 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
/******************************************************************************
* vectors: *
* This is the ARM vector table *
* Long call exception handlers are used for simplicity between flash *
* bootloader and SDRAM main-application. These need to be copied to address *
* 0x0 at start. *
******************************************************************************/
.section .vectors,"ax"
.code 32
.global _vectors
@entry:
_vectors:
#if defined(SHORT_VECTORS) /* Use relative branch vectors (64 MB limit) */
b _start /* Reset Vector */
b _undefined_instruction /* Undefined instruction */
b _software_interrupt /* Software Vector */
b _prefetch_abort /* Prefetch Abort */
b _data_abort /* Data Abort */
b _dead_loop /* Reserved/Unused */
b irq_handler /* IRQ vector */
b fiq_handler /* FIQ vector */
#else
#if defined(LONG_VECTORS)
/* Load the PC with the word values stored below */
ldr pc, [pc, #0x18] /* Reset */
ldr pc, [pc, #0x18] /* Undefined instruction */
ldr pc, [pc, #0x18] /* Software interrupt */
ldr pc, [pc, #0x18] /* Prefetch Abort */
ldr pc, [pc, #0x18] /* Data Abort */
ldr pc, [pc, #0x18] /* Reserved/Unused */
ldr pc, [pc, #0x18] /* IRQ */
ldr pc, [pc, #0x18] /* FIQ */
/* Addresses of the handlers */
.word _start
.word _undefined_instruction
.word _software_interrupt
.word _prefetch_abort
.word _data_abort
.word _dead_loop
.word irq_handler
.word fiq_handler
#else
#error Vector type undefined
#endif
#endif
/* Disable data and instruction cache, high vectors (at 0xffff0000 instead of 0x00000000) */
/******************************************************************************
* _start: *
* This is the main entry point to the program *
******************************************************************************/
.section .init, "ax"
.code 32
.align 0x04
.global _start
_start:
/* Go into supervisor state with IRQ's disabled.
* This register is described in section "A2.5 Program status registers"
* of the "ARM Architecture Reference Manual".
*/
msr cpsr, #0xd3
/* Disable all the fancy stuff */
mov r0, #0
mcr p15, 0, r0, c1, c0, 0
/* Disable data and instruction cache, high vectors (at 0xffff0000 instead
* of 0x00000000)
*/
mrc p15, 0, r0, c1, c0, 0
/* clear bits 13, 9:8 (--VI --RS) */
bic r0, r0, #0x00003300
@ -54,112 +107,236 @@ start:
orr r0, r0, #0x00000002
mcr p15, 0, r0, c1, c0, 0
#if !defined(STUB)
/* Zero out IBSS */
ldr r2, =_iedata
ldr r3, =_iend
mov r4, #0
1:
cmp r3, r2
strhi r4, [r2], #4
bhi 1b
/* Add a few cycles of delay before continuing due to system requirements */
mov r0, #0x20
bl _delay_cycles
#ifndef CREATIVE_ZVx
/* Copy the IRAM */
ldr r2, =_iramcopy
ldr r3, =_iramstart
ldr r4, =_iramend
1:
cmp r4, r3
ldrhi r5, [r2], #4
strhi r5, [r3], #4
bhi 1b
#if defined(BOOTLOADER)
bl _init_board
#endif
#endif /* !STUB */
/* Copy exception handler code to address 0 */
ldr r0, =_vectorscopy
ldr r1, =_vectorsstart
ldr r2, =_vectorsend
bl _copy_section
/* Initialise bss section to zero */
ldr r2, =_edata
ldr r3, =_end
mov r4, #0
bsszero:
cmp r3, r2
strhi r4, [r2], #4
bhi bsszero
/* Add some delay time to make sure JTAG can be accessed cleanly */
mov r0, #0x100000
bl _delay_cycles
/* Set up some stack and munge it with 0xdeadbeef */
ldr sp, =stackend
mov r3, sp
ldr r2, =stackbegin
ldr r4, =0xdeadbeef
stackmunge:
cmp r3, r2
strhi r4, [r2], #4
bhi stackmunge
#if defined(BOOTLOADER)
/* Copy the DRAM */
ldr r0, =_dramcopy
ldr r1, =_dramstart
ldr r2, =_dramend
bl _copy_section
#endif
/* Set up stack for IRQ mode */
msr cpsr_c, #0xd2 /* IRQ disabled, FIQ enabled */
ldr sp, =irq_stack
/* Set up stack for FIQ mode */
msr cpsr_c, #0xd1 /* IRQ/FIQ disabled */
ldr sp, =fiq_stack
/* Zero out the IBSS */
mov r0, #0
ldr r1, =_ibss_start
ldr r2, =_ibss_end
bl _init_section
/* Let abort and undefined modes use IRQ stack */
msr cpsr_c, #0xd7 /* IRQ/FIQ disabled */
ldr sp, =irq_stack
msr cpsr_c, #0xdb /* IRQ/FIQ disabled */
ldr sp, =irq_stack
/* Copy the IRAM */
ldr r0, =_iramcopy
ldr r1, =_iramstart
ldr r2, =_iramend
bl _copy_section
/* Switch to supervisor mode (no IRQ) */
msr cpsr_c, #0xd3
ldr sp, =stackend
/* Zero out the BSS */
mov r0, #0
ldr r1, =_bss_start
ldr r2, =_bss_end
bl _init_section
start_loc:
bl main
/* main() should never return */
/* Initialize fiq stack */
ldr r0, =0xDEADBEEF
ldr r1, =_fiq_stack_end /* Stack counts backwards, so end is first*/
ldr r2, =_fiq_stack_start
bl _init_section
/* Exception handlers. Will be copied to address 0 after memory remapping */
.section .vectors,"aw"
b start
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
msr cpsr_c, #0xd1 /* Go into fiq state */
ldr sp, =_fiq_stack_start /* set the fiq stack pointer */
.text
/* Initialize irq stack */
ldr r0, =0xDEADBEEF /* Can be taken out; left for clarity */
ldr r1, =_irq_stack_end /* Stack counts backwards, so end is first*/
ldr r2, =_irq_stack_start
bl _init_section
/* 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.
msr cpsr_c, #0xd2 /* Go into irq state */
ldr sp, =_irq_stack_start /* set the irq stack pointer */
/* This should not be needed, but set the stack location for abort and
* undefined to at least a known stack location (IRQ)
*/
msr cpsr_c, #0xd7 /* Go into abort state */
ldr sp, =_irq_stack_start /* set the stack pointer */
msr cpsr_c, #0xdb /* Go into undefined state */
ldr sp, =_irq_stack_start /* set the stack pointer */
/* Initialize program stack */
msr cpsr_c, #0xd3 /* Go into supervisor state */
ldr r0, =0xDEADBEEF /* Can be taken out; left for clarity */
ldr r1, =_pro_stack_end /* Stack counts backwards, so end is first*/
ldr r2, =_pro_stack_start
bl _init_section
ldr sp, =_pro_stack_start /* set the supervisor stack pointer */
/* MMU initialization */
bl ttb_init
/* Make sure everything is mapped on itself */
ldr r0, =0x0
ldr r1, =0x0
ldr r2, =0x1000
mov r3, #CACHE_NONE
bl map_section
/* Enable caching for FLASH */
ldr r0, =_flash_start
ldr r1, =_flash_start
ldr r2, =_flash_sizem
mov r3, #CACHE_ALL
bl map_section
/* Enable caching for RAM */
ldr r0, =_sdram_start
ldr r1, =_sdram_start
ldr r2, =_sdram_sizem
mov r3, #CACHE_ALL
bl map_section
bl enable_mmu
/* Initial setup is complete, go into main */
ldr pc, =main
/* If main returns go into an infinite loop */
b _dead_loop
/* Constants go here (from _start - .ltorg): */
.ltorg
/******************************************************************************
* _init_section: *
* This function initializes a section with the 32-bit value specified. *
******************************************************************************/
.section .init, "ax"
.code 32
.align 0x04
.global _init_section
.type _init_section, %function
/* r0 = init value
* r1 = start location
* r2 = end location
*/
undef_instr_handler:
/* This function will not run if end is less than or equal to start */
_init_section:
cmp r2, r1
strhi r0, [r1], #4 /* store and increment start location */
bhi _init_section
bx lr
.ltorg
.size _init_section, .-_init_section
/******************************************************************************
* _copy_section: *
* This function copies a section to a new location *
******************************************************************************/
.section .init, "ax"
.code 32
.align 0x04
.global _copy_section
.type _copy_section, %function
/* r0 = source address
* r1 = destination start address
* r2 = destination end address
*
* r3 is a scratch register
*/
_copy_section:
cmp r2, r1
ldrhi r3, [r0], #4
strhi r3, [r1], #4
bhi _copy_section
bx lr
.ltorg
.size _copy_section, .-_copy_section
/******************************************************************************
* _delay_cycles: *
* This function delays for the specified number of cycles *
******************************************************************************/
.section .init, "ax"
.code 32
.align 0x04
.global _delay_cycles
.type _delay_cycles, %function
/* r0 = number of cycles to delay */
/* If r0 is zero it will be the maximum length delay */
_delay_cycles:
subs r0, r0, #1
bne _delay_cycles
bx lr
.ltorg
.size _delay_cycles, .-_delay_cycles
/******************************************************************************
* Unused exception vectors. These call the UIE function. *
* Arguements are: *
* r0: PC of exception *
* r1: Exception number. *
* Exception numbers are as defined: *
* 0: Undefined Instruction *
* 1: Prefetch Abort *
* 2: Data Abort *
* The exceptions return operations are documented in section A2.6 of the *
* ARM Architecture Reference Manual. *
******************************************************************************/
/* A2.6.3: Undefined Instruction Exception - LR=PC of next instruction */
_undefined_instruction:
sub r0, lr, #4
mov r1, #0
b UIE
bl 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?
/* A2.6.4: Software Interrupt exception - These should not happen in Rockbox,
* but for now leave this as a placeholder and continue with the program.
* LR=PC of next instruction.
*/
software_int_handler:
reserved_handler:
movs pc, lr
_software_interrupt:
mov pc, lr
prefetch_abort_handler:
/* A2.6.5 Prefetch Abort - This is also the BKPT instruction since this is a
* v5 target. Pass it on to UIE since it is not currently used.
*/
_prefetch_abort:
sub r0, lr, #4
mov r1, #1
b UIE
bl UIE
data_abort_handler:
/* A2.6.6 Data Abort - There was a memory abort, can return after fixing cause
* with the LR address.
*/
_data_abort:
sub r0, lr, #8
mov r1, #2
b UIE
bl UIE
#ifdef STUB
UIE:
b UIE
#endif
/******************************************************************************
* _dead_loop: Something really unexpected happened (like a reserved *
* exception). Just hang. *
******************************************************************************/
_dead_loop:
b _dead_loop
.ltorg