From 924121005083bf6f07f877dfc6eb6c0e2908316d Mon Sep 17 00:00:00 2001 From: Karl Kurbjun Date: Sun, 6 Feb 2011 20:10:45 +0000 Subject: 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 --- firmware/target/arm/tms320dm320/app.lds | 164 ++++++++----- firmware/target/arm/tms320dm320/crt0.S | 409 +++++++++++++++++++++++--------- 2 files changed, 392 insertions(+), 181 deletions(-) (limited to 'firmware/target/arm') 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 + * 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 -- cgit v1.2.3