start_gcc.S 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330
  1. /*
  2. * Copyright (c) 2006-2018, 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. /* todo:copyself to link address */
  110. /* Copy vector to the correct address */
  111. ldr r0, =system_vectors
  112. mrc p15, 0, r2, c1, c0, 0
  113. ands r2, r2, #(1 << 13)
  114. ldreq r1, =0x00000000
  115. ldrne r1, =0xffff0000
  116. ldmia r0!, {r2-r8, r10}
  117. stmia r1!, {r2-r8, r10}
  118. ldmia r0!, {r2-r8, r10}
  119. stmia r1!, {r2-r8, r10}
  120. /* turn off the watchdog */
  121. ldr r0, =0x01C20CB8
  122. mov r1, #0x0
  123. str r1, [r0]
  124. /* mask all IRQs source */
  125. ldr r1, =0xffffffff
  126. ldr r0, =0x01C20430
  127. str r1, [r0], #0x04
  128. str r1, [r0]
  129. /* Call low level init function */
  130. ldr sp, =svc_stack_start
  131. ldr r0, =rt_low_level_init
  132. blx r0
  133. /* init stack */
  134. bl stack_setup
  135. /* clear bss */
  136. mov r0, #0
  137. ldr r1, =__bss_start
  138. ldr r2, =__bss_end
  139. bss_clear_loop:
  140. cmp r1, r2
  141. strlo r0, [r1], #4
  142. blo bss_clear_loop
  143. /* call c++ constructors of global objects */
  144. /*
  145. ldr r0, =__ctors_start__
  146. ldr r1, =__ctors_end__
  147. ctor_loop:
  148. cmp r0, r1
  149. beq ctor_end
  150. ldr r2, [r0], #4
  151. stmfd sp!, {r0-r1}
  152. mov lr, pc
  153. bx r2
  154. ldmfd sp!, {r0-r1}
  155. b ctor_loop
  156. ctor_end:
  157. */
  158. /* start RT-Thread Kernel */
  159. ldr pc, _rtthread_startup
  160. _rtthread_startup:
  161. .word rtthread_startup
  162. cpu_init_crit:
  163. /* invalidate I/D caches */
  164. mov r0, #0
  165. mcr p15, 0, r0, c7, c7, 0
  166. mcr p15, 0, r0, c8, c7, 0
  167. /* disable MMU stuff and caches */
  168. mrc p15, 0, r0, c1, c0, 0
  169. bic r0, r0, #0x00002300
  170. bic r0, r0, #0x00000087
  171. orr r0, r0, #0x00000002
  172. orr r0, r0, #0x00001000
  173. mcr p15, 0, r0, c1, c0, 0
  174. bx lr
  175. stack_setup:
  176. /* Setup Stack for each mode */
  177. mrs r0, cpsr
  178. bic r0, r0, #MODEMASK
  179. orr r1, r0, #MODE_UND|NOINT
  180. msr cpsr_cxsf, r1
  181. ldr sp, =und_stack_start
  182. orr r1, r0, #MODE_ABT|NOINT
  183. msr cpsr_cxsf, r1
  184. ldr sp, =abt_stack_start
  185. orr r1, r0, #MODE_IRQ|NOINT
  186. msr cpsr_cxsf, r1
  187. ldr sp, =irq_stack_start
  188. orr r1, r0, #MODE_FIQ|NOINT
  189. msr cpsr_cxsf, r1
  190. ldr sp, =fiq_stack_start
  191. orr r1, r0, #MODE_SYS|NOINT
  192. msr cpsr_cxsf,r1
  193. ldr sp, =sys_stack_start
  194. orr r1, r0, #MODE_SVC|NOINT
  195. msr cpsr_cxsf, r1
  196. ldr sp, =svc_stack_start
  197. bx lr
  198. /*
  199. ***************************************
  200. * exception handlers
  201. ***************************************
  202. */
  203. /* Interrupt */
  204. vector_fiq:
  205. stmfd sp!,{r0-r7,lr}
  206. bl rt_hw_trap_fiq
  207. ldmfd sp!,{r0-r7,lr}
  208. subs pc, lr, #4
  209. vector_irq:
  210. stmfd sp!, {r0-r12,lr}
  211. bl rt_interrupt_enter
  212. bl rt_hw_trap_irq
  213. bl rt_interrupt_leave
  214. ldr r0, =rt_thread_switch_interrupt_flag
  215. ldr r1, [r0]
  216. cmp r1, #1
  217. beq rt_hw_context_switch_interrupt_do
  218. ldmfd sp!, {r0-r12,lr}
  219. subs pc, lr, #4
  220. rt_hw_context_switch_interrupt_do:
  221. mov r1, #0
  222. str r1, [r0]
  223. mov r1, sp
  224. add sp, sp, #4*4
  225. ldmfd sp!, {r4-r12,lr}
  226. mrs r0, spsr
  227. sub r2, lr, #4
  228. msr cpsr_c, #I_BIT|F_BIT|MODE_SVC
  229. stmfd sp!, {r2}
  230. stmfd sp!, {r4-r12,lr}
  231. ldmfd r1, {r1-r4}
  232. stmfd sp!, {r1-r4}
  233. stmfd sp!, {r0}
  234. ldr r4, =rt_interrupt_from_thread
  235. ldr r5, [r4]
  236. str sp, [r5]
  237. ldr r6, =rt_interrupt_to_thread
  238. ldr r6, [r6]
  239. ldr sp, [r6]
  240. ldmfd sp!, {r4}
  241. msr spsr_cxsf, r4
  242. ldmfd sp!, {r0-r12,lr,pc}^
  243. /* Exception */
  244. .macro push_svc_reg
  245. sub sp, sp, #17 * 4
  246. stmia sp, {r0 - r12}
  247. mov r0, sp
  248. mrs r6, spsr
  249. str lr, [r0, #15*4]
  250. str r6, [r0, #16*4]
  251. str sp, [r0, #13*4]
  252. str lr, [r0, #14*4]
  253. .endm
  254. vector_swi:
  255. push_svc_reg
  256. bl rt_hw_trap_swi
  257. b .
  258. vector_undef:
  259. push_svc_reg
  260. bl rt_hw_trap_udef
  261. b .
  262. vector_pabt:
  263. push_svc_reg
  264. bl rt_hw_trap_pabt
  265. b .
  266. vector_dabt:
  267. push_svc_reg
  268. bl rt_hw_trap_dabt
  269. b .
  270. vector_resv:
  271. push_svc_reg
  272. bl rt_hw_trap_resv
  273. b .