start_rvds.S 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301
  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-08-14 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. UND_STK_SIZE EQU 512
  14. SVC_STK_SIZE EQU 4096
  15. ABT_STK_SIZE EQU 512
  16. IRQ_STK_SIZE EQU 1024
  17. FIQ_STK_SIZE EQU 1024
  18. SYS_STK_SIZE EQU 512
  19. Heap_Size EQU 512
  20. S_FRAME_SIZE EQU (18*4) ;72
  21. S_PC EQU (15*4) ;R15
  22. MODE_USR EQU 0X10
  23. MODE_FIQ EQU 0X11
  24. MODE_IRQ EQU 0X12
  25. MODE_SVC EQU 0X13
  26. MODE_ABT EQU 0X17
  27. MODE_UND EQU 0X1B
  28. MODE_SYS EQU 0X1F
  29. MODEMASK EQU 0X1F
  30. NOINT EQU 0xC0
  31. ;----------------------- Stack and Heap Definitions ----------------------------
  32. AREA STACK, NOINIT, READWRITE, ALIGN=3
  33. Stack_Mem
  34. SPACE UND_STK_SIZE
  35. EXPORT UND_STACK_START
  36. UND_STACK_START
  37. ALIGN 8
  38. SPACE ABT_STK_SIZE
  39. EXPORT ABT_STACK_START
  40. ABT_STACK_START
  41. ALIGN 8
  42. SPACE FIQ_STK_SIZE
  43. EXPORT FIQ_STACK_START
  44. FIQ_STACK_START
  45. ALIGN 8
  46. SPACE IRQ_STK_SIZE
  47. EXPORT IRQ_STACK_START
  48. IRQ_STACK_START
  49. ALIGN 8
  50. SPACE SYS_STK_SIZE
  51. EXPORT SYS_STACK_START
  52. SYS_STACK_START
  53. ALIGN 8
  54. SPACE SVC_STK_SIZE
  55. EXPORT SVC_STACK_START
  56. SVC_STACK_START
  57. Stack_Top
  58. __initial_sp
  59. __heap_base
  60. Heap_Mem SPACE Heap_Size
  61. __heap_limit
  62. PRESERVE8
  63. ;--------------Jump vector table------------------------------------------------
  64. EXPORT Entry_Point
  65. AREA RESET, CODE, READONLY
  66. ARM
  67. Entry_Point
  68. LDR PC, vector_reset
  69. LDR PC, vector_undef
  70. LDR PC, vector_swi
  71. LDR PC, vector_pabt
  72. LDR PC, vector_dabt
  73. LDR PC, vector_resv
  74. LDR PC, vector_irq
  75. LDR PC, vector_fiq
  76. vector_reset
  77. DCD Reset_Handler
  78. vector_undef
  79. DCD Undef_Handler
  80. vector_swi
  81. DCD SWI_Handler
  82. vector_pabt
  83. DCD PAbt_Handler
  84. vector_dabt
  85. DCD DAbt_Handler
  86. vector_resv
  87. DCD Resv_Handler
  88. vector_irq
  89. DCD IRQ_Handler
  90. vector_fiq
  91. DCD FIQ_Handler
  92. ;----------------- Reset Handler -----------------------------------------------
  93. IMPORT rt_low_level_init
  94. IMPORT __main
  95. EXPORT Reset_Handler
  96. Reset_Handler
  97. ; set the cpu to SVC32 mode
  98. MRS R0,CPSR
  99. BIC R0,R0,#MODEMASK
  100. ORR R0,R0,#MODE_SVC:OR:NOINT
  101. MSR CPSR_cxsf,R0
  102. ; Set CO-Processor
  103. ; little-end,disbale I/D Cache MMU, vector table is 0x00000000
  104. MRC p15, 0, R0, c1, c0, 0 ; Read CP15
  105. LDR R1, =0x00003085 ; set clear bits
  106. BIC R0, R0, R1
  107. MCR p15, 0, R0, c1, c0, 0 ; Write CP15
  108. ; Call low level init function,
  109. ; disable and clear all IRQs, Init MMU, Init interrupt controller, etc.
  110. LDR SP, =SVC_STACK_START
  111. LDR R0, =rt_low_level_init
  112. BLX R0
  113. Setup_Stack
  114. ; Setup Stack for each mode
  115. MRS R0, CPSR
  116. BIC R0, R0, #MODEMASK
  117. ORR R1, R0, #MODE_UND:OR:NOINT
  118. MSR CPSR_cxsf, R1 ; Undef mode
  119. LDR SP, =UND_STACK_START
  120. ORR R1,R0,#MODE_ABT:OR:NOINT
  121. MSR CPSR_cxsf,R1 ; Abort mode
  122. LDR SP, =ABT_STACK_START
  123. ORR R1,R0,#MODE_IRQ:OR:NOINT
  124. MSR CPSR_cxsf,R1 ; IRQ mode
  125. LDR SP, =IRQ_STACK_START
  126. ORR R1,R0,#MODE_FIQ:OR:NOINT
  127. MSR CPSR_cxsf,R1 ; FIQ mode
  128. LDR SP, =FIQ_STACK_START
  129. ORR R1,R0,#MODE_SYS:OR:NOINT
  130. MSR CPSR_cxsf,R1 ; SYS/User mode
  131. LDR SP, =SYS_STACK_START
  132. ORR R1,R0,#MODE_SVC:OR:NOINT
  133. MSR CPSR_cxsf,R1 ; SVC mode
  134. LDR SP, =SVC_STACK_START
  135. ; Enter the C code
  136. LDR R0, =__main
  137. BLX R0
  138. ;----------------- Exception Handler -------------------------------------------
  139. IMPORT rt_hw_trap_udef
  140. IMPORT rt_hw_trap_swi
  141. IMPORT rt_hw_trap_pabt
  142. IMPORT rt_hw_trap_dabt
  143. IMPORT rt_hw_trap_resv
  144. IMPORT rt_hw_trap_irq
  145. IMPORT rt_hw_trap_fiq
  146. IMPORT rt_interrupt_enter
  147. IMPORT rt_interrupt_leave
  148. IMPORT rt_thread_switch_interrupt_flag
  149. IMPORT rt_interrupt_from_thread
  150. IMPORT rt_interrupt_to_thread
  151. Undef_Handler PROC
  152. SUB SP, SP, #S_FRAME_SIZE
  153. STMIA SP, {R0 - R12} ; Calling R0-R12
  154. ADD R8, SP, #S_PC
  155. STMDB R8, {SP, LR} ; Calling SP, LR
  156. STR LR, [R8, #0] ; Save calling PC
  157. MRS R6, SPSR
  158. STR R6, [R8, #4] ; Save CPSR
  159. STR R0, [R8, #8] ; Save SPSR
  160. MOV R0, SP
  161. BL rt_hw_trap_udef
  162. ENDP
  163. SWI_Handler PROC
  164. BL rt_hw_trap_swi
  165. ENDP
  166. PAbt_Handler PROC
  167. BL rt_hw_trap_pabt
  168. ENDP
  169. DAbt_Handler PROC
  170. SUB SP, SP, #S_FRAME_SIZE
  171. STMIA SP, {R0 - R12} ; Calling R0-R12
  172. ADD R8, SP, #S_PC
  173. STMDB R8, {SP, LR} ; Calling SP, LR
  174. STR LR, [R8, #0] ; Save calling PC
  175. MRS R6, SPSR
  176. STR R6, [R8, #4] ; Save CPSR
  177. STR R0, [R8, #8] ; Save SPSR
  178. MOV R0, SP
  179. BL rt_hw_trap_dabt
  180. ENDP
  181. Resv_Handler PROC
  182. BL rt_hw_trap_resv
  183. ENDP
  184. FIQ_Handler PROC
  185. STMFD SP!, {R0-R7,LR}
  186. BL rt_hw_trap_fiq
  187. LDMFD SP!, {R0-R7,LR}
  188. SUBS PC, LR, #4
  189. ENDP
  190. IRQ_Handler PROC
  191. STMFD SP!, {R0-R12,LR}
  192. BL rt_interrupt_enter
  193. BL rt_hw_trap_irq
  194. BL rt_interrupt_leave
  195. ; If rt_thread_switch_interrupt_flag set,
  196. ; jump to rt_hw_context_switch_interrupt_do and don't return
  197. LDR R0, =rt_thread_switch_interrupt_flag
  198. LDR R1, [R0]
  199. CMP R1, #1
  200. BEQ rt_hw_context_switch_interrupt_do
  201. LDMFD SP!, {R0-R12,LR}
  202. SUBS PC, LR, #4
  203. ENDP
  204. ;------ void rt_hw_context_switch_interrupt_do(rt_base_t flag) -----------------
  205. rt_hw_context_switch_interrupt_do PROC
  206. MOV R1, #0 ; Clear flag
  207. STR R1, [R0] ; Save to flag variable
  208. LDMFD SP!, {R0-R12,LR} ; Reload saved registers
  209. STMFD SP, {R0-R2} ; Save R0-R2
  210. SUB R1, SP, #4*3 ; Save old task's SP to R1
  211. SUB R2, LR, #4 ; Save old task's PC to R2
  212. MRS R0, SPSR ; Get CPSR of interrupt thread
  213. MSR CPSR_c, #MODE_SVC:OR:NOINT ; Switch to SVC mode and no interrupt
  214. STMFD SP!, {R2} ; Push old task's PC
  215. STMFD SP!, {R3-R12,LR} ; Push old task's LR,R12-R3
  216. LDMFD R1, {R1-R3}
  217. STMFD SP!, {R1-R3} ; Push old task's R2-R0
  218. STMFD SP!, {R0} ; Push old task's CPSR
  219. LDR R4, =rt_interrupt_from_thread
  220. LDR R5, [R4] ; R5 = stack ptr in old tasks's TCB
  221. STR SP, [R5] ; Store SP in preempted tasks's TCB
  222. LDR R6, =rt_interrupt_to_thread
  223. LDR R6, [R6] ; R6 = stack ptr in new tasks's TCB
  224. LDR SP, [R6] ; Get new task's stack pointer
  225. LDMFD SP!, {R4} ; Pop new task's SPSR
  226. MSR SPSR_cxsf, R4
  227. LDMFD SP!, {R0-R12,LR,PC}^ ; pop new task's R0-R12,LR & PC SPSR to CPSR
  228. ENDP
  229. ;*******************************************************************************
  230. ; User Stack and Heap initialization
  231. ;*******************************************************************************
  232. IF :DEF:__MICROLIB
  233. EXPORT __initial_sp
  234. EXPORT __heap_base
  235. EXPORT __heap_limit
  236. ELSE
  237. IMPORT __use_two_region_memory
  238. EXPORT __user_initial_stackheap
  239. __user_initial_stackheap
  240. LDR R0, = Heap_Mem ; heap base
  241. LDR R1, = SVC_STACK_START ; stack base (top-address)
  242. LDR R2, = (Heap_Mem + Heap_Size) ; heap limit
  243. LDR R3, = (SVC_STACK_START - SVC_STK_SIZE) ; stack limit (low-address)
  244. BX LR
  245. ALIGN
  246. ENDIF
  247. END