start_gcc.S 9.0 KB

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