start_rvds.S 9.5 KB

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