| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297 |
- /*
- * Copyright (C) 2005-2008 by egnite Software GmbH
- * Copyright (C) 2011 by egnite GmbH
- *
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the copyright holders nor the names of
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
- * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
- * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
- * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * For additional information see http://www.ethernut.de/
- */
- /*
- * $Id$
- *
- * This file contains the runtime initialization of the AT91SAM7SE
- * family for code loaded into external RAM, typically SDRAM. It
- * has been written for GNU binutils and definitely needs to be
- * rewritten for other toolchains.
- *
- * Loading and running code in external RAM may be mainly used for
- * debugging, because the executable can be loaded faster than
- * programming flash memory and the number of breakpoints is not
- * limited by the debug hardware. Another application is to use a boot
- * loader running in internal flash, which loads very large executables,
- * which won't fit in internal flash, from external flash memory, e.g.
- * serial flash or memory card.
- *
- * In any case, the loader, either the debug tool or the boot loader,
- * must properly initialize the hardware upfront. This may include
- * various clocks, SDRAM, watchdog timer, reset controller etc. This
- * initialization code is intentionally kept simple and will not do any
- * hardware initialization that could be done by the loader. As a
- * result, some options provided by the Configurator like watchdog, PLL
- * or SDRAM settings are ignored here, but may be honored by the loader.
- */
- #include <cfg/clock.h>
- #include <cfg/memory.h>
- #include <arch/arm.h>
- /*
- * By default, the internal RAM will be mapped to address zero and is
- * used for the exception vectors, RAM functions, exception stacks and
- * the system initialization stack.
- *
- * +-----------+ Top of internal RAM
- * | FIQ stack | (System initialization stack)
- * | |
- * +-----------+
- * | ABT stack |
- * +-----------+
- * | UND stack |
- * +-----------+
- * | IRQ stack |
- * ~ ~
- * | |
- * +-----------+ Top of relocation area (__reloc_end)
- * | RAM funct |
- * ~ ~
- * | |
- * +-----------+
- * | Vectors |
- * +-----------+ Address 0x00000000 (__reloc_start)
- *
- * System routines as well as application code are executed in system
- * mode. During system initialization, the related stack pointer is set
- * to the top of internal RAM, overlaying the fast interrupt stack, and
- * possibly any following exception stack. This is usually no problem,
- * because no interrupts will be enabled before entering the idle thread.
- * Threads will allocate their own stacks from heap memory, located in
- * external RAM.
- */
- /*
- * Exception stack sizes.
- *
- * No explicit size is given for the interrupt stack. As long as there
- * are a few small RAM functions only, almost all internal RAM will be
- * available.
- *
- * The supervisory mode is currently not used in Nut/OS and no stack
- * space is allocated for this mode. System routines as well as
- */
- #ifndef FIQ_STACK_SIZE
- #define FIQ_STACK_SIZE (128 * 4)
- #endif
- #ifndef ABT_STACK_SIZE
- #define ABT_STACK_SIZE (64 * 4)
- #endif
- #ifndef UND_STACK_SIZE
- #define UND_STACK_SIZE (64 * 4)
- #endif
- #ifndef SVC_STACK_SIZE
- #define SVC_STACK_SIZE (0 * 4)
- #endif
- /* =======================================================================
- * Vector table section
- * ======================================================================= */
- .section .vectors, "ax", %progbits
- .code 32
- /*
- * Note, that this section is implemented in relocatable code.
- * It will be loaded into and executed in external RAM and will
- * then be moved to remapped internal RAM.
- */
- ldr pc, [pc, #24] /* Reset */
- ldr pc, [pc, #24] /* Undefined instruction */
- ldr pc, [pc, #24] /* Software interrupt */
- ldr pc, [pc, #24] /* Prefetch abort */
- ldr pc, [pc, #24] /* Data abort */
- .word 0 /* Reserved */
- /*
- * On IRQ the PC will be loaded from AIC_IVR, which
- * provides the address previously set in AIC_SVR.
- * The interrupt routine will be called in ARM_MODE_IRQ
- * with IRQ disabled and FIQ unchanged.
- */
- ldr pc, [pc, #-0xF20] /* Interrupt request, auto vectoring. */
- ldr pc, [pc, #-0xF20] /* Fast interrupt request, auto vectoring. */
- .word _start
- .word __undef
- .word __swi
- .word __prefetch_abort
- .word __data_abort
- /*
- * We use weakly defined default handlers for exceptions. They
- * consist of endless loops and can be overridden by the appli-
- * cation. Although a single loop may serve all exceptions, we
- * intentionally use individual loops. This allows us to easily
- * determine the type of exception by halting the trapped CPU
- * and querying the program counter.
- */
- .weak __undef
- .set __undef, __undef_dummy
- .global __undef_dummy
- __undef_dummy:
- b __undef_dummy
- .weak __swi
- .set __swi, __swi_dummy
- .global __swi_dummy
- __swi_dummy:
- b __swi_dummy
- .weak __prefetch_abort
- .set __prefetch_abort, __prefetch_abort_dummy
- .global __prefetch_abort_dummy
- __prefetch_abort_dummy:
- b __prefetch_abort_dummy
- .weak __data_abort
- .set __data_abort, __data_abort_dummy
- .global __data_abort_dummy
- __data_abort_dummy:
- b __data_abort_dummy
- .ltorg
- /* =======================================================================
- * Initialization section
- * ======================================================================= */
- .section .init0, "ax", %progbits
- .code 32
- /*
- * Weakly define the stack top at the end of internal RAM.
- */
- .weak __stack
- .set __stack, 0x00200000 + MCU_IRAM_SIZE
- _start:
- /*
- * Disable all interrupts. Useful for debugging w/o target reset.
- */
- ldr r1, =AIC_BASE
- mvn r0, #0
- str r0, [r1, #AIC_EOICR_OFF]
- str r0, [r1, #AIC_IDCR_OFF]
- /*
- * Set exception stack pointers and enable interrupts.
- */
- ldr r1, =__stack
- msr CPSR_c, #ARM_MODE_FIQ | ARM_CPSR_I_BIT | ARM_CPSR_F_BIT
- mov sp, r1
- sub r0, r1, #FIQ_STACK_SIZE
- msr CPSR_c, #ARM_MODE_ABORT | ARM_CPSR_I_BIT | ARM_CPSR_F_BIT
- mov sp, r0
- sub r0, r0, #ABT_STACK_SIZE
- msr CPSR_c, #ARM_MODE_UNDEF | ARM_CPSR_I_BIT | ARM_CPSR_F_BIT
- mov sp, r0
- sub r0, r0, #UND_STACK_SIZE
- msr CPSR_c, #ARM_MODE_SVC | ARM_CPSR_I_BIT | ARM_CPSR_F_BIT
- mov sp, r0
- sub r0, r0, #SVC_STACK_SIZE
- msr CPSR_c, #ARM_MODE_IRQ | ARM_CPSR_I_BIT | ARM_CPSR_F_BIT
- mov sp, r0
- /*
- * Enter system mode and initialize the system stack pointer.
- * The stack will use the same memory as the exception stacks
- * that had been setup above. It will be used only until the
- * system enters the idle thread.
- */
- msr CPSR_c, #ARM_MODE_SYS | ARM_CPSR_I_BIT | ARM_CPSR_F_BIT
- mov sp, r1
- /*
- * Remap internal RAM to address zero.
- */
- mov r0, #1
- ldr r1, =MC_BASE
- str r0, [r1, #MC_RCR_OFF]
- /*
- * The .init section contains code (and possibly data), which
- * has been loaded into external RAM and needs to be moved to
- * internal RAM.
- *
- * The load address __data_end and the target addresses
- * __reloc_start and __reloc_end must be provided by the linker
- * script.
- */
- ldr r1, =__data_end
- ldr r2, =__reloc_start
- ldr r3, =__reloc_end
- 1: cmp r2, r3
- ldrne r0, [r1], #4
- strne r0, [r2], #4
- bne 1b
- /*
- * The .bss section keeps all data, that must be initialized to
- * zero. It typically contains uninitialized global and static
- * variables.
- *
- * Note, that __bss_start and __bss_end must be provided by the
- * linker script.
- */
- ldr r1, =__bss_start
- ldr r2, =__bss_end
- mov r3, #0
- 1: cmp r1, r2
- strne r3, [r1], #4
- bne 1b
- /*
- * Set return address and jump to Nut/OS initialization.
- */
- ldr lr, =_exit
- ldr r0, =NutInit
- bx r0
- /*
- * Usually neither the system initialization nor the application
- * will ever return. If it does, we will keep the CPU in an
- * endless loop.
- */
- .weak _exit
- .set _exit, _exit_loop
- .global _exit
- _exit_loop:
- b _exit
- .ltorg
|