start_gcc.s 8.1 KB

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