start_iar.S 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278
  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. MODULE ?cstartup
  43. SECTION .noinit:DATA:NOROOT(3)
  44. DATA
  45. ALIGNRAM 3
  46. DS8 UND_STK_SIZE
  47. PUBLIC UND_STACK_START
  48. UND_STACK_START:
  49. ALIGNRAM 3
  50. DS8 ABT_STK_SIZE
  51. PUBLIC ABT_STACK_START
  52. ABT_STACK_START:
  53. ALIGNRAM 3
  54. DS8 FIQ_STK_SIZE
  55. PUBLIC FIQ_STACK_START
  56. FIQ_STACK_START:
  57. ALIGNRAM 3
  58. DS8 IRQ_STK_SIZE
  59. PUBLIC IRQ_STACK_START
  60. IRQ_STACK_START:
  61. ALIGNRAM 3
  62. DS8 SYS_STK_SIZE
  63. PUBLIC SYS_STACK_START
  64. SYS_STACK_START:
  65. ALIGNRAM 3
  66. DS8 SVC_STK_SIZE
  67. PUBLIC SVC_STACK_START
  68. SVC_STACK_START:
  69. ;--------------Jump vector table------------------------------------------------
  70. SECTION .intvec:CODE:ROOT(2)
  71. ARM
  72. PUBLIC Entry_Point
  73. Entry_Point:
  74. __iar_init$$done: ; The interrupt vector is not needed
  75. ; until after copy initialization is done
  76. LDR PC, vector_reset
  77. LDR PC, vector_undef
  78. LDR PC, vector_swi
  79. LDR PC, vector_pabt
  80. LDR PC, vector_dabt
  81. LDR PC, vector_resv
  82. LDR PC, vector_irq
  83. LDR PC, vector_fiq
  84. vector_reset:
  85. DC32 Reset_Handler
  86. vector_undef:
  87. DC32 Undef_Handler
  88. vector_swi:
  89. DC32 SWI_Handler
  90. vector_pabt:
  91. DC32 PAbt_Handler
  92. vector_dabt:
  93. DC32 DAbt_Handler
  94. vector_resv:
  95. DC32 Resv_Handler
  96. vector_irq:
  97. DC32 IRQ_Handler
  98. vector_fiq:
  99. DC32 FIQ_Handler
  100. ;----------------- Reset Handler -----------------------------------------------
  101. EXTERN rt_low_level_init
  102. EXTERN ?main
  103. PUBLIC __iar_program_start
  104. __iar_program_start:
  105. Reset_Handler:
  106. ; Set the cpu to SVC32 mode
  107. MRS R0, CPSR
  108. BIC R0, R0, #MODEMASK
  109. ORR R0, R0, #MODE_SVC|NOINT
  110. MSR CPSR_cxsf, R0
  111. ; Set CO-Processor
  112. ; little-end,disbale I/D Cache MMU, vector table is 0x00000000
  113. MRC P15, 0, R0, C1, C0, 0 ; Read CP15
  114. LDR R1, =0x00003085 ; set clear bits
  115. BIC R0, R0, R1
  116. MCR P15, 0, R0, C1, C0, 0 ; Write CP15
  117. ; Call low level init function,
  118. ; disable and clear all IRQs, Init MMU, Init interrupt controller, etc.
  119. LDR SP, =SVC_STACK_START
  120. LDR R0, =rt_low_level_init
  121. BLX R0
  122. Setup_Stack:
  123. ; Setup Stack for each mode
  124. MRS R0, CPSR
  125. BIC R0, R0, #MODEMASK
  126. ORR R1, R0, #MODE_UND|NOINT
  127. MSR CPSR_cxsf, R1 ; Undef mode
  128. LDR SP, =UND_STACK_START
  129. ORR R1,R0,#MODE_ABT|NOINT
  130. MSR CPSR_cxsf,R1 ; Abort mode
  131. LDR SP, =ABT_STACK_START
  132. ORR R1,R0,#MODE_IRQ|NOINT
  133. MSR CPSR_cxsf,R1 ; IRQ mode
  134. LDR SP, =IRQ_STACK_START
  135. ORR R1,R0,#MODE_FIQ|NOINT
  136. MSR CPSR_cxsf,R1 ; FIQ mode
  137. LDR SP, =FIQ_STACK_START
  138. ORR R1,R0,#MODE_SYS|NOINT
  139. MSR CPSR_cxsf,R1 ; SYS/User mode
  140. LDR SP, =SYS_STACK_START
  141. ORR R1,R0,#MODE_SVC|NOINT
  142. MSR CPSR_cxsf,R1 ; SVC mode
  143. LDR SP, =SVC_STACK_START
  144. ; Enter the C code
  145. LDR R0, =?main
  146. BLX R0
  147. ;----------------- Exception Handler -------------------------------------------
  148. IMPORT rt_hw_trap_udef
  149. IMPORT rt_hw_trap_swi
  150. IMPORT rt_hw_trap_pabt
  151. IMPORT rt_hw_trap_dabt
  152. IMPORT rt_hw_trap_resv
  153. IMPORT rt_hw_trap_irq
  154. IMPORT rt_hw_trap_fiq
  155. IMPORT rt_interrupt_enter
  156. IMPORT rt_interrupt_leave
  157. IMPORT rt_thread_switch_interrupt_flag
  158. IMPORT rt_interrupt_from_thread
  159. IMPORT rt_interrupt_to_thread
  160. SECTION .text:CODE:ROOT(2)
  161. ARM
  162. Undef_Handler:
  163. SUB SP, SP, #S_FRAME_SIZE
  164. STMIA SP, {R0 - R12} ; Calling R0-R12
  165. ADD R8, SP, #S_PC
  166. STMDB R8, {SP, LR} ; Calling SP, LR
  167. STR LR, [R8, #0] ; Save calling PC
  168. MRS R6, SPSR
  169. STR R6, [R8, #4] ; Save CPSR
  170. STR R0, [R8, #8] ; Save SPSR
  171. MOV R0, SP
  172. BL rt_hw_trap_udef
  173. SWI_Handler:
  174. BL rt_hw_trap_swi
  175. PAbt_Handler:
  176. BL rt_hw_trap_pabt
  177. DAbt_Handler:
  178. SUB SP, SP, #S_FRAME_SIZE
  179. STMIA SP, {R0 - R12} ; Calling R0-R12
  180. ADD R8, SP, #S_PC
  181. STMDB R8, {SP, LR} ; Calling SP, LR
  182. STR LR, [R8, #0] ; Save calling PC
  183. MRS R6, SPSR
  184. STR R6, [R8, #4] ; Save CPSR
  185. STR R0, [R8, #8] ; Save SPSR
  186. MOV R0, SP
  187. BL rt_hw_trap_dabt
  188. Resv_Handler:
  189. BL rt_hw_trap_resv
  190. IRQ_Handler:
  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. FIQ_Handler:
  204. STMFD SP!, {R0-R7,LR}
  205. BL rt_hw_trap_fiq
  206. LDMFD SP!, {R0-R7,LR}
  207. SUBS PC, LR, #4
  208. ;------ void rt_hw_context_switch_interrupt_do(rt_base_t flag) -----------------
  209. rt_hw_context_switch_interrupt_do:
  210. MOV R1, #0 ; Clear flag
  211. STR R1, [R0] ; Save to flag variable
  212. LDMFD SP!, {R0-R12,LR} ; Reload saved registers
  213. STMFD SP, {R0-R2} ; Save R0-R2
  214. SUB R1, SP, #4*3 ; Save old task's SP to R1
  215. SUB R2, LR, #4 ; Save old task's PC to R2
  216. MRS R0, SPSR ; Get CPSR of interrupt thread
  217. MSR CPSR_c, #MODE_SVC|NOINT ; Switch to SVC mode and no interrupt
  218. STMFD SP!, {R2} ; Push old task's PC
  219. STMFD SP!, {R3-R12,LR} ; Push old task's LR,R12-R3
  220. LDMFD R1, {R1-R3}
  221. STMFD SP!, {R1-R3} ; Push old task's R2-R0
  222. STMFD SP!, {R0} ; Push old task's CPSR
  223. LDR R4, =rt_interrupt_from_thread
  224. LDR R5, [R4] ; R5 = stack ptr in old tasks's TCB
  225. STR SP, [R5] ; Store SP in preempted tasks's TCB
  226. LDR R6, =rt_interrupt_to_thread
  227. LDR R6, [R6] ; R6 = stack ptr in new tasks's TCB
  228. LDR SP, [R6] ; Get new task's stack pointer
  229. LDMFD SP!, {R4} ; Pop new task's SPSR
  230. MSR SPSR_cxsf, R4
  231. LDMFD SP!, {R0-R12,LR,PC}^ ; pop new task's R0-R12,LR & PC SPSR to CPSR
  232. END