start_gcc.S 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385
  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. * 2011-01-13 weety first version
  13. */
  14. #define CONFIG_STACKSIZE 512
  15. #define S_FRAME_SIZE 72
  16. #define S_OLD_R0 68
  17. #define S_PSR 64
  18. #define S_PC 60
  19. #define S_LR 56
  20. #define S_SP 52
  21. #define S_IP 48
  22. #define S_FP 44
  23. #define S_R10 40
  24. #define S_R9 36
  25. #define S_R8 32
  26. #define S_R7 28
  27. #define S_R6 24
  28. #define S_R5 20
  29. #define S_R4 16
  30. #define S_R3 12
  31. #define S_R2 8
  32. #define S_R1 4
  33. #define S_R0 0
  34. .equ USERMODE, 0x10
  35. .equ FIQMODE, 0x11
  36. .equ IRQMODE, 0x12
  37. .equ SVCMODE, 0x13
  38. .equ ABORTMODE, 0x17
  39. .equ UNDEFMODE, 0x1b
  40. .equ MODEMASK, 0x1f
  41. .equ NOINT, 0xc0
  42. .equ RAM_BASE, 0x00000000 /*Start address of RAM */
  43. .equ ROM_BASE, 0x20000000 /*Start address of Flash */
  44. #define AT91_RSTC_PROCRST (1 << 0) /* Processor Reset */
  45. #define AT91_RSTC_PERRST (1 << 2)
  46. #define AT91_RSTC_KEY (0xa5 << 24)
  47. #define AT91_MATRIX_BASE 0xffffee00
  48. #define AT91_MATRIX_MRCR (AT91_MATRIX_BASE + 0x100) /* Master Remap Control Register */
  49. #define AT91_MATRIX_RCB0 (1 << 0) /* Remap Command for AHB Master 0 (ARM926EJ-S Instruction Master) */
  50. #define AT91_MATRIX_RCB1 (1 << 1) /* Remap Command for AHB Master 1 (ARM926EJ-S Data Master) */
  51. #define AT91_AIC_BASE 0xfffff000
  52. #define AT91_AIC_IDCR 0x124 /* Interrupt Disable Command Register */
  53. #define AT91_AIC_ICCR 0x128 /* Interrupt Clear Command Register */
  54. /*
  55. *************************************************************************
  56. *
  57. * Jump vector table
  58. *
  59. *************************************************************************
  60. */
  61. .section .init, "ax"
  62. .code 32
  63. .globl _start
  64. _start:
  65. b reset
  66. ldr pc, _vector_undef
  67. ldr pc, _vector_swi
  68. ldr pc, _vector_pabt
  69. ldr pc, _vector_dabt
  70. ldr pc, _vector_resv
  71. ldr pc, _vector_irq
  72. ldr pc, _vector_fiq
  73. _vector_undef: .word vector_undef
  74. _vector_swi: .word vector_swi
  75. _vector_pabt: .word vector_pabt
  76. _vector_dabt: .word vector_dabt
  77. _vector_resv: .word vector_resv
  78. _vector_irq: .word vector_irq
  79. _vector_fiq: .word vector_fiq
  80. .balignl 16,0xdeadbeef
  81. /*
  82. *************************************************************************
  83. *
  84. * Startup Code (reset vector)
  85. * relocate armboot to ram
  86. * setup stack
  87. * jump to second stage
  88. *
  89. *************************************************************************
  90. */
  91. _TEXT_BASE:
  92. .word TEXT_BASE
  93. /*
  94. * rtthread kernel start and end
  95. * which are defined in linker script
  96. */
  97. .globl _rtthread_start
  98. _rtthread_start:
  99. .word _start
  100. .globl _rtthread_end
  101. _rtthread_end:
  102. .word _end
  103. /*
  104. * rtthread bss start and end which are defined in linker script
  105. */
  106. .globl _bss_start
  107. _bss_start:
  108. .word __bss_start
  109. .globl _bss_end
  110. _bss_end:
  111. .word __bss_end
  112. /* IRQ stack memory (calculated at run-time) */
  113. .globl IRQ_STACK_START
  114. IRQ_STACK_START:
  115. .word _irq_stack_start + 1024
  116. .globl FIQ_STACK_START
  117. FIQ_STACK_START:
  118. .word _fiq_stack_start + 1024
  119. .globl UNDEFINED_STACK_START
  120. UNDEFINED_STACK_START:
  121. .word _undefined_stack_start + CONFIG_STACKSIZE
  122. .globl ABORT_STACK_START
  123. ABORT_STACK_START:
  124. .word _abort_stack_start + CONFIG_STACKSIZE
  125. .globl _STACK_START
  126. _STACK_START:
  127. .word _svc_stack_start + 4096
  128. /* ----------------------------------entry------------------------------*/
  129. reset:
  130. /* set the cpu to SVC32 mode */
  131. mrs r0,cpsr
  132. bic r0,r0,#MODEMASK
  133. orr r0,r0,#SVCMODE
  134. msr cpsr,r0
  135. /* mask all IRQs by clearing all bits in the INTMRs */
  136. ldr r1, =AT91_AIC_BASE
  137. ldr r0, =0xffffffff
  138. str r0, [r1, #AT91_AIC_IDCR]
  139. str r0, [r1, #AT91_AIC_ICCR]
  140. /*remap internal ram to 0x00000000 address*/
  141. ldr r0, =AT91_MATRIX_MRCR
  142. ldr r1, =(AT91_MATRIX_RCB0|AT91_MATRIX_RCB1)
  143. str r1, [r0]
  144. /* set interrupt vector */
  145. #if 1
  146. ldr r0, _TEXT_BASE//_load_address
  147. //ldr r1, =0x200000 /* target address */
  148. mov r1, #0x00
  149. add r2, r0, #0x40 /* size, 32bytes */
  150. copy_loop:
  151. ldmia r0!, {r3-r10} /* copy from source address [r0] */
  152. stmia r1!, {r3-r10} /* copy to target address [r1] */
  153. cmp r0, r2 /* until source end addreee [r2] */
  154. ble copy_loop
  155. #endif
  156. /* setup stack */
  157. bl stack_setup
  158. /* clear .bss */
  159. mov r0,#0 /* get a zero */
  160. ldr r1,=__bss_start /* bss start */
  161. ldr r2,=__bss_end /* bss end */
  162. bss_loop:
  163. cmp r1,r2 /* check if data to clear */
  164. strlo r0,[r1],#4 /* clear 4 bytes */
  165. blo bss_loop /* loop until done */
  166. /* call C++ constructors of global objects */
  167. ldr r0, =__ctors_start__
  168. ldr r1, =__ctors_end__
  169. ctor_loop:
  170. cmp r0, r1
  171. beq ctor_end
  172. ldr r2, [r0], #4
  173. stmfd sp!, {r0-r1}
  174. mov lr, pc
  175. bx r2
  176. ldmfd sp!, {r0-r1}
  177. b ctor_loop
  178. ctor_end:
  179. /* start RT-Thread Kernel */
  180. ldr pc, _rtthread_startup
  181. _rtthread_startup:
  182. .word rtthread_startup
  183. #if defined (__FLASH_BUILD__)
  184. _load_address:
  185. .word ROM_BASE + _TEXT_BASE
  186. #else
  187. _load_address:
  188. .word RAM_BASE + _TEXT_BASE
  189. #endif
  190. .global cpu_reset
  191. cpu_reset:
  192. ldr r0, =0xfffffd00
  193. ldr r1, =(AT91_RSTC_KEY | AT91_RSTC_PROCRST | AT91_RSTC_PERRST)
  194. str r1, [r0]
  195. mov pc, lr
  196. /*
  197. *************************************************************************
  198. *
  199. * Interrupt handling
  200. *
  201. *************************************************************************
  202. */
  203. /* exception handlers */
  204. .align 5
  205. vector_undef:
  206. sub sp, sp, #S_FRAME_SIZE
  207. stmia sp, {r0 - r12} /* Calling r0-r12 */
  208. add r8, sp, #S_PC
  209. stmdb r8, {sp, lr}^ /* Calling SP, LR */
  210. str lr, [r8, #0] /* Save calling PC */
  211. mrs r6, spsr
  212. str r6, [r8, #4] /* Save CPSR */
  213. str r0, [r8, #8] /* Save OLD_R0 */
  214. mov r0, sp
  215. bl rt_hw_trap_udef
  216. .align 5
  217. vector_swi:
  218. bl rt_hw_trap_swi
  219. .align 5
  220. vector_pabt:
  221. bl rt_hw_trap_pabt
  222. .align 5
  223. vector_dabt:
  224. sub sp, sp, #S_FRAME_SIZE
  225. stmia sp, {r0 - r12} /* Calling r0-r12 */
  226. add r8, sp, #S_PC
  227. stmdb r8, {sp, lr}^ /* Calling SP, LR */
  228. str lr, [r8, #0] /* Save calling PC */
  229. mrs r6, spsr
  230. str r6, [r8, #4] /* Save CPSR */
  231. str r0, [r8, #8] /* Save OLD_R0 */
  232. mov r0, sp
  233. bl rt_hw_trap_dabt
  234. .align 5
  235. vector_resv:
  236. bl rt_hw_trap_resv
  237. .globl rt_interrupt_enter
  238. .globl rt_interrupt_leave
  239. .globl rt_thread_switch_interrput_flag
  240. .globl rt_interrupt_from_thread
  241. .globl rt_interrupt_to_thread
  242. vector_irq:
  243. stmfd sp!, {r0-r12,lr}
  244. bl rt_interrupt_enter
  245. bl rt_hw_trap_irq
  246. bl rt_interrupt_leave
  247. /* if rt_thread_switch_interrput_flag set, jump to _interrupt_thread_switch and don't return */
  248. ldr r0, =rt_thread_switch_interrput_flag
  249. ldr r1, [r0]
  250. cmp r1, #1
  251. beq _interrupt_thread_switch
  252. ldmfd sp!, {r0-r12,lr}
  253. subs pc, lr, #4
  254. .align 5
  255. vector_fiq:
  256. stmfd sp!,{r0-r7,lr}
  257. bl rt_hw_trap_fiq
  258. ldmfd sp!,{r0-r7,lr}
  259. subs pc,lr,#4
  260. _interrupt_thread_switch:
  261. mov r1, #0 /* clear rt_thread_switch_interrput_flag*/
  262. str r1, [r0]
  263. ldmfd sp!, {r0-r12,lr} /* reload saved registers */
  264. stmfd sp!, {r0-r3} /* save r0-r3 */
  265. mov r1, sp
  266. add sp, sp, #16 /* restore sp */
  267. sub r2, lr, #4 /* save old task's pc to r2 */
  268. mrs r3, spsr /* disable interrupt */
  269. orr r0, r3, #NOINT
  270. msr spsr_c, r0
  271. ldr r0, =.+8 /* switch to interrupted task's stack*/
  272. movs pc, r0
  273. stmfd sp!, {r2} /* push old task's pc */
  274. stmfd sp!, {r4-r12,lr} /* push old task's lr,r12-r4 */
  275. mov r4, r1 /* Special optimised code below */
  276. mov r5, r3
  277. ldmfd r4!, {r0-r3}
  278. stmfd sp!, {r0-r3} /* push old task's r3-r0 */
  279. stmfd sp!, {r5} /* push old task's psr */
  280. mrs r4, spsr
  281. stmfd sp!, {r4} /* push old task's spsr */
  282. ldr r4, =rt_interrupt_from_thread
  283. ldr r5, [r4]
  284. str sp, [r5] /* store sp in preempted tasks's TCB*/
  285. ldr r6, =rt_interrupt_to_thread
  286. ldr r6, [r6]
  287. ldr sp, [r6] /* get new task's stack pointer */
  288. ldmfd sp!, {r4} /* pop new task's spsr */
  289. msr SPSR_cxsf, r4
  290. ldmfd sp!, {r4} /* pop new task's psr */
  291. msr CPSR_cxsf, r4
  292. ldmfd sp!, {r0-r12,lr,pc} /* pop new task's r0-r12,lr & pc */
  293. stack_setup:
  294. mrs r0, cpsr
  295. bic r0, r0, #MODEMASK
  296. orr r1, r0, #UNDEFMODE|NOINT
  297. msr cpsr_cxsf, r1 /* undef mode */
  298. ldr sp, UNDEFINED_STACK_START
  299. orr r1,r0,#ABORTMODE|NOINT
  300. msr cpsr_cxsf,r1 /* abort mode */
  301. ldr sp, ABORT_STACK_START
  302. orr r1,r0,#IRQMODE|NOINT
  303. msr cpsr_cxsf,r1 /* IRQ mode */
  304. ldr sp, IRQ_STACK_START
  305. orr r1,r0,#FIQMODE|NOINT
  306. msr cpsr_cxsf,r1 /* FIQ mode */
  307. ldr sp, FIQ_STACK_START
  308. bic r0,r0,#MODEMASK
  309. orr r1,r0,#SVCMODE|NOINT
  310. msr cpsr_cxsf,r1 /* SVC mode */
  311. ldr sp, _STACK_START
  312. /* USER mode is not initialized. */
  313. mov pc,lr /* The LR register may be not valid for the mode changes.*/
  314. /*/*}*/