start_gcc.S 6.0 KB

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