start_iar.S 8.4 KB

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