start_gcc.S 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486
  1. /*
  2. * Copyright (c) 2006-2018, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. */
  9. @-------------------------------------------------------------------------------
  10. @ sys_core.asm
  11. @
  12. @ (c) Texas Instruments 2009-2013, All rights reserved.
  13. @
  14. #include <rtconfig.h>
  15. .equ Mode_USR, 0x10
  16. .equ Mode_FIQ, 0x11
  17. .equ Mode_IRQ, 0x12
  18. .equ Mode_SVC, 0x13
  19. .equ Mode_ABT, 0x17
  20. .equ Mode_UND, 0x1B
  21. .equ Mode_SYS, 0x1F
  22. .equ I_Bit, 0x80 @ when I bit is set, IRQ is disabled
  23. .equ F_Bit, 0x40 @ when F bit is set, FIQ is disabled
  24. .equ UND_Stack_Size, 0x00000000
  25. .equ SVC_Stack_Size, 0x00000000
  26. .equ ABT_Stack_Size, 0x00000000
  27. .equ FIQ_Stack_Size, 0x00001000
  28. .equ IRQ_Stack_Size, 0x00001000
  29. .section .bss.noinit
  30. /* stack */
  31. .globl stack_start
  32. .globl stack_top
  33. stack_start:
  34. .rept (UND_Stack_Size + SVC_Stack_Size + ABT_Stack_Size + FIQ_Stack_Size + IRQ_Stack_Size)
  35. .byte 0
  36. .endr
  37. stack_top:
  38. .section .text, "ax"
  39. .text
  40. .arm
  41. .globl _c_int00
  42. .globl _reset
  43. _reset:
  44. @-------------------------------------------------------------------------------
  45. @ Initialize CPU Registers
  46. @ After reset, the CPU is in the Supervisor mode (M = 10011)
  47. cpsid if, #19
  48. #if defined (__VFP_FP__) && !defined(__SOFTFP__) && defined(RT_VFP_LAZY_STACKING)
  49. @ Turn on FPV coprocessor
  50. mrc p15, #0x00, r2, c1, c0, #0x02
  51. orr r2, r2, #0xF00000
  52. mcr p15, #0x00, r2, c1, c0, #0x02
  53. fmrx r2, fpexc
  54. orr r2, r2, #0x40000000
  55. fmxr fpexc, r2
  56. #endif
  57. @-------------------------------------------------------------------------------
  58. @ Initialize Stack Pointers
  59. ldr r0, =stack_top
  60. @ Set the startup stack for svc
  61. mov sp, r0
  62. @ Enter Undefined Instruction Mode and set its Stack Pointer
  63. msr cpsr_c, #Mode_UND|I_Bit|F_Bit
  64. mov sp, r0
  65. sub r0, r0, #UND_Stack_Size
  66. @ Enter Abort Mode and set its Stack Pointer
  67. msr cpsr_c, #Mode_ABT|I_Bit|F_Bit
  68. mov sp, r0
  69. sub r0, r0, #ABT_Stack_Size
  70. @ Enter FIQ Mode and set its Stack Pointer
  71. msr cpsr_c, #Mode_FIQ|I_Bit|F_Bit
  72. mov sp, r0
  73. sub r0, r0, #FIQ_Stack_Size
  74. @ Enter IRQ Mode and set its Stack Pointer
  75. msr cpsr_c, #Mode_IRQ|I_Bit|F_Bit
  76. mov sp, r0
  77. sub r0, r0, #IRQ_Stack_Size
  78. @ Switch back to SVC
  79. msr cpsr_c, #Mode_SVC|I_Bit|F_Bit
  80. bl next1
  81. next1:
  82. bl next2
  83. next2:
  84. bl next3
  85. next3:
  86. bl next4
  87. next4:
  88. ldr lr, =_c_int00
  89. bx lr
  90. .globl data_init
  91. data_init:
  92. /* copy .data to SRAM */
  93. ldr r1, =_sidata /* .data start in image */
  94. ldr r2, =_edata /* .data end in image */
  95. ldr r3, =_sdata /* sram data start */
  96. data_loop:
  97. ldr r0, [r1, #0]
  98. str r0, [r3]
  99. add r1, r1, #4
  100. add r3, r3, #4
  101. cmp r3, r2 /* check if data to clear */
  102. blo data_loop /* loop until done */
  103. /* clear .bss */
  104. mov r0,#0 /* get a zero */
  105. ldr r1,=__bss_start /* bss start */
  106. ldr r2,=__bss_end /* bss end */
  107. bss_loop:
  108. cmp r1,r2 /* check if data to clear */
  109. strlo r0,[r1],#4 /* clear 4 bytes */
  110. blo bss_loop /* loop until done */
  111. /* call C++ constructors of global objects */
  112. ldr r0, =__ctors_start__
  113. ldr r1, =__ctors_end__
  114. ctor_loop:
  115. cmp r0, r1
  116. beq ctor_end
  117. ldr r2, [r0], #4
  118. stmfd sp!, {r0-r3, ip, lr}
  119. mov lr, pc
  120. bx r2
  121. ldmfd sp!, {r0-r3, ip, lr}
  122. b ctor_loop
  123. ctor_end:
  124. bx lr
  125. @-------------------------------------------------------------------------------
  126. @ Enable RAM ECC Support
  127. .globl _coreEnableRamEcc_
  128. _coreEnableRamEcc_:
  129. stmfd sp!, {r0}
  130. mrc p15, #0x00, r0, c1, c0, #0x01
  131. orr r0, r0, #0x0C000000
  132. mcr p15, #0x00, r0, c1, c0, #0x01
  133. ldmfd sp!, {r0}
  134. bx lr
  135. @-------------------------------------------------------------------------------
  136. @ Disable RAM ECC Support
  137. .globl _coreDisableRamEcc_
  138. _coreDisableRamEcc_:
  139. stmfd sp!, {r0}
  140. mrc p15, #0x00, r0, c1, c0, #0x01
  141. bic r0, r0, #0x0C000000
  142. mcr p15, #0x00, r0, c1, c0, #0x01
  143. ldmfd sp!, {r0}
  144. bx lr
  145. @-------------------------------------------------------------------------------
  146. @ Enable Flash ECC Support
  147. .globl _coreEnableFlashEcc_
  148. _coreEnableFlashEcc_:
  149. stmfd sp!, {r0}
  150. mrc p15, #0x00, r0, c1, c0, #0x01
  151. orr r0, r0, #0x02000000
  152. dmb
  153. mcr p15, #0x00, r0, c1, c0, #0x01
  154. ldmfd sp!, {r0}
  155. bx lr
  156. @-------------------------------------------------------------------------------
  157. @ Disable Flash ECC Support
  158. .globl _coreDisableFlashEcc_
  159. _coreDisableFlashEcc_:
  160. stmfd sp!, {r0}
  161. mrc p15, #0x00, r0, c1, c0, #0x01
  162. bic r0, r0, #0x02000000
  163. mcr p15, #0x00, r0, c1, c0, #0x01
  164. ldmfd sp!, {r0}
  165. bx lr
  166. @-------------------------------------------------------------------------------
  167. @ Get data fault status register
  168. .globl _coreGetDataFault_
  169. _coreGetDataFault_:
  170. mrc p15, #0, r0, c5, c0, #0
  171. bx lr
  172. @-------------------------------------------------------------------------------
  173. @ Clear data fault status register
  174. .globl _coreClearDataFault_
  175. _coreClearDataFault_:
  176. stmfd sp!, {r0}
  177. mov r0, #0
  178. mcr p15, #0, r0, c5, c0, #0
  179. ldmfd sp!, {r0}
  180. bx lr
  181. @-------------------------------------------------------------------------------
  182. @ Get instruction fault status register
  183. .globl _coreGetInstructionFault_
  184. _coreGetInstructionFault_:
  185. mrc p15, #0, r0, c5, c0, #1
  186. bx lr
  187. @-------------------------------------------------------------------------------
  188. @ Clear instruction fault status register
  189. .globl _coreClearInstructionFault_
  190. _coreClearInstructionFault_:
  191. stmfd sp!, {r0}
  192. mov r0, #0
  193. mcr p15, #0, r0, c5, c0, #1
  194. ldmfd sp!, {r0}
  195. bx lr
  196. @-------------------------------------------------------------------------------
  197. @ Get data fault address register
  198. .globl _coreGetDataFaultAddress_
  199. _coreGetDataFaultAddress_:
  200. mrc p15, #0, r0, c6, c0, #0
  201. bx lr
  202. @-------------------------------------------------------------------------------
  203. @ Clear data fault address register
  204. .globl _coreClearDataFaultAddress_
  205. _coreClearDataFaultAddress_:
  206. stmfd sp!, {r0}
  207. mov r0, #0
  208. mcr p15, #0, r0, c6, c0, #0
  209. ldmfd sp!, {r0}
  210. bx lr
  211. @-------------------------------------------------------------------------------
  212. @ Get instruction fault address register
  213. .globl _coreGetInstructionFaultAddress_
  214. _coreGetInstructionFaultAddress_:
  215. mrc p15, #0, r0, c6, c0, #2
  216. bx lr
  217. @-------------------------------------------------------------------------------
  218. @ Clear instruction fault address register
  219. .globl _coreClearInstructionFaultAddress_
  220. _coreClearInstructionFaultAddress_:
  221. stmfd sp!, {r0}
  222. mov r0, #0
  223. mcr p15, #0, r0, c6, c0, #2
  224. ldmfd sp!, {r0}
  225. bx lr
  226. @-------------------------------------------------------------------------------
  227. @ Get auxiliary data fault status register
  228. .globl _coreGetAuxiliaryDataFault_
  229. _coreGetAuxiliaryDataFault_:
  230. mrc p15, #0, r0, c5, c1, #0
  231. bx lr
  232. @-------------------------------------------------------------------------------
  233. @ Clear auxiliary data fault status register
  234. .globl _coreClearAuxiliaryDataFault_
  235. _coreClearAuxiliaryDataFault_:
  236. stmfd sp!, {r0}
  237. mov r0, #0
  238. mcr p15, #0, r0, c5, c1, #0
  239. ldmfd sp!, {r0}
  240. bx lr
  241. @-------------------------------------------------------------------------------
  242. @ Get auxiliary instruction fault status register
  243. .globl _coreGetAuxiliaryInstructionFault_
  244. _coreGetAuxiliaryInstructionFault_:
  245. mrc p15, #0, r0, c5, c1, #1
  246. bx lr
  247. @-------------------------------------------------------------------------------
  248. @ Clear auxiliary instruction fault status register
  249. .globl _coreClearAuxiliaryInstructionFault_
  250. _coreClearAuxiliaryInstructionFault_:
  251. stmfd sp!, {r0}
  252. mov r0, #0
  253. mrc p15, #0, r0, c5, c1, #1
  254. ldmfd sp!, {r0}
  255. bx lr
  256. @-------------------------------------------------------------------------------
  257. @ Clear ESM CCM errorss
  258. .globl _esmCcmErrorsClear_
  259. _esmCcmErrorsClear_:
  260. stmfd sp!, {r0-r2}
  261. ldr r0, ESMSR1_REG @ load the ESMSR1 status register address
  262. ldr r2, ESMSR1_ERR_CLR
  263. str r2, [r0] @ clear the ESMSR1 register
  264. ldr r0, ESMSR2_REG @ load the ESMSR2 status register address
  265. ldr r2, ESMSR2_ERR_CLR
  266. str r2, [r0] @ clear the ESMSR2 register
  267. ldr r0, ESMSSR2_REG @ load the ESMSSR2 status register address
  268. ldr r2, ESMSSR2_ERR_CLR
  269. str r2, [r0] @ clear the ESMSSR2 register
  270. ldr r0, ESMKEY_REG @ load the ESMKEY register address
  271. mov r2, #0x5 @ load R2 with 0x5
  272. str r2, [r0] @ clear the ESMKEY register
  273. ldr r0, VIM_INTREQ @ load the INTREQ register address
  274. ldr r2, VIM_INT_CLR
  275. str r2, [r0] @ clear the INTREQ register
  276. ldr r0, CCMR4_STAT_REG @ load the CCMR4 status register address
  277. ldr r2, CCMR4_ERR_CLR
  278. str r2, [r0] @ clear the CCMR4 status register
  279. ldmfd sp!, {r0-r2}
  280. bx lr
  281. ESMSR1_REG: .word 0xFFFFF518
  282. ESMSR2_REG: .word 0xFFFFF51C
  283. ESMSR3_REG: .word 0xFFFFF520
  284. ESMKEY_REG: .word 0xFFFFF538
  285. ESMSSR2_REG: .word 0xFFFFF53C
  286. CCMR4_STAT_REG: .word 0xFFFFF600
  287. ERR_CLR_WRD: .word 0xFFFFFFFF
  288. CCMR4_ERR_CLR: .word 0x00010000
  289. ESMSR1_ERR_CLR: .word 0x80000000
  290. ESMSR2_ERR_CLR: .word 0x00000004
  291. ESMSSR2_ERR_CLR: .word 0x00000004
  292. VIM_INT_CLR: .word 0x00000001
  293. VIM_INTREQ: .word 0xFFFFFE20
  294. @-------------------------------------------------------------------------------
  295. @ Work Around for Errata CORTEX-R4#57:
  296. @
  297. @ Errata Description:
  298. @ Conditional VMRS APSR_Nzcv, FPSCR May Evaluate With Incorrect Flags
  299. @ Workaround:
  300. @ Disable out-of-order single-precision floating point
  301. @ multiply-accumulate instruction completion
  302. .globl _errata_CORTEXR4_57_
  303. _errata_CORTEXR4_57_:
  304. push {r0}
  305. mrc p15, #0, r0, c15, c0, #0 @ Read Secondary Auxiliary Control Register
  306. orr r0, r0, #0x10000 @ Set BIT 16 (Set DOOFMACS)
  307. mcr p15, #0, r0, c15, c0, #0 @ Write Secondary Auxiliary Control Register
  308. pop {r0}
  309. bx lr
  310. @-------------------------------------------------------------------------------
  311. @ Work Around for Errata CORTEX-R4#66:
  312. @
  313. @ Errata Description:
  314. @ Register Corruption During A Load-Multiple Instruction At
  315. @ an Exception Vector
  316. @ Workaround:
  317. @ Disable out-of-order completion for divide instructions in
  318. @ Auxiliary Control register
  319. .globl _errata_CORTEXR4_66_
  320. _errata_CORTEXR4_66_:
  321. push {r0}
  322. mrc p15, #0, r0, c1, c0, #1 @ Read Auxiliary Control register
  323. orr r0, r0, #0x80 @ Set BIT 7 (Disable out-of-order completion
  324. @ for divide instructions.)
  325. mcr p15, #0, r0, c1, c0, #1 @ Write Auxiliary Control register
  326. pop {r0}
  327. bx lr
  328. .globl turnon_VFP
  329. turnon_VFP:
  330. @ Enable FPV
  331. STMDB sp!, {r0}
  332. fmrx r0, fpexc
  333. orr r0, r0, #0x40000000
  334. fmxr fpexc, r0
  335. LDMIA sp!, {r0}
  336. subs pc, lr, #4
  337. .macro push_svc_reg
  338. sub sp, sp, #17 * 4 @/* Sizeof(struct rt_hw_exp_stack) */
  339. stmia sp, {r0 - r12} @/* Calling r0-r12 */
  340. mov r0, sp
  341. mrs r6, spsr @/* Save CPSR */
  342. str lr, [r0, #15*4] @/* Push PC */
  343. str r6, [r0, #16*4] @/* Push CPSR */
  344. cps #Mode_SVC
  345. str sp, [r0, #13*4] @/* Save calling SP */
  346. str lr, [r0, #14*4] @/* Save calling PC */
  347. .endm
  348. .globl vector_svc
  349. vector_svc:
  350. push_svc_reg
  351. bl rt_hw_trap_svc
  352. b .
  353. .globl vector_pabort
  354. vector_pabort:
  355. push_svc_reg
  356. bl rt_hw_trap_pabt
  357. b .
  358. .globl vector_dabort
  359. vector_dabort:
  360. push_svc_reg
  361. bl rt_hw_trap_dabt
  362. b .
  363. .globl vector_resv
  364. vector_resv:
  365. push_svc_reg
  366. bl rt_hw_trap_resv
  367. b .