thumb_crt0.s 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405
  1. // SEGGER Embedded Studio, runtime support.
  2. //
  3. // Copyright (c) 2014-2017 SEGGER Microcontroller GmbH & Co KG
  4. // Copyright (c) 2001-2017 Rowley Associates Limited.
  5. //
  6. // This file may be distributed under the terms of the License Agreement
  7. // provided with this software.
  8. //
  9. // THIS FILE IS PROVIDED AS IS WITH NO WARRANTY OF ANY KIND, INCLUDING THE
  10. // WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  11. //
  12. //
  13. // Preprocessor Definitions
  14. // ------------------------
  15. // APP_ENTRY_POINT
  16. //
  17. // Defines the application entry point function, if undefined this setting
  18. // defaults to "main".
  19. //
  20. // INITIALIZE_STACK
  21. //
  22. // If defined, the contents of the stack will be initialized to a the
  23. // value 0xCC.
  24. //
  25. // INITIALIZE_SECONDARY_SECTIONS
  26. //
  27. // If defined, the .data2, .text2, .rodata2 and .bss2 sections will be initialized.
  28. //
  29. // INITIALIZE_TCM_SECTIONS
  30. //
  31. // If defined, the .data_tcm, .text_tcm, .rodata_tcm and .bss_tcm sections
  32. // will be initialized.
  33. //
  34. // FULL_LIBRARY
  35. //
  36. // If defined then
  37. // - argc, argv are setup by the debug_getargs.
  38. // - the exit symbol is defined and executes on return from main.
  39. // - the exit symbol calls destructors, atexit functions and then debug_exit.
  40. //
  41. // If not defined then
  42. // - argc and argv are zero.
  43. // - the exit symbol is defined, executes on return from main and loops
  44. //
  45. #ifndef APP_ENTRY_POINT
  46. #define APP_ENTRY_POINT main
  47. #endif
  48. #ifndef ARGSSPACE
  49. #define ARGSSPACE 128
  50. #endif
  51. .syntax unified
  52. .global _start
  53. .extern APP_ENTRY_POINT
  54. .global exit
  55. .weak exit
  56. .section .init, "ax"
  57. .code 16
  58. .align 2
  59. .thumb_func
  60. _start:
  61. /* Set up main stack if size > 0 */
  62. ldr r1, =__stack_end__
  63. ldr r0, =__stack_start__
  64. subs r2, r1, r0
  65. beq 1f
  66. #ifdef __ARM_EABI__
  67. movs r2, #0x7
  68. bics r1, r2
  69. #endif
  70. mov sp, r1
  71. #ifdef INITIALIZE_STACK
  72. movs r2, #0xCC
  73. ldr r0, =__stack_start__
  74. bl memory_set
  75. #endif
  76. 1:
  77. /* Set up process stack if size > 0 */
  78. ldr r1, =__stack_process_end__
  79. ldr r0, =__stack_process_start__
  80. subs r2, r1, r0
  81. beq 1f
  82. #ifdef __ARM_EABI__
  83. movs r2, #0x7
  84. bics r1, r2
  85. #endif
  86. msr psp, r1
  87. movs r2, #2
  88. msr control, r2
  89. #ifdef INITIALIZE_STACK
  90. movs r2, #0xCC
  91. bl memory_set
  92. #endif
  93. 1:
  94. /* Copy initialised memory sections into RAM (if necessary). */
  95. ldr r0, =__data_load_start__
  96. ldr r1, =__data_start__
  97. ldr r2, =__data_end__
  98. bl memory_copy
  99. ldr r0, =__start_nrf_sections
  100. ldr r1, =__start_nrf_sections_run
  101. ldr r2, =__end_nrf_sections_run
  102. bl memory_copy
  103. ldr r0, =__text_load_start__
  104. ldr r1, =__text_start__
  105. ldr r2, =__text_end__
  106. bl memory_copy
  107. ldr r0, =__fast_load_start__
  108. ldr r1, =__fast_start__
  109. ldr r2, =__fast_end__
  110. bl memory_copy
  111. ldr r0, =__ctors_load_start__
  112. ldr r1, =__ctors_start__
  113. ldr r2, =__ctors_end__
  114. bl memory_copy
  115. ldr r0, =__dtors_load_start__
  116. ldr r1, =__dtors_start__
  117. ldr r2, =__dtors_end__
  118. bl memory_copy
  119. ldr r0, =__rodata_load_start__
  120. ldr r1, =__rodata_start__
  121. ldr r2, =__rodata_end__
  122. bl memory_copy
  123. ldr r0, =__tdata_load_start__
  124. ldr r1, =__tdata_start__
  125. ldr r2, =__tdata_end__
  126. bl memory_copy
  127. #ifdef INITIALIZE_SECONDARY_SECTIONS
  128. ldr r0, =__data2_load_start__
  129. ldr r1, =__data2_start__
  130. ldr r2, =__data2_end__
  131. bl memory_copy
  132. ldr r0, =__text2_load_start__
  133. ldr r1, =__text2_start__
  134. ldr r2, =__text2_end__
  135. bl memory_copy
  136. ldr r0, =__rodata2_load_start__
  137. ldr r1, =__rodata2_start__
  138. ldr r2, =__rodata2_end__
  139. bl memory_copy
  140. #endif /* #ifdef INITIALIZE_SECONDARY_SECTIONS */
  141. #ifdef INITIALIZE_TCM_SECTIONS
  142. ldr r0, =__data_tcm_load_start__
  143. ldr r1, =__data_tcm_start__
  144. ldr r2, =__data_tcm_end__
  145. bl memory_copy
  146. ldr r0, =__text_tcm_load_start__
  147. ldr r1, =__text_tcm_start__
  148. ldr r2, =__text_tcm_end__
  149. bl memory_copy
  150. ldr r0, =__rodata_tcm_load_start__
  151. ldr r1, =__rodata_tcm_start__
  152. ldr r2, =__rodata_tcm_end__
  153. bl memory_copy
  154. #endif /* #ifdef INITIALIZE_TCM_SECTIONS */
  155. /* Zero the bss. */
  156. ldr r0, =__bss_start__
  157. ldr r1, =__bss_end__
  158. movs r2, #0
  159. bl memory_set
  160. ldr r0, =__tbss_start__
  161. ldr r1, =__tbss_end__
  162. movs r2, #0
  163. bl memory_set
  164. #ifdef INITIALIZE_SECONDARY_SECTIONS
  165. ldr r0, =__bss2_start__
  166. ldr r1, =__bss2_end__
  167. mov r2, #0
  168. bl memory_set
  169. #endif /* #ifdef INITIALIZE_SECONDARY_SECTIONS */
  170. #ifdef INITIALIZE_TCM_SECTIONS
  171. ldr r0, =__bss_tcm_start__
  172. ldr r1, =__bss_tcm_end__
  173. mov r2, #0
  174. bl memory_set
  175. #endif /* #ifdef INITIALIZE_TCM_SECTIONS */
  176. /* Initialise the heap */
  177. ldr r0, = __heap_start__
  178. ldr r1, = __heap_end__
  179. subs r1, r1, r0
  180. cmp r1, #8
  181. blt 1f
  182. movs r2, #0
  183. str r2, [r0]
  184. adds r0, r0, #4
  185. str r1, [r0]
  186. 1:
  187. /* Call constructors */
  188. ldr r0, =__ctors_start__
  189. ldr r1, =__ctors_end__
  190. ctor_loop:
  191. cmp r0, r1
  192. beq ctor_end
  193. ldr r2, [r0]
  194. adds r0, #4
  195. push {r0-r1}
  196. blx r2
  197. pop {r0-r1}
  198. b ctor_loop
  199. ctor_end:
  200. /* Setup initial call frame */
  201. movs r0, #0
  202. mov lr, r0
  203. mov r12, sp
  204. .type start, function
  205. start:
  206. /* Jump to application entry point */
  207. #ifdef FULL_LIBRARY
  208. movs r0, #ARGSSPACE
  209. ldr r1, =args
  210. ldr r2, =debug_getargs
  211. blx r2
  212. ldr r1, =args
  213. #else
  214. movs r0, #0
  215. movs r1, #0
  216. #endif
  217. ldr r2, =APP_ENTRY_POINT
  218. blx r2
  219. .thumb_func
  220. exit:
  221. #ifdef FULL_LIBRARY
  222. mov r5, r0 // save the exit parameter/return result
  223. /* Call destructors */
  224. ldr r0, =__dtors_start__
  225. ldr r1, =__dtors_end__
  226. dtor_loop:
  227. cmp r0, r1
  228. beq dtor_end
  229. ldr r2, [r0]
  230. add r0, #4
  231. push {r0-r1}
  232. blx r2
  233. pop {r0-r1}
  234. b dtor_loop
  235. dtor_end:
  236. /* Call atexit functions */
  237. ldr r2, =_execute_at_exit_fns
  238. blx r2
  239. /* Call debug_exit with return result/exit parameter */
  240. mov r0, r5
  241. ldr r2, =debug_exit
  242. blx r2
  243. #endif
  244. /* Returned from application entry point, loop forever. */
  245. exit_loop:
  246. b exit_loop
  247. .thumb_func
  248. memory_copy:
  249. cmp r0, r1
  250. beq 2f
  251. subs r2, r2, r1
  252. beq 2f
  253. 1:
  254. ldrb r3, [r0]
  255. adds r0, r0, #1
  256. strb r3, [r1]
  257. adds r1, r1, #1
  258. subs r2, r2, #1
  259. bne 1b
  260. 2:
  261. bx lr
  262. .thumb_func
  263. memory_set:
  264. cmp r0, r1
  265. beq 1f
  266. strb r2, [r0]
  267. adds r0, r0, #1
  268. b memory_set
  269. 1:
  270. bx lr
  271. // default C/C++ library helpers
  272. .macro HELPER helper_name
  273. .section .text.\helper_name, "ax", %progbits
  274. .global \helper_name
  275. .weak \helper_name
  276. \helper_name:
  277. .thumb_func
  278. .endm
  279. .macro JUMPTO name
  280. #if defined(__thumb__) && !defined(__thumb2__)
  281. mov r12, r0
  282. ldr r0, =\name
  283. push {r0}
  284. mov r0, r12
  285. pop {pc}
  286. #else
  287. b \name
  288. #endif
  289. .endm
  290. HELPER __aeabi_read_tp
  291. ldr r0, =__tbss_start__-8
  292. bx lr
  293. HELPER __heap_lock
  294. bx lr
  295. HELPER __heap_unlock
  296. bx lr
  297. HELPER __printf_lock
  298. bx lr
  299. HELPER __printf_unlock
  300. bx lr
  301. HELPER __scanf_lock
  302. bx lr
  303. HELPER __scanf_unlock
  304. bx lr
  305. HELPER __debug_io_lock
  306. bx lr
  307. HELPER __debug_io_unlock
  308. bx lr
  309. HELPER abort
  310. b .
  311. HELPER __assert
  312. b .
  313. HELPER __aeabi_assert
  314. b .
  315. HELPER __cxa_pure_virtual
  316. b .
  317. HELPER __cxa_guard_acquire
  318. ldr r3, [r0]
  319. #if defined(__thumb__) && !defined(__thumb2__)
  320. movs r0, #1
  321. tst r3, r0
  322. #else
  323. tst r3, #1
  324. #endif
  325. beq 1f
  326. movs r0, #0
  327. bx lr
  328. 1:
  329. movs r0, #1
  330. bx lr
  331. HELPER __cxa_guard_release
  332. movs r3, #1
  333. str r3, [r0]
  334. bx lr
  335. HELPER __cxa_guard_abort
  336. bx lr
  337. HELPER __sync_synchronize
  338. bx lr
  339. HELPER __open
  340. JUMPTO debug_fopen
  341. HELPER __close
  342. JUMPTO debug_fclose
  343. HELPER __write
  344. mov r3, r0
  345. mov r0, r1
  346. movs r1, #1
  347. JUMPTO debug_fwrite
  348. HELPER __read
  349. mov r3, r0
  350. mov r0, r1
  351. movs r1, #1
  352. JUMPTO debug_fread
  353. HELPER __seek
  354. push {r4, lr}
  355. mov r4, r0
  356. bl debug_fseek
  357. cmp r0, #0
  358. bne 1f
  359. mov r0, r4
  360. bl debug_ftell
  361. pop {r4, pc}
  362. 1:
  363. ldr r0, =-1
  364. pop {r4, pc}
  365. // char __user_locale_name_buffer[];
  366. .section .bss.__user_locale_name_buffer, "aw", %nobits
  367. .global __user_locale_name_buffer
  368. .weak __user_locale_name_buffer
  369. __user_locale_name_buffer:
  370. .word 0x0
  371. #ifdef FULL_LIBRARY
  372. .bss
  373. args:
  374. .space ARGSSPACE
  375. #endif
  376. /* Setup attibutes of stack and heap sections so they don't take up room in the elf file */
  377. .section .stack, "wa", %nobits
  378. .section .stack_process, "wa", %nobits
  379. .section .heap, "wa", %nobits