1*54fd6939SJiyong Park/* 2*54fd6939SJiyong Park * Copyright (c) 2013-2021, ARM Limited and Contributors. All rights reserved. 3*54fd6939SJiyong Park * 4*54fd6939SJiyong Park * SPDX-License-Identifier: BSD-3-Clause 5*54fd6939SJiyong Park */ 6*54fd6939SJiyong Park 7*54fd6939SJiyong Park#include <platform_def.h> 8*54fd6939SJiyong Park 9*54fd6939SJiyong Park#include <arch.h> 10*54fd6939SJiyong Park#include <asm_macros.S> 11*54fd6939SJiyong Park#include <bl31/ea_handle.h> 12*54fd6939SJiyong Park#include <bl31/interrupt_mgmt.h> 13*54fd6939SJiyong Park#include <common/runtime_svc.h> 14*54fd6939SJiyong Park#include <context.h> 15*54fd6939SJiyong Park#include <el3_common_macros.S> 16*54fd6939SJiyong Park#include <lib/el3_runtime/cpu_data.h> 17*54fd6939SJiyong Park#include <lib/smccc.h> 18*54fd6939SJiyong Park 19*54fd6939SJiyong Park .globl runtime_exceptions 20*54fd6939SJiyong Park 21*54fd6939SJiyong Park .globl sync_exception_sp_el0 22*54fd6939SJiyong Park .globl irq_sp_el0 23*54fd6939SJiyong Park .globl fiq_sp_el0 24*54fd6939SJiyong Park .globl serror_sp_el0 25*54fd6939SJiyong Park 26*54fd6939SJiyong Park .globl sync_exception_sp_elx 27*54fd6939SJiyong Park .globl irq_sp_elx 28*54fd6939SJiyong Park .globl fiq_sp_elx 29*54fd6939SJiyong Park .globl serror_sp_elx 30*54fd6939SJiyong Park 31*54fd6939SJiyong Park .globl sync_exception_aarch64 32*54fd6939SJiyong Park .globl irq_aarch64 33*54fd6939SJiyong Park .globl fiq_aarch64 34*54fd6939SJiyong Park .globl serror_aarch64 35*54fd6939SJiyong Park 36*54fd6939SJiyong Park .globl sync_exception_aarch32 37*54fd6939SJiyong Park .globl irq_aarch32 38*54fd6939SJiyong Park .globl fiq_aarch32 39*54fd6939SJiyong Park .globl serror_aarch32 40*54fd6939SJiyong Park 41*54fd6939SJiyong Park /* 42*54fd6939SJiyong Park * Macro that prepares entry to EL3 upon taking an exception. 43*54fd6939SJiyong Park * 44*54fd6939SJiyong Park * With RAS_EXTENSION, this macro synchronizes pending errors with an ESB 45*54fd6939SJiyong Park * instruction. When an error is thus synchronized, the handling is 46*54fd6939SJiyong Park * delegated to platform EA handler. 47*54fd6939SJiyong Park * 48*54fd6939SJiyong Park * Without RAS_EXTENSION, this macro synchronizes pending errors using 49*54fd6939SJiyong Park * a DSB, unmasks Asynchronous External Aborts and saves X30 before 50*54fd6939SJiyong Park * setting the flag CTX_IS_IN_EL3. 51*54fd6939SJiyong Park */ 52*54fd6939SJiyong Park .macro check_and_unmask_ea 53*54fd6939SJiyong Park#if RAS_EXTENSION 54*54fd6939SJiyong Park /* Synchronize pending External Aborts */ 55*54fd6939SJiyong Park esb 56*54fd6939SJiyong Park 57*54fd6939SJiyong Park /* Unmask the SError interrupt */ 58*54fd6939SJiyong Park msr daifclr, #DAIF_ABT_BIT 59*54fd6939SJiyong Park 60*54fd6939SJiyong Park /* 61*54fd6939SJiyong Park * Explicitly save x30 so as to free up a register and to enable 62*54fd6939SJiyong Park * branching 63*54fd6939SJiyong Park */ 64*54fd6939SJiyong Park str x30, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_LR] 65*54fd6939SJiyong Park 66*54fd6939SJiyong Park /* Check for SErrors synchronized by the ESB instruction */ 67*54fd6939SJiyong Park mrs x30, DISR_EL1 68*54fd6939SJiyong Park tbz x30, #DISR_A_BIT, 1f 69*54fd6939SJiyong Park 70*54fd6939SJiyong Park /* 71*54fd6939SJiyong Park * Save general purpose and ARMv8.3-PAuth registers (if enabled). 72*54fd6939SJiyong Park * If Secure Cycle Counter is not disabled in MDCR_EL3 when 73*54fd6939SJiyong Park * ARMv8.5-PMU is implemented, save PMCR_EL0 and disable Cycle Counter. 74*54fd6939SJiyong Park */ 75*54fd6939SJiyong Park bl save_gp_pmcr_pauth_regs 76*54fd6939SJiyong Park 77*54fd6939SJiyong Park bl handle_lower_el_ea_esb 78*54fd6939SJiyong Park 79*54fd6939SJiyong Park /* Restore general purpose, PMCR_EL0 and ARMv8.3-PAuth registers */ 80*54fd6939SJiyong Park bl restore_gp_pmcr_pauth_regs 81*54fd6939SJiyong Park1: 82*54fd6939SJiyong Park#else 83*54fd6939SJiyong Park /* 84*54fd6939SJiyong Park * For SoCs which do not implement RAS, use DSB as a barrier to 85*54fd6939SJiyong Park * synchronize pending external aborts. 86*54fd6939SJiyong Park */ 87*54fd6939SJiyong Park dsb sy 88*54fd6939SJiyong Park 89*54fd6939SJiyong Park /* Unmask the SError interrupt */ 90*54fd6939SJiyong Park msr daifclr, #DAIF_ABT_BIT 91*54fd6939SJiyong Park 92*54fd6939SJiyong Park /* Use ISB for the above unmask operation to take effect immediately */ 93*54fd6939SJiyong Park isb 94*54fd6939SJiyong Park 95*54fd6939SJiyong Park /* 96*54fd6939SJiyong Park * Refer Note 1. No need to restore X30 as both handle_sync_exception 97*54fd6939SJiyong Park * and handle_interrupt_exception macro which follow this macro modify 98*54fd6939SJiyong Park * X30 anyway. 99*54fd6939SJiyong Park */ 100*54fd6939SJiyong Park str x30, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_LR] 101*54fd6939SJiyong Park mov x30, #1 102*54fd6939SJiyong Park str x30, [sp, #CTX_EL3STATE_OFFSET + CTX_IS_IN_EL3] 103*54fd6939SJiyong Park dmb sy 104*54fd6939SJiyong Park#endif 105*54fd6939SJiyong Park .endm 106*54fd6939SJiyong Park 107*54fd6939SJiyong Park#if !RAS_EXTENSION 108*54fd6939SJiyong Park /* 109*54fd6939SJiyong Park * Note 1: The explicit DSB at the entry of various exception vectors 110*54fd6939SJiyong Park * for handling exceptions from lower ELs can inadvertently trigger an 111*54fd6939SJiyong Park * SError exception in EL3 due to pending asynchronous aborts in lower 112*54fd6939SJiyong Park * ELs. This will end up being handled by serror_sp_elx which will 113*54fd6939SJiyong Park * ultimately panic and die. 114*54fd6939SJiyong Park * The way to workaround is to update a flag to indicate if the exception 115*54fd6939SJiyong Park * truly came from EL3. This flag is allocated in the cpu_context 116*54fd6939SJiyong Park * structure and located at offset "CTX_EL3STATE_OFFSET + CTX_IS_IN_EL3" 117*54fd6939SJiyong Park * This is not a bullet proof solution to the problem at hand because 118*54fd6939SJiyong Park * we assume the instructions following "isb" that help to update the 119*54fd6939SJiyong Park * flag execute without causing further exceptions. 120*54fd6939SJiyong Park */ 121*54fd6939SJiyong Park 122*54fd6939SJiyong Park /* --------------------------------------------------------------------- 123*54fd6939SJiyong Park * This macro handles Asynchronous External Aborts. 124*54fd6939SJiyong Park * --------------------------------------------------------------------- 125*54fd6939SJiyong Park */ 126*54fd6939SJiyong Park .macro handle_async_ea 127*54fd6939SJiyong Park /* 128*54fd6939SJiyong Park * Use a barrier to synchronize pending external aborts. 129*54fd6939SJiyong Park */ 130*54fd6939SJiyong Park dsb sy 131*54fd6939SJiyong Park 132*54fd6939SJiyong Park /* Unmask the SError interrupt */ 133*54fd6939SJiyong Park msr daifclr, #DAIF_ABT_BIT 134*54fd6939SJiyong Park 135*54fd6939SJiyong Park /* Use ISB for the above unmask operation to take effect immediately */ 136*54fd6939SJiyong Park isb 137*54fd6939SJiyong Park 138*54fd6939SJiyong Park /* Refer Note 1 */ 139*54fd6939SJiyong Park str x30, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_LR] 140*54fd6939SJiyong Park mov x30, #1 141*54fd6939SJiyong Park str x30, [sp, #CTX_EL3STATE_OFFSET + CTX_IS_IN_EL3] 142*54fd6939SJiyong Park dmb sy 143*54fd6939SJiyong Park 144*54fd6939SJiyong Park b handle_lower_el_async_ea 145*54fd6939SJiyong Park .endm 146*54fd6939SJiyong Park 147*54fd6939SJiyong Park /* 148*54fd6939SJiyong Park * This macro checks if the exception was taken due to SError in EL3 or 149*54fd6939SJiyong Park * because of pending asynchronous external aborts from lower EL that got 150*54fd6939SJiyong Park * triggered due to explicit synchronization in EL3. Refer Note 1. 151*54fd6939SJiyong Park */ 152*54fd6939SJiyong Park .macro check_if_serror_from_EL3 153*54fd6939SJiyong Park /* Assumes SP_EL3 on entry */ 154*54fd6939SJiyong Park str x30, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_LR] 155*54fd6939SJiyong Park ldr x30, [sp, #CTX_EL3STATE_OFFSET + CTX_IS_IN_EL3] 156*54fd6939SJiyong Park cbnz x30, exp_from_EL3 157*54fd6939SJiyong Park 158*54fd6939SJiyong Park /* Handle asynchronous external abort from lower EL */ 159*54fd6939SJiyong Park b handle_lower_el_async_ea 160*54fd6939SJiyong Park 161*54fd6939SJiyong Parkexp_from_EL3: 162*54fd6939SJiyong Park /* Jump to plat_handle_el3_ea which does not return */ 163*54fd6939SJiyong Park .endm 164*54fd6939SJiyong Park#endif 165*54fd6939SJiyong Park 166*54fd6939SJiyong Park /* --------------------------------------------------------------------- 167*54fd6939SJiyong Park * This macro handles Synchronous exceptions. 168*54fd6939SJiyong Park * Only SMC exceptions are supported. 169*54fd6939SJiyong Park * --------------------------------------------------------------------- 170*54fd6939SJiyong Park */ 171*54fd6939SJiyong Park .macro handle_sync_exception 172*54fd6939SJiyong Park#if ENABLE_RUNTIME_INSTRUMENTATION 173*54fd6939SJiyong Park /* 174*54fd6939SJiyong Park * Read the timestamp value and store it in per-cpu data. The value 175*54fd6939SJiyong Park * will be extracted from per-cpu data by the C level SMC handler and 176*54fd6939SJiyong Park * saved to the PMF timestamp region. 177*54fd6939SJiyong Park */ 178*54fd6939SJiyong Park mrs x30, cntpct_el0 179*54fd6939SJiyong Park str x29, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X29] 180*54fd6939SJiyong Park mrs x29, tpidr_el3 181*54fd6939SJiyong Park str x30, [x29, #CPU_DATA_PMF_TS0_OFFSET] 182*54fd6939SJiyong Park ldr x29, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X29] 183*54fd6939SJiyong Park#endif 184*54fd6939SJiyong Park 185*54fd6939SJiyong Park mrs x30, esr_el3 186*54fd6939SJiyong Park ubfx x30, x30, #ESR_EC_SHIFT, #ESR_EC_LENGTH 187*54fd6939SJiyong Park 188*54fd6939SJiyong Park /* Handle SMC exceptions separately from other synchronous exceptions */ 189*54fd6939SJiyong Park cmp x30, #EC_AARCH32_SMC 190*54fd6939SJiyong Park b.eq smc_handler32 191*54fd6939SJiyong Park 192*54fd6939SJiyong Park cmp x30, #EC_AARCH64_SMC 193*54fd6939SJiyong Park b.eq smc_handler64 194*54fd6939SJiyong Park 195*54fd6939SJiyong Park /* Synchronous exceptions other than the above are assumed to be EA */ 196*54fd6939SJiyong Park ldr x30, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_LR] 197*54fd6939SJiyong Park b enter_lower_el_sync_ea 198*54fd6939SJiyong Park .endm 199*54fd6939SJiyong Park 200*54fd6939SJiyong Park 201*54fd6939SJiyong Park /* --------------------------------------------------------------------- 202*54fd6939SJiyong Park * This macro handles FIQ or IRQ interrupts i.e. EL3, S-EL1 and NS 203*54fd6939SJiyong Park * interrupts. 204*54fd6939SJiyong Park * --------------------------------------------------------------------- 205*54fd6939SJiyong Park */ 206*54fd6939SJiyong Park .macro handle_interrupt_exception label 207*54fd6939SJiyong Park 208*54fd6939SJiyong Park /* 209*54fd6939SJiyong Park * Save general purpose and ARMv8.3-PAuth registers (if enabled). 210*54fd6939SJiyong Park * If Secure Cycle Counter is not disabled in MDCR_EL3 when 211*54fd6939SJiyong Park * ARMv8.5-PMU is implemented, save PMCR_EL0 and disable Cycle Counter. 212*54fd6939SJiyong Park */ 213*54fd6939SJiyong Park bl save_gp_pmcr_pauth_regs 214*54fd6939SJiyong Park 215*54fd6939SJiyong Park#if ENABLE_PAUTH 216*54fd6939SJiyong Park /* Load and program APIAKey firmware key */ 217*54fd6939SJiyong Park bl pauth_load_bl31_apiakey 218*54fd6939SJiyong Park#endif 219*54fd6939SJiyong Park 220*54fd6939SJiyong Park /* Save the EL3 system registers needed to return from this exception */ 221*54fd6939SJiyong Park mrs x0, spsr_el3 222*54fd6939SJiyong Park mrs x1, elr_el3 223*54fd6939SJiyong Park stp x0, x1, [sp, #CTX_EL3STATE_OFFSET + CTX_SPSR_EL3] 224*54fd6939SJiyong Park 225*54fd6939SJiyong Park /* Switch to the runtime stack i.e. SP_EL0 */ 226*54fd6939SJiyong Park ldr x2, [sp, #CTX_EL3STATE_OFFSET + CTX_RUNTIME_SP] 227*54fd6939SJiyong Park mov x20, sp 228*54fd6939SJiyong Park msr spsel, #MODE_SP_EL0 229*54fd6939SJiyong Park mov sp, x2 230*54fd6939SJiyong Park 231*54fd6939SJiyong Park /* 232*54fd6939SJiyong Park * Find out whether this is a valid interrupt type. 233*54fd6939SJiyong Park * If the interrupt controller reports a spurious interrupt then return 234*54fd6939SJiyong Park * to where we came from. 235*54fd6939SJiyong Park */ 236*54fd6939SJiyong Park bl plat_ic_get_pending_interrupt_type 237*54fd6939SJiyong Park cmp x0, #INTR_TYPE_INVAL 238*54fd6939SJiyong Park b.eq interrupt_exit_\label 239*54fd6939SJiyong Park 240*54fd6939SJiyong Park /* 241*54fd6939SJiyong Park * Get the registered handler for this interrupt type. 242*54fd6939SJiyong Park * A NULL return value could be 'cause of the following conditions: 243*54fd6939SJiyong Park * 244*54fd6939SJiyong Park * a. An interrupt of a type was routed correctly but a handler for its 245*54fd6939SJiyong Park * type was not registered. 246*54fd6939SJiyong Park * 247*54fd6939SJiyong Park * b. An interrupt of a type was not routed correctly so a handler for 248*54fd6939SJiyong Park * its type was not registered. 249*54fd6939SJiyong Park * 250*54fd6939SJiyong Park * c. An interrupt of a type was routed correctly to EL3, but was 251*54fd6939SJiyong Park * deasserted before its pending state could be read. Another 252*54fd6939SJiyong Park * interrupt of a different type pended at the same time and its 253*54fd6939SJiyong Park * type was reported as pending instead. However, a handler for this 254*54fd6939SJiyong Park * type was not registered. 255*54fd6939SJiyong Park * 256*54fd6939SJiyong Park * a. and b. can only happen due to a programming error. The 257*54fd6939SJiyong Park * occurrence of c. could be beyond the control of Trusted Firmware. 258*54fd6939SJiyong Park * It makes sense to return from this exception instead of reporting an 259*54fd6939SJiyong Park * error. 260*54fd6939SJiyong Park */ 261*54fd6939SJiyong Park bl get_interrupt_type_handler 262*54fd6939SJiyong Park cbz x0, interrupt_exit_\label 263*54fd6939SJiyong Park mov x21, x0 264*54fd6939SJiyong Park 265*54fd6939SJiyong Park mov x0, #INTR_ID_UNAVAILABLE 266*54fd6939SJiyong Park 267*54fd6939SJiyong Park /* Set the current security state in the 'flags' parameter */ 268*54fd6939SJiyong Park mrs x2, scr_el3 269*54fd6939SJiyong Park ubfx x1, x2, #0, #1 270*54fd6939SJiyong Park 271*54fd6939SJiyong Park /* Restore the reference to the 'handle' i.e. SP_EL3 */ 272*54fd6939SJiyong Park mov x2, x20 273*54fd6939SJiyong Park 274*54fd6939SJiyong Park /* x3 will point to a cookie (not used now) */ 275*54fd6939SJiyong Park mov x3, xzr 276*54fd6939SJiyong Park 277*54fd6939SJiyong Park /* Call the interrupt type handler */ 278*54fd6939SJiyong Park blr x21 279*54fd6939SJiyong Park 280*54fd6939SJiyong Parkinterrupt_exit_\label: 281*54fd6939SJiyong Park /* Return from exception, possibly in a different security state */ 282*54fd6939SJiyong Park b el3_exit 283*54fd6939SJiyong Park 284*54fd6939SJiyong Park .endm 285*54fd6939SJiyong Park 286*54fd6939SJiyong Park 287*54fd6939SJiyong Parkvector_base runtime_exceptions 288*54fd6939SJiyong Park 289*54fd6939SJiyong Park /* --------------------------------------------------------------------- 290*54fd6939SJiyong Park * Current EL with SP_EL0 : 0x0 - 0x200 291*54fd6939SJiyong Park * --------------------------------------------------------------------- 292*54fd6939SJiyong Park */ 293*54fd6939SJiyong Parkvector_entry sync_exception_sp_el0 294*54fd6939SJiyong Park#ifdef MONITOR_TRAPS 295*54fd6939SJiyong Park stp x29, x30, [sp, #-16]! 296*54fd6939SJiyong Park 297*54fd6939SJiyong Park mrs x30, esr_el3 298*54fd6939SJiyong Park ubfx x30, x30, #ESR_EC_SHIFT, #ESR_EC_LENGTH 299*54fd6939SJiyong Park 300*54fd6939SJiyong Park /* Check for BRK */ 301*54fd6939SJiyong Park cmp x30, #EC_BRK 302*54fd6939SJiyong Park b.eq brk_handler 303*54fd6939SJiyong Park 304*54fd6939SJiyong Park ldp x29, x30, [sp], #16 305*54fd6939SJiyong Park#endif /* MONITOR_TRAPS */ 306*54fd6939SJiyong Park 307*54fd6939SJiyong Park /* We don't expect any synchronous exceptions from EL3 */ 308*54fd6939SJiyong Park b report_unhandled_exception 309*54fd6939SJiyong Parkend_vector_entry sync_exception_sp_el0 310*54fd6939SJiyong Park 311*54fd6939SJiyong Parkvector_entry irq_sp_el0 312*54fd6939SJiyong Park /* 313*54fd6939SJiyong Park * EL3 code is non-reentrant. Any asynchronous exception is a serious 314*54fd6939SJiyong Park * error. Loop infinitely. 315*54fd6939SJiyong Park */ 316*54fd6939SJiyong Park b report_unhandled_interrupt 317*54fd6939SJiyong Parkend_vector_entry irq_sp_el0 318*54fd6939SJiyong Park 319*54fd6939SJiyong Park 320*54fd6939SJiyong Parkvector_entry fiq_sp_el0 321*54fd6939SJiyong Park b report_unhandled_interrupt 322*54fd6939SJiyong Parkend_vector_entry fiq_sp_el0 323*54fd6939SJiyong Park 324*54fd6939SJiyong Park 325*54fd6939SJiyong Parkvector_entry serror_sp_el0 326*54fd6939SJiyong Park no_ret plat_handle_el3_ea 327*54fd6939SJiyong Parkend_vector_entry serror_sp_el0 328*54fd6939SJiyong Park 329*54fd6939SJiyong Park /* --------------------------------------------------------------------- 330*54fd6939SJiyong Park * Current EL with SP_ELx: 0x200 - 0x400 331*54fd6939SJiyong Park * --------------------------------------------------------------------- 332*54fd6939SJiyong Park */ 333*54fd6939SJiyong Parkvector_entry sync_exception_sp_elx 334*54fd6939SJiyong Park /* 335*54fd6939SJiyong Park * This exception will trigger if anything went wrong during a previous 336*54fd6939SJiyong Park * exception entry or exit or while handling an earlier unexpected 337*54fd6939SJiyong Park * synchronous exception. There is a high probability that SP_EL3 is 338*54fd6939SJiyong Park * corrupted. 339*54fd6939SJiyong Park */ 340*54fd6939SJiyong Park b report_unhandled_exception 341*54fd6939SJiyong Parkend_vector_entry sync_exception_sp_elx 342*54fd6939SJiyong Park 343*54fd6939SJiyong Parkvector_entry irq_sp_elx 344*54fd6939SJiyong Park b report_unhandled_interrupt 345*54fd6939SJiyong Parkend_vector_entry irq_sp_elx 346*54fd6939SJiyong Park 347*54fd6939SJiyong Parkvector_entry fiq_sp_elx 348*54fd6939SJiyong Park b report_unhandled_interrupt 349*54fd6939SJiyong Parkend_vector_entry fiq_sp_elx 350*54fd6939SJiyong Park 351*54fd6939SJiyong Parkvector_entry serror_sp_elx 352*54fd6939SJiyong Park#if !RAS_EXTENSION 353*54fd6939SJiyong Park check_if_serror_from_EL3 354*54fd6939SJiyong Park#endif 355*54fd6939SJiyong Park no_ret plat_handle_el3_ea 356*54fd6939SJiyong Parkend_vector_entry serror_sp_elx 357*54fd6939SJiyong Park 358*54fd6939SJiyong Park /* --------------------------------------------------------------------- 359*54fd6939SJiyong Park * Lower EL using AArch64 : 0x400 - 0x600 360*54fd6939SJiyong Park * --------------------------------------------------------------------- 361*54fd6939SJiyong Park */ 362*54fd6939SJiyong Parkvector_entry sync_exception_aarch64 363*54fd6939SJiyong Park /* 364*54fd6939SJiyong Park * This exception vector will be the entry point for SMCs and traps 365*54fd6939SJiyong Park * that are unhandled at lower ELs most commonly. SP_EL3 should point 366*54fd6939SJiyong Park * to a valid cpu context where the general purpose and system register 367*54fd6939SJiyong Park * state can be saved. 368*54fd6939SJiyong Park */ 369*54fd6939SJiyong Park apply_at_speculative_wa 370*54fd6939SJiyong Park check_and_unmask_ea 371*54fd6939SJiyong Park handle_sync_exception 372*54fd6939SJiyong Parkend_vector_entry sync_exception_aarch64 373*54fd6939SJiyong Park 374*54fd6939SJiyong Parkvector_entry irq_aarch64 375*54fd6939SJiyong Park apply_at_speculative_wa 376*54fd6939SJiyong Park check_and_unmask_ea 377*54fd6939SJiyong Park handle_interrupt_exception irq_aarch64 378*54fd6939SJiyong Parkend_vector_entry irq_aarch64 379*54fd6939SJiyong Park 380*54fd6939SJiyong Parkvector_entry fiq_aarch64 381*54fd6939SJiyong Park apply_at_speculative_wa 382*54fd6939SJiyong Park check_and_unmask_ea 383*54fd6939SJiyong Park handle_interrupt_exception fiq_aarch64 384*54fd6939SJiyong Parkend_vector_entry fiq_aarch64 385*54fd6939SJiyong Park 386*54fd6939SJiyong Parkvector_entry serror_aarch64 387*54fd6939SJiyong Park apply_at_speculative_wa 388*54fd6939SJiyong Park#if RAS_EXTENSION 389*54fd6939SJiyong Park msr daifclr, #DAIF_ABT_BIT 390*54fd6939SJiyong Park b enter_lower_el_async_ea 391*54fd6939SJiyong Park#else 392*54fd6939SJiyong Park handle_async_ea 393*54fd6939SJiyong Park#endif 394*54fd6939SJiyong Parkend_vector_entry serror_aarch64 395*54fd6939SJiyong Park 396*54fd6939SJiyong Park /* --------------------------------------------------------------------- 397*54fd6939SJiyong Park * Lower EL using AArch32 : 0x600 - 0x800 398*54fd6939SJiyong Park * --------------------------------------------------------------------- 399*54fd6939SJiyong Park */ 400*54fd6939SJiyong Parkvector_entry sync_exception_aarch32 401*54fd6939SJiyong Park /* 402*54fd6939SJiyong Park * This exception vector will be the entry point for SMCs and traps 403*54fd6939SJiyong Park * that are unhandled at lower ELs most commonly. SP_EL3 should point 404*54fd6939SJiyong Park * to a valid cpu context where the general purpose and system register 405*54fd6939SJiyong Park * state can be saved. 406*54fd6939SJiyong Park */ 407*54fd6939SJiyong Park apply_at_speculative_wa 408*54fd6939SJiyong Park check_and_unmask_ea 409*54fd6939SJiyong Park handle_sync_exception 410*54fd6939SJiyong Parkend_vector_entry sync_exception_aarch32 411*54fd6939SJiyong Park 412*54fd6939SJiyong Parkvector_entry irq_aarch32 413*54fd6939SJiyong Park apply_at_speculative_wa 414*54fd6939SJiyong Park check_and_unmask_ea 415*54fd6939SJiyong Park handle_interrupt_exception irq_aarch32 416*54fd6939SJiyong Parkend_vector_entry irq_aarch32 417*54fd6939SJiyong Park 418*54fd6939SJiyong Parkvector_entry fiq_aarch32 419*54fd6939SJiyong Park apply_at_speculative_wa 420*54fd6939SJiyong Park check_and_unmask_ea 421*54fd6939SJiyong Park handle_interrupt_exception fiq_aarch32 422*54fd6939SJiyong Parkend_vector_entry fiq_aarch32 423*54fd6939SJiyong Park 424*54fd6939SJiyong Parkvector_entry serror_aarch32 425*54fd6939SJiyong Park apply_at_speculative_wa 426*54fd6939SJiyong Park#if RAS_EXTENSION 427*54fd6939SJiyong Park msr daifclr, #DAIF_ABT_BIT 428*54fd6939SJiyong Park b enter_lower_el_async_ea 429*54fd6939SJiyong Park#else 430*54fd6939SJiyong Park handle_async_ea 431*54fd6939SJiyong Park#endif 432*54fd6939SJiyong Parkend_vector_entry serror_aarch32 433*54fd6939SJiyong Park 434*54fd6939SJiyong Park#ifdef MONITOR_TRAPS 435*54fd6939SJiyong Park .section .rodata.brk_string, "aS" 436*54fd6939SJiyong Parkbrk_location: 437*54fd6939SJiyong Park .asciz "Error at instruction 0x" 438*54fd6939SJiyong Parkbrk_message: 439*54fd6939SJiyong Park .asciz "Unexpected BRK instruction with value 0x" 440*54fd6939SJiyong Park#endif /* MONITOR_TRAPS */ 441*54fd6939SJiyong Park 442*54fd6939SJiyong Park /* --------------------------------------------------------------------- 443*54fd6939SJiyong Park * The following code handles secure monitor calls. 444*54fd6939SJiyong Park * Depending upon the execution state from where the SMC has been 445*54fd6939SJiyong Park * invoked, it frees some general purpose registers to perform the 446*54fd6939SJiyong Park * remaining tasks. They involve finding the runtime service handler 447*54fd6939SJiyong Park * that is the target of the SMC & switching to runtime stacks (SP_EL0) 448*54fd6939SJiyong Park * before calling the handler. 449*54fd6939SJiyong Park * 450*54fd6939SJiyong Park * Note that x30 has been explicitly saved and can be used here 451*54fd6939SJiyong Park * --------------------------------------------------------------------- 452*54fd6939SJiyong Park */ 453*54fd6939SJiyong Parkfunc smc_handler 454*54fd6939SJiyong Parksmc_handler32: 455*54fd6939SJiyong Park /* Check whether aarch32 issued an SMC64 */ 456*54fd6939SJiyong Park tbnz x0, #FUNCID_CC_SHIFT, smc_prohibited 457*54fd6939SJiyong Park 458*54fd6939SJiyong Parksmc_handler64: 459*54fd6939SJiyong Park /* NOTE: The code below must preserve x0-x4 */ 460*54fd6939SJiyong Park 461*54fd6939SJiyong Park /* 462*54fd6939SJiyong Park * Save general purpose and ARMv8.3-PAuth registers (if enabled). 463*54fd6939SJiyong Park * If Secure Cycle Counter is not disabled in MDCR_EL3 when 464*54fd6939SJiyong Park * ARMv8.5-PMU is implemented, save PMCR_EL0 and disable Cycle Counter. 465*54fd6939SJiyong Park */ 466*54fd6939SJiyong Park bl save_gp_pmcr_pauth_regs 467*54fd6939SJiyong Park 468*54fd6939SJiyong Park#if ENABLE_PAUTH 469*54fd6939SJiyong Park /* Load and program APIAKey firmware key */ 470*54fd6939SJiyong Park bl pauth_load_bl31_apiakey 471*54fd6939SJiyong Park#endif 472*54fd6939SJiyong Park 473*54fd6939SJiyong Park /* 474*54fd6939SJiyong Park * Populate the parameters for the SMC handler. 475*54fd6939SJiyong Park * We already have x0-x4 in place. x5 will point to a cookie (not used 476*54fd6939SJiyong Park * now). x6 will point to the context structure (SP_EL3) and x7 will 477*54fd6939SJiyong Park * contain flags we need to pass to the handler. 478*54fd6939SJiyong Park */ 479*54fd6939SJiyong Park mov x5, xzr 480*54fd6939SJiyong Park mov x6, sp 481*54fd6939SJiyong Park 482*54fd6939SJiyong Park /* 483*54fd6939SJiyong Park * Restore the saved C runtime stack value which will become the new 484*54fd6939SJiyong Park * SP_EL0 i.e. EL3 runtime stack. It was saved in the 'cpu_context' 485*54fd6939SJiyong Park * structure prior to the last ERET from EL3. 486*54fd6939SJiyong Park */ 487*54fd6939SJiyong Park ldr x12, [x6, #CTX_EL3STATE_OFFSET + CTX_RUNTIME_SP] 488*54fd6939SJiyong Park 489*54fd6939SJiyong Park /* Switch to SP_EL0 */ 490*54fd6939SJiyong Park msr spsel, #MODE_SP_EL0 491*54fd6939SJiyong Park 492*54fd6939SJiyong Park /* 493*54fd6939SJiyong Park * Save the SPSR_EL3, ELR_EL3, & SCR_EL3 in case there is a world 494*54fd6939SJiyong Park * switch during SMC handling. 495*54fd6939SJiyong Park * TODO: Revisit if all system registers can be saved later. 496*54fd6939SJiyong Park */ 497*54fd6939SJiyong Park mrs x16, spsr_el3 498*54fd6939SJiyong Park mrs x17, elr_el3 499*54fd6939SJiyong Park mrs x18, scr_el3 500*54fd6939SJiyong Park stp x16, x17, [x6, #CTX_EL3STATE_OFFSET + CTX_SPSR_EL3] 501*54fd6939SJiyong Park str x18, [x6, #CTX_EL3STATE_OFFSET + CTX_SCR_EL3] 502*54fd6939SJiyong Park 503*54fd6939SJiyong Park /* Clear flag register */ 504*54fd6939SJiyong Park mov x7, xzr 505*54fd6939SJiyong Park 506*54fd6939SJiyong Park#if ENABLE_RME 507*54fd6939SJiyong Park /* Copy SCR_EL3.NSE bit to the flag to indicate caller's security */ 508*54fd6939SJiyong Park ubfx x7, x18, #SCR_NSE_SHIFT, 1 509*54fd6939SJiyong Park 510*54fd6939SJiyong Park /* 511*54fd6939SJiyong Park * Shift copied SCR_EL3.NSE bit by 5 to create space for 512*54fd6939SJiyong Park * SCR_EL3.NS bit. Bit 5 of the flag correspondes to 513*54fd6939SJiyong Park * the SCR_EL3.NSE bit. 514*54fd6939SJiyong Park */ 515*54fd6939SJiyong Park lsl x7, x7, #5 516*54fd6939SJiyong Park#endif /* ENABLE_RME */ 517*54fd6939SJiyong Park 518*54fd6939SJiyong Park /* Copy SCR_EL3.NS bit to the flag to indicate caller's security */ 519*54fd6939SJiyong Park bfi x7, x18, #0, #1 520*54fd6939SJiyong Park 521*54fd6939SJiyong Park mov sp, x12 522*54fd6939SJiyong Park 523*54fd6939SJiyong Park /* Get the unique owning entity number */ 524*54fd6939SJiyong Park ubfx x16, x0, #FUNCID_OEN_SHIFT, #FUNCID_OEN_WIDTH 525*54fd6939SJiyong Park ubfx x15, x0, #FUNCID_TYPE_SHIFT, #FUNCID_TYPE_WIDTH 526*54fd6939SJiyong Park orr x16, x16, x15, lsl #FUNCID_OEN_WIDTH 527*54fd6939SJiyong Park 528*54fd6939SJiyong Park /* Load descriptor index from array of indices */ 529*54fd6939SJiyong Park adrp x14, rt_svc_descs_indices 530*54fd6939SJiyong Park add x14, x14, :lo12:rt_svc_descs_indices 531*54fd6939SJiyong Park ldrb w15, [x14, x16] 532*54fd6939SJiyong Park 533*54fd6939SJiyong Park /* Any index greater than 127 is invalid. Check bit 7. */ 534*54fd6939SJiyong Park tbnz w15, 7, smc_unknown 535*54fd6939SJiyong Park 536*54fd6939SJiyong Park /* 537*54fd6939SJiyong Park * Get the descriptor using the index 538*54fd6939SJiyong Park * x11 = (base + off), w15 = index 539*54fd6939SJiyong Park * 540*54fd6939SJiyong Park * handler = (base + off) + (index << log2(size)) 541*54fd6939SJiyong Park */ 542*54fd6939SJiyong Park adr x11, (__RT_SVC_DESCS_START__ + RT_SVC_DESC_HANDLE) 543*54fd6939SJiyong Park lsl w10, w15, #RT_SVC_SIZE_LOG2 544*54fd6939SJiyong Park ldr x15, [x11, w10, uxtw] 545*54fd6939SJiyong Park 546*54fd6939SJiyong Park /* 547*54fd6939SJiyong Park * Call the Secure Monitor Call handler and then drop directly into 548*54fd6939SJiyong Park * el3_exit() which will program any remaining architectural state 549*54fd6939SJiyong Park * prior to issuing the ERET to the desired lower EL. 550*54fd6939SJiyong Park */ 551*54fd6939SJiyong Park#if DEBUG 552*54fd6939SJiyong Park cbz x15, rt_svc_fw_critical_error 553*54fd6939SJiyong Park#endif 554*54fd6939SJiyong Park blr x15 555*54fd6939SJiyong Park 556*54fd6939SJiyong Park b el3_exit 557*54fd6939SJiyong Park 558*54fd6939SJiyong Parksmc_unknown: 559*54fd6939SJiyong Park /* 560*54fd6939SJiyong Park * Unknown SMC call. Populate return value with SMC_UNK and call 561*54fd6939SJiyong Park * el3_exit() which will restore the remaining architectural state 562*54fd6939SJiyong Park * i.e., SYS, GP and PAuth registers(if any) prior to issuing the ERET 563*54fd6939SJiyong Park * to the desired lower EL. 564*54fd6939SJiyong Park */ 565*54fd6939SJiyong Park mov x0, #SMC_UNK 566*54fd6939SJiyong Park str x0, [x6, #CTX_GPREGS_OFFSET + CTX_GPREG_X0] 567*54fd6939SJiyong Park b el3_exit 568*54fd6939SJiyong Park 569*54fd6939SJiyong Parksmc_prohibited: 570*54fd6939SJiyong Park restore_ptw_el1_sys_regs 571*54fd6939SJiyong Park ldp x28, x29, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X28] 572*54fd6939SJiyong Park ldr x30, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_LR] 573*54fd6939SJiyong Park mov x0, #SMC_UNK 574*54fd6939SJiyong Park exception_return 575*54fd6939SJiyong Park 576*54fd6939SJiyong Park#if DEBUG 577*54fd6939SJiyong Parkrt_svc_fw_critical_error: 578*54fd6939SJiyong Park /* Switch to SP_ELx */ 579*54fd6939SJiyong Park msr spsel, #MODE_SP_ELX 580*54fd6939SJiyong Park no_ret report_unhandled_exception 581*54fd6939SJiyong Park#endif 582*54fd6939SJiyong Parkendfunc smc_handler 583*54fd6939SJiyong Park 584*54fd6939SJiyong Park /* --------------------------------------------------------------------- 585*54fd6939SJiyong Park * The following code handles exceptions caused by BRK instructions. 586*54fd6939SJiyong Park * Following a BRK instruction, the only real valid cause of action is 587*54fd6939SJiyong Park * to print some information and panic, as the code that caused it is 588*54fd6939SJiyong Park * likely in an inconsistent internal state. 589*54fd6939SJiyong Park * 590*54fd6939SJiyong Park * This is initially intended to be used in conjunction with 591*54fd6939SJiyong Park * __builtin_trap. 592*54fd6939SJiyong Park * --------------------------------------------------------------------- 593*54fd6939SJiyong Park */ 594*54fd6939SJiyong Park#ifdef MONITOR_TRAPS 595*54fd6939SJiyong Parkfunc brk_handler 596*54fd6939SJiyong Park /* Extract the ISS */ 597*54fd6939SJiyong Park mrs x10, esr_el3 598*54fd6939SJiyong Park ubfx x10, x10, #ESR_ISS_SHIFT, #ESR_ISS_LENGTH 599*54fd6939SJiyong Park 600*54fd6939SJiyong Park /* Ensure the console is initialized */ 601*54fd6939SJiyong Park bl plat_crash_console_init 602*54fd6939SJiyong Park 603*54fd6939SJiyong Park adr x4, brk_location 604*54fd6939SJiyong Park bl asm_print_str 605*54fd6939SJiyong Park mrs x4, elr_el3 606*54fd6939SJiyong Park bl asm_print_hex 607*54fd6939SJiyong Park bl asm_print_newline 608*54fd6939SJiyong Park 609*54fd6939SJiyong Park adr x4, brk_message 610*54fd6939SJiyong Park bl asm_print_str 611*54fd6939SJiyong Park mov x4, x10 612*54fd6939SJiyong Park mov x5, #28 613*54fd6939SJiyong Park bl asm_print_hex_bits 614*54fd6939SJiyong Park bl asm_print_newline 615*54fd6939SJiyong Park 616*54fd6939SJiyong Park no_ret plat_panic_handler 617*54fd6939SJiyong Parkendfunc brk_handler 618*54fd6939SJiyong Park#endif /* MONITOR_TRAPS */ 619