start_gcc.S 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367
  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. * 2010-11-13 weety first version
  23. */
  24. #define CONFIG_STACKSIZE 512
  25. #define S_FRAME_SIZE 68
  26. #define S_PC 64
  27. #define S_LR 60
  28. #define S_SP 56
  29. #define S_IP 52
  30. #define S_FP 48
  31. #define S_R10 44
  32. #define S_R9 40
  33. #define S_R8 36
  34. #define S_R7 32
  35. #define S_R6 28
  36. #define S_R5 24
  37. #define S_R4 20
  38. #define S_R3 16
  39. #define S_R2 12
  40. #define S_R1 8
  41. #define S_R0 4
  42. #define S_CPSR 0
  43. .equ I_BIT, 0x80 @ when I bit is set, IRQ is disabled
  44. .equ F_BIT, 0x40 @ when F bit is set, FIQ is disabled
  45. .equ USERMODE, 0x10
  46. .equ FIQMODE, 0x11
  47. .equ IRQMODE, 0x12
  48. .equ SVCMODE, 0x13
  49. .equ ABORTMODE, 0x17
  50. .equ UNDEFMODE, 0x1b
  51. .equ MODEMASK, 0x1f
  52. .equ NOINT, 0xc0
  53. .equ RAM_BASE, 0x00000000 /*Start address of RAM */
  54. .equ ROM_BASE, 0x80000000 /*Start address of Flash */
  55. .equ EINT_ENABLE0, 0x01c48018
  56. .equ EINT_ENABLE1, 0x01c4801c
  57. /*
  58. *************************************************************************
  59. *
  60. * Jump vector table
  61. *
  62. *************************************************************************
  63. */
  64. .section .init, "ax"
  65. .code 32
  66. .globl _start
  67. _start:
  68. b reset
  69. ldr pc, _vector_undef
  70. ldr pc, _vector_swi
  71. ldr pc, _vector_pabt
  72. ldr pc, _vector_dabt
  73. ldr pc, _vector_resv
  74. ldr pc, _vector_irq
  75. ldr pc, _vector_fiq
  76. _vector_undef: .word vector_undef
  77. _vector_swi: .word vector_swi
  78. _vector_pabt: .word vector_pabt
  79. _vector_dabt: .word vector_dabt
  80. _vector_resv: .word vector_resv
  81. _vector_irq: .word vector_irq
  82. _vector_fiq: .word vector_fiq
  83. .balignl 16,0xdeadbeef
  84. /*
  85. *************************************************************************
  86. *
  87. * Startup Code (reset vector)
  88. * relocate armboot to ram
  89. * setup stack
  90. * jump to second stage
  91. *
  92. *************************************************************************
  93. */
  94. _TEXT_BASE:
  95. .word TEXT_BASE
  96. /*
  97. * rtthread kernel start and end
  98. * which are defined in linker script
  99. */
  100. .globl _rtthread_start
  101. _rtthread_start:
  102. .word _start
  103. .globl _rtthread_end
  104. _rtthread_end:
  105. .word _end
  106. /*
  107. * rtthread bss start and end which are defined in linker script
  108. */
  109. .globl _bss_start
  110. _bss_start:
  111. .word __bss_start
  112. .globl _bss_end
  113. _bss_end:
  114. .word __bss_end
  115. /* IRQ stack memory (calculated at run-time) */
  116. .globl IRQ_STACK_START
  117. IRQ_STACK_START:
  118. .word _irq_stack_start + 1024
  119. .globl FIQ_STACK_START
  120. FIQ_STACK_START:
  121. .word _fiq_stack_start + 1024
  122. .globl UNDEFINED_STACK_START
  123. UNDEFINED_STACK_START:
  124. .word _undefined_stack_start + CONFIG_STACKSIZE
  125. .globl ABORT_STACK_START
  126. ABORT_STACK_START:
  127. .word _abort_stack_start + CONFIG_STACKSIZE
  128. .globl _STACK_START
  129. _STACK_START:
  130. .word _svc_stack_start + 1024
  131. /* ----------------------------------entry------------------------------*/
  132. reset:
  133. /* set the cpu to SVC32 mode */
  134. mrs r0,cpsr
  135. bic r0,r0,#MODEMASK
  136. orr r0,r0,#SVCMODE
  137. msr cpsr,r0
  138. /* mask all IRQs by clearing all bits in the INTMRs */
  139. mov r1, $0
  140. ldr r0, =EINT_ENABLE0
  141. str r1, [r0]
  142. ldr r0, =EINT_ENABLE1
  143. str r1, [r0]
  144. #if 0
  145. /* set interrupt vector */
  146. ldr r0, _TEXT_BASE
  147. mov r1, #0x00
  148. add r2, r0, #0x40 /* size, 32bytes */
  149. copy_loop:
  150. ldmia r0!, {r3-r10} /* copy from source address [r0] */
  151. stmia r1!, {r3-r10} /* copy to target address [r1] */
  152. cmp r0, r2 /* until source end addreee [r2] */
  153. ble copy_loop
  154. #endif
  155. /* setup stack */
  156. bl stack_setup
  157. /* clear .bss */
  158. mov r0,#0 /* get a zero */
  159. ldr r1,=__bss_start /* bss start */
  160. ldr r2,=__bss_end /* bss end */
  161. bss_loop:
  162. cmp r1,r2 /* check if data to clear */
  163. strlo r0,[r1],#4 /* clear 4 bytes */
  164. blo bss_loop /* loop until done */
  165. /* call C++ constructors of global objects */
  166. ldr r0, =__ctors_start__
  167. ldr r1, =__ctors_end__
  168. ctor_loop:
  169. cmp r0, r1
  170. beq ctor_end
  171. ldr r2, [r0], #4
  172. stmfd sp!, {r0-r1}
  173. mov lr, pc
  174. bx r2
  175. ldmfd sp!, {r0-r1}
  176. b ctor_loop
  177. ctor_end:
  178. /* start RT-Thread Kernel */
  179. ldr pc, _rtthread_startup
  180. _rtthread_startup:
  181. .word rtthread_startup
  182. #if defined (__FLASH_BUILD__)
  183. _load_address:
  184. .word ROM_BASE + _TEXT_BASE
  185. #else
  186. _load_address:
  187. .word RAM_BASE + _TEXT_BASE
  188. #endif
  189. /*
  190. *************************************************************************
  191. *
  192. * Interrupt handling
  193. *
  194. *************************************************************************
  195. */
  196. .macro push_exp_reg
  197. sub sp, sp, #S_FRAME_SIZE @/* Sizeof(struct rt_hw_stack) */
  198. stmib sp, {r0 - r12} @/* Calling r0-r12 */
  199. mov r0, sp
  200. mrs r6, spsr @/* Save CPSR */
  201. str lr, [r0, #S_PC] @/* Push PC */
  202. str r6, [r0, #S_CPSR] @/* Push CPSR */
  203. @ switch to SVC mode with no interrupt
  204. msr cpsr_c, #I_BIT|F_BIT|SVCMODE
  205. str sp, [r0, #S_SP] @/* Save calling SP */
  206. str lr, [r0, #S_LR] @/* Save calling PC */
  207. .endm
  208. /* exception handlers */
  209. .align 5
  210. vector_undef:
  211. push_exp_reg
  212. bl rt_hw_trap_udef
  213. .align 5
  214. vector_swi:
  215. push_exp_reg
  216. bl rt_hw_trap_swi
  217. .align 5
  218. vector_pabt:
  219. push_exp_reg
  220. bl rt_hw_trap_pabt
  221. .align 5
  222. vector_dabt:
  223. push_exp_reg
  224. bl rt_hw_trap_dabt
  225. .align 5
  226. vector_resv:
  227. push_exp_reg
  228. bl rt_hw_trap_resv
  229. .globl rt_interrupt_enter
  230. .globl rt_interrupt_leave
  231. .globl rt_thread_switch_interrupt_flag
  232. .globl rt_interrupt_from_thread
  233. .globl rt_interrupt_to_thread
  234. vector_irq:
  235. stmfd sp!, {r0-r12,lr}
  236. bl rt_interrupt_enter
  237. bl rt_hw_trap_irq
  238. bl rt_interrupt_leave
  239. @ if rt_thread_switch_interrupt_flag set, jump to
  240. @ rt_hw_context_switch_interrupt_do and don't return
  241. ldr r0, =rt_thread_switch_interrupt_flag
  242. ldr r1, [r0]
  243. cmp r1, #1
  244. beq rt_hw_context_switch_interrupt_do
  245. ldmfd sp!, {r0-r12,lr}
  246. subs pc, lr, #4
  247. .align 5
  248. vector_fiq:
  249. stmfd sp!,{r0-r7,lr}
  250. bl rt_hw_trap_fiq
  251. ldmfd sp!,{r0-r7,lr}
  252. subs pc,lr,#4
  253. rt_hw_context_switch_interrupt_do:
  254. mov r1, #0 @ clear flag
  255. str r1, [r0]
  256. ldmfd sp!, {r0-r12,lr}@ reload saved registers
  257. stmfd sp, {r0-r2} @ save r0-r2
  258. mrs r0, spsr @ get cpsr of interrupt thread
  259. sub r1, sp, #4*3
  260. sub r2, lr, #4 @ save old task's pc to r2
  261. @ switch to SVC mode with no interrupt
  262. msr cpsr_c, #I_BIT|F_BIT|SVCMODE
  263. stmfd sp!, {r2} @ push old task's pc
  264. stmfd sp!, {r3-r12,lr}@ push old task's lr,r12-r4
  265. ldmfd r1, {r1-r3} @ restore r0-r2 of the interrupt thread
  266. stmfd sp!, {r1-r3} @ push old task's r0-r2
  267. stmfd sp!, {r0} @ push old task's cpsr
  268. ldr r4, =rt_interrupt_from_thread
  269. ldr r5, [r4]
  270. str sp, [r5] @ store sp in preempted tasks's TCB
  271. ldr r6, =rt_interrupt_to_thread
  272. ldr r6, [r6]
  273. ldr sp, [r6] @ get new task's stack pointer
  274. ldmfd sp!, {r4} @ pop new task's cpsr to spsr
  275. msr spsr_cxsf, r4
  276. ldmfd sp!, {r0-r12,lr,pc}^ @ pop new task's r0-r12,lr & pc, copy spsr to cpsr
  277. stack_setup:
  278. mrs r0, cpsr
  279. bic r0, r0, #MODEMASK
  280. orr r1, r0, #UNDEFMODE|NOINT
  281. msr cpsr_cxsf, r1 /* undef mode */
  282. ldr sp, UNDEFINED_STACK_START
  283. orr r1,r0,#ABORTMODE|NOINT
  284. msr cpsr_cxsf,r1 /* abort mode */
  285. ldr sp, ABORT_STACK_START
  286. orr r1,r0,#IRQMODE|NOINT
  287. msr cpsr_cxsf,r1 /* IRQ mode */
  288. ldr sp, IRQ_STACK_START
  289. orr r1,r0,#FIQMODE|NOINT
  290. msr cpsr_cxsf,r1 /* FIQ mode */
  291. ldr sp, FIQ_STACK_START
  292. bic r0,r0,#MODEMASK
  293. orr r1,r0,#SVCMODE|NOINT
  294. msr cpsr_cxsf,r1 /* SVC mode */
  295. ldr sp, _STACK_START
  296. /* USER mode is not initialized. */
  297. bx lr /* The LR register may be not valid for the mode changes.*/
  298. /*/*}*/