start_gcc.S 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305
  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. #include "rt_low_level_init.h"
  14. #define S_FRAME_SIZE (18*4) //72
  15. @#define S_SPSR (17*4) //SPSR
  16. @#define S_CPSR (16*4) //CPSR
  17. #define S_PC (15*4) //R15
  18. @#define S_LR (14*4) //R14
  19. @#define S_SP (13*4) //R13
  20. @#define S_IP (12*4) //R12
  21. @#define S_FP (11*4) //R11
  22. @#define S_R10 (10*4)
  23. @#define S_R9 (9*4)
  24. @#define S_R8 (8*4)
  25. @#define S_R7 (7*4)
  26. @#define S_R6 (6*4)
  27. @#define S_R5 (5*4)
  28. @#define S_R4 (4*4)
  29. @#define S_R3 (3*4)
  30. @#define S_R2 (2*4)
  31. @#define S_R1 (1*4)
  32. @#define S_R0 (0*4)
  33. #define MODE_SYS 0x1F
  34. #define MODE_FIQ 0x11
  35. #define MODE_IRQ 0x12
  36. #define MODE_SVC 0x13
  37. #define MODE_ABT 0x17
  38. #define MODE_UND 0x1B
  39. #define MODEMASK 0x1F
  40. #define NOINT 0xC0
  41. @;----------------------- Stack and Heap Definitions ---------------------------
  42. .section .nobss, "w"
  43. .space UND_STK_SIZE
  44. .align 3
  45. .global UND_STACK_START
  46. UND_STACK_START:
  47. .space ABT_STK_SIZE
  48. .align 3
  49. .global ABT_STACK_START
  50. ABT_STACK_START:
  51. .space FIQ_STK_SIZE
  52. .align 3
  53. .global FIQ_STACK_START
  54. FIQ_STACK_START:
  55. .space IRQ_STK_SIZE
  56. .align 3
  57. .global IRQ_STACK_START
  58. IRQ_STACK_START:
  59. .skip SYS_STK_SIZE
  60. .align 3
  61. .global SYS_STACK_START
  62. SYS_STACK_START:
  63. .space SVC_STK_SIZE
  64. .align 3
  65. .global SVC_STACK_START
  66. SVC_STACK_START:
  67. @;--------------Jump vector table-----------------------------------------------
  68. .section .init, "ax"
  69. .arm
  70. .global start
  71. start:
  72. LDR PC, vector_reset
  73. LDR PC, vector_undef
  74. LDR PC, vector_swi
  75. LDR PC, vector_pabt
  76. LDR PC, vector_dabt
  77. LDR PC, vector_resv
  78. LDR PC, vector_irq
  79. LDR PC, vector_fiq
  80. vector_reset:
  81. .word Reset_Handler
  82. vector_undef:
  83. .word Undef_Handler
  84. vector_swi:
  85. .word SWI_Handler
  86. vector_pabt:
  87. .word PAbt_Handler
  88. vector_dabt:
  89. .word DAbt_Handler
  90. vector_resv:
  91. .word Resv_Handler
  92. vector_irq:
  93. .word IRQ_Handler
  94. vector_fiq:
  95. .word FIQ_Handler
  96. .balignl 16,0xdeadbeef
  97. @;----------------- Reset Handler ---------------------------------------------
  98. .global rt_low_level_init
  99. .global main
  100. .global Reset_Handler
  101. Reset_Handler:
  102. @; Set the cpu to SVC32 mode
  103. MRS R0, CPSR
  104. BIC R0, R0, #MODEMASK
  105. ORR R0, R0, #MODE_SVC|NOINT
  106. MSR CPSR_cxsf, R0
  107. @; Set CO-Processor
  108. @; little-end锛宒isbale I/D Cache MMU, vector table is 0x00000000
  109. MRC P15, 0, R0, C1, C0, 0 @; Read CP15
  110. LDR R1, =0x00003085 @; set clear bits
  111. BIC R0, R0, R1
  112. MCR P15, 0, R0, C1, C0, 0 @; Write CP15
  113. @; Call low level init function,
  114. @; disable and clear all IRQs, Init MMU, Init interrupt controller, etc.
  115. LDR SP, =SVC_STACK_START
  116. LDR R0, =rt_low_level_init
  117. BLX R0
  118. Setup_Stack:
  119. @; Setup Stack for each mode
  120. MRS R0, CPSR
  121. BIC R0, R0, #MODEMASK
  122. ORR R1, R0, #MODE_UND|NOINT
  123. MSR CPSR_cxsf, R1 @; Undef mode
  124. LDR SP, =UND_STACK_START
  125. ORR R1, R0, #MODE_ABT|NOINT
  126. MSR CPSR_cxsf, R1 @; Abort mode
  127. LDR SP, =ABT_STACK_START
  128. ORR R1, R0, #MODE_IRQ|NOINT
  129. MSR CPSR_cxsf, R1 @; IRQ mode
  130. LDR SP, =IRQ_STACK_START
  131. ORR R1, R0, #MODE_FIQ|NOINT
  132. MSR CPSR_cxsf, R1 @; FIQ mode
  133. LDR SP, =FIQ_STACK_START
  134. ORR R1, R0, #MODE_SYS|NOINT
  135. MSR CPSR_cxsf,R1 @; SYS/User mode
  136. LDR SP, =SYS_STACK_START
  137. ORR R1, R0, #MODE_SVC|NOINT
  138. MSR CPSR_cxsf, R1 @; SVC mode
  139. LDR SP, =SVC_STACK_START
  140. @; clear .bss
  141. MOV R0, #0 @; get a zero
  142. LDR R1, =__bss_start__ @; bss start
  143. LDR R2, =__bss_end__ @; bss end
  144. bss_clear_loop:
  145. CMP R1, R2 @; check if data to clear
  146. STRLO R0, [R1], #4 @; clear 4 bytes
  147. BLO bss_clear_loop @; loop until done
  148. @; call C++ constructors of global objects
  149. LDR R0, =__ctors_start__
  150. LDR R1, =__ctors_end__
  151. ctor_loop:
  152. CMP R0, R1
  153. BEQ ctor_end
  154. LDR R2, [R0], #4
  155. STMFD SP!, {R0-R1}
  156. MOV LR, PC
  157. BX R2
  158. LDMFD SP!, {R0-R1}
  159. B ctor_loop
  160. ctor_end:
  161. @; Enter the C code
  162. LDR R0, =rtthread_startup
  163. BLX R0
  164. @;----------------- Exception Handler -----------------------------------------
  165. .global rt_hw_trap_udef
  166. .global rt_hw_trap_swi
  167. .global rt_hw_trap_pabt
  168. .global rt_hw_trap_dabt
  169. .global rt_hw_trap_resv
  170. .global rt_hw_trap_irq
  171. .global rt_hw_trap_fiq
  172. .global rt_interrupt_enter
  173. .global rt_interrupt_leave
  174. .global rt_thread_switch_interrupt_flag
  175. .global rt_interrupt_from_thread
  176. .global rt_interrupt_to_thread
  177. .align 5
  178. Undef_Handler:
  179. SUB SP, SP, #S_FRAME_SIZE
  180. STMIA SP, {R0 - R12} @; Calling R0-R12
  181. ADD R8, SP, #S_PC
  182. STMDB R8, {SP, LR} @; Calling SP, LR
  183. STR LR, [R8, #0] @; Save calling PC
  184. MRS R6, SPSR
  185. STR R6, [R8, #4] @; Save CPSR
  186. STR R0, [R8, #8] @; Save SPSR
  187. MOV R0, SP
  188. BL rt_hw_trap_udef
  189. .align 5
  190. SWI_Handler:
  191. BL rt_hw_trap_swi
  192. .align 5
  193. PAbt_Handler:
  194. BL rt_hw_trap_pabt
  195. .align 5
  196. DAbt_Handler:
  197. SUB SP, SP, #S_FRAME_SIZE
  198. STMIA SP, {R0 - R12} @; Calling R0-R12
  199. ADD R8, SP, #S_PC
  200. STMDB R8, {SP, LR} @; Calling SP, LR
  201. STR LR, [R8, #0] @; Save calling PC
  202. MRS R6, SPSR
  203. STR R6, [R8, #4] @; Save CPSR
  204. STR R0, [R8, #8] @; Save SPSR
  205. MOV R0, SP
  206. BL rt_hw_trap_dabt
  207. .align 5
  208. Resv_Handler:
  209. BL rt_hw_trap_resv
  210. .align 5
  211. FIQ_Handler:
  212. STMFD SP!, {R0-R7,LR}
  213. BL rt_hw_trap_fiq
  214. LDMFD SP!, {R0-R7,LR}
  215. SUBS PC, LR, #4
  216. .align 5
  217. IRQ_Handler:
  218. STMFD SP!, {R0-R12,LR}
  219. BL rt_interrupt_enter
  220. BL rt_hw_trap_irq
  221. BL rt_interrupt_leave
  222. @; If rt_thread_switch_interrupt_flag set,
  223. @; jump to rt_hw_context_switch_interrupt_do and don't return
  224. LDR R0, =rt_thread_switch_interrupt_flag
  225. LDR R1, [R0]
  226. CMP R1, #1
  227. BEQ rt_hw_context_switch_interrupt_do
  228. LDMFD SP!, {R0-R12,LR}
  229. SUBS PC, LR, #4
  230. @;------ void rt_hw_context_switch_interrupt_do(rt_base_t flag) -----------------
  231. rt_hw_context_switch_interrupt_do:
  232. MOV R1, #0 @; Clear flag
  233. STR R1, [R0] @; Save to flag variable
  234. LDMFD SP!, {R0-R12,LR} @; Reload saved registers
  235. STMFD SP, {R0-R2} @; Save R0-R2
  236. SUB R1, SP, #4*3 @; Save old task's SP to R1
  237. SUB R2, LR, #4 @; Save old task's PC to R2
  238. MRS R0, SPSR @; Get CPSR of interrupt thread
  239. MSR CPSR_c, #MODE_SVC|NOINT @; Switch to SVC mode and no interrupt
  240. STMFD SP!, {R2} @; Push old task's PC
  241. STMFD SP!, {R3-R12,LR} @; Push old task's LR,R12-R3
  242. LDMFD R1, {R1-R3}
  243. STMFD SP!, {R1-R3} @; Push old task's R2-R0
  244. STMFD SP!, {R0} @; Push old task's CPSR
  245. LDR R4, =rt_interrupt_from_thread
  246. LDR R5, [R4] @; R5 = stack ptr in old tasks's TCB
  247. STR SP, [R5] @; Store SP in preempted tasks's TCB
  248. LDR R6, =rt_interrupt_to_thread
  249. LDR R6, [R6] @; R6 = stack ptr in new tasks's TCB
  250. LDR SP, [R6] @; Get new task's stack pointer
  251. LDMFD SP!, {R4} @; Pop new task's SPSR
  252. MSR SPSR_cxsf, R4
  253. LDMFD SP!, {R0-R12,LR,PC}^ @; pop new task's R0-R12,LR & PC SPSR 2 CPSR