start_gcc.S 8.2 KB

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