1/* 2 * Copyright (c) 2013-2020, 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 * If Secure Cycle Counter is not disabled in MDCR_EL3 222 * when ARMv8.5-PMU is implemented, save PMCR_EL0 and 223 * disable Cycle Counter. 224 * TODO: Revisit to store only SMCCC specified registers. 225 * ----------------------------------------------------- 226 */ 227 bl save_gp_pmcr_pauth_regs 228 229#if ENABLE_PAUTH 230 /* ----------------------------------------------------- 231 * Load and program stored APIAKey firmware key. 232 * Re-enable pointer authentication in EL3, as it was 233 * disabled before jumping to the next boot image. 234 * ----------------------------------------------------- 235 */ 236 bl pauth_load_bl1_apiakey_enable 237#endif 238 /* ----------------------------------------------------- 239 * Populate the parameters for the SMC handler. We 240 * already have x0-x4 in place. x5 will point to a 241 * cookie (not used now). x6 will point to the context 242 * structure (SP_EL3) and x7 will contain flags we need 243 * to pass to the handler. 244 * ----------------------------------------------------- 245 */ 246 mov x5, xzr 247 mov x6, sp 248 249 /* ----------------------------------------------------- 250 * Restore the saved C runtime stack value which will 251 * become the new SP_EL0 i.e. EL3 runtime stack. It was 252 * saved in the 'cpu_context' structure prior to the last 253 * ERET from EL3. 254 * ----------------------------------------------------- 255 */ 256 ldr x12, [x6, #CTX_EL3STATE_OFFSET + CTX_RUNTIME_SP] 257 258 /* --------------------------------------------- 259 * Switch back to SP_EL0 for the C runtime stack. 260 * --------------------------------------------- 261 */ 262 msr spsel, #MODE_SP_EL0 263 mov sp, x12 264 265 /* ----------------------------------------------------- 266 * Save the SPSR_EL3, ELR_EL3, & SCR_EL3 in case there 267 * is a world switch during SMC handling. 268 * ----------------------------------------------------- 269 */ 270 mrs x16, spsr_el3 271 mrs x17, elr_el3 272 mrs x18, scr_el3 273 stp x16, x17, [x6, #CTX_EL3STATE_OFFSET + CTX_SPSR_EL3] 274 str x18, [x6, #CTX_EL3STATE_OFFSET + CTX_SCR_EL3] 275 276 /* Copy SCR_EL3.NS bit to the flag to indicate caller's security */ 277 bfi x7, x18, #0, #1 278 279 /* ----------------------------------------------------- 280 * Go to BL1 SMC handler. 281 * ----------------------------------------------------- 282 */ 283 bl bl1_smc_handler 284 285 /* ----------------------------------------------------- 286 * Do the transition to next BL image. 287 * ----------------------------------------------------- 288 */ 289 b el3_exit 290