thumb_crt0.s 8.2 KB

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