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