bl1_exceptions.S 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287
  1. /*
  2. * Copyright (c) 2013-2022, ARM Limited and Contributors. All rights reserved.
  3. *
  4. * SPDX-License-Identifier: BSD-3-Clause
  5. */
  6. #include <arch.h>
  7. #include <asm_macros.S>
  8. #include <bl1/bl1.h>
  9. #include <common/bl_common.h>
  10. #include <context.h>
  11. /* -----------------------------------------------------------------------------
  12. * Very simple stackless exception handlers used by BL1.
  13. * -----------------------------------------------------------------------------
  14. */
  15. .globl bl1_exceptions
  16. vector_base bl1_exceptions
  17. /* -----------------------------------------------------
  18. * Current EL with SP0 : 0x0 - 0x200
  19. * -----------------------------------------------------
  20. */
  21. vector_entry SynchronousExceptionSP0
  22. mov x0, #SYNC_EXCEPTION_SP_EL0
  23. bl plat_report_exception
  24. no_ret plat_panic_handler
  25. end_vector_entry SynchronousExceptionSP0
  26. vector_entry IrqSP0
  27. mov x0, #IRQ_SP_EL0
  28. bl plat_report_exception
  29. no_ret plat_panic_handler
  30. end_vector_entry IrqSP0
  31. vector_entry FiqSP0
  32. mov x0, #FIQ_SP_EL0
  33. bl plat_report_exception
  34. no_ret plat_panic_handler
  35. end_vector_entry FiqSP0
  36. vector_entry SErrorSP0
  37. mov x0, #SERROR_SP_EL0
  38. bl plat_report_exception
  39. no_ret plat_panic_handler
  40. end_vector_entry SErrorSP0
  41. /* -----------------------------------------------------
  42. * Current EL with SPx: 0x200 - 0x400
  43. * -----------------------------------------------------
  44. */
  45. vector_entry SynchronousExceptionSPx
  46. mov x0, #SYNC_EXCEPTION_SP_ELX
  47. bl plat_report_exception
  48. no_ret plat_panic_handler
  49. end_vector_entry SynchronousExceptionSPx
  50. vector_entry IrqSPx
  51. mov x0, #IRQ_SP_ELX
  52. bl plat_report_exception
  53. no_ret plat_panic_handler
  54. end_vector_entry IrqSPx
  55. vector_entry FiqSPx
  56. mov x0, #FIQ_SP_ELX
  57. bl plat_report_exception
  58. no_ret plat_panic_handler
  59. end_vector_entry FiqSPx
  60. vector_entry SErrorSPx
  61. mov x0, #SERROR_SP_ELX
  62. bl plat_report_exception
  63. no_ret plat_panic_handler
  64. end_vector_entry SErrorSPx
  65. /* -----------------------------------------------------
  66. * Lower EL using AArch64 : 0x400 - 0x600
  67. * -----------------------------------------------------
  68. */
  69. vector_entry SynchronousExceptionA64
  70. /* Enable the SError interrupt */
  71. msr daifclr, #DAIF_ABT_BIT
  72. str x30, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_LR]
  73. /* Expect only SMC exceptions */
  74. mrs x30, esr_el3
  75. ubfx x30, x30, #ESR_EC_SHIFT, #ESR_EC_LENGTH
  76. cmp x30, #EC_AARCH64_SMC
  77. b.ne unexpected_sync_exception
  78. b smc_handler64
  79. end_vector_entry SynchronousExceptionA64
  80. vector_entry IrqA64
  81. mov x0, #IRQ_AARCH64
  82. bl plat_report_exception
  83. no_ret plat_panic_handler
  84. end_vector_entry IrqA64
  85. vector_entry FiqA64
  86. mov x0, #FIQ_AARCH64
  87. bl plat_report_exception
  88. no_ret plat_panic_handler
  89. end_vector_entry FiqA64
  90. vector_entry SErrorA64
  91. mov x0, #SERROR_AARCH64
  92. bl plat_report_exception
  93. no_ret plat_panic_handler
  94. end_vector_entry SErrorA64
  95. /* -----------------------------------------------------
  96. * Lower EL using AArch32 : 0x600 - 0x800
  97. * -----------------------------------------------------
  98. */
  99. vector_entry SynchronousExceptionA32
  100. mov x0, #SYNC_EXCEPTION_AARCH32
  101. bl plat_report_exception
  102. no_ret plat_panic_handler
  103. end_vector_entry SynchronousExceptionA32
  104. vector_entry IrqA32
  105. mov x0, #IRQ_AARCH32
  106. bl plat_report_exception
  107. no_ret plat_panic_handler
  108. end_vector_entry IrqA32
  109. vector_entry FiqA32
  110. mov x0, #FIQ_AARCH32
  111. bl plat_report_exception
  112. no_ret plat_panic_handler
  113. end_vector_entry FiqA32
  114. vector_entry SErrorA32
  115. mov x0, #SERROR_AARCH32
  116. bl plat_report_exception
  117. no_ret plat_panic_handler
  118. end_vector_entry SErrorA32
  119. func smc_handler64
  120. /* ----------------------------------------------
  121. * Detect if this is a RUN_IMAGE or other SMC.
  122. * ----------------------------------------------
  123. */
  124. mov x30, #BL1_SMC_RUN_IMAGE
  125. cmp x30, x0
  126. b.ne smc_handler
  127. /* ------------------------------------------------
  128. * Make sure only Secure world reaches here.
  129. * ------------------------------------------------
  130. */
  131. mrs x30, scr_el3
  132. tst x30, #SCR_NS_BIT
  133. b.ne unexpected_sync_exception
  134. /* ----------------------------------------------
  135. * Handling RUN_IMAGE SMC. First switch back to
  136. * SP_EL0 for the C runtime stack.
  137. * ----------------------------------------------
  138. */
  139. ldr x30, [sp, #CTX_EL3STATE_OFFSET + CTX_RUNTIME_SP]
  140. msr spsel, #MODE_SP_EL0
  141. mov sp, x30
  142. /* ---------------------------------------------------------------------
  143. * Pass EL3 control to next BL image.
  144. * Here it expects X1 with the address of a entry_point_info_t
  145. * structure describing the next BL image entrypoint.
  146. * ---------------------------------------------------------------------
  147. */
  148. mov x20, x1
  149. mov x0, x20
  150. bl bl1_print_next_bl_ep_info
  151. ldp x0, x1, [x20, #ENTRY_POINT_INFO_PC_OFFSET]
  152. msr elr_el3, x0
  153. msr spsr_el3, x1
  154. ubfx x0, x1, #MODE_EL_SHIFT, #2
  155. cmp x0, #MODE_EL3
  156. b.ne unexpected_sync_exception
  157. bl disable_mmu_icache_el3
  158. tlbi alle3
  159. dsb ish /* ERET implies ISB, so it is not needed here */
  160. #if SPIN_ON_BL1_EXIT
  161. bl print_debug_loop_message
  162. debug_loop:
  163. b debug_loop
  164. #endif
  165. mov x0, x20
  166. bl bl1_plat_prepare_exit
  167. ldp x6, x7, [x20, #(ENTRY_POINT_INFO_ARGS_OFFSET + 0x30)]
  168. ldp x4, x5, [x20, #(ENTRY_POINT_INFO_ARGS_OFFSET + 0x20)]
  169. ldp x2, x3, [x20, #(ENTRY_POINT_INFO_ARGS_OFFSET + 0x10)]
  170. ldp x0, x1, [x20, #(ENTRY_POINT_INFO_ARGS_OFFSET + 0x0)]
  171. exception_return
  172. endfunc smc_handler64
  173. unexpected_sync_exception:
  174. mov x0, #SYNC_EXCEPTION_AARCH64
  175. bl plat_report_exception
  176. no_ret plat_panic_handler
  177. /* -----------------------------------------------------
  178. * Save Secure/Normal world context and jump to
  179. * BL1 SMC handler.
  180. * -----------------------------------------------------
  181. */
  182. smc_handler:
  183. /* -----------------------------------------------------
  184. * Save x0-x29 and ARMv8.3-PAuth (if enabled) registers.
  185. * Save PMCR_EL0 and disable Cycle Counter.
  186. * TODO: Revisit to store only SMCCC specified registers.
  187. * -----------------------------------------------------
  188. */
  189. bl prepare_el3_entry
  190. #if ENABLE_PAUTH
  191. /* -----------------------------------------------------
  192. * Load and program stored APIAKey firmware key.
  193. * Re-enable pointer authentication in EL3, as it was
  194. * disabled before jumping to the next boot image.
  195. * -----------------------------------------------------
  196. */
  197. bl pauth_load_bl1_apiakey_enable
  198. #endif
  199. /* -----------------------------------------------------
  200. * Populate the parameters for the SMC handler. We
  201. * already have x0-x4 in place. x5 will point to a
  202. * cookie (not used now). x6 will point to the context
  203. * structure (SP_EL3) and x7 will contain flags we need
  204. * to pass to the handler.
  205. * -----------------------------------------------------
  206. */
  207. mov x5, xzr
  208. mov x6, sp
  209. /* -----------------------------------------------------
  210. * Restore the saved C runtime stack value which will
  211. * become the new SP_EL0 i.e. EL3 runtime stack. It was
  212. * saved in the 'cpu_context' structure prior to the last
  213. * ERET from EL3.
  214. * -----------------------------------------------------
  215. */
  216. ldr x12, [x6, #CTX_EL3STATE_OFFSET + CTX_RUNTIME_SP]
  217. /* ---------------------------------------------
  218. * Switch back to SP_EL0 for the C runtime stack.
  219. * ---------------------------------------------
  220. */
  221. msr spsel, #MODE_SP_EL0
  222. mov sp, x12
  223. /* -----------------------------------------------------
  224. * Save the SPSR_EL3, ELR_EL3, & SCR_EL3 in case there
  225. * is a world switch during SMC handling.
  226. * -----------------------------------------------------
  227. */
  228. mrs x16, spsr_el3
  229. mrs x17, elr_el3
  230. mrs x18, scr_el3
  231. stp x16, x17, [x6, #CTX_EL3STATE_OFFSET + CTX_SPSR_EL3]
  232. str x18, [x6, #CTX_EL3STATE_OFFSET + CTX_SCR_EL3]
  233. /* Copy SCR_EL3.NS bit to the flag to indicate caller's security */
  234. bfi x7, x18, #0, #1
  235. /* -----------------------------------------------------
  236. * Go to BL1 SMC handler.
  237. * -----------------------------------------------------
  238. */
  239. bl bl1_smc_handler
  240. /* -----------------------------------------------------
  241. * Do the transition to next BL image.
  242. * -----------------------------------------------------
  243. */
  244. b el3_exit