123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350 |
- /*
- ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
- http://www.apache.org/licenses/LICENSE-2.0
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- */
- /**
- * @file crt0_v7m.S
- * @brief Generic ARMv7-M (Cortex-M3/M4/M7) startup file for ChibiOS.
- *
- * @addtogroup ARMCMx_GCC_STARTUP_V7M
- * @{
- */
- /*===========================================================================*/
- /* Module constants. */
- /*===========================================================================*/
- #if !defined(FALSE) || defined(__DOXYGEN__)
- #define FALSE 0
- #endif
- #if !defined(TRUE) || defined(__DOXYGEN__)
- #define TRUE 1
- #endif
- #define CONTROL_MODE_PRIVILEGED 0
- #define CONTROL_MODE_UNPRIVILEGED 1
- #define CONTROL_USE_MSP 0
- #define CONTROL_USE_PSP 2
- #define CONTROL_FPCA 4
- #define FPCCR_ASPEN (1 << 31)
- #define FPCCR_LSPEN (1 << 30)
- #define SCB_VTOR 0xE000ED08
- #define SCB_CPACR 0xE000ED88
- #define SCB_FPCCR 0xE000EF34
- #define SCB_FPDSCR 0xE000EF3C
- /*===========================================================================*/
- /* Module pre-compile time settings. */
- /*===========================================================================*/
- /**
- * @brief Enforces initialization of MSP.
- * @note This is required if the boot process is not reliable for whatever
- * reason (bad ROMs, bad bootloaders, bad debuggers=.
- */
- #if !defined(CRT0_FORCE_MSP_INIT) || defined(__DOXYGEN__)
- #define CRT0_FORCE_MSP_INIT TRUE
- #endif
- /**
- * @brief VTOR special register initialization.
- * @details VTOR is initialized to point to the vectors table.
- */
- #if !defined(CRT0_VTOR_INIT) || defined(__DOXYGEN__)
- #define CRT0_VTOR_INIT TRUE
- #endif
- /**
- * @brief FPU initialization switch.
- */
- #if !defined(CRT0_INIT_FPU) || defined(__DOXYGEN__)
- #if defined(CORTEX_USE_FPU) || defined(__DOXYGEN__)
- #define CRT0_INIT_FPU CORTEX_USE_FPU
- #else
- #define CRT0_INIT_FPU FALSE
- #endif
- #endif
- /**
- * @brief Control special register initialization value.
- * @details The system is setup to run in privileged mode using the PSP
- * stack (dual stack mode).
- */
- #if !defined(CRT0_CONTROL_INIT) || defined(__DOXYGEN__)
- #define CRT0_CONTROL_INIT (CONTROL_USE_PSP | \
- CONTROL_MODE_PRIVILEGED)
- #endif
- /**
- * @brief Core initialization switch.
- */
- #if !defined(CRT0_INIT_CORE) || defined(__DOXYGEN__)
- #define CRT0_INIT_CORE TRUE
- #endif
- /**
- * @brief Stack segments initialization switch.
- */
- #if !defined(CRT0_STACKS_FILL_PATTERN) || defined(__DOXYGEN__)
- #define CRT0_STACKS_FILL_PATTERN 0x55555555
- #endif
- /**
- * @brief Stack segments initialization switch.
- */
- #if !defined(CRT0_INIT_STACKS) || defined(__DOXYGEN__)
- #define CRT0_INIT_STACKS TRUE
- #endif
- /**
- * @brief DATA segment initialization switch.
- */
- #if !defined(CRT0_INIT_DATA) || defined(__DOXYGEN__)
- #define CRT0_INIT_DATA TRUE
- #endif
- /**
- * @brief BSS segment initialization switch.
- */
- #if !defined(CRT0_INIT_BSS) || defined(__DOXYGEN__)
- #define CRT0_INIT_BSS TRUE
- #endif
- /**
- * @brief RAM areas initialization switch.
- */
- #if !defined(CRT0_INIT_RAM_AREAS) || defined(__DOXYGEN__)
- #define CRT0_INIT_RAM_AREAS TRUE
- #endif
- /**
- * @brief Constructors invocation switch.
- */
- #if !defined(CRT0_CALL_CONSTRUCTORS) || defined(__DOXYGEN__)
- #define CRT0_CALL_CONSTRUCTORS TRUE
- #endif
- /**
- * @brief Destructors invocation switch.
- */
- #if !defined(CRT0_CALL_DESTRUCTORS) || defined(__DOXYGEN__)
- #define CRT0_CALL_DESTRUCTORS TRUE
- #endif
- /**
- * @brief FPU FPCCR register initialization value.
- * @note Only used if @p CRT0_INIT_FPU is equal to @p TRUE.
- */
- #if !defined(CRT0_FPCCR_INIT) || defined(__DOXYGEN__)
- #define CRT0_FPCCR_INIT (FPCCR_ASPEN | FPCCR_LSPEN)
- #endif
- /**
- * @brief CPACR register initialization value.
- * @note Only used if @p CRT0_INIT_FPU is equal to @p TRUE.
- */
- #if !defined(CRT0_CPACR_INIT) || defined(__DOXYGEN__)
- #define CRT0_CPACR_INIT 0x00F00000
- #endif
- /*===========================================================================*/
- /* Code section. */
- /*===========================================================================*/
- #if !defined(__DOXYGEN__)
- .syntax unified
- .cpu cortex-m3
- #if CRT0_INIT_FPU == TRUE
- .fpu fpv4-sp-d16
- #else
- .fpu softvfp
- #endif
- .thumb
- .text
- /*
- * CRT0 entry point.
- */
- .align 2
- .thumb_func
- .global _crt0_entry
- _crt0_entry:
- /* Interrupts are globally masked initially.*/
- cpsid i
- #if CRT0_FORCE_MSP_INIT == TRUE
- /* MSP stack pointers initialization.*/
- ldr r0, =__main_stack_end__
- msr MSP, r0
- #endif
- /* PSP stack pointers initialization.*/
- ldr r0, =__process_stack_end__
- msr PSP, r0
- #if CRT0_VTOR_INIT == TRUE
- ldr r0, =_vectors
- movw r1, #SCB_VTOR & 0xFFFF
- movt r1, #SCB_VTOR >> 16
- str r0, [r1]
- #endif
- #if CRT0_INIT_FPU == TRUE
- /* FPU FPCCR initialization.*/
- movw r0, #CRT0_FPCCR_INIT & 0xFFFF
- movt r0, #CRT0_FPCCR_INIT >> 16
- movw r1, #SCB_FPCCR & 0xFFFF
- movt r1, #SCB_FPCCR >> 16
- str r0, [r1]
- dsb
- isb
- /* CPACR initialization.*/
- movw r0, #CRT0_CPACR_INIT & 0xFFFF
- movt r0, #CRT0_CPACR_INIT >> 16
- movw r1, #SCB_CPACR & 0xFFFF
- movt r1, #SCB_CPACR >> 16
- str r0, [r1]
- dsb
- isb
- /* FPU FPSCR initially cleared.*/
- mov r0, #0
- vmsr FPSCR, r0
- /* FPU FPDSCR initially cleared.*/
- movw r1, #SCB_FPDSCR & 0xFFFF
- movt r1, #SCB_FPDSCR >> 16
- str r0, [r1]
- /* Enforcing FPCA bit in the CONTROL register.*/
- movs r0, #CRT0_CONTROL_INIT | CONTROL_FPCA
- #else
- movs r0, #CRT0_CONTROL_INIT
- #endif
- /* CONTROL register initialization as configured.*/
- msr CONTROL, r0
- isb
- #if CRT0_INIT_CORE == TRUE
- /* Core initialization.*/
- bl __core_init
- #endif
- /* Early initialization.*/
- bl __early_init
- #if CRT0_INIT_STACKS == TRUE
- ldr r0, =CRT0_STACKS_FILL_PATTERN
- /* Main Stack initialization. Note, it assumes that the
- stack size is a multiple of 4 so the linker file must
- ensure this.*/
- ldr r1, =__main_stack_base__
- ldr r2, =__main_stack_end__
- msloop:
- cmp r1, r2
- itt lo
- strlo r0, [r1], #4
- blo msloop
- /* Process Stack initialization. Note, it assumes that the
- stack size is a multiple of 4 so the linker file must
- ensure this.*/
- ldr r1, =__process_stack_base__
- ldr r2, =__process_stack_end__
- psloop:
- cmp r1, r2
- itt lo
- strlo r0, [r1], #4
- blo psloop
- #endif
- #if CRT0_INIT_DATA == TRUE
- /* Data initialization. Note, it assumes that the DATA size
- is a multiple of 4 so the linker file must ensure this.*/
- ldr r1, =_textdata_start
- ldr r2, =_data_start
- ldr r3, =_data_end
- dloop:
- cmp r2, r3
- ittt lo
- ldrlo r0, [r1], #4
- strlo r0, [r2], #4
- blo dloop
- #endif
- #if CRT0_INIT_BSS == TRUE
- /* BSS initialization. Note, it assumes that the DATA size
- is a multiple of 4 so the linker file must ensure this.*/
- movs r0, #0
- ldr r1, =_bss_start
- ldr r2, =_bss_end
- bloop:
- cmp r1, r2
- itt lo
- strlo r0, [r1], #4
- blo bloop
- #endif
- #if CRT0_INIT_RAM_AREAS == TRUE
- /* RAM areas initialization.*/
- bl __init_ram_areas
- #endif
- /* Late initialization..*/
- bl __late_init
- #if CRT0_CALL_CONSTRUCTORS == TRUE
- /* Constructors invocation.*/
- ldr r4, =__init_array_start
- ldr r5, =__init_array_end
- initloop:
- cmp r4, r5
- bge endinitloop
- ldr r1, [r4], #4
- blx r1
- b initloop
- endinitloop:
- #endif
- /* Main program invocation, r0 contains the returned value.*/
- bl main
- #if CRT0_CALL_DESTRUCTORS == TRUE
- /* Destructors invocation.*/
- ldr r4, =__fini_array_start
- ldr r5, =__fini_array_end
- finiloop:
- cmp r4, r5
- bge endfiniloop
- ldr r1, [r4], #4
- blx r1
- b finiloop
- endfiniloop:
- #endif
- /* Branching to the defined exit handler.*/
- b __default_exit
- #endif /* !defined(__DOXYGEN__) */
- /** @} */
|