crt0_v6m.S 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288
  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_v6m.S
  15. * @brief Generic ARMv6-M (Cortex-M0/M1) startup file for ChibiOS.
  16. *
  17. * @addtogroup ARMCMx_GCC_STARTUP_V6M
  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 SCB_VTOR 0xE000ED08
  34. /*===========================================================================*/
  35. /* Module pre-compile time settings. */
  36. /*===========================================================================*/
  37. /**
  38. * @brief Enforces initialization of MSP.
  39. * @note This is required if the boot process is not reliable for whatever
  40. * reason (bad ROMs, bad bootloaders, bad debuggers=.
  41. */
  42. #if !defined(CRT0_FORCE_MSP_INIT) || defined(__DOXYGEN__)
  43. #define CRT0_FORCE_MSP_INIT TRUE
  44. #endif
  45. /**
  46. * @brief VTOR special register initialization.
  47. * @details VTOR is initialized to point to the vectors table.
  48. * @note This option can only be enabled on Cortex-M0+ cores.
  49. */
  50. #if !defined(CRT0_VTOR_INIT) || defined(__DOXYGEN__)
  51. #define CRT0_VTOR_INIT FALSE
  52. #endif
  53. /**
  54. * @brief Control special register initialization value.
  55. * @details The system is setup to run in privileged mode using the PSP
  56. * stack (dual stack mode).
  57. */
  58. #if !defined(CRT0_CONTROL_INIT) || defined(__DOXYGEN__)
  59. #define CRT0_CONTROL_INIT (CONTROL_USE_PSP | \
  60. CONTROL_MODE_PRIVILEGED)
  61. #endif
  62. /**
  63. * @brief Core initialization switch.
  64. */
  65. #if !defined(CRT0_INIT_CORE) || defined(__DOXYGEN__)
  66. #define CRT0_INIT_CORE TRUE
  67. #endif
  68. /**
  69. * @brief Stack segments initialization switch.
  70. */
  71. #if !defined(CRT0_STACKS_FILL_PATTERN) || defined(__DOXYGEN__)
  72. #define CRT0_STACKS_FILL_PATTERN 0x55555555
  73. #endif
  74. /**
  75. * @brief Stack segments initialization switch.
  76. */
  77. #if !defined(CRT0_INIT_STACKS) || defined(__DOXYGEN__)
  78. #define CRT0_INIT_STACKS TRUE
  79. #endif
  80. /**
  81. * @brief DATA segment initialization switch.
  82. */
  83. #if !defined(CRT0_INIT_DATA) || defined(__DOXYGEN__)
  84. #define CRT0_INIT_DATA TRUE
  85. #endif
  86. /**
  87. * @brief BSS segment initialization switch.
  88. */
  89. #if !defined(CRT0_INIT_BSS) || defined(__DOXYGEN__)
  90. #define CRT0_INIT_BSS TRUE
  91. #endif
  92. /**
  93. * @brief RAM areas initialization switch.
  94. */
  95. #if !defined(CRT0_INIT_RAM_AREAS) || defined(__DOXYGEN__)
  96. #define CRT0_INIT_RAM_AREAS TRUE
  97. #endif
  98. /**
  99. * @brief Constructors invocation switch.
  100. */
  101. #if !defined(CRT0_CALL_CONSTRUCTORS) || defined(__DOXYGEN__)
  102. #define CRT0_CALL_CONSTRUCTORS TRUE
  103. #endif
  104. /**
  105. * @brief Destructors invocation switch.
  106. */
  107. #if !defined(CRT0_CALL_DESTRUCTORS) || defined(__DOXYGEN__)
  108. #define CRT0_CALL_DESTRUCTORS TRUE
  109. #endif
  110. /*===========================================================================*/
  111. /* Code section. */
  112. /*===========================================================================*/
  113. #if !defined(__DOXYGEN__)
  114. .cpu cortex-m0
  115. .fpu softvfp
  116. .syntax unified
  117. .thumb
  118. .text
  119. /*
  120. * CRT0 entry point.
  121. */
  122. .align 2
  123. .thumb_func
  124. .global _crt0_entry
  125. _crt0_entry:
  126. /* Interrupts are globally masked initially.*/
  127. cpsid i
  128. #if CRT0_FORCE_MSP_INIT == TRUE
  129. /* MSP stack pointers initialization.*/
  130. ldr r0, =__main_stack_end__
  131. msr MSP, r0
  132. #endif
  133. /* PSP stack pointers initialization.*/
  134. ldr r0, =__process_stack_end__
  135. msr PSP, r0
  136. /* CPU mode initialization as configured.*/
  137. movs r0, #CRT0_CONTROL_INIT
  138. msr CONTROL, r0
  139. isb
  140. #if CRT0_VTOR_INIT == TRUE
  141. ldr r0, =_vectors
  142. ldr r1, =SCB_VTOR
  143. str r0, [r1]
  144. #endif
  145. #if CRT0_INIT_CORE == TRUE
  146. /* Core initialization.*/
  147. bl __core_init
  148. #endif
  149. /* Early initialization..*/
  150. bl __early_init
  151. #if CRT0_INIT_STACKS == TRUE
  152. ldr r0, =CRT0_STACKS_FILL_PATTERN
  153. /* Main Stack initialization. Note, it assumes that the
  154. stack size is a multiple of 4 so the linker file must
  155. ensure this.*/
  156. ldr r1, =__main_stack_base__
  157. ldr r2, =__main_stack_end__
  158. msloop:
  159. cmp r1, r2
  160. bge endmsloop
  161. str r0, [r1]
  162. adds r1, #4
  163. b msloop
  164. endmsloop:
  165. /* Process Stack initialization. Note, it assumes that the
  166. stack size is a multiple of 4 so the linker file must
  167. ensure this.*/
  168. ldr r1, =__process_stack_base__
  169. ldr r2, =__process_stack_end__
  170. psloop:
  171. cmp r1, r2
  172. bge endpsloop
  173. str r0, [r1]
  174. adds r1, #4
  175. b psloop
  176. endpsloop:
  177. #endif
  178. #if CRT0_INIT_DATA == TRUE
  179. /* Data initialization. Note, it assumes that the DATA size
  180. is a multiple of 4 so the linker file must ensure this.*/
  181. ldr r1, =_textdata
  182. ldr r2, =_data
  183. ldr r3, =_edata
  184. dloop:
  185. cmp r2, r3
  186. bge enddloop
  187. ldr r0, [r1]
  188. str r0, [r2]
  189. adds r1, #4
  190. adds r2, #4
  191. b dloop
  192. enddloop:
  193. #endif
  194. #if CRT0_INIT_BSS == TRUE
  195. /* BSS initialization. Note, it assumes that the DATA size
  196. is a multiple of 4 so the linker file must ensure this.*/
  197. movs r0, #0
  198. ldr r1, =_bss_start
  199. ldr r2, =_bss_end
  200. bloop:
  201. cmp r1, r2
  202. bge endbloop
  203. str r0, [r1]
  204. adds r1, #4
  205. b bloop
  206. endbloop:
  207. #endif
  208. #if CRT0_INIT_RAM_AREAS == TRUE
  209. /* RAM areas initialization.*/
  210. bl __init_ram_areas
  211. #endif
  212. /* Late initialization..*/
  213. bl __late_init
  214. #if CRT0_CALL_CONSTRUCTORS == TRUE
  215. /* Constructors invocation.*/
  216. ldr r4, =__init_array_start
  217. ldr r5, =__init_array_end
  218. initloop:
  219. cmp r4, r5
  220. bge endinitloop
  221. ldr r1, [r4]
  222. blx r1
  223. adds r4, #4
  224. b initloop
  225. endinitloop:
  226. #endif
  227. /* Main program invocation, r0 contains the returned value.*/
  228. bl main
  229. #if CRT0_CALL_DESTRUCTORS == TRUE
  230. /* Destructors invocation.*/
  231. ldr r4, =__fini_array_start
  232. ldr r5, =__fini_array_end
  233. finiloop:
  234. cmp r4, r5
  235. bge endfiniloop
  236. ldr r1, [r4]
  237. blx r1
  238. adds r4, #4
  239. b finiloop
  240. endfiniloop:
  241. #endif
  242. /* Branching to the defined exit handler.*/
  243. ldr r1, =__default_exit
  244. bx r1
  245. #endif
  246. /** @} */