summaryrefslogtreecommitdiffstats
path: root/firmware/target/arm
diff options
context:
space:
mode:
authorKarl Kurbjun <kkurbjun@gmail.com>2011-02-06 20:10:45 +0000
committerKarl Kurbjun <kkurbjun@gmail.com>2011-02-06 20:10:45 +0000
commit924121005083bf6f07f877dfc6eb6c0e2908316d (patch)
treedfe3b9140965dca6c0b2adfc71a46dcad693bc98 /firmware/target/arm
parent02dbde70970b002f1a77583a496c1d669e6c0537 (diff)
downloadrockbox-924121005083bf6f07f877dfc6eb6c0e2908316d.tar.gz
rockbox-924121005083bf6f07f877dfc6eb6c0e2908316d.zip
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
Diffstat (limited to 'firmware/target/arm')
-rw-r--r--firmware/target/arm/tms320dm320/app.lds164
-rw-r--r--firmware/target/arm/tms320dm320/crt0.S409
2 files changed, 392 insertions, 181 deletions
diff --git a/firmware/target/arm/tms320dm320/app.lds b/firmware/target/arm/tms320dm320/app.lds
index 3a9c01708a..ab871bb9c5 100644
--- a/firmware/target/arm/tms320dm320/app.lds
+++ b/firmware/target/arm/tms320dm320/app.lds
@@ -1,6 +1,6 @@
#include "config.h"
-ENTRY(start)
+ENTRY(_start)
OUTPUT_FORMAT(elf32-littlearm)
OUTPUT_ARCH(arm)
@@ -16,7 +16,7 @@ STARTUP(target/arm/tms320dm320/crt0.o)
#define LCD_FUDGE LCD_NATIVE_WIDTH%32
-#define LCD_BUFFER_SIZE ((LCD_NATIVE_WIDTH+LCD_FUDGE)*LCD_NATIVE_HEIGHT*2)
+#define LCD_BUFFER_SIZE ((LCD_NATIVE_WIDTH+LCD_FUDGE)*LCD_NATIVE_HEIGHT*2)
/* must be 16Kb (0x4000) aligned */
#define TTB_SIZE 0x4000
@@ -30,112 +30,144 @@ STARTUP(target/arm/tms320dm320/crt0.o)
#define DRAMSIZE (MEMORYSIZE * 0x100000)
#define DRAMORIG 0x00900000
-#define IRAMORIG 0x00000000
-#define IRAMSIZE 0x4000
+
+#define FLASHORIG 0x00100000
+#define FLASHSIZE 0x00800000
+
+#define ITCMORIG 0x00000000
+#define ITCMSIZE 0x4000
+
+#define DTCMORIG 0x00020000
+#define DTCMSIZE 0x4000
+
+PRO_STACK_SIZE = 0x2000;
+IRQ_STACK_SIZE = 0x600;
+FIQ_STACK_SIZE = 0x400;
/* End of the audio buffer, where the codec buffer starts */
-#define ENDAUDIOADDR (DRAMORIG + DRAMSIZE - PLUGIN_BUFFER_SIZE - CODEC_SIZE - LCD_TTB_AREA)
+#define ENDAUDIOADDR \
+ (DRAMORIG + DRAMSIZE - PLUGIN_BUFFER_SIZE - CODEC_SIZE - LCD_TTB_AREA)
MEMORY
{
DRAM : ORIGIN = DRAMORIG, LENGTH = DRAMSIZE
- IRAM : ORIGIN = IRAMORIG, LENGTH = IRAMSIZE
+ ITCM : ORIGIN = ITCMORIG, LENGTH = ITCMSIZE
+ DTCM : ORIGIN = DTCMORIG, LENGTH = DTCMSIZE
}
SECTIONS
{
- .text :
+ /* Set up variables needed for memory initialization */
+ _sdram_start = DRAMORIG;
+ _sdram_sizem = ((_endsdram - _sdram_start) / 0x100000);
+
+ _flash_start = FLASHORIG;
+ _flash_sizem = (FLASHSIZE / 0x100000);
+
+ /* crt0.S initialization */
+ .init :
{
+ . = ALIGN(0x4);
loadaddress = .;
- _loadaddress = .;
- *(.init.text)
- *(.text*)
- *(.glue_7)
- *(.glue_7t)
+ *(.init)
+ } > DRAM
+
+ .vectors ITCMORIG :
+ {
. = ALIGN(0x4);
+ _vectorsstart = .;
+ *(.vectors);
+ _vectorsend = .;
+ } > ITCM AT> DRAM
+
+ _vectorscopy = LOADADDR(.vectors);
+
+ .text :
+ {
+ . = ALIGN(0x4);
+ *(.text*)
+ } > DRAM
+
+ /* Thumb interworking sections - for some reason LD dies even if these
+ * sections are empty.
+ */
+ .glue :
+ {
+ . = ALIGN(0x4);
+ *(.glue_7) /* ARM calling Thumb */
+ *(.glue_7t) /* Thumb calling ARM */
} > DRAM
.rodata :
{
- *(.rodata) /* problems without this, dunno why */
- *(.rodata*)
. = ALIGN(0x4);
+ *(.rodata*)
} > DRAM
.data :
{
- *(.data*)
. = ALIGN(0x4);
+ *(.data*)
} > DRAM
- /DISCARD/ :
- {
- *(.eh_frame)
- }
-
- .vectors IRAMORIG :
+ .bss (NOLOAD) :
{
- _vectorsstart = .;
- *(.vectors);
- _vectorsend = .;
- } > IRAM AT> DRAM
-
- _vectorscopy = LOADADDR(.vectors);
+ . = ALIGN(0x4);
+ _bss_start = .;
+ *(.bss*)
+ *(COMMON)
+ _bss_end = .;
+ } > DRAM
.iram :
{
+ . = ALIGN(0x4);
_iramstart = .;
*(.icode)
- *(.irodata*)
+ *(.irodata)
*(.idata)
- . = ALIGN(0x4);
_iramend = .;
- } > IRAM AT> DRAM
+ } > ITCM AT> DRAM
_iramcopy = LOADADDR(.iram);
-
- .ibss (NOLOAD) :
+
+ .ibss DTCMORIG + _iramend (NOLOAD) :
{
- _iedata = .;
- *(.ibss)
. = ALIGN(0x4);
- _iend = .;
- } > IRAM
+ _ibss_start = .;
+ *(.ibss)
+ _ibss_end = .;
+ } > DTCM
- .stack (NOLOAD) :
+ /* Program stack space */
+ .pro_stack (NOLOAD):
{
- *(.stack)
- stackbegin = .;
- . += 0x2000;
- stackend = .;
- } > IRAM
+ . = ALIGN(0x4);
+ *(.stack)
+ stackbegin = .; /* Variable for thread.c */
+ _pro_stack_end = .;
+ . += PRO_STACK_SIZE;
+ _pro_stack_start = .;
+ stackend = .; /* Variable for tread.c */
+ } > DTCM
- .irqstack (NOLOAD) :
+ /* IRQ stack space */
+ .irq_stack (NOLOAD):
{
- *(.stack)
- . += 0x400;
- irq_stack = .;
- } > IRAM
-
- .fiqstack (NOLOAD) :
- {
- *(.stack)
- . += 0x400;
- fiq_stack = .;
- } > IRAM
-
- /* This overwrites the iram (in ram), so make sure that the iram is copied
- * out in crt0.s before the bss section and the rest are used.
- */
- .bss (NOLOAD) :
+ . = ALIGN(0x4);
+ _irq_stack_end = .;
+ . += IRQ_STACK_SIZE;
+ _irq_stack_start = .;
+ } > DTCM
+
+ /* FIQ stack space */
+ .fiq_stack (NOLOAD):
{
- . = ADDR(.data) + SIZEOF(.data);
- _edata = .;
- *(.bss*)
- *(COMMON)
. = ALIGN(0x4);
- _end = .;
- } > DRAM
+ _fiq_stack_end = .;
+ . += FIQ_STACK_SIZE;
+ _fiq_stack_start = .;
+ } > DTCM
.audiobuf (NOLOAD) :
{
@@ -160,6 +192,8 @@ SECTIONS
. += PLUGIN_BUFFER_SIZE;
} > DRAM
+ _endsdram = .;
+
.ttbtable (NOLOAD) :
{
. = ALIGN (0x4000);
diff --git a/firmware/target/arm/tms320dm320/crt0.S b/firmware/target/arm/tms320dm320/crt0.S
index 440897d67f..69bc8b1622 100644
--- a/firmware/target/arm/tms320dm320/crt0.S
+++ b/firmware/target/arm/tms320dm320/crt0.S
@@ -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
-
-#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
+ /* Add a few cycles of delay before continuing due to system requirements */
+ mov r0, #0x20
+ bl _delay_cycles
+
+#if defined(BOOTLOADER)
+ bl _init_board
+#endif
+
+ /* Copy exception handler code to address 0 */
+ ldr r0, =_vectorscopy
+ ldr r1, =_vectorsstart
+ ldr r2, =_vectorsend
+ bl _copy_section
+
+ /* Add some delay time to make sure JTAG can be accessed cleanly */
+ mov r0, #0x100000
+ bl _delay_cycles
+
+#if defined(BOOTLOADER)
+ /* Copy the DRAM */
+ ldr r0, =_dramcopy
+ ldr r1, =_dramstart
+ ldr r2, =_dramend
+ bl _copy_section
#endif
-#endif /* !STUB */
-
-
- /* Initialise bss section to zero */
- ldr r2, =_edata
- ldr r3, =_end
- mov r4, #0
-bsszero:
- cmp r3, r2
- strhi r4, [r2], #4
- bhi bsszero
-
- /* 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
-
- /* 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
-
- /* 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
-
- /* Switch to supervisor mode (no IRQ) */
- msr cpsr_c, #0xd3
- ldr sp, =stackend
-
-start_loc:
- bl main
- /* main() should never return */
-
-/* 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
-
- .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.
+
+ /* Zero out the IBSS */
+ mov r0, #0
+ ldr r1, =_ibss_start
+ ldr r2, =_ibss_end
+ bl _init_section
+
+ /* Copy the IRAM */
+ ldr r0, =_iramcopy
+ ldr r1, =_iramstart
+ ldr r2, =_iramend
+ bl _copy_section
+
+ /* Zero out the BSS */
+ mov r0, #0
+ ldr r1, =_bss_start
+ ldr r2, =_bss_end
+ bl _init_section
+
+ /* 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
+
+ msr cpsr_c, #0xd1 /* Go into fiq state */
+ ldr sp, =_fiq_stack_start /* set the fiq stack pointer */
+
+ /* 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
+
+ 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
+ */
+
+/* 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
*/
-undef_instr_handler:
+
+_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