start_gcc.S 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363
  1. /*
  2. * File : start.S
  3. * This file is part of RT-Thread RTOS
  4. * COPYRIGHT (C) 2006 - 2013, 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. * 2013-07-13 Peng Fan First implementation
  23. */
  24. #define CONFIG_STACKSIZE 1024
  25. #define S_FRAME_SIZE 132
  26. #define S_OLD_R0 132
  27. #define S_PSR 128
  28. #define S_PC 124
  29. #define S_LR 120
  30. #define S_SP 116
  31. #define S_IP 112
  32. #define S_FP 108
  33. #define S_R26 104
  34. #define S_R25 100
  35. #define S_R24 96
  36. #define S_R23 92
  37. #define S_R22 88
  38. #define S_R21 84
  39. #define S_R20 80
  40. #define S_R19 76
  41. #define S_R18 72
  42. #define S_R17 68
  43. #define S_R16 64
  44. #define S_R15 60
  45. #define S_R14 56
  46. #define S_R13 52
  47. #define S_R12 48
  48. #define S_R11 44
  49. #define S_R10 40
  50. #define S_R9 36
  51. #define S_R8 32
  52. #define S_R7 28
  53. #define S_R6 24
  54. #define S_R5 20
  55. #define S_R4 16
  56. #define S_R3 12
  57. #define S_R2 8
  58. #define S_R1 4
  59. #define S_R0 0
  60. .equ USERMODE, 0x10
  61. .equ REALMODE, 0x11
  62. .equ IRQMODE, 0x12
  63. .equ PRIVMODE, 0x13
  64. .equ TRAPMODE, 0x17
  65. .equ EXTNMODE, 0x1b
  66. .equ MODEMASK, 0x1f
  67. .equ NOINT, 0xc0
  68. /*
  69. *************************************************************************
  70. *
  71. * Jump vector table
  72. *
  73. *************************************************************************
  74. */
  75. .section .init, "ax"
  76. .code 32
  77. .globl _start
  78. _start:
  79. b reset
  80. ldw pc, _extend_handle
  81. ldw pc, _swi_handle
  82. ldw pc, _iabort_handle
  83. ldw pc, _dabort_handle
  84. ldw pc, _reserve_handle
  85. ldw pc, _IRQ_handle
  86. ldw pc, _FIQ_handle
  87. _extend_handle: .word extend_handle
  88. _swi_handle: .word swi_handle
  89. _iabort_handle: .word iabort_handle
  90. _dabort_handle: .word dabort_handle
  91. _reserve_handle: .word reserve_handle
  92. _IRQ_handle: .word IRQ_handle
  93. _FIQ_handle: .word FIQ_handle
  94. .balignl 16,0xdeadbeef
  95. /*
  96. *************************************************************************
  97. *
  98. * Startup Code (reset vector)
  99. * relocate armboot to ram
  100. * setup stack
  101. * jump to second stage
  102. *
  103. *************************************************************************
  104. */
  105. .global _TEXT_BASE
  106. _TEXT_BASE:
  107. .word TEXT_BASE
  108. .globl _rtthread_start
  109. _rtthread_start:
  110. .word _start
  111. .globl _rtthread_end
  112. _rtthread_end:
  113. .word _end
  114. .globl _bss_start
  115. _bss_start:
  116. .word __bss_start @ load end address
  117. .globl _bss_end
  118. _bss_end:
  119. .word __bss_end
  120. .globl IRQ_STACK_START
  121. IRQ_STACK_START:
  122. .word _irq_stack_start + 1024
  123. .globl FIQ_STACK_START
  124. FIQ_STACK_START:
  125. .word _fiq_stack_start +1024
  126. .globl UNDEFINED_STACK_START
  127. UNDEFINED_STACK_START:
  128. .word _undefined_stack_start + CONFIG_STACKSIZE
  129. .globl ABORT_STACK_START
  130. ABORT_STACK_START:
  131. .word _abort_stack_start + CONFIG_STACKSIZE
  132. .globl _STACK_START
  133. _STACK_START:
  134. .word _priv_stack_start + 4096
  135. .equ SEP6200_VIC_BASE, 0xb0000000
  136. .equ SEP6200_SYSCTL_BASE, 0xb0008000
  137. /* ----------------------------------entry------------------------------*/
  138. reset:
  139. /* set the cpu to PRIV mode and disable cpu interrupt */
  140. mov r0, asr
  141. andn r0, r0, #0xff
  142. or r0, r0, #PRIVMODE|NOINT
  143. mov.a asr, r0
  144. /* mask all IRQs by clearing all bits in the INTMRs */
  145. ldw r1, =SEP6200_VIC_BASE
  146. ldw r0, =0xffffffff
  147. stw r0, [r1+], #0x20 /*interrupt enable clear*/
  148. stw r0, [r1+], #0x24
  149. /*remap ddr to 0x00000000 address*/
  150. ldw r1, =SEP6200_SYSCTL_BASE
  151. ldw r0, [r1+]
  152. ldw r2, =0x80000000
  153. or r0, r0, r2
  154. stw r2, [r1+]
  155. /* set interrupt vector */
  156. /*do nothing here for vector*/
  157. /* setup stack */
  158. b.l stack_setup
  159. /* copy the vector code to address 0 */
  160. ldw r12, =0x100
  161. ldw r0, = 0x40000000
  162. ldw r1, = 0x00000000
  163. copy_vetor:
  164. ldw r2, [r0]
  165. stw r2, [r1]
  166. add r0, r0, #4
  167. add r1, r1, #4
  168. sub r12, r12, #4
  169. cmpsub.a r12, #0
  170. bne copy_vetor
  171. /* clear .bss */
  172. ldw r0, _bss_start /* bss start */
  173. ldw r1, _bss_end /* bss end */
  174. mov r2,#0 /* get a zero */
  175. bss_loop:
  176. stw r2, [r0] @ clear loop...
  177. add r0, r0, #4
  178. cmpsub.a r0, r1
  179. bel bss_loop
  180. /* call C++ constructors of global objects */
  181. ldw r0, =__ctors_start__
  182. ldw r1, =__ctors_end__
  183. ctor_loop:
  184. cmpsub.a r0, r1
  185. beq ctor_end
  186. ldw.w r2, [r0]+, #4
  187. stm.w (r0, r1), [sp-]
  188. add lr, pc, #4
  189. mov pc, r2
  190. ldm.w (r0, r1), [sp]+
  191. b ctor_loop
  192. ctor_end:
  193. /*enable interrupt*/
  194. mov r0, asr
  195. andn r1, r0, #NOINT
  196. mov.a asr, r1
  197. /* start RT-Thread Kernel */
  198. ldw pc, _rtthread_startup
  199. _rtthread_startup:
  200. .word rtthread_startup
  201. /*
  202. *************************************************************************
  203. *
  204. * Interrupt handling
  205. *
  206. *************************************************************************
  207. */
  208. /* exception handlers */
  209. /*Just simple implementation here */
  210. .align 5
  211. extend_handle:
  212. b rt_hw_trap_extn
  213. swi_handle:
  214. b rt_hw_trap_swi
  215. iabort_handle:
  216. b rt_hw_trap_pabt
  217. dabort_handle:
  218. b rt_hw_trap_dabt
  219. reserve_handle:
  220. b rt_hw_trap_resv
  221. .globl rt_interrupt_enter
  222. .globl rt_interrupt_leave
  223. .globl rt_thread_switch_interrupt_flag
  224. .globl rt_interrupt_from_thread
  225. .globl rt_interrupt_to_thread
  226. IRQ_handle:
  227. stm.w (lr), [sp-]
  228. stm.w (r16 - r28), [sp-]
  229. stm.w (r0 - r15), [sp-]
  230. b.l rt_interrupt_enter
  231. b.l rt_hw_trap_irq
  232. b.l rt_interrupt_leave
  233. /* if rt_thread_switch_interrupt_flag set, jump to _interrupt_thread_switch and don't return */
  234. ldw r0, =rt_thread_switch_interrupt_flag
  235. ldw r1, [r0+]
  236. cmpsub.a r1, #1
  237. beq _interrupt_thread_switch
  238. ldm.w (r0 - r15), [sp]+
  239. ldm.w (r16 - r28), [sp]+
  240. ldm.w (lr), [sp]+
  241. mov.a pc, lr
  242. .align 5
  243. FIQ_handle:
  244. b rt_hw_trap_fiq
  245. _interrupt_thread_switch:
  246. mov r1, #0 /* clear rt_thread_switch_interrupt_flag*/
  247. stw r1, [r0+]
  248. /*reload register*/
  249. ldm.w (r0 - r15), [sp]+
  250. ldm.w (r16 - r28), [sp]+
  251. ldm.w (lr), [sp]+
  252. stm.w (r0 - r3), [sp-] /*save r0-r3*/
  253. mov r1, sp
  254. add sp, sp, #16 /* restore sp */
  255. mov r2, lr /* save old task's pc to r2 */
  256. mov r3, bsr
  257. mov r0, #0xd3 /*I:F:0:PRIV*/
  258. mov.a asr, r0
  259. stm.w (r2), [sp-] /* push old task's pc */
  260. /* push old task's registers */
  261. stm.w (lr), [sp-]
  262. stm.w (r16 - r28), [sp-]
  263. stm.w (r4 - r15), [sp-]
  264. mov r4, r1 /* Special optimised code below */
  265. mov r5, r3
  266. ldm.w (r0 - r3), [r4]+
  267. stm.w (r0 - r3), [sp-] /*push old task's r3-r0*/
  268. stm.w (r5), [sp-] /* push old task's asr */
  269. mov r4, bsr
  270. stm.w (r4), [sp-] /* push old task's bsr*/
  271. ldw r4, =rt_interrupt_from_thread
  272. ldw r5, [r4+]
  273. stw sp, [r5+] /* store sp in preempted tasks's TCB*/
  274. ldw r6, =rt_interrupt_to_thread
  275. ldw r6, [r6+]
  276. ldw sp, [r6+] /* get new task's stack pointer */
  277. ldm.w (r4), [sp]+ /* pop new task's spsr */
  278. mov.a bsr, r4
  279. ldm.w (r4), [sp]+ /* pop new task's psr */
  280. mov.a asr, r4
  281. /* pop new task's r0-r28,lr & pc */
  282. ldm.w (r0 - r15), [sp]+
  283. ldm.w (r16 - r28), [sp]+
  284. ldm.w (lr), [sp]+
  285. ldm.w (pc), [sp]+
  286. stack_setup:
  287. /*irq*/
  288. mov ip, lr
  289. mov r0, asr
  290. andn r0, r0, #0x1f
  291. or r0, r0, #IRQMODE|NOINT
  292. mov.a asr, r0 /*IRQMODE*/
  293. ldw r0, =IRQ_STACK_START
  294. ldw sp, [r0+]
  295. /*ldw sp, IRQ_STACK_START*/
  296. /*priv*/
  297. mov r0, asr
  298. andn r0, r0, #0x1f
  299. or r0, r0, #PRIVMODE|NOINT
  300. mov.a asr, r0 /*PRIVMODE*/
  301. ldw r0, =_STACK_START
  302. ldw sp, [r0+]
  303. /*ldw sp, _STACK_START*/
  304. mov lr, ip
  305. /*fiq and other mode is not implemented in code here*/
  306. mov pc, lr /*lr may not be valid for the mode changes*/
  307. /*/*}*/