boot_entry_v7a.S 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302
  1. /* Copyright (C) 2018 RDA Technologies Limited and/or its affiliates("RDA").
  2. * All rights reserved.
  3. *
  4. * This software is supplied "AS IS" without any warranties.
  5. * RDA assumes no responsibility or liability for the use of the software,
  6. * conveys no license or title under any patent, copyright, or mask work
  7. * right to the product. RDA reserves the right to make changes in the
  8. * software without notification. RDA also make no representation or
  9. * warranty that such application will be suitable for the specified use
  10. * without further testing or modification.
  11. */
  12. #include "boot_config.h"
  13. #define CPSR_M_USR 0x10U
  14. #define CPSR_M_FIQ 0x11U
  15. #define CPSR_M_IRQ 0x12U
  16. #define CPSR_M_SVC 0x13U
  17. #define CPSR_M_MON 0x16U
  18. #define CPSR_M_ABT 0x17U
  19. #define CPSR_M_HYP 0x1AU
  20. #define CPSR_M_UND 0x1BU
  21. #define CPSR_M_SYS 0x1FU
  22. #define CPSR_T (1UL << 5)
  23. // Refer to halArmv7aRegs_t
  24. #define OFFSET_R0 (0 * 4)
  25. #define OFFSET_R1 (1 * 4)
  26. #define OFFSET_R2 (2 * 4)
  27. #define OFFSET_R8 (8 * 4)
  28. #define OFFSET_R15 (15 * 4)
  29. #define OFFSET_D0 (16 * 4)
  30. #define OFFSET_CPSR (80 * 4)
  31. #define OFFSET_FPSCR (81 * 4)
  32. #define OFFSET_EPSR (82 * 4)
  33. #define OFFSET_SP_USR (83 * 4)
  34. #define OFFSET_LR_USR (84 * 4)
  35. #define OFFSET_SP_HYP (85 * 4)
  36. #define OFFSET_SPSR_HYP (86 * 4)
  37. #define OFFSET_ELR_HYP (87 * 4)
  38. #define OFFSET_SP_SVC (88 * 4)
  39. #define OFFSET_LR_SVC (89 * 4)
  40. #define OFFSET_SPSR_SVC (90 * 4)
  41. #define OFFSET_SP_ABT (91 * 4)
  42. #define OFFSET_LR_ABT (92 * 4)
  43. #define OFFSET_SPSR_ABT (93 * 4)
  44. #define OFFSET_SP_UND (94 * 4)
  45. #define OFFSET_LR_UND (95 * 4)
  46. #define OFFSET_SPSR_UND (96 * 4)
  47. #define OFFSET_SP_MON (97 * 4)
  48. #define OFFSET_LR_MON (98 * 4)
  49. #define OFFSET_SPSR_MON (99 * 4)
  50. #define OFFSET_SP_IRQ (100 * 4)
  51. #define OFFSET_LR_IRQ (101 * 4)
  52. #define OFFSET_SPSR_IRQ (102 * 4)
  53. #define OFFSET_R8_FIQ (103 * 4)
  54. #define OFFSET_SP_FIQ (108 * 4)
  55. #define OFFSET_LR_FIQ (109 * 4)
  56. #define OFFSET_SPSR_FIQ (110 * 4)
  57. .text
  58. .arm
  59. .section BOOT_ENTRY, #alloc, #execinstr
  60. // ====================================================================
  61. // vectors, can be used as entry
  62. // ====================================================================
  63. .align 5
  64. .global Vectors
  65. .type Vectors, %function
  66. Vectors:
  67. LDR pc, =bootEntry
  68. LDR pc, =Undef_Handler
  69. LDR pc, =SVC_Handler
  70. LDR pc, =PAbt_Handler
  71. LDR pc, =DAbt_Handler
  72. B .
  73. LDR pc, =IRQ_Handler
  74. LDR pc, =FIQ_Handler
  75. // ====================================================================
  76. // IRQ handler
  77. // ====================================================================
  78. .type IRQ_Handler, %function
  79. IRQ_Handler:
  80. PUSH {r0-r12, r14}
  81. BLX bootIrqHandler
  82. POP {r0-r12, r14}
  83. SUBS pc, lr, #4
  84. // ====================================================================
  85. // UND/SVC handler
  86. // ====================================================================
  87. .type Undef_Handler, %function
  88. .type SVC_Handler, %function
  89. Undef_Handler:
  90. SVC_Handler:
  91. CPSID aif /* disable irq/fiq */
  92. PUSH {r0}
  93. MRS r0, spsr
  94. TST r0, #CPSR_T
  95. SUBNE lr, lr, #2 /* thumb elr: -2 bytes */
  96. SUBEQ lr, lr, #4 /* arm elr: -4 bytes */
  97. B .LAbortCommon
  98. // ====================================================================
  99. // PAbt handler
  100. // ====================================================================
  101. .type PAbt_Handler, %function
  102. PAbt_Handler:
  103. CPSID aif /* disable irq/fiq */
  104. PUSH {r0}
  105. SUB lr, lr, #4 /* elr: -4 bytes */
  106. B .LAbortCommon
  107. // ====================================================================
  108. // DAbt handler
  109. // ====================================================================
  110. .type DAbt_Handler, %function
  111. DAbt_Handler:
  112. CPSID aif /* disable irq/fiq */
  113. PUSH {r0}
  114. SUB lr, lr, #8 /* elr: -8 bytes */
  115. B .LAbortCommon
  116. // ====================================================================
  117. // FIQ handler
  118. // ====================================================================
  119. .type FIQ_Handler, %function
  120. FIQ_Handler:
  121. CPSID aif /* disable irq/fiq */
  122. PUSH {r0}
  123. SUB lr, lr, #4 /* elr: -4 bytes */
  124. B .LAbortCommon
  125. // ====================================================================
  126. // abort common, jump to blue screen
  127. // ====================================================================
  128. .LAbortCommon:
  129. LDR r0, =gBlueScreenRegs
  130. STR r1, [r0, #OFFSET_R1]
  131. POP {r1}
  132. STR r1, [r0, #OFFSET_R0]
  133. STR lr, [r0, #OFFSET_R15]
  134. ADD r1, r0, #OFFSET_R2
  135. STM r1, {r2-r7} /* r2-r7 */
  136. MRS r3, spsr
  137. STR r3, [r0, #OFFSET_CPSR] /* cpsr before exception */
  138. VMRS r1, fpscr
  139. STR r1, [r0, #OFFSET_FPSCR]
  140. MRS r2, cpsr
  141. STR r2, [r0, #OFFSET_EPSR] /* cpsr of exception */
  142. ADD r1, r0, #OFFSET_D0
  143. VSTMIA r1!, {d0-d15}
  144. VSTMIA r1!, {d16-d31}
  145. AND r3, r3, #0x1f
  146. BIC r1, r2, #0x1f
  147. ORR r1, r3
  148. MSR cpsr_c, r1 /* change M bit to spsr */
  149. ADD r1, r0, #OFFSET_R8
  150. STM r1, {r8-r14} /* r8-r14 */
  151. MOV r3, #0
  152. CPS #CPSR_M_SYS
  153. STR sp, [r0, #OFFSET_SP_USR]
  154. STR lr, [r0, #OFFSET_LR_USR]
  155. STR r3, [r0, #OFFSET_SP_HYP]
  156. STR r3, [r0, #OFFSET_SPSR_HYP]
  157. STR r3, [r0, #OFFSET_ELR_HYP]
  158. CPS #CPSR_M_SVC
  159. STR sp, [r0, #OFFSET_SP_SVC]
  160. STR lr, [r0, #OFFSET_LR_SVC]
  161. MRS r1, spsr
  162. STR r1, [r0, #OFFSET_SPSR_SVC]
  163. CPS #CPSR_M_ABT
  164. STR sp, [r0, #OFFSET_SP_ABT]
  165. STR lr, [r0, #OFFSET_LR_ABT]
  166. MRS r1, spsr
  167. STR r1, [r0, #OFFSET_SPSR_ABT]
  168. CPS #CPSR_M_UND
  169. STR sp, [r0, #OFFSET_SP_UND]
  170. STR lr, [r0, #OFFSET_LR_UND]
  171. MRS r1, spsr
  172. STR r1, [r0, #OFFSET_SPSR_UND]
  173. STR r3, [r0, #OFFSET_SP_MON]
  174. STR r3, [r0, #OFFSET_LR_MON]
  175. STR r3, [r0, #OFFSET_SPSR_MON]
  176. CPS #CPSR_M_IRQ
  177. STR sp, [r0, #OFFSET_SP_IRQ]
  178. STR lr, [r0, #OFFSET_LR_IRQ]
  179. MRS r1, spsr
  180. STR r1, [r0, #OFFSET_SPSR_IRQ]
  181. CPS #CPSR_M_FIQ
  182. ADD r1, r0, #OFFSET_R8_FIQ
  183. STM r1, {r8-r12} /* r8-r12 (fiq) */
  184. STR sp, [r0, #OFFSET_SP_FIQ]
  185. STR lr, [r0, #OFFSET_LR_FIQ]
  186. MRS r1, spsr
  187. STR r1, [r0, #OFFSET_SPSR_FIQ]
  188. MSR cpsr_c, r2
  189. LDR sp, =__blue_screen_end
  190. SUB sp, #(26*4) /* reeserve space for halBsContextArmv7a_t */
  191. MOV r0, #0
  192. BLX bootBlueScreen
  193. .LAbortEnd:
  194. B .LAbortEnd
  195. .ltorg
  196. .size Vectors, .-Vectors
  197. // ====================================================================
  198. // Entry of boot.
  199. // ====================================================================
  200. .global bootEntry
  201. .type bootEntry, %function
  202. bootEntry:
  203. CPSID if
  204. // Reset SCTLR Settings
  205. MRC p15, 0, r4, c1, c0, 0 // Read CP15 System Control register
  206. BIC r4, r4, #(0x1 << 12) // Clear I bit 12 to disable I Cache
  207. BIC r4, r4, #(0x1 << 2) // Clear C bit 2 to disable D Cache
  208. BIC r4, r4, #0x1 // Clear M bit 0 to disable MMU
  209. BIC r4, r4, #(0x1 << 11) // Clear Z bit 11 to disable branch prediction
  210. BIC r4, r4, #(0x1 << 13) // Clear V bit 13 to disable hivecs
  211. MCR p15, 0, r4, c1, c0, 0 // Write value back to CP15 System Control register
  212. ISB
  213. ORR r4, r4, #(0x1 << 12) // Set I bit 12 to enable I Cache
  214. MCR p15, 0, r4, c1, c0, 0 // Write value back to CP15 System Control register
  215. ISB
  216. LDR r4, =Vectors
  217. MCR p15, 0, r4, c12, c0, 0
  218. CPS CPSR_M_UND
  219. LDR sp, =__blue_screen_end
  220. CPS CPSR_M_ABT
  221. LDR sp, =__blue_screen_end
  222. CPS CPSR_M_FIQ
  223. LDR sp, =__blue_screen_end
  224. CPS CPSR_M_SVC
  225. LDR sp, =__blue_screen_end
  226. CPS CPSR_M_IRQ
  227. LDR sp, =__irq_stack_end
  228. CPS CPSR_M_SYS
  229. LDR sp, =__sys_stack_end
  230. BLX bootStart
  231. .ltorg
  232. .size bootEntry, .-bootEntry
  233. // ====================================================================
  234. // void bootJumpImageEntry(unsigned param, bootJumpEntry_t entry)
  235. // ====================================================================
  236. .global bootJumpImageEntry
  237. .type bootJumpImageEntry, %function
  238. bootJumpImageEntry:
  239. CPSID if
  240. MOV r4, #0
  241. MCR p15, 0, r4, c7, c5, 0 // Invalidate I Cache All
  242. // Reset SCTLR Settings
  243. MRC p15, 0, r4, c1, c0, 0 // Read CP15 System Control register
  244. BIC r4, r4, #(0x1 << 12) // Clear I bit 12 to disable I Cache
  245. BIC r4, r4, #(0x1 << 2) // Clear C bit 2 to disable D Cache
  246. BIC r4, r4, #0x1 // Clear M bit 0 to disable MMU
  247. BIC r4, r4, #(0x1 << 11) // Clear Z bit 11 to disable branch prediction
  248. BIC r4, r4, #(0x1 << 13) // Clear V bit 13 to disable hivecs
  249. MCR p15, 0, r4, c1, c0, 0 // Write value back to CP15 System Control register
  250. ISB
  251. ORR r4, r4, #(0x1 << 12) // Set I bit 12 to enable I Cache
  252. MCR p15, 0, r4, c1, c0, 0 // Write value back to CP15 System Control register
  253. ISB
  254. BLX r1
  255. .ltorg
  256. .size bootJumpImageEntry, .-bootJumpImageEntry