start_gcc.S 14 KB

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