start_gcc.s 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481
  1. /*
  2. * File : start.S
  3. * This file is part of RT-Thread RTOS
  4. * COPYRIGHT (C) 2006, RT-Thread Development Team
  5. *
  6. * This program is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation; either version 2 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License along
  17. * with this program; if not, write to the Free Software Foundation, Inc.,
  18. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  19. *
  20. * Change Logs:
  21. * Date Author Notes
  22. * 2016/3/9 16:27:48 louis first version
  23. */
  24. #define CONFIG_STACKSIZE 512
  25. #define S_FRAME_SIZE 72
  26. #define S_OLD_R0 68
  27. #define S_PSR 64
  28. #define S_PC 60
  29. #define S_LR 56
  30. #define S_SP 52
  31. #define S_IP 48
  32. #define S_FP 44
  33. #define S_R10 40
  34. #define S_R9 36
  35. #define S_R8 32
  36. #define S_R7 28
  37. #define S_R6 24
  38. #define S_R5 20
  39. #define S_R4 16
  40. #define S_R3 12
  41. #define S_R2 8
  42. #define S_R1 4
  43. #define S_R0 0
  44. .equ USERMODE, 0x10
  45. .equ FIQMODE, 0x11
  46. .equ IRQMODE, 0x12
  47. .equ SVCMODE, 0x13
  48. .equ ABORTMODE, 0x17
  49. .equ UNDEFMODE, 0x1b
  50. .equ MODEMASK, 0x1f
  51. .equ NOINT, 0xc0
  52. .text
  53. .section ".ARM1176START"
  54. .code 32
  55. @*******************************************************************************
  56. @** Common cpu modes
  57. @*******************************************************************************
  58. .equ ARM1176_MODE_USR, 0x10 @ CPSR_c xxx10000
  59. .equ ARM1176_MODE_FIQ, 0x11 @ CPSR_c xxx10001
  60. .equ ARM1176_MODE_IRQ, 0x12 @ CPSR_c xxx10010
  61. .equ ARM1176_MODE_SVC, 0x13 @ CPSR_c xxx10011
  62. .equ ARM1176_MODE_ABT, 0x17 @ CPSR_c xxx10111
  63. .equ ARM1176_MODE_UND, 0x1B @ CPSR_c xxx11011
  64. .equ ARM1176_MODE_SYS, 0x1F @ CPSR_c xxx11111
  65. .equ ARM1176_CPSR_I_BIT, 0x80 @ CPSR_c 100xxxxx
  66. .equ ARM1176_CPSR_F_BIT, 0x40 @ CPSR_c 010xxxxx
  67. .equ ARM1176_CPSR_T_BIT, 0x20 @ CPSR_c 001xxxxx
  68. .globl _start
  69. .globl ARM1176_Start
  70. _start:
  71. ARM1176_Start:
  72. msr cpsr_c,#(ARM1176_MODE_SYS | ARM1176_CPSR_I_BIT | ARM1176_CPSR_F_BIT) @disable irq/fiq first
  73. ldr r0, =Reset ;@load translation table base address
  74. mcr p15,0,r0,c12,c0,0 ;@write translation table base address req
  75. nop
  76. nop
  77. nop
  78. nop
  79. nop
  80. nop
  81. nop
  82. nop
  83. nop
  84. nop
  85. nop
  86. nop
  87. nop
  88. Reset:
  89. ldr pc, =reset
  90. ldr pc, =vector_undef
  91. ldr pc, =vector_swi
  92. ldr pc, =vector_pabt
  93. ldr pc, =vector_dabt
  94. ldr pc, =vector_resv
  95. ldr pc, =vector_irq
  96. ldr pc, =vector_fiq
  97. nop
  98. nop
  99. .balignl 16,0xdeadbeef
  100. /*
  101. *************************************************************************
  102. *
  103. * Startup Code (reset vector)
  104. * relocate armboot to ram
  105. * setup stack
  106. * jump to second stage
  107. *
  108. *************************************************************************
  109. */
  110. /*
  111. * rtthread bss start and end which are defined in linker script
  112. */
  113. .extern __stack_start__
  114. .equ Mode_USR, 0x10
  115. .equ Mode_FIQ, 0x11
  116. .equ Mode_IRQ, 0x12
  117. .equ Mode_SVC, 0x13
  118. .equ Mode_ABT, 0x17
  119. .equ Mode_UND, 0x1B
  120. .equ Mode_SYS, 0x1F
  121. .equ I_Bit, 0x80 @ when I bit is set, IRQ is disabled
  122. .equ F_Bit, 0x40 @ when F bit is set, FIQ is disabled
  123. .equ UND_Stack_Size, 0x00000200
  124. .equ SVC_Stack_Size, 0x00000200
  125. .equ ABT_Stack_Size, 0x00000000
  126. .equ FIQ_Stack_Size, 0x00000000
  127. .equ IRQ_Stack_Size, 0x00000200
  128. .equ USR_Stack_Size, 0x00000200
  129. #define ISR_Stack_Size (UND_Stack_Size + SVC_Stack_Size + ABT_Stack_Size + \
  130. FIQ_Stack_Size + IRQ_Stack_Size)
  131. .globl stack_top
  132. stack_top:
  133. .word __stack_start__
  134. .extern ARM1176_TcmInitialise
  135. .extern ARM1176_MmuInitialise
  136. .extern GH_VIC_set_EdgeClr
  137. .extern entry
  138. /*
  139. *************************************************************************
  140. *
  141. * Jump vector table
  142. *
  143. *************************************************************************
  144. */
  145. /* ----------------------------------entry------------------------------*/
  146. reset:
  147. msr cpsr_c,#(ARM1176_MODE_SYS | ARM1176_CPSR_I_BIT | ARM1176_CPSR_F_BIT) @disable irq/fiq first
  148. @/* First read in some misc registers */
  149. mrc p15, 0, r0, c0, c0, 0 @/* Read ID value {A5S=0x41 1 7 b36 5}*/
  150. mrc p15, 0, r1, c0, c0, 1 @/* Read cache type {0x1d152152}*/
  151. mrc p15, 0, r2, c0, c0, 2 @/* Read TCM status {0x10001}*/
  152. #ifdef GK7102C
  153. @mrc p15, 0, r0, c15,c14,0 @ read CP15 register c15 into r0
  154. @orr r0, r0,#0x80000000 @ system bit enabled
  155. @bic r0, r0,#0x00000077 @
  156. @orr r0, r0,#0x00000055 @ specifies 16KB data cache
  157. @mcr p15, 0, r0, c15,c14,0 @ wraite CP15 register c15 into r0
  158. mrc p15, 0, r0, c1, c0, 1 @read CP15 register c1 into r0
  159. orr r0, r0,#0x00000040 @CZ bit enabled
  160. mcr p15, 0, r0, c1, c0, 1 @read CP15 register c1 into r0
  161. #endif
  162. @/* Turn on instrucion cache and disable MMU */
  163. mrc p15, 0, r0, c1, c0, 0 @/* Read control register {0x5327d}*/
  164. @bic r0, r0, #0x1000 @ Turn off bit 12 - I-cache
  165. orr r0, r0, #0x1000 @ Turn on bit 12 - I-cache
  166. @bic r0, r0, #0x0004 @ Turn off bit 03 - D-cache
  167. orr r0, r0, #0x0004 @ Turn on bit 03 - D-cache
  168. bic r0, r0, #0x2000 @ Turn off bit 13 - HV
  169. bic r0, r0, #0x0001 @ Turn off bit 1 - MMU
  170. @orr r0, r0, #0x2 @ Turn on bit 1 - Alignment fault
  171. bic r0, r0, #0x400000 @ Turn off bit 22 - Unainged support
  172. @bic r0, r0, #0x2 @ Turn off bit 1 - Alignment fault
  173. @orr r0, r0, #0x400000 @ Turn on bit 22 - Unainged support
  174. mcr p15, 0, r0, c1, c0, 0 @/* Write control register */
  175. mov r0, #0x1
  176. mcr p15, 0, r0, c3, c0, 0 @/* Write domain access control reg */
  177. @bl switch_core_freq @/* Change PLL for core if necessary */
  178. @bl memsetup5 @/* Initialize Memory */
  179. @/* -------------------------------------------------- */
  180. @/* Redirect peripheral port 0x60000000 - 0x7fffffff */
  181. @/* -------------------------------------------------- */
  182. .if CPU_USE_GK710XS==1
  183. mov r0, #0x80000000
  184. orr r0, r0, #0x00000015 @0x14=512M
  185. .else
  186. mov r0, #0x60000000
  187. orr r0, r0, #0x00000014 @0x14=512M
  188. .endif
  189. mcr p15, 0, r0, c15, c2, 4
  190. @ clear the irq or fiq first
  191. mov r0,#0x0
  192. mov r1,#0xFFFFFFFF
  193. bl GH_VIC_set_EdgeClr
  194. mov r0,#0x1
  195. mov r1,#0xFFFFFFFF
  196. bl GH_VIC_set_EdgeClr
  197. nop
  198. @ bl ARM1176_TcmInitialise
  199. msr cpsr_c,#(ARM1176_MODE_SYS | ARM1176_CPSR_I_BIT | ARM1176_CPSR_F_BIT) @disable irq/fiq first
  200. .if ARM1176_USE_VFP == 1
  201. bl ARM1176_VfpInitialise
  202. bl ARM1176_VfpSetFastmode
  203. .endif
  204. bl ARM1176_Invalid_Cache
  205. /* setup stack */
  206. ldr r0, =stack_top
  207. ldr r0, [r0]
  208. @ Enter Undefined Instruction Mode and set its Stack Pointer
  209. msr cpsr_c, #Mode_UND|I_Bit|F_Bit
  210. mov sp, r0
  211. sub r0, r0, #UND_Stack_Size
  212. @ Enter Abort Mode and set its Stack Pointer
  213. msr cpsr_c, #Mode_ABT|I_Bit|F_Bit
  214. mov sp, r0
  215. sub r0, r0, #ABT_Stack_Size
  216. @ Enter FIQ Mode and set its Stack Pointer
  217. msr cpsr_c, #Mode_FIQ|I_Bit|F_Bit
  218. mov sp, r0
  219. sub r0, r0, #FIQ_Stack_Size
  220. @ Enter IRQ Mode and set its Stack Pointer
  221. msr cpsr_c, #Mode_IRQ|I_Bit|F_Bit
  222. mov sp, r0
  223. sub r0, r0, #IRQ_Stack_Size
  224. @ Enter Supervisor Mode and set its Stack Pointer
  225. msr cpsr_c, #Mode_SVC|I_Bit|F_Bit
  226. mov sp, r0
  227. sub r0, r0, #SVC_Stack_Size
  228. @ Enter User Mode and set its Stack Pointer
  229. mov sp, r0
  230. sub sl, sp, #USR_Stack_Size
  231. /* clear .bss */
  232. mov r0,#0 /* get a zero */
  233. ldr r1,=__bss_start__ /* bss start */
  234. ldr r2,=__bss_end__ /* bss end */
  235. bss_loop:
  236. cmp r1,r2 /* check if data to clear */
  237. strlo r0,[r1],#4 /* clear 4 bytes */
  238. blo bss_loop /* loop until done */
  239. /* call C++ constructors of global objects */
  240. ldr r0, =__ctors_start__
  241. ldr r1, =__ctors_end__
  242. ctor_loop:
  243. cmp r0, r1
  244. beq ctor_end
  245. ldr r2, [r0], #4
  246. stmfd sp!, {r0-r1}
  247. mov lr, pc
  248. bx r2
  249. ldmfd sp!, {r0-r1}
  250. b ctor_loop
  251. ctor_end:
  252. @ need nocache buffer
  253. bl ARM1176_MmuInitialise
  254. /* start RT-Thread Kernel */
  255. ldr pc, =entry
  256. .global ARM1176_Invalid_Cache
  257. .func ARM1176_Invalid_Cache
  258. ARM1176_Invalid_Cache:
  259. stmfd sp!,{r0-r12,lr}
  260. mov r11,lr
  261. mov r0,#0x0 @Set [31:30]
  262. mov r1,#0x3
  263. loop1:
  264. mov r2,#0x0
  265. mov r3,#0x80
  266. loop2:
  267. mov r4,r0,LSL #30
  268. mov r5,r2,LSL #5 @Index [S+4:5] S=8 32K
  269. add r4,r4,r5
  270. mcr p15, 0, r4, c7, c5, 2
  271. add r2,r2,#0x1
  272. cmp r2,r3
  273. bne loop2
  274. add r0,r0,#1
  275. cmp r0,r1
  276. bne loop1
  277. mov lr,r11 @ restore link register
  278. ldmfd sp!,{r0-r12,lr}
  279. bx lr @ branch back to caller
  280. .size ARM1176_Invalid_Cache, . - ARM1176_Invalid_Cache
  281. .endfunc
  282. .global cpu_reset
  283. cpu_reset:
  284. mov pc, lr
  285. /*
  286. *************************************************************************
  287. *
  288. * Interrupt handling
  289. *
  290. *************************************************************************
  291. */
  292. /* exception handlers */
  293. .align 5
  294. vector_undef:
  295. sub sp, sp, #S_FRAME_SIZE
  296. stmia sp, {r0 - r12} /* Calling r0-r12 */
  297. add r8, sp, #S_PC
  298. stmdb r8, {sp, lr}^ /* Calling SP, LR */
  299. str lr, [r8, #0] /* Save calling PC */
  300. mrs r6, spsr
  301. str r6, [r8, #4] /* Save CPSR */
  302. str r0, [r8, #8] /* Save OLD_R0 */
  303. mov r0, sp
  304. bl rt_hw_trap_udef
  305. .align 5
  306. vector_swi:
  307. bl rt_hw_trap_swi
  308. .align 5
  309. vector_pabt:
  310. bl rt_hw_trap_pabt
  311. .align 5
  312. vector_dabt:
  313. sub sp, sp, #S_FRAME_SIZE
  314. stmia sp, {r0 - r12} /* Calling r0-r12 */
  315. add r8, sp, #S_PC
  316. stmdb r8, {sp, lr}^ /* Calling SP, LR */
  317. str lr, [r8, #0] /* Save calling PC */
  318. mrs r6, spsr
  319. str r6, [r8, #4] /* Save CPSR */
  320. str r0, [r8, #8] /* Save OLD_R0 */
  321. mov r0, sp
  322. bl rt_hw_trap_dabt
  323. .align 5
  324. vector_resv:
  325. bl rt_hw_trap_resv
  326. .align 5
  327. .globl rt_interrupt_enter
  328. .globl rt_interrupt_leave
  329. .globl rt_thread_switch_interrupt_flag
  330. .globl rt_interrupt_from_thread
  331. .globl rt_interrupt_to_thread
  332. vector_irq:
  333. stmfd sp!, {r0-r12,lr}
  334. bl rt_interrupt_enter
  335. bl rt_hw_trap_irq
  336. bl rt_interrupt_leave
  337. /* if rt_thread_switch_interrupt_flag set, jump to _interrupt_thread_switch and don't return */
  338. ldr r0, =rt_thread_switch_interrupt_flag
  339. ldr r1, [r0]
  340. cmp r1, #1
  341. beq _interrupt_thread_switch
  342. ldmfd sp!, {r0-r12,lr}
  343. subs pc, lr, #4
  344. .align 5
  345. vector_fiq:
  346. stmfd sp!,{r0-r7,lr}
  347. bl rt_hw_trap_fiq
  348. ldmfd sp!,{r0-r7,lr}
  349. subs pc,lr,#4
  350. _interrupt_thread_switch:
  351. mov r1, #0 /* clear rt_thread_switch_interrupt_flag*/
  352. str r1, [r0]
  353. ldmfd sp!, {r0-r12,lr} /* reload saved registers */
  354. stmfd sp!, {r0-r3} /* save r0-r3 */
  355. mov r1, sp
  356. add sp, sp, #16 /* restore sp */
  357. sub r2, lr, #4 /* save old task's pc to r2 */
  358. mrs r3, spsr /* disable interrupt */
  359. orr r0, r3, #NOINT
  360. msr spsr_c, r0
  361. ldr r0, =.+8 /* switch to interrupted task's stack*/
  362. movs pc, r0
  363. stmfd sp!, {r2} /* push old task's pc */
  364. stmfd sp!, {r4-r12,lr} /* push old task's lr,r12-r4 */
  365. mov r4, r1 /* Special optimised code below */
  366. mov r5, r3
  367. ldmfd r4!, {r0-r3}
  368. stmfd sp!, {r0-r3} /* push old task's r3-r0 */
  369. stmfd sp!, {r5} /* push old task's psr */
  370. mrs r4, spsr
  371. stmfd sp!, {r4} /* push old task's spsr */
  372. ldr r4, =rt_interrupt_from_thread
  373. ldr r5, [r4]
  374. str sp, [r5] /* store sp in preempted tasks's TCB*/
  375. ldr r6, =rt_interrupt_to_thread
  376. ldr r6, [r6]
  377. ldr sp, [r6] /* get new task's stack pointer */
  378. ldmfd sp!, {r4} /* pop new task's spsr */
  379. msr SPSR_cxsf, r4
  380. ldmfd sp!, {r4} /* pop new task's psr */
  381. msr CPSR_cxsf, r4
  382. ldmfd sp!, {r0-r12,lr,pc} /* pop new task's r0-r12,lr & pc */
  383. @*******************************************************************************
  384. @** End of file
  385. @*******************************************************************************