start_rvds.S 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325
  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. ; */
  24. ; Standard definitions of Mode bits and Interrupt (I & F) flags in PSRs
  25. Mode_USR EQU 0x10
  26. Mode_FIQ EQU 0x11
  27. Mode_IRQ EQU 0x12
  28. Mode_SVC EQU 0x13
  29. Mode_ABT EQU 0x17
  30. Mode_UND EQU 0x1B
  31. Mode_SYS EQU 0x1F
  32. SVCMODE EQU 0x13
  33. MODEMASK EQU 0x1f
  34. I_Bit EQU 0x80 ; when I bit is set, IRQ is disabled
  35. F_Bit EQU 0x40 ; when F bit is set, FIQ is disabled
  36. ;----------------------- Stack and Heap Definitions ----------------------------
  37. ;// <h> Stack Configuration (Stack Sizes in Bytes)
  38. ;// <o0> Undefined Mode <0x0-0xFFFFFFFF:8>
  39. ;// <o1> Supervisor Mode <0x0-0xFFFFFFFF:8>
  40. ;// <o2> Abort Mode <0x0-0xFFFFFFFF:8>
  41. ;// <o3> Fast Interrupt Mode <0x0-0xFFFFFFFF:8>
  42. ;// <o4> Interrupt Mode <0x0-0xFFFFFFFF:8>
  43. ;// <o5> User/System Mode <0x0-0xFFFFFFFF:8>
  44. ;// </h>
  45. UND_Stack_Size EQU 512
  46. SVC_Stack_Size EQU 4096
  47. ABT_Stack_Size EQU 512
  48. FIQ_Stack_Size EQU 1024
  49. IRQ_Stack_Size EQU 1024
  50. USR_Stack_Size EQU 512
  51. ISR_Stack_Size EQU (UND_Stack_Size + SVC_Stack_Size + ABT_Stack_Size + \
  52. FIQ_Stack_Size + IRQ_Stack_Size)
  53. AREA STACK, NOINIT, READWRITE, ALIGN=3
  54. Stack_Mem SPACE USR_Stack_Size
  55. __initial_sp SPACE ISR_Stack_Size
  56. Stack_Top
  57. ;// <h> Heap Configuration
  58. ;// <o> Heap Size (in Bytes) <0x0-0xFFFFFFFF>
  59. ;// </h>
  60. Heap_Size EQU 0x00000000
  61. AREA HEAP, NOINIT, READWRITE, ALIGN=3
  62. __heap_base
  63. Heap_Mem SPACE Heap_Size
  64. __heap_limit
  65. ;----------------------- Memory Definitions ------------------------------------
  66. AT91_MATRIX_BASE EQU 0xffffee00
  67. AT91_MATRIX_MRCR EQU (AT91_MATRIX_BASE + 0x100)
  68. AT91_MATRIX_RCB0 EQU 0x00000001
  69. AT91_MATRIX_RCB1 EQU 0x00000002
  70. AT91_AIC_BASE EQU 0xfffff000
  71. AT91_AIC_IDCR EQU 0x124
  72. AT91_AIC_ICCR EQU 0x128
  73. ;----------------------- CODE --------------------------------------------------
  74. PRESERVE8
  75. ; Area Definition and Entry Point
  76. ; Startup Code must be linked first at Address at which it expects to run.
  77. AREA RESET, CODE, READONLY
  78. ARM
  79. ; Exception Vectors
  80. ; Mapped to Address 0.
  81. ; Absolute addressing mode must be used.
  82. ; Dummy Handlers are implemented as infinite loops which can be modified.
  83. EXPORT Entry_Point
  84. Entry_Point
  85. Vectors LDR PC, Reset_Addr
  86. LDR PC, Undef_Addr
  87. LDR PC, SWI_Addr
  88. LDR PC, PAbt_Addr
  89. LDR PC, DAbt_Addr
  90. NOP
  91. LDR PC, IRQ_Addr
  92. LDR PC, FIQ_Addr
  93. Reset_Addr DCD Reset_Handler
  94. Undef_Addr DCD Undef_Handler
  95. SWI_Addr DCD SWI_Handler
  96. PAbt_Addr DCD PAbt_Handler
  97. DAbt_Addr DCD DAbt_Handler
  98. DCD 0 ; Reserved Address
  99. IRQ_Addr DCD IRQ_Handler
  100. FIQ_Addr DCD FIQ_Handler
  101. Undef_Handler B Undef_Handler
  102. SWI_Handler B SWI_Handler
  103. PAbt_Handler B PAbt_Handler
  104. ;DAbt_Handler B DAbt_Handler
  105. FIQ_Handler B FIQ_Handler
  106. ;*
  107. ;*************************************************************************
  108. ;*
  109. ;* Interrupt handling
  110. ;*
  111. ;*************************************************************************
  112. ;*
  113. ; DAbt Handler
  114. DAbt_Handler
  115. IMPORT rt_hw_trap_dabt
  116. sub sp, sp, #72
  117. stmia sp, {r0 - r12} ;/* Calling r0-r12 */
  118. add r8, sp, #60
  119. stmdb r8, {sp, lr} ;/* Calling SP, LR */
  120. str lr, [r8, #0] ;/* Save calling PC */
  121. mrs r6, spsr
  122. str r6, [r8, #4] ;/* Save CPSR */
  123. str r0, [r8, #8] ;/* Save OLD_R0 */
  124. mov r0, sp
  125. bl rt_hw_trap_dabt
  126. ;##########################################
  127. ; Reset Handler
  128. EXPORT Reset_Handler
  129. Reset_Handler
  130. ; set the cpu to SVC32 mode-----------------------------------------------------
  131. MRS R0,CPSR
  132. BIC R0,R0,#MODEMASK
  133. ORR R0,R0,#SVCMODE
  134. MSR CPSR_cxsf,R0
  135. LDR R1, =AT91_AIC_BASE
  136. LDR R0, =0xffffffff
  137. STR R0, [R1, #AT91_AIC_IDCR]
  138. STR R0, [R1, #AT91_AIC_ICCR]
  139. ; remap internal ram to 0x00000000 address
  140. LDR R0, =AT91_MATRIX_MRCR
  141. LDR R1, =(AT91_MATRIX_RCB0|AT91_MATRIX_RCB1)
  142. STR R1, [R0]
  143. ; Copy Exception Vectors to Internal RAM ---------------------------------------
  144. ADR R8, Vectors ; Source
  145. LDR R9, =0x00 ; Destination
  146. LDMIA R8!, {R0-R7} ; Load Vectors
  147. STMIA R9!, {R0-R7} ; Store Vectors
  148. LDMIA R8!, {R0-R7} ; Load Handler Addresses
  149. STMIA R9!, {R0-R7} ; Store Handler Addresses
  150. ; Setup Stack for each mode ----------------------------------------------------
  151. LDR R0, =Stack_Top
  152. ; Enter Undefined Instruction Mode and set its Stack Pointer
  153. MSR CPSR_c, #Mode_UND:OR:I_Bit:OR:F_Bit
  154. MOV SP, R0
  155. SUB R0, R0, #UND_Stack_Size
  156. ; Enter Abort Mode and set its Stack Pointer
  157. MSR CPSR_c, #Mode_ABT:OR:I_Bit:OR:F_Bit
  158. MOV SP, R0
  159. SUB R0, R0, #ABT_Stack_Size
  160. ; Enter FIQ Mode and set its Stack Pointer
  161. MSR CPSR_c, #Mode_FIQ:OR:I_Bit:OR:F_Bit
  162. MOV SP, R0
  163. SUB R0, R0, #FIQ_Stack_Size
  164. ; Enter IRQ Mode and set its Stack Pointer
  165. MSR CPSR_c, #Mode_IRQ:OR:I_Bit:OR:F_Bit
  166. MOV SP, R0
  167. SUB R0, R0, #IRQ_Stack_Size
  168. ; Enter Supervisor Mode and set its Stack Pointer
  169. MSR CPSR_c, #Mode_SVC:OR:I_Bit:OR:F_Bit
  170. MOV SP, R0
  171. SUB R0, R0, #SVC_Stack_Size
  172. ; Enter User Mode and set its Stack Pointer
  173. ; MSR CPSR_c, #Mode_USR
  174. MOV SP, R0
  175. SUB SL, SP, #USR_Stack_Size
  176. ; Enter the C code -------------------------------------------------------------
  177. IMPORT __main
  178. LDR R0, =__main
  179. BX R0
  180. IMPORT rt_interrupt_enter
  181. IMPORT rt_interrupt_leave
  182. IMPORT rt_thread_switch_interrupt_flag
  183. IMPORT rt_interrupt_from_thread
  184. IMPORT rt_interrupt_to_thread
  185. IMPORT rt_hw_trap_irq
  186. IRQ_Handler PROC
  187. EXPORT IRQ_Handler
  188. STMFD sp!, {r0-r12,lr}
  189. BL rt_interrupt_enter
  190. BL rt_hw_trap_irq
  191. BL rt_interrupt_leave
  192. ; if rt_thread_switch_interrupt_flag set, jump to
  193. ; rt_hw_context_switch_interrupt_do and don't return
  194. LDR r0, =rt_thread_switch_interrupt_flag
  195. LDR r1, [r0]
  196. CMP r1, #1
  197. BEQ rt_hw_context_switch_interrupt_do
  198. LDMFD sp!, {r0-r12,lr}
  199. SUBS pc, lr, #4
  200. ENDP
  201. ; /*
  202. ; * void rt_hw_context_switch_interrupt_do(rt_base_t flag)
  203. ; */
  204. rt_hw_context_switch_interrupt_do PROC
  205. EXPORT rt_hw_context_switch_interrupt_do
  206. MOV r1, #0 ; clear flag
  207. STR r1, [r0]
  208. LDMFD sp!, {r0-r12,lr}; reload saved registers
  209. STMFD sp!, {r0-r3} ; save r0-r3
  210. MOV r1, sp
  211. ADD sp, sp, #16 ; restore sp
  212. SUB r2, lr, #4 ; save old task's pc to r2
  213. MRS r3, spsr ; get cpsr of interrupt thread
  214. ; switch to SVC mode and no interrupt
  215. MSR cpsr_c, #I_Bit:OR:F_Bit:OR:Mode_SVC
  216. STMFD sp!, {r2} ; push old task's pc
  217. STMFD sp!, {r4-r12,lr}; push old task's lr,r12-r4
  218. MOV r4, r1 ; Special optimised code below
  219. MOV r5, r3
  220. LDMFD r4!, {r0-r3}
  221. STMFD sp!, {r0-r3} ; push old task's r3-r0
  222. STMFD sp!, {r5} ; push old task's cpsr
  223. MRS r4, spsr
  224. STMFD sp!, {r4} ; push old task's spsr
  225. LDR r4, =rt_interrupt_from_thread
  226. LDR r5, [r4]
  227. STR sp, [r5] ; store sp in preempted tasks's TCB
  228. LDR r6, =rt_interrupt_to_thread
  229. LDR r6, [r6]
  230. LDR sp, [r6] ; get new task's stack pointer
  231. LDMFD sp!, {r4} ; pop new task's spsr
  232. MSR spsr_cxsf, r4
  233. LDMFD sp!, {r4} ; pop new task's psr
  234. MSR cpsr_cxsf, r4
  235. LDMFD sp!, {r0-r12,lr,pc} ; pop new task's r0-r12,lr & pc
  236. ENDP
  237. IF :DEF:__MICROLIB
  238. EXPORT __heap_base
  239. EXPORT __heap_limit
  240. ELSE
  241. ; User Initial Stack & Heap
  242. AREA |.text|, CODE, READONLY
  243. IMPORT __use_two_region_memory
  244. EXPORT __user_initial_stackheap
  245. __user_initial_stackheap
  246. LDR R0, = Heap_Mem
  247. LDR R1, =(Stack_Mem + USR_Stack_Size)
  248. LDR R2, = (Heap_Mem + Heap_Size)
  249. LDR R3, = Stack_Mem
  250. BX LR
  251. ENDIF
  252. END