start_gcc.S 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275
  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. * 2006-08-31 Bernard first version
  9. */
  10. /* Internal Memory Base Addresses */
  11. .equ FLASH_BASE, 0x00100000
  12. .equ RAM_BASE, 0x00200000
  13. /* Stack Configuration */
  14. .equ TOP_STACK, 0x00204000
  15. .equ UND_STACK_SIZE, 0x00000100
  16. .equ SVC_STACK_SIZE, 0x00000400
  17. .equ ABT_STACK_SIZE, 0x00000100
  18. .equ FIQ_STACK_SIZE, 0x00000100
  19. .equ IRQ_STACK_SIZE, 0x00000100
  20. .equ USR_STACK_SIZE, 0x00000004
  21. /* ARM architecture definitions */
  22. .equ MODE_USR, 0x10
  23. .equ MODE_FIQ, 0x11
  24. .equ MODE_IRQ, 0x12
  25. .equ MODE_SVC, 0x13
  26. .equ MODE_ABT, 0x17
  27. .equ MODE_UND, 0x1B
  28. .equ MODE_SYS, 0x1F
  29. .equ I_BIT, 0x80 /* when this bit is set, IRQ is disabled */
  30. .equ F_BIT, 0x40 /* when this bit is set, FIQ is disabled */
  31. .section .init, "ax"
  32. .code 32
  33. .align 0
  34. .globl _start
  35. _start:
  36. b reset
  37. ldr pc, _vector_undef
  38. ldr pc, _vector_swi
  39. ldr pc, _vector_pabt
  40. ldr pc, _vector_dabt
  41. nop /* reserved vector */
  42. ldr pc, _vector_irq
  43. ldr pc, _vector_fiq
  44. _vector_undef: .word vector_undef
  45. _vector_swi: .word vector_swi
  46. _vector_pabt: .word vector_pabt
  47. _vector_dabt: .word vector_dabt
  48. _vector_resv: .word vector_resv
  49. _vector_irq: .word vector_irq
  50. _vector_fiq: .word vector_fiq
  51. /*
  52. * rtthread bss start and end
  53. * which are defined in linker script
  54. */
  55. .globl _bss_start
  56. _bss_start: .word __bss_start
  57. .globl _bss_end
  58. _bss_end: .word __bss_end
  59. /* the system entry */
  60. reset:
  61. /* disable watchdog */
  62. ldr r0, =0xFFFFFD40
  63. ldr r1, =0x00008000
  64. str r1, [r0, #0x04]
  65. /* enable the main oscillator */
  66. ldr r0, =0xFFFFFC00
  67. ldr r1, =0x00000601
  68. str r1, [r0, #0x20]
  69. /* wait for main oscillator to stabilize */
  70. moscs_loop:
  71. ldr r2, [r0, #0x68]
  72. ands r2, r2, #1
  73. beq moscs_loop
  74. /* set up the PLL */
  75. ldr r1, =0x00191C05
  76. str r1, [r0, #0x2C]
  77. /* wait for PLL to lock */
  78. pll_loop:
  79. ldr r2, [r0, #0x68]
  80. ands r2, r2, #0x04
  81. beq pll_loop
  82. /* select clock */
  83. ldr r1, =0x00000007
  84. str r1, [r0, #0x30]
  85. #ifdef __FLASH_BUILD__
  86. /* copy exception vectors into internal sram */
  87. /*
  88. mov r8, #RAM_BASE
  89. ldr r9, =_start
  90. ldmia r9!, {r0-r7}
  91. stmia r8!, {r0-r7}
  92. ldmia r9!, {r0-r6}
  93. stmia r8!, {r0-r6}
  94. */
  95. #endif
  96. /* setup stack for each mode */
  97. ldr r0, =TOP_STACK
  98. /* set stack */
  99. /* undefined instruction mode */
  100. msr cpsr_c, #MODE_UND|I_BIT|F_BIT
  101. mov sp, r0
  102. sub r0, r0, #UND_STACK_SIZE
  103. /* abort mode */
  104. msr cpsr_c, #MODE_ABT|I_BIT|F_BIT
  105. mov sp, r0
  106. sub r0, r0, #ABT_STACK_SIZE
  107. /* FIQ mode */
  108. msr cpsr_c, #MODE_FIQ|I_BIT|F_BIT
  109. mov sp, r0
  110. sub r0, r0, #FIQ_STACK_SIZE
  111. /* IRQ mode */
  112. msr cpsr_c, #MODE_IRQ|I_BIT|F_BIT
  113. mov sp, r0
  114. sub r0, r0, #IRQ_STACK_SIZE
  115. /* supervisor mode */
  116. msr cpsr_c, #MODE_SVC|I_BIT|F_BIT
  117. mov sp, r0
  118. /* remap SRAM to 0x0000 */
  119. /*
  120. ldr r0, =0xFFFFFF00
  121. mov r1, #0x01
  122. str r1, [r0]
  123. */
  124. /* mask all IRQs */
  125. ldr r1, =0xFFFFF124
  126. ldr r0, =0XFFFFFFFF
  127. str r0, [r1]
  128. /* copy .data to SRAM */
  129. ldr r1, =_sidata /* .data start in image */
  130. ldr r2, =_edata /* .data end in image */
  131. ldr r3, =_sdata /* sram data start */
  132. data_loop:
  133. ldr r0, [r1, #0]
  134. str r0, [r3]
  135. add r1, r1, #4
  136. add r3, r3, #4
  137. cmp r3, r2 /* check if data to clear */
  138. blo data_loop /* loop until done */
  139. /* clear .bss */
  140. mov r0,#0 /* get a zero */
  141. ldr r1,=__bss_start /* bss start */
  142. ldr r2,=__bss_end /* bss end */
  143. bss_loop:
  144. cmp r1,r2 /* check if data to clear */
  145. strlo r0,[r1],#4 /* clear 4 bytes */
  146. blo bss_loop /* loop until done */
  147. /* call C++ constructors of global objects */
  148. ldr r0, =__ctors_start__
  149. ldr r1, =__ctors_end__
  150. ctor_loop:
  151. cmp r0, r1
  152. beq ctor_end
  153. ldr r2, [r0], #4
  154. stmfd sp!, {r0-r1}
  155. mov lr, pc
  156. bx r2
  157. ldmfd sp!, {r0-r1}
  158. b ctor_loop
  159. ctor_end:
  160. /* start RT-Thread Kernel */
  161. ldr pc, _rtthread_startup
  162. _rtthread_startup: .word rtthread_startup
  163. /* exception handlers */
  164. vector_undef: b vector_undef
  165. vector_swi : b vector_swi
  166. vector_pabt : b vector_pabt
  167. vector_dabt : b vector_dabt
  168. vector_resv : b vector_resv
  169. .globl rt_interrupt_enter
  170. .globl rt_interrupt_leave
  171. .globl rt_thread_switch_interrupt_flag
  172. .globl rt_interrupt_from_thread
  173. .globl rt_interrupt_to_thread
  174. vector_irq:
  175. stmfd sp!, {r0-r12,lr}
  176. bl rt_interrupt_enter
  177. bl rt_hw_trap_irq
  178. bl rt_interrupt_leave
  179. /*
  180. * if rt_thread_switch_interrupt_flag set, jump to
  181. * rt_hw_context_switch_interrupt_do and don't return
  182. */
  183. ldr r0, =rt_thread_switch_interrupt_flag
  184. ldr r1, [r0]
  185. cmp r1, #1
  186. beq rt_hw_context_switch_interrupt_do
  187. ldmfd sp!, {r0-r12,lr}
  188. subs pc, lr, #4
  189. vector_fiq:
  190. stmfd sp!,{r0-r7,lr}
  191. bl rt_hw_trap_fiq
  192. ldmfd sp!,{r0-r7,lr}
  193. subs pc,lr,#4
  194. /*
  195. * void rt_hw_context_switch_interrupt_do(rt_base_t flag)
  196. */
  197. rt_hw_context_switch_interrupt_do:
  198. mov r1, #0 @ clear flag
  199. str r1, [r0]
  200. ldmfd sp!, {r0-r12,lr}@ reload saved registers
  201. stmfd sp!, {r0-r3} @ save r0-r3
  202. mov r1, sp
  203. add sp, sp, #16 @ restore sp
  204. sub r2, lr, #4 @ save old task's pc to r2
  205. mrs r3, spsr @ disable interrupt
  206. orr r0, r3, #I_BIT|F_BIT
  207. msr spsr_c, r0
  208. ldr r0, =.+8 @ switch to interrupted task's stack
  209. movs pc, r0
  210. stmfd sp!, {r2} @ push old task's pc
  211. stmfd sp!, {r4-r12,lr}@ push old task's lr,r12-r4
  212. mov r4, r1 @ Special optimised code below
  213. mov r5, r3
  214. ldmfd r4!, {r0-r3}
  215. stmfd sp!, {r0-r3} @ push old task's r3-r0
  216. stmfd sp!, {r5} @ push old task's psr
  217. mrs r4, spsr
  218. stmfd sp!, {r4} @ push old task's spsr
  219. ldr r4, =rt_interrupt_from_thread
  220. ldr r5, [r4]
  221. str sp, [r5] @ store sp in preempted tasks's TCB
  222. ldr r6, =rt_interrupt_to_thread
  223. ldr r6, [r6]
  224. ldr sp, [r6] @ get new task's stack pointer
  225. ldmfd sp!, {r4} @ pop new task's spsr
  226. msr SPSR_cxsf, r4
  227. ldmfd sp!, {r4} @ pop new task's psr
  228. msr CPSR_cxsf, r4
  229. ldmfd sp!, {r0-r12,lr,pc} @ pop new task's r0-r12,lr & pc