start_iar.s 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292
  1. /*
  2. * File : start_iar.s
  3. * This file is part of RT-Thread RTOS
  4. * COPYRIGHT (C) 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. * 2015-04-06 zchong the first version
  23. */
  24. MODULE ?cstartup
  25. ; --------------------
  26. ; Mode, correspords to bits 0-5 in CPSR
  27. MODE_MSK DEFINE 0x1F ; Bit mask for mode bits in CPSR
  28. I_Bit DEFINE 0x80 ; when I bit is set, IRQ is disabled
  29. F_Bit DEFINE 0x40 ; when F bit is set, FIQ is disabled
  30. USR_MODE DEFINE 0x10 ; User mode
  31. FIQ_MODE DEFINE 0x11 ; Fast Interrupt Request mode
  32. IRQ_MODE DEFINE 0x12 ; Interrupt Request mode
  33. SVC_MODE DEFINE 0x13 ; Supervisor mode
  34. ABT_MODE DEFINE 0x17 ; Abort mode
  35. UND_MODE DEFINE 0x1B ; Undefined Instruction mode
  36. SYS_MODE DEFINE 0x1F ; System mode
  37. ;; Forward declaration of sections.
  38. SECTION IRQ_STACK:DATA:NOROOT(3)
  39. SECTION FIQ_STACK:DATA:NOROOT(3)
  40. SECTION SVC_STACK:DATA:NOROOT(3)
  41. SECTION ABT_STACK:DATA:NOROOT(3)
  42. SECTION UND_STACK:DATA:NOROOT(3)
  43. SECTION CSTACK:DATA:NOROOT(3)
  44. SECTION .text:CODE
  45. SECTION .intvec:CODE:NOROOT(5)
  46. PUBLIC __vector
  47. PUBLIC __iar_program_start
  48. __iar_init$$done: ; The vector table is not needed
  49. ; until after copy initialization is done
  50. __vector: ; Make this a DATA label, so that stack usage
  51. ; analysis doesn't consider it an uncalled fun
  52. ARM
  53. ; All default exception handlers (except reset) are
  54. ; defined as weak symbol definitions.
  55. ; If a handler is defined by the application it will take precedence.
  56. LDR PC,Reset_Addr ; Reset
  57. LDR PC,Undefined_Addr ; Undefined instructions
  58. LDR PC,SWI_Addr ; Software interrupt (SWI/SVC)
  59. LDR PC,Prefetch_Addr ; Prefetch abort
  60. LDR PC,Abort_Addr ; Data abort
  61. DCD 0 ; RESERVED
  62. LDR PC,IRQ_Addr ; IRQ
  63. LDR PC,FIQ_Addr ; FIQ
  64. DATA
  65. Reset_Addr: DCD __iar_program_start
  66. Undefined_Addr: DCD Undefined_Handler
  67. SWI_Addr: DCD SWI_Handler
  68. Prefetch_Addr: DCD Prefetch_Handler
  69. Abort_Addr: DCD Abort_Handler
  70. IRQ_Addr: DCD IRQ_Handler
  71. FIQ_Addr: DCD FIQ_Handler
  72. ; --------------------------------------------------
  73. ; ?cstartup -- low-level system initialization code.
  74. ;
  75. ; After a reset execution starts here, the mode is ARM, supervisor
  76. ; with interrupts disabled.
  77. ;
  78. SECTION .text:CODE:NOROOT(2)
  79. EXTERN rt_hw_trap_udef
  80. EXTERN rt_hw_trap_swi
  81. EXTERN rt_hw_trap_pabt
  82. EXTERN rt_hw_trap_dabt
  83. EXTERN rt_hw_trap_fiq
  84. EXTERN rt_hw_trap_irq
  85. EXTERN rt_interrupt_enter
  86. EXTERN rt_interrupt_leave
  87. EXTERN rt_thread_switch_interrupt_flag
  88. EXTERN rt_interrupt_from_thread
  89. EXTERN rt_interrupt_to_thread
  90. EXTERN rt_current_thread
  91. EXTERN vmm_thread
  92. EXTERN vmm_virq_check
  93. EXTERN __cmain
  94. REQUIRE __vector
  95. EXTWEAK __iar_init_core
  96. EXTWEAK __iar_init_vfp
  97. ARM
  98. __iar_program_start:
  99. ?cstartup:
  100. ;
  101. ; Add initialization needed before setup of stackpointers here.
  102. ;
  103. ;
  104. ; Initialize the stack pointers.
  105. ; The pattern below can be used for any of the exception stacks:
  106. ; FIQ, IRQ, SVC, ABT, UND, SYS.
  107. ; The USR mode uses the same stack as SYS.
  108. ; The stack segments must be defined in the linker command file,
  109. ; and be declared above.
  110. ;
  111. MRS r0, cpsr ; Original PSR value
  112. ;; Set up the interrupt stack pointer.
  113. BIC r0, r0, #MODE_MSK ; Clear the mode bits
  114. ORR r0, r0, #IRQ_MODE ; Set IRQ mode bits
  115. MSR cpsr_c, r0 ; Change the mode
  116. LDR sp, =SFE(IRQ_STACK) ; End of IRQ_STACK
  117. BIC sp,sp,#0x7 ; Make sure SP is 8 aligned
  118. ;; Set up the fast interrupt stack pointer.
  119. BIC r0, r0, #MODE_MSK ; Clear the mode bits
  120. ORR r0, r0, #FIQ_MODE ; Set FIR mode bits
  121. MSR cpsr_c, r0 ; Change the mode
  122. LDR sp, =SFE(FIQ_STACK) ; End of FIQ_STACK
  123. BIC sp,sp,#0x7 ; Make sure SP is 8 aligned
  124. BIC r0,r0,#MODE_MSK ; Clear the mode bits
  125. ORR r0,r0,#ABT_MODE ; Set Abort mode bits
  126. MSR cpsr_c,r0 ; Change the mode
  127. LDR sp,=SFE(ABT_STACK) ; End of ABT_STACK
  128. BIC sp,sp,#0x7 ; Make sure SP is 8 aligned
  129. BIC r0,r0,#MODE_MSK ; Clear the mode bits
  130. ORR r0,r0,#UND_MODE ; Set Undefined mode bits
  131. MSR cpsr_c,r0 ; Change the mode
  132. LDR sp,=SFE(UND_STACK) ; End of UND_STACK
  133. BIC sp,sp,#0x7 ; Make sure SP is 8 aligned
  134. ;; Set up the normal stack pointer.
  135. BIC r0 ,r0, #MODE_MSK ; Clear the mode bits
  136. ORR r0 ,r0, #SVC_MODE ; Set System mode bits
  137. MSR cpsr_c, r0 ; Change the mode
  138. LDR sp, =SFE(SVC_STACK) ; End of SVC_STACK
  139. BIC sp,sp,#0x7 ; Make sure SP is 8 aligned
  140. ;; Turn on core features assumed to be enabled.
  141. BL __iar_init_core
  142. ;; Initialize VFP (if needed).
  143. BL __iar_init_vfp
  144. ;; Continue to __cmain for C-level initialization.
  145. B __cmain
  146. Undefined_Handler:
  147. SUB sp, sp, #72
  148. STMIA sp, {r0 - r12} ;/* Calling r0-r12 */
  149. ADD r8, sp, #60
  150. MRS r1, cpsr
  151. MRS r2, spsr
  152. ORR r2,r2, #I_Bit | F_Bit
  153. MSR cpsr_c, r2
  154. MOV r0, r0
  155. STMDB r8, {sp, lr} ;/* Calling SP, LR */
  156. MSR cpsr_c, r1 ;/* return to Undefined Instruction mode */
  157. STR lr, [r8, #0] ;/* Save calling PC */
  158. MRS r6, spsr
  159. STR r6, [r8, #4] ;/* Save CPSR */
  160. STR r0, [r8, #8] ;/* Save OLD_R0 */
  161. MOV r0, sp
  162. BL rt_hw_trap_udef
  163. LDMIA sp, {r0 - r12} ;/* Calling r0 - r2 */
  164. MOV r0, r0
  165. LDR lr, [sp, #60] ;/* Get PC */
  166. ADD sp, sp, #72
  167. MOVS pc, lr ;/* return & move spsr_svc into cpsr */
  168. SWI_Handler:
  169. BL rt_hw_trap_swi
  170. Prefetch_Handler:
  171. BL rt_hw_trap_pabt
  172. Abort_Handler:
  173. SUB sp, sp, #72
  174. STMIA sp, {r0 - r12} ;/* Calling r0-r12 */
  175. ADD r8, sp, #60
  176. STMDB r8, {sp, lr} ;/* Calling SP, LR */
  177. STR lr, [r8, #0] ;/* Save calling PC */
  178. MRS r6, spsr
  179. STR r6, [r8, #4] ;/* Save CPSR */
  180. STR r0, [r8, #8] ;/* Save OLD_R0 */
  181. MOV r0, sp
  182. BL rt_hw_trap_dabt
  183. LDMIA sp, {r0 - r12} ;/* Calling r0 - r2 */
  184. MOV r0, r0
  185. LDR lr, [sp, #60] ;/* Get PC */
  186. ADD sp, sp, #72
  187. MOVS pc, lr ;/* return & move spsr_svc into cpsr */
  188. FIQ_Handler:
  189. STMFD sp!,{r0-r7,lr}
  190. BL rt_hw_trap_fiq
  191. LDMFD sp!,{r0-r7,lr}
  192. SUBS pc,lr,#4
  193. IRQ_Handler:
  194. STMFD sp!, {r0-r12,lr}
  195. BL rt_interrupt_enter
  196. BL rt_hw_trap_irq
  197. BL rt_interrupt_leave
  198. ; if rt_thread_switch_interrupt_flag set, jump to
  199. ; rt_hw_context_switch_interrupt_do and don't return
  200. LDR r0, =rt_thread_switch_interrupt_flag
  201. LDR r1, [r0]
  202. CMP r1, #1
  203. BEQ rt_hw_context_switch_interrupt_do
  204. LDMFD sp!, {r0-r12,lr}
  205. SUBS pc, lr, #4
  206. rt_hw_context_switch_interrupt_do:
  207. MOV r1, #0 ; clear flag
  208. STR r1, [r0]
  209. LDMFD sp!, {r0-r12,lr}; reload saved registers
  210. STMFD sp, {r0-r2} ; save r0-r2
  211. MRS r0, spsr ; get cpsr of interrupt thread
  212. SUB r1, sp, #4*3
  213. SUB r2, lr, #4 ; save old task's pc to r2
  214. ; switch to SVC mode with no interrupt
  215. MSR cpsr_c, #I_Bit | F_Bit | SVC_MODE
  216. STMFD sp!, {r2} ; push old task's pc
  217. STMFD sp!, {r3-r12,lr}; push old task's lr,r12-r4
  218. LDMFD r1, {r1-r3} ; restore r0-r2 of the interrupt thread
  219. STMFD sp!, {r1-r3} ; push old task's r0-r2
  220. STMFD sp!, {r0} ; push old task's cpsr
  221. LDR r4, =rt_interrupt_from_thread
  222. LDR r5, [r4]
  223. STR sp, [r5] ; store sp in preempted tasks's TCB
  224. LDR r6, =rt_interrupt_to_thread
  225. LDR r6, [r6]
  226. LDR sp, [r6] ; get new task's stack pointer
  227. LDMFD sp!, {r4} ; pop new task's cpsr to spsr
  228. MSR spsr_cxsf, r4
  229. LDMFD sp!, {r0-r12,lr,pc}^ ; pop new task's r0-r12,lr & pc, copy spsr to cpsr
  230. END