crt0.s 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258
  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 CW/crt0.s
  15. * @brief Generic PowerPC startup file for CodeWarrior.
  16. *
  17. * @addtogroup PPC_CW_CORE
  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. /*===========================================================================*/
  30. /* Module pre-compile time settings. */
  31. /*===========================================================================*/
  32. /**
  33. * @brief Stack segments initialization switch.
  34. */
  35. #if !defined(CRT0_STACKS_FILL_PATTERN) || defined(__DOXYGEN__)
  36. #define CRT0_STACKS_FILL_PATTERN 0x55555555
  37. #endif
  38. /**
  39. * @brief Stack segments initialization switch.
  40. */
  41. #if !defined(CRT0_INIT_STACKS) || defined(__DOXYGEN__)
  42. #define CRT0_INIT_STACKS TRUE
  43. #endif
  44. /**
  45. * @brief DATA segment initialization switch.
  46. */
  47. #if !defined(CRT0_INIT_DATA) || defined(__DOXYGEN__)
  48. #define CRT0_INIT_DATA TRUE
  49. #endif
  50. /**
  51. * @brief BSS segment initialization switch.
  52. */
  53. #if !defined(CRT0_INIT_BSS) || defined(__DOXYGEN__)
  54. #define CRT0_INIT_BSS TRUE
  55. #endif
  56. /**
  57. * @brief Constructors invocation switch.
  58. */
  59. #if !defined(CRT0_CALL_CONSTRUCTORS) || defined(__DOXYGEN__)
  60. #define CRT0_CALL_CONSTRUCTORS FALSE
  61. #endif
  62. /**
  63. * @brief Destructors invocation switch.
  64. */
  65. #if !defined(CRT0_CALL_DESTRUCTORS) || defined(__DOXYGEN__)
  66. #define CRT0_CALL_DESTRUCTORS FALSE
  67. #endif
  68. /*===========================================================================*/
  69. /* Code section. */
  70. /*===========================================================================*/
  71. #if !defined(__DOXYGEN__)
  72. .extern __sdata2_start__
  73. .extern __sdata_start__
  74. .extern __bss_start__
  75. .extern __bss_end__
  76. .extern __irq_stack_base__
  77. .extern __irq_stack_end__
  78. .extern __process_stack_end__
  79. .extern __process_stack_base__
  80. .extern __romdata_start__
  81. .extern __data_start__
  82. .extern __data_end__
  83. .extern __init_array_start
  84. .extern __init_array_end
  85. .extern __fini_array_start
  86. .extern __fini_array_end
  87. .extern main
  88. .section .crt0, text_vle
  89. .align 16
  90. .globl _boot_address
  91. .type _boot_address, @function
  92. _boot_address:
  93. /* Stack setup.*/
  94. e_lis r1, __process_stack_end__@h
  95. e_or2i r1, __process_stack_end__@l
  96. se_li r0, 0
  97. e_stwu r0, -8(r1)
  98. /* Small sections registers initialization.*/
  99. e_lis r2, __sdata2_start__@h
  100. e_or2i r2, __sdata2_start__@l
  101. e_lis r13, __sdata_start__@h
  102. e_or2i r13, __sdata_start__@l
  103. /* Early initialization.*/
  104. e_bl __early_init
  105. #if CRT0_INIT_STACKS == TRUE
  106. /* Stacks fill pattern.*/
  107. e_lis r7, CRT0_STACKS_FILL_PATTERN@h
  108. e_or2i r7, CRT0_STACKS_FILL_PATTERN@l
  109. /* IRQ Stack initialization. Note, the architecture does not use this
  110. stack, the size is usually zero. An OS can have special SW handling
  111. and require this. A 4 bytes alignment is assumed and required.*/
  112. e_lis r4, __irq_stack_base__@h
  113. e_or2i r4, __irq_stack_base__@l
  114. e_lis r5, __irq_stack_end__@h
  115. e_or2i r5, __irq_stack_end__@l
  116. .irqsloop:
  117. se_cmpl r4, r5
  118. se_bge .irqsend
  119. se_stw r7, 0(r4)
  120. se_addi r4, 4
  121. se_b .irqsloop
  122. .irqsend:
  123. /* Process Stack initialization. Note, does not overwrite the already
  124. written EABI frame. A 4 bytes alignment is assumed and required.*/
  125. e_lis r4, __process_stack_base__@h
  126. e_or2i r4, __process_stack_base__@l
  127. e_lis r5, (__process_stack_end__ - 8)@h
  128. e_or2i r5, (__process_stack_end__ - 8)@l
  129. .prcsloop:
  130. se_cmpl r4, r5
  131. se_bge .prcsend
  132. se_stw r7, 0(r4)
  133. se_addi r4, 4
  134. se_b .prcsloop
  135. .prcsend:
  136. #endif
  137. #if CRT0_INIT_BSS == TRUE
  138. /* BSS clearing.*/
  139. e_lis r4, __bss_start__@h
  140. e_or2i r4, __bss_start__@l
  141. e_lis r5, __bss_end__@h
  142. e_or2i r5, __bss_end__@l
  143. se_li r7, 0
  144. .bssloop:
  145. se_cmpl r4, r5
  146. se_bge .bssend
  147. se_stw r7, 0(r4)
  148. se_addi r4, 4
  149. se_b .bssloop
  150. .bssend:
  151. #endif
  152. #if CRT0_INIT_DATA == TRUE
  153. /* DATA initialization.*/
  154. e_lis r4, __romdata_start__@h
  155. e_or2i r4, __romdata_start__@l
  156. e_lis r5, __data_start__@h
  157. e_or2i r5, __data_start__@l
  158. e_lis r6, __data_end__@h
  159. e_or2i r6, __data_end__@l
  160. .dataloop:
  161. se_cmpl r5, r6
  162. se_bge .dataend
  163. se_lwz r7, 0(r4)
  164. se_addi r4, 4
  165. se_stw r7, 0(r5)
  166. se_addi r5, 4
  167. se_b .dataloop
  168. .dataend:
  169. #endif
  170. /* Late initialization.*/
  171. e_bl __late_init
  172. #if CRT0_CALL_CONSTRUCTORS == TRUE
  173. /* Constructors invocation.*/
  174. e_lis r4, __init_array_start@h
  175. e_or2i r4, __init_array_start@l
  176. e_lis r5, __init_array_end@h
  177. e_or2i r5, __init_array_end@l
  178. .iniloop:
  179. se_cmpl r4, r5
  180. se_bge .iniend
  181. se_lwz r6, 0(r4)
  182. se_mtctr r6
  183. se_addi r4, 4
  184. se_bctrl
  185. se_b .iniloop
  186. .iniend:
  187. #endif
  188. /* Main program invocation.*/
  189. e_bl main
  190. #if CRT0_CALL_DESTRUCTORS == TRUE
  191. /* Destructors invocation.*/
  192. e_lis r4, __fini_array_start@h
  193. e_or2i r4, __fini_array_start@l
  194. e_lis r5, __fini_array_end@h
  195. e_or2i r5, __fini_array_end@l
  196. .finiloop:
  197. se_cmpl r4, r5
  198. se_bge .finiend
  199. se_lwz r6, 0(r4)
  200. se_mtctr r6
  201. se_addi r4, 4
  202. se_bctrl
  203. se_b .finiloop
  204. .finiend:
  205. #endif
  206. /* Branching to the defined exit handler.*/
  207. e_b __default_exit
  208. #endif /* !defined(__DOXYGEN__) */
  209. .section .text_vle
  210. .align 4
  211. /* Default main exit code, infinite loop.*/
  212. .weak __default_exit
  213. __default_exit:
  214. e_b __default_exit
  215. /* Default early initialization code, none.*/
  216. .weak __early_init
  217. se_blr
  218. /* Default late initialization code, none.*/
  219. .weak __late_init
  220. __late_init:
  221. se_blr
  222. /** @} */