crt0_v7m.S 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350
  1. /*
  2. ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio
  3. Licensed under the Apache License, Version 2.0 (the "License");
  4. you may not use this file except in compliance with the License.
  5. You may obtain a copy of the License at
  6. http://www.apache.org/licenses/LICENSE-2.0
  7. Unless required by applicable law or agreed to in writing, software
  8. distributed under the License is distributed on an "AS IS" BASIS,
  9. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  10. See the License for the specific language governing permissions and
  11. limitations under the License.
  12. */
  13. /**
  14. * @file crt0_v7m.S
  15. * @brief Generic ARMv7-M (Cortex-M3/M4/M7) startup file for ChibiOS.
  16. *
  17. * @addtogroup ARMCMx_GCC_STARTUP_V7M
  18. * @{
  19. */
  20. /*===========================================================================*/
  21. /* Module constants. */
  22. /*===========================================================================*/
  23. #if !defined(FALSE) || defined(__DOXYGEN__)
  24. #define FALSE 0
  25. #endif
  26. #if !defined(TRUE) || defined(__DOXYGEN__)
  27. #define TRUE 1
  28. #endif
  29. #define CONTROL_MODE_PRIVILEGED 0
  30. #define CONTROL_MODE_UNPRIVILEGED 1
  31. #define CONTROL_USE_MSP 0
  32. #define CONTROL_USE_PSP 2
  33. #define CONTROL_FPCA 4
  34. #define FPCCR_ASPEN (1 << 31)
  35. #define FPCCR_LSPEN (1 << 30)
  36. #define SCB_VTOR 0xE000ED08
  37. #define SCB_CPACR 0xE000ED88
  38. #define SCB_FPCCR 0xE000EF34
  39. #define SCB_FPDSCR 0xE000EF3C
  40. /*===========================================================================*/
  41. /* Module pre-compile time settings. */
  42. /*===========================================================================*/
  43. /**
  44. * @brief Enforces initialization of MSP.
  45. * @note This is required if the boot process is not reliable for whatever
  46. * reason (bad ROMs, bad bootloaders, bad debuggers=.
  47. */
  48. #if !defined(CRT0_FORCE_MSP_INIT) || defined(__DOXYGEN__)
  49. #define CRT0_FORCE_MSP_INIT TRUE
  50. #endif
  51. /**
  52. * @brief VTOR special register initialization.
  53. * @details VTOR is initialized to point to the vectors table.
  54. */
  55. #if !defined(CRT0_VTOR_INIT) || defined(__DOXYGEN__)
  56. #define CRT0_VTOR_INIT TRUE
  57. #endif
  58. /**
  59. * @brief FPU initialization switch.
  60. */
  61. #if !defined(CRT0_INIT_FPU) || defined(__DOXYGEN__)
  62. #if defined(CORTEX_USE_FPU) || defined(__DOXYGEN__)
  63. #define CRT0_INIT_FPU CORTEX_USE_FPU
  64. #else
  65. #define CRT0_INIT_FPU FALSE
  66. #endif
  67. #endif
  68. /**
  69. * @brief Control special register initialization value.
  70. * @details The system is setup to run in privileged mode using the PSP
  71. * stack (dual stack mode).
  72. */
  73. #if !defined(CRT0_CONTROL_INIT) || defined(__DOXYGEN__)
  74. #define CRT0_CONTROL_INIT (CONTROL_USE_PSP | \
  75. CONTROL_MODE_PRIVILEGED)
  76. #endif
  77. /**
  78. * @brief Core initialization switch.
  79. */
  80. #if !defined(CRT0_INIT_CORE) || defined(__DOXYGEN__)
  81. #define CRT0_INIT_CORE TRUE
  82. #endif
  83. /**
  84. * @brief Stack segments initialization switch.
  85. */
  86. #if !defined(CRT0_STACKS_FILL_PATTERN) || defined(__DOXYGEN__)
  87. #define CRT0_STACKS_FILL_PATTERN 0x55555555
  88. #endif
  89. /**
  90. * @brief Stack segments initialization switch.
  91. */
  92. #if !defined(CRT0_INIT_STACKS) || defined(__DOXYGEN__)
  93. #define CRT0_INIT_STACKS TRUE
  94. #endif
  95. /**
  96. * @brief DATA segment initialization switch.
  97. */
  98. #if !defined(CRT0_INIT_DATA) || defined(__DOXYGEN__)
  99. #define CRT0_INIT_DATA TRUE
  100. #endif
  101. /**
  102. * @brief BSS segment initialization switch.
  103. */
  104. #if !defined(CRT0_INIT_BSS) || defined(__DOXYGEN__)
  105. #define CRT0_INIT_BSS TRUE
  106. #endif
  107. /**
  108. * @brief RAM areas initialization switch.
  109. */
  110. #if !defined(CRT0_INIT_RAM_AREAS) || defined(__DOXYGEN__)
  111. #define CRT0_INIT_RAM_AREAS TRUE
  112. #endif
  113. /**
  114. * @brief Constructors invocation switch.
  115. */
  116. #if !defined(CRT0_CALL_CONSTRUCTORS) || defined(__DOXYGEN__)
  117. #define CRT0_CALL_CONSTRUCTORS TRUE
  118. #endif
  119. /**
  120. * @brief Destructors invocation switch.
  121. */
  122. #if !defined(CRT0_CALL_DESTRUCTORS) || defined(__DOXYGEN__)
  123. #define CRT0_CALL_DESTRUCTORS TRUE
  124. #endif
  125. /**
  126. * @brief FPU FPCCR register initialization value.
  127. * @note Only used if @p CRT0_INIT_FPU is equal to @p TRUE.
  128. */
  129. #if !defined(CRT0_FPCCR_INIT) || defined(__DOXYGEN__)
  130. #define CRT0_FPCCR_INIT (FPCCR_ASPEN | FPCCR_LSPEN)
  131. #endif
  132. /**
  133. * @brief CPACR register initialization value.
  134. * @note Only used if @p CRT0_INIT_FPU is equal to @p TRUE.
  135. */
  136. #if !defined(CRT0_CPACR_INIT) || defined(__DOXYGEN__)
  137. #define CRT0_CPACR_INIT 0x00F00000
  138. #endif
  139. /*===========================================================================*/
  140. /* Code section. */
  141. /*===========================================================================*/
  142. #if !defined(__DOXYGEN__)
  143. .syntax unified
  144. .cpu cortex-m3
  145. #if CRT0_INIT_FPU == TRUE
  146. .fpu fpv4-sp-d16
  147. #else
  148. .fpu softvfp
  149. #endif
  150. .thumb
  151. .text
  152. /*
  153. * CRT0 entry point.
  154. */
  155. .align 2
  156. .thumb_func
  157. .global _crt0_entry
  158. _crt0_entry:
  159. /* Interrupts are globally masked initially.*/
  160. cpsid i
  161. #if CRT0_FORCE_MSP_INIT == TRUE
  162. /* MSP stack pointers initialization.*/
  163. ldr r0, =__main_stack_end__
  164. msr MSP, r0
  165. #endif
  166. /* PSP stack pointers initialization.*/
  167. ldr r0, =__process_stack_end__
  168. msr PSP, r0
  169. #if CRT0_VTOR_INIT == TRUE
  170. ldr r0, =_vectors
  171. movw r1, #SCB_VTOR & 0xFFFF
  172. movt r1, #SCB_VTOR >> 16
  173. str r0, [r1]
  174. #endif
  175. #if CRT0_INIT_FPU == TRUE
  176. /* FPU FPCCR initialization.*/
  177. movw r0, #CRT0_FPCCR_INIT & 0xFFFF
  178. movt r0, #CRT0_FPCCR_INIT >> 16
  179. movw r1, #SCB_FPCCR & 0xFFFF
  180. movt r1, #SCB_FPCCR >> 16
  181. str r0, [r1]
  182. dsb
  183. isb
  184. /* CPACR initialization.*/
  185. movw r0, #CRT0_CPACR_INIT & 0xFFFF
  186. movt r0, #CRT0_CPACR_INIT >> 16
  187. movw r1, #SCB_CPACR & 0xFFFF
  188. movt r1, #SCB_CPACR >> 16
  189. str r0, [r1]
  190. dsb
  191. isb
  192. /* FPU FPSCR initially cleared.*/
  193. mov r0, #0
  194. vmsr FPSCR, r0
  195. /* FPU FPDSCR initially cleared.*/
  196. movw r1, #SCB_FPDSCR & 0xFFFF
  197. movt r1, #SCB_FPDSCR >> 16
  198. str r0, [r1]
  199. /* Enforcing FPCA bit in the CONTROL register.*/
  200. movs r0, #CRT0_CONTROL_INIT | CONTROL_FPCA
  201. #else
  202. movs r0, #CRT0_CONTROL_INIT
  203. #endif
  204. /* CONTROL register initialization as configured.*/
  205. msr CONTROL, r0
  206. isb
  207. #if CRT0_INIT_CORE == TRUE
  208. /* Core initialization.*/
  209. bl __core_init
  210. #endif
  211. /* Early initialization.*/
  212. bl __early_init
  213. #if CRT0_INIT_STACKS == TRUE
  214. ldr r0, =CRT0_STACKS_FILL_PATTERN
  215. /* Main Stack initialization. Note, it assumes that the
  216. stack size is a multiple of 4 so the linker file must
  217. ensure this.*/
  218. ldr r1, =__main_stack_base__
  219. ldr r2, =__main_stack_end__
  220. msloop:
  221. cmp r1, r2
  222. itt lo
  223. strlo r0, [r1], #4
  224. blo msloop
  225. /* Process Stack initialization. Note, it assumes that the
  226. stack size is a multiple of 4 so the linker file must
  227. ensure this.*/
  228. ldr r1, =__process_stack_base__
  229. ldr r2, =__process_stack_end__
  230. psloop:
  231. cmp r1, r2
  232. itt lo
  233. strlo r0, [r1], #4
  234. blo psloop
  235. #endif
  236. #if CRT0_INIT_DATA == TRUE
  237. /* Data initialization. Note, it assumes that the DATA size
  238. is a multiple of 4 so the linker file must ensure this.*/
  239. ldr r1, =_textdata_start
  240. ldr r2, =_data_start
  241. ldr r3, =_data_end
  242. dloop:
  243. cmp r2, r3
  244. ittt lo
  245. ldrlo r0, [r1], #4
  246. strlo r0, [r2], #4
  247. blo dloop
  248. #endif
  249. #if CRT0_INIT_BSS == TRUE
  250. /* BSS initialization. Note, it assumes that the DATA size
  251. is a multiple of 4 so the linker file must ensure this.*/
  252. movs r0, #0
  253. ldr r1, =_bss_start
  254. ldr r2, =_bss_end
  255. bloop:
  256. cmp r1, r2
  257. itt lo
  258. strlo r0, [r1], #4
  259. blo bloop
  260. #endif
  261. #if CRT0_INIT_RAM_AREAS == TRUE
  262. /* RAM areas initialization.*/
  263. bl __init_ram_areas
  264. #endif
  265. /* Late initialization..*/
  266. bl __late_init
  267. #if CRT0_CALL_CONSTRUCTORS == TRUE
  268. /* Constructors invocation.*/
  269. ldr r4, =__init_array_start
  270. ldr r5, =__init_array_end
  271. initloop:
  272. cmp r4, r5
  273. bge endinitloop
  274. ldr r1, [r4], #4
  275. blx r1
  276. b initloop
  277. endinitloop:
  278. #endif
  279. /* Main program invocation, r0 contains the returned value.*/
  280. bl main
  281. #if CRT0_CALL_DESTRUCTORS == TRUE
  282. /* Destructors invocation.*/
  283. ldr r4, =__fini_array_start
  284. ldr r5, =__fini_array_end
  285. finiloop:
  286. cmp r4, r5
  287. bge endfiniloop
  288. ldr r1, [r4], #4
  289. blx r1
  290. b finiloop
  291. endfiniloop:
  292. #endif
  293. /* Branching to the defined exit handler.*/
  294. b __default_exit
  295. #endif /* !defined(__DOXYGEN__) */
  296. /** @} */