1
0

start_gcc.S 6.9 KB

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