bl1_exceptions.S 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. /*
  2. * Copyright (c) 2016-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. #include <lib/xlat_tables/xlat_tables.h>
  12. #include <smccc_helpers.h>
  13. #include <smccc_macros.S>
  14. .globl bl1_aarch32_smc_handler
  15. func bl1_aarch32_smc_handler
  16. /* On SMC entry, `sp` points to `smc_ctx_t`. Save `lr`. */
  17. str lr, [sp, #SMC_CTX_LR_MON]
  18. /* ------------------------------------------------
  19. * SMC in BL1 is handled assuming that the MMU is
  20. * turned off by BL2.
  21. * ------------------------------------------------
  22. */
  23. /* ----------------------------------------------
  24. * Detect if this is a RUN_IMAGE or other SMC.
  25. * ----------------------------------------------
  26. */
  27. mov lr, #BL1_SMC_RUN_IMAGE
  28. cmp lr, r0
  29. bne smc_handler
  30. /* ------------------------------------------------
  31. * Make sure only Secure world reaches here.
  32. * ------------------------------------------------
  33. */
  34. ldcopr r8, SCR
  35. tst r8, #SCR_NS_BIT
  36. blne report_exception
  37. /* ---------------------------------------------------------------------
  38. * Pass control to next secure image.
  39. * Here it expects r1 to contain the address of a entry_point_info_t
  40. * structure describing the BL entrypoint.
  41. * ---------------------------------------------------------------------
  42. */
  43. mov r8, r1
  44. mov r0, r1
  45. bl bl1_print_next_bl_ep_info
  46. #if SPIN_ON_BL1_EXIT
  47. bl print_debug_loop_message
  48. debug_loop:
  49. b debug_loop
  50. #endif
  51. mov r0, r8
  52. bl bl1_plat_prepare_exit
  53. stcopr r0, TLBIALL
  54. dsb sy
  55. isb
  56. /*
  57. * Extract PC and SPSR based on struct `entry_point_info_t`
  58. * and load it in LR and SPSR registers respectively.
  59. */
  60. ldr lr, [r8, #ENTRY_POINT_INFO_PC_OFFSET]
  61. ldr r1, [r8, #(ENTRY_POINT_INFO_PC_OFFSET + 4)]
  62. msr spsr_xc, r1
  63. /* Some BL32 stages expect lr_svc to provide the BL33 entry address */
  64. cps #MODE32_svc
  65. ldr lr, [r8, #ENTRY_POINT_INFO_LR_SVC_OFFSET]
  66. cps #MODE32_mon
  67. add r8, r8, #ENTRY_POINT_INFO_ARGS_OFFSET
  68. ldm r8, {r0, r1, r2, r3}
  69. exception_return
  70. endfunc bl1_aarch32_smc_handler
  71. /* -----------------------------------------------------
  72. * Save Secure/Normal world context and jump to
  73. * BL1 SMC handler.
  74. * -----------------------------------------------------
  75. */
  76. func smc_handler
  77. /* -----------------------------------------------------
  78. * Save the GP registers.
  79. * -----------------------------------------------------
  80. */
  81. smccc_save_gp_mode_regs
  82. /*
  83. * `sp` still points to `smc_ctx_t`. Save it to a register
  84. * and restore the C runtime stack pointer to `sp`.
  85. */
  86. mov r6, sp
  87. ldr sp, [r6, #SMC_CTX_SP_MON]
  88. ldr r0, [r6, #SMC_CTX_SCR]
  89. and r7, r0, #SCR_NS_BIT /* flags */
  90. /* Switch to Secure Mode */
  91. bic r0, #SCR_NS_BIT
  92. stcopr r0, SCR
  93. isb
  94. /* If caller is from Secure world then turn on the MMU */
  95. tst r7, #SCR_NS_BIT
  96. bne skip_mmu_on
  97. /* Turn on the MMU */
  98. mov r0, #DISABLE_DCACHE
  99. bl enable_mmu_svc_mon
  100. /*
  101. * Invalidate `smc_ctx_t` in data cache to prevent dirty data being
  102. * used.
  103. */
  104. mov r0, r6
  105. mov r1, #SMC_CTX_SIZE
  106. bl inv_dcache_range
  107. /* Enable the data cache. */
  108. ldcopr r9, SCTLR
  109. orr r9, r9, #SCTLR_C_BIT
  110. stcopr r9, SCTLR
  111. isb
  112. skip_mmu_on:
  113. /* Prepare arguments for BL1 SMC wrapper. */
  114. ldr r0, [r6, #SMC_CTX_GPREG_R0] /* smc_fid */
  115. mov r1, #0 /* cookie */
  116. mov r2, r6 /* handle */
  117. mov r3, r7 /* flags */
  118. bl bl1_smc_wrapper
  119. /* Get the smc_context for next BL image */
  120. bl smc_get_next_ctx
  121. mov r4, r0
  122. /* Only turn-off MMU if going to secure world */
  123. ldr r5, [r4, #SMC_CTX_SCR]
  124. tst r5, #SCR_NS_BIT
  125. bne skip_mmu_off
  126. /* Disable the MMU */
  127. bl disable_mmu_icache_secure
  128. stcopr r0, TLBIALL
  129. dsb sy
  130. isb
  131. skip_mmu_off:
  132. /* -----------------------------------------------------
  133. * Do the transition to next BL image.
  134. * -----------------------------------------------------
  135. */
  136. mov r0, r4
  137. monitor_exit
  138. endfunc smc_handler