start_gcc.S 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319
  1. /*
  2. * File : start_gcc.S
  3. * This file is part of RT-Thread RTOS
  4. * COPYRIGHT (C) 2006 - 2015, RT-Thread Development Team
  5. *
  6. * This program is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation; either version 2 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License along
  17. * with this program; if not, write to the Free Software Foundation, Inc.,
  18. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  19. *
  20. * Change Logs:
  21. * Date Author Notes
  22. * 2011-01-13 weety first version
  23. * 2015-04-15 ArdaFu Split from AT91SAM9260 BSP
  24. * 2015-04-21 ArdaFu Remove remap code. Using mmu to map vector table
  25. * 2015-06-04 aozima Align stack address to 8 byte.
  26. */
  27. #include "rt_low_level_init.h"
  28. #define S_FRAME_SIZE (18*4) //72
  29. @#define S_SPSR (17*4) //SPSR
  30. @#define S_CPSR (16*4) //CPSR
  31. #define S_PC (15*4) //R15
  32. @#define S_LR (14*4) //R14
  33. @#define S_SP (13*4) //R13
  34. @#define S_IP (12*4) //R12
  35. @#define S_FP (11*4) //R11
  36. @#define S_R10 (10*4)
  37. @#define S_R9 (9*4)
  38. @#define S_R8 (8*4)
  39. @#define S_R7 (7*4)
  40. @#define S_R6 (6*4)
  41. @#define S_R5 (5*4)
  42. @#define S_R4 (4*4)
  43. @#define S_R3 (3*4)
  44. @#define S_R2 (2*4)
  45. @#define S_R1 (1*4)
  46. @#define S_R0 (0*4)
  47. #define MODE_SYS 0x1F
  48. #define MODE_FIQ 0x11
  49. #define MODE_IRQ 0x12
  50. #define MODE_SVC 0x13
  51. #define MODE_ABT 0x17
  52. #define MODE_UND 0x1B
  53. #define MODEMASK 0x1F
  54. #define NOINT 0xC0
  55. @;----------------------- Stack and Heap Definitions ---------------------------
  56. .section .nobss, "w"
  57. .space UND_STK_SIZE
  58. .align 3
  59. .global UND_STACK_START
  60. UND_STACK_START:
  61. .space ABT_STK_SIZE
  62. .align 3
  63. .global ABT_STACK_START
  64. ABT_STACK_START:
  65. .space FIQ_STK_SIZE
  66. .align 3
  67. .global FIQ_STACK_START
  68. FIQ_STACK_START:
  69. .space IRQ_STK_SIZE
  70. .align 3
  71. .global IRQ_STACK_START
  72. IRQ_STACK_START:
  73. .skip SYS_STK_SIZE
  74. .align 3
  75. .global SYS_STACK_START
  76. SYS_STACK_START:
  77. .space SVC_STK_SIZE
  78. .align 3
  79. .global SVC_STACK_START
  80. SVC_STACK_START:
  81. @;--------------Jump vector table-----------------------------------------------
  82. .section .init, "ax"
  83. .arm
  84. .global start
  85. start:
  86. LDR PC, vector_reset
  87. LDR PC, vector_undef
  88. LDR PC, vector_swi
  89. LDR PC, vector_pabt
  90. LDR PC, vector_dabt
  91. LDR PC, vector_resv
  92. LDR PC, vector_irq
  93. LDR PC, vector_fiq
  94. vector_reset:
  95. .word Reset_Handler
  96. vector_undef:
  97. .word Undef_Handler
  98. vector_swi:
  99. .word SWI_Handler
  100. vector_pabt:
  101. .word PAbt_Handler
  102. vector_dabt:
  103. .word DAbt_Handler
  104. vector_resv:
  105. .word Resv_Handler
  106. vector_irq:
  107. .word IRQ_Handler
  108. vector_fiq:
  109. .word FIQ_Handler
  110. .balignl 16,0xdeadbeef
  111. @;----------------- Reset Handler ---------------------------------------------
  112. .global rt_low_level_init
  113. .global main
  114. .global Reset_Handler
  115. Reset_Handler:
  116. @; Set the cpu to SVC32 mode
  117. MRS R0, CPSR
  118. BIC R0, R0, #MODEMASK
  119. ORR R0, R0, #MODE_SVC|NOINT
  120. MSR CPSR_cxsf, R0
  121. @; Set CO-Processor
  122. @; little-end,disbale I/D Cache MMU, vector table is 0x00000000
  123. MRC P15, 0, R0, C1, C0, 0 @; Read CP15
  124. LDR R1, =0x00003085 @; set clear bits
  125. BIC R0, R0, R1
  126. MCR P15, 0, R0, C1, C0, 0 @; Write CP15
  127. @; Call low level init function,
  128. @; disable and clear all IRQs, Init MMU, Init interrupt controller, etc.
  129. LDR SP, =SVC_STACK_START
  130. LDR R0, =rt_low_level_init
  131. BLX R0
  132. Setup_Stack:
  133. @; Setup Stack for each mode
  134. MRS R0, CPSR
  135. BIC R0, R0, #MODEMASK
  136. ORR R1, R0, #MODE_UND|NOINT
  137. MSR CPSR_cxsf, R1 @; Undef mode
  138. LDR SP, =UND_STACK_START
  139. ORR R1, R0, #MODE_ABT|NOINT
  140. MSR CPSR_cxsf, R1 @; Abort mode
  141. LDR SP, =ABT_STACK_START
  142. ORR R1, R0, #MODE_IRQ|NOINT
  143. MSR CPSR_cxsf, R1 @; IRQ mode
  144. LDR SP, =IRQ_STACK_START
  145. ORR R1, R0, #MODE_FIQ|NOINT
  146. MSR CPSR_cxsf, R1 @; FIQ mode
  147. LDR SP, =FIQ_STACK_START
  148. ORR R1, R0, #MODE_SYS|NOINT
  149. MSR CPSR_cxsf,R1 @; SYS/User mode
  150. LDR SP, =SYS_STACK_START
  151. ORR R1, R0, #MODE_SVC|NOINT
  152. MSR CPSR_cxsf, R1 @; SVC mode
  153. LDR SP, =SVC_STACK_START
  154. @; clear .bss
  155. MOV R0, #0 @; get a zero
  156. LDR R1, =__bss_start__ @; bss start
  157. LDR R2, =__bss_end__ @; bss end
  158. bss_clear_loop:
  159. CMP R1, R2 @; check if data to clear
  160. STRLO R0, [R1], #4 @; clear 4 bytes
  161. BLO bss_clear_loop @; loop until done
  162. @; call C++ constructors of global objects
  163. LDR R0, =__ctors_start__
  164. LDR R1, =__ctors_end__
  165. ctor_loop:
  166. CMP R0, R1
  167. BEQ ctor_end
  168. LDR R2, [R0], #4
  169. STMFD SP!, {R0-R1}
  170. MOV LR, PC
  171. BX R2
  172. LDMFD SP!, {R0-R1}
  173. B ctor_loop
  174. ctor_end:
  175. @; Enter the C code
  176. LDR R0, =rtthread_startup
  177. BLX R0
  178. @;----------------- Exception Handler -----------------------------------------
  179. .global rt_hw_trap_udef
  180. .global rt_hw_trap_swi
  181. .global rt_hw_trap_pabt
  182. .global rt_hw_trap_dabt
  183. .global rt_hw_trap_resv
  184. .global rt_hw_trap_irq
  185. .global rt_hw_trap_fiq
  186. .global rt_interrupt_enter
  187. .global rt_interrupt_leave
  188. .global rt_thread_switch_interrupt_flag
  189. .global rt_interrupt_from_thread
  190. .global rt_interrupt_to_thread
  191. .align 5
  192. Undef_Handler:
  193. SUB SP, SP, #S_FRAME_SIZE
  194. STMIA SP, {R0 - R12} @; Calling R0-R12
  195. ADD R8, SP, #S_PC
  196. STMDB R8, {SP, LR} @; Calling SP, LR
  197. STR LR, [R8, #0] @; Save calling PC
  198. MRS R6, SPSR
  199. STR R6, [R8, #4] @; Save CPSR
  200. STR R0, [R8, #8] @; Save SPSR
  201. MOV R0, SP
  202. BL rt_hw_trap_udef
  203. .align 5
  204. SWI_Handler:
  205. BL rt_hw_trap_swi
  206. .align 5
  207. PAbt_Handler:
  208. BL rt_hw_trap_pabt
  209. .align 5
  210. DAbt_Handler:
  211. SUB SP, SP, #S_FRAME_SIZE
  212. STMIA SP, {R0 - R12} @; Calling R0-R12
  213. ADD R8, SP, #S_PC
  214. STMDB R8, {SP, LR} @; Calling SP, LR
  215. STR LR, [R8, #0] @; Save calling PC
  216. MRS R6, SPSR
  217. STR R6, [R8, #4] @; Save CPSR
  218. STR R0, [R8, #8] @; Save SPSR
  219. MOV R0, SP
  220. BL rt_hw_trap_dabt
  221. .align 5
  222. Resv_Handler:
  223. BL rt_hw_trap_resv
  224. .align 5
  225. FIQ_Handler:
  226. STMFD SP!, {R0-R7,LR}
  227. BL rt_hw_trap_fiq
  228. LDMFD SP!, {R0-R7,LR}
  229. SUBS PC, LR, #4
  230. .align 5
  231. IRQ_Handler:
  232. STMFD SP!, {R0-R12,LR}
  233. BL rt_interrupt_enter
  234. BL rt_hw_trap_irq
  235. BL rt_interrupt_leave
  236. @; If rt_thread_switch_interrupt_flag set,
  237. @; jump to rt_hw_context_switch_interrupt_do and don't return
  238. LDR R0, =rt_thread_switch_interrupt_flag
  239. LDR R1, [R0]
  240. CMP R1, #1
  241. BEQ rt_hw_context_switch_interrupt_do
  242. LDMFD SP!, {R0-R12,LR}
  243. SUBS PC, LR, #4
  244. @;------ void rt_hw_context_switch_interrupt_do(rt_base_t flag) -----------------
  245. rt_hw_context_switch_interrupt_do:
  246. MOV R1, #0 @; Clear flag
  247. STR R1, [R0] @; Save to flag variable
  248. LDMFD SP!, {R0-R12,LR} @; Reload saved registers
  249. STMFD SP, {R0-R2} @; Save R0-R2
  250. SUB R1, SP, #4*3 @; Save old task's SP to R1
  251. SUB R2, LR, #4 @; Save old task's PC to R2
  252. MRS R0, SPSR @; Get CPSR of interrupt thread
  253. MSR CPSR_c, #MODE_SVC|NOINT @; Switch to SVC mode and no interrupt
  254. STMFD SP!, {R2} @; Push old task's PC
  255. STMFD SP!, {R3-R12,LR} @; Push old task's LR,R12-R3
  256. LDMFD R1, {R1-R3}
  257. STMFD SP!, {R1-R3} @; Push old task's R2-R0
  258. STMFD SP!, {R0} @; Push old task's CPSR
  259. LDR R4, =rt_interrupt_from_thread
  260. LDR R5, [R4] @; R5 = stack ptr in old tasks's TCB
  261. STR SP, [R5] @; Store SP in preempted tasks's TCB
  262. LDR R6, =rt_interrupt_to_thread
  263. LDR R6, [R6] @; R6 = stack ptr in new tasks's TCB
  264. LDR SP, [R6] @; Get new task's stack pointer
  265. LDMFD SP!, {R4} @; Pop new task's SPSR
  266. MSR SPSR_cxsf, R4
  267. LDMFD SP!, {R0-R12,LR,PC}^ @; pop new task's R0-R12,LR & PC SPSR 2 CPSR