start_gcc.S 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257
  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-09-06 XuXinming first version
  13. * 2006-09-20 Bernard clean the code
  14. */
  15. /**
  16. * @addtogroup S3C44B0
  17. */
  18. /*@{*/
  19. .section .init, "ax"
  20. .code 32
  21. .globl _start
  22. _start:
  23. b reset
  24. ldr pc, _vector_undef
  25. ldr pc, _vector_swi
  26. ldr pc, _vector_pabt
  27. ldr pc, _vector_dabt
  28. ldr pc, _vector_resv
  29. ldr pc, _vector_irq
  30. ldr pc, _vector_fiq
  31. _vector_undef: .word vector_undef
  32. _vector_swi: .word vector_swi
  33. _vector_pabt: .word vector_pabt
  34. _vector_dabt: .word vector_dabt
  35. _vector_resv: .word vector_resv
  36. _vector_irq: .word vector_irq
  37. _vector_fiq: .word vector_fiq
  38. .text
  39. .code 32
  40. /*
  41. * rtthread kernel start and end
  42. * which are defined in linker script
  43. */
  44. .globl _rtthread_start
  45. _rtthread_start:.word _start
  46. .globl _rtthread_end
  47. _rtthread_end: .word _end
  48. /*
  49. * rtthread bss start and end
  50. * which are defined in linker script
  51. */
  52. .globl _bss_start
  53. _bss_start: .word __bss_start
  54. .globl _bss_end
  55. _bss_end: .word __bss_end
  56. #if defined(__FLASH_BUILD__)
  57. /*
  58. * TEXT_BASE,
  59. * which is defined in macro of make
  60. */
  61. _TEXT_BASE: .word TEXT_BASE
  62. #endif
  63. .equ WTCON, 0x1d30000
  64. .equ INTCON, 0x1e00000
  65. .equ INTMSK, 0x1e0000c
  66. /* the system entry */
  67. reset:
  68. /* enter svc mode */
  69. msr cpsr_c, #SVCMODE|NOINT
  70. /*watch dog disable */
  71. ldr r0,=WTCON
  72. ldr r1,=0x0
  73. str r1,[r0]
  74. /* all interrupt disable */
  75. ldr r0,=INTMSK
  76. ldr r1,=0x07ffffff
  77. str r1,[r0]
  78. ldr r1, =INTCON
  79. ldr r0, =0x05
  80. str r0, [r1]
  81. #if defined(__FLASH_BUILD__)
  82. /* init lowlevel */
  83. bl lowlevel_init
  84. #endif
  85. /* setup stack */
  86. bl stack_setup
  87. #if defined(__FLASH_BUILD__)
  88. mov r0, #0x0 /* r0 <- flash base address */
  89. ldr r1, _TEXT_BASE /* r1 <- the taget address */
  90. ldr r2, _rtthread_start
  91. ldr r3, _bss_start
  92. sub r2, r3, r2 /* r2 <- size of rtthread kernel */
  93. add r2, r0, r2 /* r2 <- source end address */
  94. copy_loop:
  95. ldmia r0!, {r3-r10} /* copy from source address [r0] */
  96. stmia r1!, {r3-r10} /* copy to target address [r1] */
  97. cmp r0, r2 /* until source end addreee [r2] */
  98. ble copy_loop
  99. #endif
  100. /* start RT-Thread Kernel */
  101. ldr pc, _rtthread_startup
  102. _rtthread_startup: .word rtthread_startup
  103. .equ USERMODE, 0x10
  104. .equ FIQMODE, 0x11
  105. .equ IRQMODE, 0x12
  106. .equ SVCMODE, 0x13
  107. .equ ABORTMODE, 0x17
  108. .equ UNDEFMODE, 0x1b
  109. .equ MODEMASK, 0x1f
  110. .equ NOINT, 0xc0
  111. /* exception handlers */
  112. vector_undef: bl rt_hw_trap_udef
  113. vector_swi: bl rt_hw_trap_swi
  114. vector_pabt: bl rt_hw_trap_pabt
  115. vector_dabt: bl rt_hw_trap_dabt
  116. vector_resv: bl rt_hw_trap_resv
  117. .globl rt_interrupt_enter
  118. .globl rt_interrupt_leave
  119. .globl rt_thread_switch_interrput_flag
  120. .globl rt_interrupt_from_thread
  121. .globl rt_interrupt_to_thread
  122. vector_irq:
  123. stmfd sp!, {r0-r12,lr}
  124. bl led_off
  125. bl rt_interrupt_enter
  126. bl rt_hw_trap_irq
  127. bl rt_interrupt_leave
  128. /* if rt_thread_switch_interrput_flag set, jump to _interrupt_thread_switch and don't return */
  129. ldr r0, =rt_thread_switch_interrput_flag
  130. ldr r1, [r0]
  131. cmp r1, #1
  132. beq _interrupt_thread_switch
  133. ldmfd sp!, {r0-r12,lr}
  134. subs pc, lr, #4
  135. .align 5
  136. vector_fiq:
  137. stmfd sp!,{r0-r7,lr}
  138. bl rt_hw_trap_fiq
  139. ldmfd sp!,{r0-r7,lr}
  140. subs pc,lr,#4
  141. _interrupt_thread_switch:
  142. mov r1, #0 @ clear rt_thread_switch_interrput_flag
  143. str r1, [r0]
  144. ldmfd sp!, {r0-r12,lr} @ reload saved registers
  145. stmfd sp!, {r0-r3} @ save r0-r3
  146. mov r1, sp
  147. add sp, sp, #16 @ restore sp
  148. sub r2, lr, #4 @ save old task's pc to r2
  149. mrs r3, spsr @ disable interrupt
  150. orr r0, r3, #NOINT
  151. msr spsr_c, r0
  152. ldr r0, =.+8 @ switch to interrupted task's stack
  153. movs pc, r0
  154. stmfd sp!, {r2} @ push old task's pc
  155. stmfd sp!, {r4-r12,lr} @ push old task's lr,r12-r4
  156. mov r4, r1 @ Special optimised code below
  157. mov r5, r3
  158. ldmfd r4!, {r0-r3}
  159. stmfd sp!, {r0-r3} @ push old task's r3-r0
  160. stmfd sp!, {r5} @ push old task's psr
  161. mrs r4, spsr
  162. stmfd sp!, {r4} @ push old task's spsr
  163. ldr r4, =rt_interrupt_from_thread
  164. ldr r5, [r4]
  165. str sp, [r5] @ store sp in preempted tasks's TCB
  166. ldr r6, =rt_interrupt_to_thread
  167. ldr r6, [r6]
  168. ldr sp, [r6] @ get new task's stack pointer
  169. ldmfd sp!, {r4} @ pop new task's spsr
  170. msr SPSR_cxsf, r4
  171. ldmfd sp!, {r4} @ pop new task's psr
  172. msr CPSR_cxsf, r4
  173. ldmfd sp!, {r0-r12,lr,pc} @ pop new task's r0-r12,lr & pc
  174. /* each mode stack memory */
  175. UNDSTACK_START: .word _undefined_stack_start + 128
  176. ABTSTACK_START: .word _abort_stack_start + 128
  177. FIQSTACK_START: .word _fiq_stack_start + 1024
  178. IRQSTACK_START: .word _irq_stack_start + 1024
  179. SVCSTACK_START: .word _svc_stack_start + 4096
  180. stack_setup:
  181. /* undefined instruction mode */
  182. msr cpsr_c, #UNDEFMODE|NOINT
  183. ldr sp, UNDSTACK_START
  184. /* abort mode */
  185. msr cpsr_c, #ABORTMODE|NOINT
  186. ldr sp, ABTSTACK_START
  187. /* FIQ mode */
  188. msr cpsr_c, #FIQMODE|NOINT
  189. ldr sp, FIQSTACK_START
  190. /* IRQ mode */
  191. msr cpsr_c, #IRQMODE|NOINT
  192. ldr sp, IRQSTACK_START
  193. /* supervisor mode */
  194. msr cpsr_c, #SVCMODE|NOINT
  195. ldr sp, SVCSTACK_START
  196. mov pc,lr @ The LR register may be not valid for the mode changes.
  197. .globl led_on
  198. led_on:
  199. ldr r1, =0x1d20014 @ r1<-PDATC
  200. ldr r0, [r1] @ r0<-[r1]
  201. orr r0, r0, #0x0e @ r0=r0 or 0x0e
  202. str r0, [r1] @ r0->[r1]
  203. mov pc, lr
  204. .globl led_off
  205. led_off:
  206. ldr r1, =0x1d20010 @ r1<-PCONC
  207. ldr r0, =0x5f555555 @ r0<-0x5f555555
  208. str r0, [r1] @ r0->[r1]
  209. ldr r1, =0x1d20014 @ r1<-PDATC
  210. ldr r0, =0x0 @ r0<-00
  211. str r0, [r1] @ r0->[r1]
  212. mov pc, lr