start_gcc.S 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237
  1. /*
  2. * File : start_gcc.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://www.rt-thread.org/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. /* setup stack for each mode */
  90. ldr r0, =TOP_STACK
  91. /* set stack */
  92. /* undefined instruction mode */
  93. msr cpsr_c, #MODE_UND|I_BIT|F_BIT
  94. mov sp, r0
  95. sub r0, r0, #UND_STACK_SIZE
  96. /* abort mode */
  97. msr cpsr_c, #MODE_ABT|I_BIT|F_BIT
  98. mov sp, r0
  99. sub r0, r0, #ABT_STACK_SIZE
  100. /* FIQ mode */
  101. msr cpsr_c, #MODE_FIQ|I_BIT|F_BIT
  102. mov sp, r0
  103. sub r0, r0, #FIQ_STACK_SIZE
  104. /* IRQ mode */
  105. msr cpsr_c, #MODE_IRQ|I_BIT|F_BIT
  106. mov sp, r0
  107. sub r0, r0, #IRQ_STACK_SIZE
  108. /* supervisor mode */
  109. msr cpsr_c, #MODE_SVC
  110. mov sp, r0
  111. #ifdef __FLASH_BUILD__
  112. /* Relocate .data section (Copy from ROM to RAM) */
  113. ldr r1, =_etext
  114. ldr r2, =_data
  115. ldr r3, =_edata
  116. data_loop:
  117. cmp r2, r3
  118. ldrlo r0, [r1], #4
  119. strlo r0, [r2], #4
  120. blo data_loop
  121. #else
  122. /* remap SRAM to 0x0000 */
  123. ldr r0, =0xFFFFFF00
  124. mov r1, #0x01
  125. str r1, [r0]
  126. #endif
  127. /* mask all IRQs */
  128. ldr r1, =0xFFFFF124
  129. ldr r0, =0XFFFFFFFF
  130. str r0, [r1]
  131. /* start RT-Thread Kernel */
  132. ldr pc, _rtthread_startup
  133. _rtthread_startup: .word rtthread_startup
  134. /* exception handlers */
  135. vector_undef: b vector_undef
  136. vector_swi : b vector_swi
  137. vector_pabt : b vector_pabt
  138. vector_dabt : b vector_dabt
  139. vector_resv : b vector_resv
  140. .globl rt_interrupt_enter
  141. .globl rt_interrupt_leave
  142. .globl rt_thread_switch_interrput_flag
  143. .globl rt_interrupt_from_thread
  144. .globl rt_interrupt_to_thread
  145. vector_irq:
  146. stmfd sp!, {r0-r12,lr}
  147. bl rt_interrupt_enter
  148. bl rt_hw_trap_irq
  149. bl rt_interrupt_leave
  150. /*
  151. * if rt_thread_switch_interrput_flag set, jump to
  152. * rt_hw_context_switch_interrupt_do and don't return
  153. */
  154. ldr r0, =rt_thread_switch_interrput_flag
  155. ldr r1, [r0]
  156. cmp r1, #1
  157. beq rt_hw_context_switch_interrupt_do
  158. ldmfd sp!, {r0-r12,lr}
  159. subs pc, lr, #4
  160. vector_fiq:
  161. stmfd sp!,{r0-r7,lr}
  162. bl rt_hw_trap_fiq
  163. ldmfd sp!,{r0-r7,lr}
  164. subs pc,lr,#4
  165. /*
  166. * void rt_hw_context_switch_interrupt_do(rt_base_t flag)
  167. */
  168. rt_hw_context_switch_interrupt_do:
  169. mov r1, #0 /* clear flag */
  170. str r1, [r0]
  171. ldmfd sp!, {r0-r12,lr} /* reload saved registers */
  172. stmfd sp!, {r0-r3} /* save r0-r3 */
  173. mov r1, sp
  174. add sp, sp, #16 /* restore sp */
  175. sub r2, lr, #4 /* save old task's pc to r2 */
  176. mrs r3, spsr /* disable interrupt */
  177. orr r0, r3, #I_BIT|F_BIT
  178. msr spsr_c, r0
  179. ldr r0, =.+8 /* switch to interrupted task's stack */
  180. movs pc, r0
  181. stmfd sp!, {r2} /* push old task's pc */
  182. stmfd sp!, {r4-r12,lr} /* push old task's lr,r12-r4 */
  183. mov r4, r1 /* Special optimised code below */
  184. mov r5, r3
  185. ldmfd r4!, {r0-r3}
  186. stmfd sp!, {r0-r3} /* push old task's r3-r0 */
  187. stmfd sp!, {r5} /* push old task's psr */
  188. mrs r4, spsr
  189. stmfd sp!, {r4} /* push old task's spsr */
  190. ldr r4, =rt_interrupt_from_thread
  191. ldr r5, [r4]
  192. str sp, [r5] /* store sp in preempted tasks's TCB */
  193. ldr r6, =rt_interrupt_to_thread
  194. ldr r6, [r6]
  195. ldr sp, [r6] /* get new task's stack pointer */
  196. ldmfd sp!, {r4} /* pop new task's spsr */
  197. msr SPSR_cxsf, r4
  198. ldmfd sp!, {r4} /* pop new task's psr */
  199. msr CPSR_cxsf, r4
  200. ldmfd sp!, {r0-r12,lr,pc} /* pop new task's r0-r12,lr & pc */