start_gcc.S 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306
  1. /*
  2. * Copyright (c) 2006-2022, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2011-01-13 weety first version
  9. * 2015-04-15 ArdaFu Split from AT91SAM9260 BSP
  10. * 2015-04-21 ArdaFu Remove remap code. Using mmu to map vector table
  11. * 2015-06-04 aozima Align stack address to 8 byte.
  12. */
  13. .equ MODE_USR, 0x10
  14. .equ MODE_FIQ, 0x11
  15. .equ MODE_IRQ, 0x12
  16. .equ MODE_SVC, 0x13
  17. .equ MODE_ABT, 0x17
  18. .equ MODE_UND, 0x1B
  19. .equ MODE_SYS, 0x1F
  20. .equ MODEMASK, 0x1F
  21. .equ NOINT, 0xC0
  22. .equ I_BIT, 0x80
  23. .equ F_BIT, 0x40
  24. .equ UND_STACK_SIZE, 0x00000100
  25. .equ SVC_STACK_SIZE, 0x00000100
  26. .equ ABT_STACK_SIZE, 0x00000100
  27. .equ FIQ_STACK_SIZE, 0x00000100
  28. .equ IRQ_STACK_SIZE, 0x00000100
  29. .equ SYS_STACK_SIZE, 0x00000100
  30. /*
  31. ***************************************
  32. * Interrupt vector table
  33. ***************************************
  34. */
  35. .section .vectors
  36. .code 32
  37. .global system_vectors
  38. system_vectors:
  39. ldr pc, _vector_reset
  40. ldr pc, _vector_undef
  41. ldr pc, _vector_swi
  42. ldr pc, _vector_pabt
  43. ldr pc, _vector_dabt
  44. ldr pc, _vector_resv
  45. ldr pc, _vector_irq
  46. ldr pc, _vector_fiq
  47. _vector_reset:
  48. .word reset
  49. _vector_undef:
  50. .word vector_undef
  51. _vector_swi:
  52. .word vector_swi
  53. _vector_pabt:
  54. .word vector_pabt
  55. _vector_dabt:
  56. .word vector_dabt
  57. _vector_resv:
  58. .word vector_resv
  59. _vector_irq:
  60. .word vector_irq
  61. _vector_fiq:
  62. .word vector_fiq
  63. .balignl 16,0xdeadbeef
  64. /*
  65. ***************************************
  66. * Stack and Heap Definitions
  67. ***************************************
  68. */
  69. .section .data
  70. .space UND_STACK_SIZE
  71. .align 3
  72. .global und_stack_start
  73. und_stack_start:
  74. .space ABT_STACK_SIZE
  75. .align 3
  76. .global abt_stack_start
  77. abt_stack_start:
  78. .space FIQ_STACK_SIZE
  79. .align 3
  80. .global fiq_stack_start
  81. fiq_stack_start:
  82. .space IRQ_STACK_SIZE
  83. .align 3
  84. .global irq_stack_start
  85. irq_stack_start:
  86. .skip SYS_STACK_SIZE
  87. .align 3
  88. .global sys_stack_start
  89. sys_stack_start:
  90. .space SVC_STACK_SIZE
  91. .align 3
  92. .global svc_stack_start
  93. svc_stack_start:
  94. /*
  95. ***************************************
  96. * Startup Code
  97. ***************************************
  98. */
  99. .section .text
  100. .global reset
  101. reset:
  102. /* Enter svc mode and mask interrupts */
  103. mrs r0, cpsr
  104. bic r0, r0, #MODEMASK
  105. orr r0, r0, #MODE_SVC|NOINT
  106. msr cpsr_cxsf, r0
  107. /* init cpu */
  108. bl cpu_init_crit
  109. /* Call low level init function */
  110. ldr sp, =svc_stack_start
  111. ldr r0, =rt_low_level_init
  112. blx r0
  113. /* init stack */
  114. bl stack_setup
  115. /* clear bss */
  116. mov r0, #0
  117. ldr r1, =__bss_start
  118. ldr r2, =__bss_end
  119. bss_clear_loop:
  120. cmp r1, r2
  121. strlo r0, [r1], #4
  122. blo bss_clear_loop
  123. /* call c++ constructors of global objects */
  124. /*
  125. ldr r0, =__ctors_start__
  126. ldr r1, =__ctors_end__
  127. ctor_loop:
  128. cmp r0, r1
  129. beq ctor_end
  130. ldr r2, [r0], #4
  131. stmfd sp!, {r0-r1}
  132. mov lr, pc
  133. bx r2
  134. ldmfd sp!, {r0-r1}
  135. b ctor_loop
  136. ctor_end:
  137. */
  138. /* start RT-Thread Kernel */
  139. ldr pc, _rtthread_startup
  140. _rtthread_startup:
  141. .word rtthread_startup
  142. cpu_init_crit:
  143. /* invalidate I/D caches */
  144. mov r0, #0
  145. mcr p15, 0, r0, c7, c7, 0
  146. mcr p15, 0, r0, c8, c7, 0
  147. /* disable MMU stuff and caches */
  148. mrc p15, 0, r0, c1, c0, 0
  149. bic r0, r0, #0x00002300
  150. bic r0, r0, #0x00000087
  151. orr r0, r0, #0x00000002
  152. orr r0, r0, #0x00001000
  153. mcr p15, 0, r0, c1, c0, 0
  154. bx lr
  155. stack_setup:
  156. /* Setup Stack for each mode */
  157. mrs r0, cpsr
  158. bic r0, r0, #MODEMASK
  159. orr r1, r0, #MODE_UND|NOINT
  160. msr cpsr_cxsf, r1
  161. ldr sp, =und_stack_start
  162. orr r1, r0, #MODE_ABT|NOINT
  163. msr cpsr_cxsf, r1
  164. ldr sp, =abt_stack_start
  165. orr r1, r0, #MODE_IRQ|NOINT
  166. msr cpsr_cxsf, r1
  167. ldr sp, =irq_stack_start
  168. orr r1, r0, #MODE_FIQ|NOINT
  169. msr cpsr_cxsf, r1
  170. ldr sp, =fiq_stack_start
  171. orr r1, r0, #MODE_SYS|NOINT
  172. msr cpsr_cxsf,r1
  173. ldr sp, =sys_stack_start
  174. orr r1, r0, #MODE_SVC|NOINT
  175. msr cpsr_cxsf, r1
  176. ldr sp, =svc_stack_start
  177. bx lr
  178. /*
  179. ***************************************
  180. * exception handlers
  181. ***************************************
  182. */
  183. /* Interrupt */
  184. vector_fiq:
  185. stmfd sp!,{r0-r7,lr}
  186. bl rt_hw_trap_fiq
  187. ldmfd sp!,{r0-r7,lr}
  188. subs pc, lr, #4
  189. vector_irq:
  190. stmfd sp!, {r0-r12,lr}
  191. bl rt_interrupt_enter
  192. bl rt_hw_trap_irq
  193. bl rt_interrupt_leave
  194. ldr r0, =rt_thread_switch_interrupt_flag
  195. ldr r1, [r0]
  196. cmp r1, #1
  197. beq rt_hw_context_switch_interrupt_do
  198. ldmfd sp!, {r0-r12,lr}
  199. subs pc, lr, #4
  200. rt_hw_context_switch_interrupt_do:
  201. mov r1, #0
  202. str r1, [r0]
  203. mov r1, sp
  204. add sp, sp, #4*4
  205. ldmfd sp!, {r4-r12,lr}
  206. mrs r0, spsr
  207. sub r2, lr, #4
  208. msr cpsr_c, #I_BIT|F_BIT|MODE_SVC
  209. stmfd sp!, {r2}
  210. stmfd sp!, {r4-r12,lr}
  211. ldmfd r1, {r1-r4}
  212. stmfd sp!, {r1-r4}
  213. stmfd sp!, {r0}
  214. ldr r4, =rt_interrupt_from_thread
  215. ldr r5, [r4]
  216. str sp, [r5]
  217. ldr r6, =rt_interrupt_to_thread
  218. ldr r6, [r6]
  219. ldr sp, [r6]
  220. ldmfd sp!, {r4}
  221. msr spsr_cxsf, r4
  222. ldmfd sp!, {r0-r12,lr,pc}^
  223. /* Exception */
  224. .macro push_svc_reg
  225. sub sp, sp, #17 * 4
  226. stmia sp, {r0 - r12}
  227. mov r0, sp
  228. mrs r6, spsr
  229. str lr, [r0, #15*4]
  230. str r6, [r0, #16*4]
  231. str sp, [r0, #13*4]
  232. str lr, [r0, #14*4]
  233. .endm
  234. vector_swi:
  235. push_svc_reg
  236. bl rt_hw_trap_swi
  237. b .
  238. vector_undef:
  239. push_svc_reg
  240. bl rt_hw_trap_udef
  241. b .
  242. vector_pabt:
  243. push_svc_reg
  244. bl rt_hw_trap_pabt
  245. b .
  246. vector_dabt:
  247. push_svc_reg
  248. bl rt_hw_trap_dabt
  249. b .
  250. vector_resv:
  251. push_svc_reg
  252. bl rt_hw_trap_resv
  253. b .