start_gcc.S 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390
  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-03-13 Bernard first version
  13. * 2006-10-05 Alsor.Z for s3c2440 initialize
  14. * 2008-01-29 Yi.Qiu for QEMU emulator
  15. */
  16. #define CONFIG_STACKSIZE 512
  17. #define S_FRAME_SIZE 72
  18. #define S_OLD_R0 68
  19. #define S_PSR 64
  20. #define S_PC 60
  21. #define S_LR 56
  22. #define S_SP 52
  23. #define S_IP 48
  24. #define S_FP 44
  25. #define S_R10 40
  26. #define S_R9 36
  27. #define S_R8 32
  28. #define S_R7 28
  29. #define S_R6 24
  30. #define S_R5 20
  31. #define S_R4 16
  32. #define S_R3 12
  33. #define S_R2 8
  34. #define S_R1 4
  35. #define S_R0 0
  36. .equ USERMODE, 0x10
  37. .equ FIQMODE, 0x11
  38. .equ IRQMODE, 0x12
  39. .equ SVCMODE, 0x13
  40. .equ ABORTMODE, 0x17
  41. .equ UNDEFMODE, 0x1b
  42. .equ MODEMASK, 0x1f
  43. .equ NOINT, 0xc0
  44. .equ RAM_BASE, 0x00000000 /*Start address of RAM */
  45. .equ ROM_BASE, 0x30000000 /*Start address of Flash */
  46. .equ MPLLCON, 0x4c000004 /*Mpll control register */
  47. .equ M_MDIV, 0x20
  48. .equ M_PDIV, 0x4
  49. .equ M_SDIV, 0x2
  50. .equ INTMSK, 0x4a000008
  51. .equ INTSUBMSK, 0x4a00001c
  52. .equ WTCON, 0x53000000
  53. .equ LOCKTIME, 0x4c000000
  54. .equ CLKDIVN, 0x4c000014 /*Clock divider control */
  55. .equ GPHCON, 0x56000070 /*Port H control */
  56. .equ GPHUP, 0x56000078 /*Pull-up control H */
  57. .equ BWSCON, 0x48000000 /*Bus width & wait status */
  58. .equ BANKCON0, 0x48000004 /*Boot ROM control */
  59. .equ BANKCON1, 0x48000008 /*BANK1 control */
  60. .equ BANKCON2, 0x4800000c /*BANK2 cControl */
  61. .equ BANKCON3, 0x48000010 /*BANK3 control */
  62. .equ BANKCON4, 0x48000014 /*BANK4 control */
  63. .equ BANKCON5, 0x48000018 /*BANK5 control */
  64. .equ BANKCON6, 0x4800001c /*BANK6 control */
  65. .equ BANKCON7, 0x48000020 /*BANK7 control */
  66. .equ REFRESH, 0x48000024 /*DRAM/SDRAM efresh */
  67. .equ BANKSIZE, 0x48000028 /*Flexible Bank Size */
  68. .equ MRSRB6, 0x4800002c /*Mode egister set for SDRAM*/
  69. .equ MRSRB7, 0x48000030 /*Mode egister set for SDRAM*/
  70. /*
  71. *************************************************************************
  72. *
  73. * Jump vector table
  74. *
  75. *************************************************************************
  76. */
  77. .section .init, "ax"
  78. .code 32
  79. .globl _start
  80. _start:
  81. b reset
  82. ldr pc, _vector_undef
  83. ldr pc, _vector_swi
  84. ldr pc, _vector_pabt
  85. ldr pc, _vector_dabt
  86. ldr pc, _vector_resv
  87. ldr pc, _vector_irq
  88. ldr pc, _vector_fiq
  89. _vector_undef: .word vector_undef
  90. _vector_swi: .word vector_swi
  91. _vector_pabt: .word vector_pabt
  92. _vector_dabt: .word vector_dabt
  93. _vector_resv: .word vector_resv
  94. _vector_irq: .word vector_irq
  95. _vector_fiq: .word vector_fiq
  96. .balignl 16, 0xdeadbeef
  97. /*
  98. *************************************************************************
  99. *
  100. * Startup Code (reset vector)
  101. * relocate armboot to ram
  102. * setup stack
  103. * jump to second stage
  104. *
  105. *************************************************************************
  106. */
  107. _TEXT_BASE: /* TEXT_BASE was defined in rtconfig.py */
  108. .word TEXT_BASE
  109. /* rtthread kernel start and end which are defined in linker script */
  110. .globl _rtthread_start
  111. _rtthread_start:
  112. .word _start
  113. /* _end was defined in link script */
  114. .globl _rtthread_end
  115. _rtthread_end:
  116. .word _end
  117. /* rtthread bss start and end which are defined in linker script */
  118. .globl _bss_start
  119. _bss_start:
  120. .word __bss_start
  121. .globl _bss_end
  122. _bss_end:
  123. .word __bss_end
  124. /* IRQ stack memory (calculated at run-time) */
  125. .globl IRQ_STACK_START
  126. IRQ_STACK_START:
  127. .word _irq_stack_start + 1024
  128. .globl FIQ_STACK_START
  129. FIQ_STACK_START:
  130. .word _fiq_stack_start + 1024
  131. .globl UNDEFINED_STACK_START
  132. UNDEFINED_STACK_START:
  133. .word _undefined_stack_start + CONFIG_STACKSIZE
  134. .globl ABORT_STACK_START
  135. ABORT_STACK_START:
  136. .word _abort_stack_start + CONFIG_STACKSIZE
  137. .globl _STACK_START
  138. _STACK_START:
  139. .word _svc_stack_start + 4096
  140. .globl _load_address
  141. #if defined (__FLASH_BUILD__)
  142. _load_address:
  143. .word ROM_BASE + _TEXT_BASE
  144. #else
  145. _load_address:
  146. .word RAM_BASE + _TEXT_BASE
  147. #endif
  148. /*
  149. *************************************************************************
  150. * Actual start (entry point)
  151. *************************************************************************
  152. */
  153. reset:
  154. /* set the cpu to SVC32 mode */
  155. mrs r0, cpsr
  156. bic r0, r0,#MODEMASK
  157. orr r0, r0,#SVCMODE
  158. msr cpsr, r0
  159. /* watch dog disable */
  160. ldr r0, =WTCON
  161. ldr r1, =0x0
  162. str r1, [r0]
  163. /* mask all IRQs by clearing all bits in the INTMRs */
  164. ldr r1, =INTMSK
  165. ldr r0, =0xffffffff
  166. str r0, [r1]
  167. ldr r1, =INTSUBMSK
  168. ldr r0, =0x7fff /*all sub interrupt disable */
  169. str r0, [r1]
  170. /* set interrupt vector */
  171. ldr r0, _load_address /* _load_address = 0x30000000 */
  172. mov r1, #0x0 /* target address */
  173. add r2, r0, #0x20 /* size, 32bytes */
  174. copy_loop:
  175. ldmia r0!, {r3-r10} /* copy from source address [r0] */
  176. stmia r1!, {r3-r10} /* copy to target address [r1] */
  177. cmp r0, r2 /* until source end addreee [r2] */
  178. ble copy_loop
  179. bl stack_setup
  180. /* clear .bss */
  181. mov r0,#0 /* get a zero */
  182. ldr r1,=__bss_start /* bss start */
  183. ldr r2,=__bss_end /* bss end */
  184. bss_loop:
  185. cmp r1,r2 /* check if data to clear */
  186. strlo r0,[r1],#4 /* clear 4 bytes */
  187. blo bss_loop /* loop until done */
  188. /* call C++ constructors of global objects */
  189. ldr r0, =__ctors_start__
  190. ldr r1, =__ctors_end__
  191. ctor_loop:
  192. cmp r0, r1
  193. beq kernel_start
  194. ldr r2, [r0], #4
  195. stmfd sp!, {r0-r1}
  196. mov lr, pc
  197. bx r2
  198. ldmfd sp!, {r0-r1}
  199. b ctor_loop
  200. kernel_start:
  201. /* start RT-Thread Kernel */
  202. ldr pc, _rtthread_startup
  203. _rtthread_startup:
  204. .word rtthread_startup
  205. /*
  206. *************************************************************************
  207. * Subroutines
  208. *************************************************************************
  209. */
  210. stack_setup:
  211. mrs r0, cpsr
  212. bic r0, r0, #MODEMASK
  213. orr r1, r0, #UNDEFMODE|NOINT
  214. msr cpsr_cxsf, r1 /* undef mode */
  215. ldr sp, UNDEFINED_STACK_START
  216. orr r1,r0,#ABORTMODE|NOINT
  217. msr cpsr_cxsf,r1 /* abort mode */
  218. ldr sp, ABORT_STACK_START
  219. orr r1,r0,#IRQMODE|NOINT
  220. msr cpsr_cxsf,r1 /* IRQ mode */
  221. ldr sp, IRQ_STACK_START
  222. orr r1,r0,#FIQMODE|NOINT
  223. msr cpsr_cxsf,r1 /* FIQ mode */
  224. ldr sp, FIQ_STACK_START
  225. bic r0,r0,#MODEMASK
  226. orr r1,r0,#SVCMODE|NOINT
  227. msr cpsr_cxsf,r1 /* SVC mode */
  228. ldr sp, _STACK_START
  229. /* USER mode is not initialized. */
  230. mov pc,lr /* The LR register may be not valid for the mode changes.*/
  231. /*
  232. *************************************************************************
  233. *
  234. * Interrupt handling
  235. *
  236. *************************************************************************
  237. */
  238. /* exception handlers */
  239. .align 5
  240. vector_undef:
  241. sub sp, sp, #S_FRAME_SIZE
  242. stmia sp, {r0 - r12} /* Calling r0-r12 */
  243. add r8, sp, #S_PC
  244. stmdb r8, {sp, lr}^ /* Calling SP, LR */
  245. str lr, [r8, #0] /* Save calling PC */
  246. mrs r6, spsr
  247. str r6, [r8, #4] /* Save CPSR */
  248. str r0, [r8, #8] /* Save OLD_R0 */
  249. mov r0, sp
  250. bl rt_hw_trap_udef
  251. .align 5
  252. vector_swi:
  253. bl rt_hw_trap_swi
  254. .align 5
  255. vector_pabt:
  256. bl rt_hw_trap_pabt
  257. .align 5
  258. vector_dabt:
  259. sub sp, sp, #S_FRAME_SIZE
  260. stmia sp, {r0 - r12} /* Calling r0-r12 */
  261. add r8, sp, #S_PC
  262. stmdb r8, {sp, lr}^ /* Calling SP, LR */
  263. str lr, [r8, #0] /* Save calling PC */
  264. mrs r6, spsr
  265. str r6, [r8, #4] /* Save CPSR */
  266. str r0, [r8, #8] /* Save OLD_R0 */
  267. mov r0, sp
  268. bl rt_hw_trap_dabt
  269. .align 5
  270. vector_resv:
  271. bl rt_hw_trap_resv
  272. .globl rt_interrupt_enter
  273. .globl rt_interrupt_leave
  274. .globl rt_thread_switch_interrput_flag
  275. .globl rt_interrupt_from_thread
  276. .globl rt_interrupt_to_thread
  277. vector_irq:
  278. stmfd sp!, {r0-r12,lr}
  279. bl rt_interrupt_enter
  280. bl rt_hw_trap_irq
  281. bl rt_interrupt_leave
  282. /* if rt_thread_switch_interrput_flag set, jump to _interrupt_thread_switch and don't return */
  283. ldr r0, =rt_thread_switch_interrput_flag
  284. ldr r1, [r0]
  285. cmp r1, #1
  286. beq _interrupt_thread_switch
  287. ldmfd sp!, {r0-r12,lr}
  288. subs pc, lr, #4
  289. .align 5
  290. vector_fiq:
  291. stmfd sp!,{r0-r7,lr}
  292. bl rt_hw_trap_fiq
  293. ldmfd sp!,{r0-r7,lr}
  294. subs pc,lr,#4
  295. _interrupt_thread_switch:
  296. mov r1, #0 /* clear rt_thread_switch_interrput_flag*/
  297. str r1, [r0]
  298. ldmfd sp!, {r0-r12,lr} /* reload saved registers */
  299. stmfd sp!, {r0-r3} /* save r0-r3 */
  300. mov r1, sp
  301. add sp, sp, #16 /* restore sp */
  302. sub r2, lr, #4 /* save old task's pc to r2 */
  303. mrs r3, spsr /* disable interrupt */
  304. orr r0, r3, #NOINT
  305. msr spsr_c, r0
  306. ldr r0, =.+8 /* switch to interrupted task's stack*/
  307. movs pc, r0
  308. stmfd sp!, {r2} /* push old task's pc */
  309. stmfd sp!, {r4-r12,lr} /* push old task's lr,r12-r4 */
  310. mov r4, r1 /* Special optimised code below */
  311. mov r5, r3
  312. ldmfd r4!, {r0-r3}
  313. stmfd sp!, {r0-r3} /* push old task's r3-r0 */
  314. stmfd sp!, {r5} /* push old task's psr */
  315. mrs r4, spsr
  316. stmfd sp!, {r4} /* push old task's spsr */
  317. ldr r4, =rt_interrupt_from_thread
  318. ldr r5, [r4]
  319. str sp, [r5] /* store sp in preempted tasks's TCB*/
  320. ldr r6, =rt_interrupt_to_thread
  321. ldr r6, [r6]
  322. ldr sp, [r6] /* get new task's stack pointer */
  323. ldmfd sp!, {r4} /* pop new task's spsr */
  324. msr SPSR_cxsf, r4
  325. ldmfd sp!, {r4} /* pop new task's psr */
  326. msr CPSR_cxsf, r4
  327. ldmfd sp!, {r0-r12,lr,pc} /* pop new task's r0-r12,lr & pc */
  328. /*/*}*/