start_gcc.S 5.1 KB

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