1
0

start_gcc.S 5.7 KB

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