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/crt0.S | 409 +++++++++++++++++++++++---------- 1 file changed, 293 insertions(+), 116 deletions(-) (limited to 'firmware/target/arm/tms320dm320/crt0.S') 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