1/* 2 * Copyright (c) 2013-2016, 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.h> 10#include <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 29 check_vector_size SynchronousExceptionSP0 30 31vector_entry IrqSP0 32 mov x0, #IRQ_SP_EL0 33 bl plat_report_exception 34 no_ret plat_panic_handler 35 check_vector_size IrqSP0 36 37vector_entry FiqSP0 38 mov x0, #FIQ_SP_EL0 39 bl plat_report_exception 40 no_ret plat_panic_handler 41 check_vector_size FiqSP0 42 43vector_entry SErrorSP0 44 mov x0, #SERROR_SP_EL0 45 bl plat_report_exception 46 no_ret plat_panic_handler 47 check_vector_size 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 57 check_vector_size SynchronousExceptionSPx 58 59vector_entry IrqSPx 60 mov x0, #IRQ_SP_ELX 61 bl plat_report_exception 62 no_ret plat_panic_handler 63 check_vector_size IrqSPx 64 65vector_entry FiqSPx 66 mov x0, #FIQ_SP_ELX 67 bl plat_report_exception 68 no_ret plat_panic_handler 69 check_vector_size FiqSPx 70 71vector_entry SErrorSPx 72 mov x0, #SERROR_SP_ELX 73 bl plat_report_exception 74 no_ret plat_panic_handler 75 check_vector_size 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 94 check_vector_size SynchronousExceptionA64 95 96vector_entry IrqA64 97 mov x0, #IRQ_AARCH64 98 bl plat_report_exception 99 no_ret plat_panic_handler 100 check_vector_size IrqA64 101 102vector_entry FiqA64 103 mov x0, #FIQ_AARCH64 104 bl plat_report_exception 105 no_ret plat_panic_handler 106 check_vector_size FiqA64 107 108vector_entry SErrorA64 109 mov x0, #SERROR_AARCH64 110 bl plat_report_exception 111 no_ret plat_panic_handler 112 check_vector_size 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 122 check_vector_size SynchronousExceptionA32 123 124vector_entry IrqA32 125 mov x0, #IRQ_AARCH32 126 bl plat_report_exception 127 no_ret plat_panic_handler 128 check_vector_size IrqA32 129 130vector_entry FiqA32 131 mov x0, #FIQ_AARCH32 132 bl plat_report_exception 133 no_ret plat_panic_handler 134 check_vector_size FiqA32 135 136vector_entry SErrorA32 137 mov x0, #SERROR_AARCH32 138 bl plat_report_exception 139 no_ret plat_panic_handler 140 check_vector_size 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, #0 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 191#if SPIN_ON_BL1_EXIT 192 bl print_debug_loop_message 193debug_loop: 194 b debug_loop 195#endif 196 197 mov x0, x20 198 bl bl1_plat_prepare_exit 199 200 ldp x6, x7, [x20, #(ENTRY_POINT_INFO_ARGS_OFFSET + 0x30)] 201 ldp x4, x5, [x20, #(ENTRY_POINT_INFO_ARGS_OFFSET + 0x20)] 202 ldp x2, x3, [x20, #(ENTRY_POINT_INFO_ARGS_OFFSET + 0x10)] 203 ldp x0, x1, [x20, #(ENTRY_POINT_INFO_ARGS_OFFSET + 0x0)] 204 eret 205endfunc smc_handler64 206 207unexpected_sync_exception: 208 mov x0, #SYNC_EXCEPTION_AARCH64 209 bl plat_report_exception 210 no_ret plat_panic_handler 211 212 /* ----------------------------------------------------- 213 * Save Secure/Normal world context and jump to 214 * BL1 SMC handler. 215 * ----------------------------------------------------- 216 */ 217smc_handler: 218 /* ----------------------------------------------------- 219 * Save the GP registers x0-x29. 220 * TODO: Revisit to store only SMCC specified registers. 221 * ----------------------------------------------------- 222 */ 223 bl save_gp_registers 224 225 /* ----------------------------------------------------- 226 * Populate the parameters for the SMC handler. We 227 * already have x0-x4 in place. x5 will point to a 228 * cookie (not used now). x6 will point to the context 229 * structure (SP_EL3) and x7 will contain flags we need 230 * to pass to the handler. 231 * ----------------------------------------------------- 232 */ 233 mov x5, xzr 234 mov x6, sp 235 236 /* ----------------------------------------------------- 237 * Restore the saved C runtime stack value which will 238 * become the new SP_EL0 i.e. EL3 runtime stack. It was 239 * saved in the 'cpu_context' structure prior to the last 240 * ERET from EL3. 241 * ----------------------------------------------------- 242 */ 243 ldr x12, [x6, #CTX_EL3STATE_OFFSET + CTX_RUNTIME_SP] 244 245 /* --------------------------------------------- 246 * Switch back to SP_EL0 for the C runtime stack. 247 * --------------------------------------------- 248 */ 249 msr spsel, #0 250 mov sp, x12 251 252 /* ----------------------------------------------------- 253 * Save the SPSR_EL3, ELR_EL3, & SCR_EL3 in case there 254 * is a world switch during SMC handling. 255 * ----------------------------------------------------- 256 */ 257 mrs x16, spsr_el3 258 mrs x17, elr_el3 259 mrs x18, scr_el3 260 stp x16, x17, [x6, #CTX_EL3STATE_OFFSET + CTX_SPSR_EL3] 261 str x18, [x6, #CTX_EL3STATE_OFFSET + CTX_SCR_EL3] 262 263 /* Copy SCR_EL3.NS bit to the flag to indicate caller's security */ 264 bfi x7, x18, #0, #1 265 266 /* ----------------------------------------------------- 267 * Go to BL1 SMC handler. 268 * ----------------------------------------------------- 269 */ 270 bl bl1_smc_handler 271 272 /* ----------------------------------------------------- 273 * Do the transition to next BL image. 274 * ----------------------------------------------------- 275 */ 276 b el3_exit 277