1df8f3188SJeenu Viswambharan/* 25283962eSAntonio Nino Diaz * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved. 3df8f3188SJeenu Viswambharan * 4df8f3188SJeenu Viswambharan * SPDX-License-Identifier: BSD-3-Clause 5df8f3188SJeenu Viswambharan */ 6df8f3188SJeenu Viswambharan 7df8f3188SJeenu Viswambharan 8d5a23af5SJeenu Viswambharan#include <assert_macros.S> 9df8f3188SJeenu Viswambharan#include <asm_macros.S> 10ee6ff1bbSJeenu Viswambharan#include <assert_macros.S> 1109d40e0eSAntonio Nino Diaz#include <bl31/ea_handle.h> 12df8f3188SJeenu Viswambharan#include <context.h> 1309d40e0eSAntonio Nino Diaz#include <lib/extensions/ras_arch.h> 14*80942622Slaurenw-arm#include <cpu_macros.S> 15*80942622Slaurenw-arm#include <context.h> 16df8f3188SJeenu Viswambharan 17df8f3188SJeenu Viswambharan .globl handle_lower_el_ea_esb 18df8f3188SJeenu Viswambharan .globl enter_lower_el_sync_ea 19df8f3188SJeenu Viswambharan .globl enter_lower_el_async_ea 20df8f3188SJeenu Viswambharan 21df8f3188SJeenu Viswambharan 22df8f3188SJeenu Viswambharan/* 23df8f3188SJeenu Viswambharan * Function to delegate External Aborts synchronized by ESB instruction at EL3 24df8f3188SJeenu Viswambharan * vector entry. This function assumes GP registers x0-x29 have been saved, and 25df8f3188SJeenu Viswambharan * are available for use. It delegates the handling of the EA to platform 26df8f3188SJeenu Viswambharan * handler, and returns only upon successfully handling the EA; otherwise 27df8f3188SJeenu Viswambharan * panics. On return from this function, the original exception handler is 28df8f3188SJeenu Viswambharan * expected to resume. 29df8f3188SJeenu Viswambharan */ 30df8f3188SJeenu Viswambharanfunc handle_lower_el_ea_esb 31df8f3188SJeenu Viswambharan mov x0, #ERROR_EA_ESB 32df8f3188SJeenu Viswambharan mrs x1, DISR_EL1 33df8f3188SJeenu Viswambharan b ea_proceed 34df8f3188SJeenu Viswambharanendfunc handle_lower_el_ea_esb 35df8f3188SJeenu Viswambharan 36df8f3188SJeenu Viswambharan 37df8f3188SJeenu Viswambharan/* 38df8f3188SJeenu Viswambharan * This function forms the tail end of Synchronous Exception entry from lower 39*80942622Slaurenw-arm * EL, and expects to handle Synchronous External Aborts from lower EL and CPU 40*80942622Slaurenw-arm * Implementation Defined Exceptions. If any other kind of exception is detected, 41*80942622Slaurenw-arm * then this function reports unhandled exception. 42df8f3188SJeenu Viswambharan * 43df8f3188SJeenu Viswambharan * Since it's part of exception vector, this function doesn't expect any GP 44df8f3188SJeenu Viswambharan * registers to have been saved. It delegates the handling of the EA to platform 45df8f3188SJeenu Viswambharan * handler, and upon successfully handling the EA, exits EL3; otherwise panics. 46df8f3188SJeenu Viswambharan */ 47df8f3188SJeenu Viswambharanfunc enter_lower_el_sync_ea 48df8f3188SJeenu Viswambharan /* 49df8f3188SJeenu Viswambharan * Explicitly save x30 so as to free up a register and to enable 50df8f3188SJeenu Viswambharan * branching. 51df8f3188SJeenu Viswambharan */ 52df8f3188SJeenu Viswambharan str x30, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_LR] 53df8f3188SJeenu Viswambharan 54df8f3188SJeenu Viswambharan mrs x30, esr_el3 55df8f3188SJeenu Viswambharan ubfx x30, x30, #ESR_EC_SHIFT, #ESR_EC_LENGTH 56df8f3188SJeenu Viswambharan 57df8f3188SJeenu Viswambharan /* Check for I/D aborts from lower EL */ 58df8f3188SJeenu Viswambharan cmp x30, #EC_IABORT_LOWER_EL 59df8f3188SJeenu Viswambharan b.eq 1f 60df8f3188SJeenu Viswambharan 61df8f3188SJeenu Viswambharan cmp x30, #EC_DABORT_LOWER_EL 62*80942622Slaurenw-arm b.eq 1f 63*80942622Slaurenw-arm 64*80942622Slaurenw-arm /* Save GP registers */ 65*80942622Slaurenw-arm stp x0, x1, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X0] 66*80942622Slaurenw-arm stp x2, x3, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X2] 67*80942622Slaurenw-arm stp x4, x5, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X4] 68*80942622Slaurenw-arm 69*80942622Slaurenw-arm /* Get the cpu_ops pointer */ 70*80942622Slaurenw-arm bl get_cpu_ops_ptr 71*80942622Slaurenw-arm 72*80942622Slaurenw-arm /* Get the cpu_ops exception handler */ 73*80942622Slaurenw-arm ldr x0, [x0, #CPU_E_HANDLER_FUNC] 74*80942622Slaurenw-arm 75*80942622Slaurenw-arm /* 76*80942622Slaurenw-arm * If the reserved function pointer is NULL, this CPU does not have an 77*80942622Slaurenw-arm * implementation defined exception handler function 78*80942622Slaurenw-arm */ 79*80942622Slaurenw-arm cbz x0, 2f 80*80942622Slaurenw-arm mrs x1, esr_el3 81*80942622Slaurenw-arm ubfx x1, x1, #ESR_EC_SHIFT, #ESR_EC_LENGTH 82*80942622Slaurenw-arm blr x0 83*80942622Slaurenw-arm b 2f 84df8f3188SJeenu Viswambharan 85df8f3188SJeenu Viswambharan1: 86df8f3188SJeenu Viswambharan /* Test for EA bit in the instruction syndrome */ 87df8f3188SJeenu Viswambharan mrs x30, esr_el3 88*80942622Slaurenw-arm tbz x30, #ESR_ISS_EABORT_EA_BIT, 3f 89df8f3188SJeenu Viswambharan 90e290a8fcSAlexei Fedorov /* 91ed108b56SAlexei Fedorov * Save general purpose and ARMv8.3-PAuth registers (if enabled). 92ed108b56SAlexei Fedorov * If Secure Cycle Counter is not disabled in MDCR_EL3 when 93ed108b56SAlexei Fedorov * ARMv8.5-PMU is implemented, save PMCR_EL0 and disable Cycle Counter. 94e290a8fcSAlexei Fedorov */ 95ed108b56SAlexei Fedorov bl save_gp_pmcr_pauth_regs 96e290a8fcSAlexei Fedorov 97b86048c4SAntonio Nino Diaz#if ENABLE_PAUTH 98ed108b56SAlexei Fedorov /* Load and program APIAKey firmware key */ 99ed108b56SAlexei Fedorov bl pauth_load_bl31_apiakey 100b86048c4SAntonio Nino Diaz#endif 1015283962eSAntonio Nino Diaz 102df8f3188SJeenu Viswambharan /* Setup exception class and syndrome arguments for platform handler */ 103df8f3188SJeenu Viswambharan mov x0, #ERROR_EA_SYNC 104df8f3188SJeenu Viswambharan mrs x1, esr_el3 105df8f3188SJeenu Viswambharan adr x30, el3_exit 106b56dc2a9SJeenu Viswambharan b delegate_sync_ea 107df8f3188SJeenu Viswambharan 108df8f3188SJeenu Viswambharan2: 109*80942622Slaurenw-arm ldp x0, x1, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X0] 110*80942622Slaurenw-arm ldp x2, x3, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X2] 111*80942622Slaurenw-arm ldp x4, x5, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X4] 112*80942622Slaurenw-arm 113*80942622Slaurenw-arm3: 114df8f3188SJeenu Viswambharan /* Synchronous exceptions other than the above are assumed to be EA */ 115df8f3188SJeenu Viswambharan ldr x30, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_LR] 116df8f3188SJeenu Viswambharan no_ret report_unhandled_exception 117df8f3188SJeenu Viswambharanendfunc enter_lower_el_sync_ea 118df8f3188SJeenu Viswambharan 119df8f3188SJeenu Viswambharan 120df8f3188SJeenu Viswambharan/* 121df8f3188SJeenu Viswambharan * This function handles SErrors from lower ELs. 122df8f3188SJeenu Viswambharan * 123df8f3188SJeenu Viswambharan * Since it's part of exception vector, this function doesn't expect any GP 124df8f3188SJeenu Viswambharan * registers to have been saved. It delegates the handling of the EA to platform 125df8f3188SJeenu Viswambharan * handler, and upon successfully handling the EA, exits EL3; otherwise panics. 126df8f3188SJeenu Viswambharan */ 127df8f3188SJeenu Viswambharanfunc enter_lower_el_async_ea 128df8f3188SJeenu Viswambharan /* 129df8f3188SJeenu Viswambharan * Explicitly save x30 so as to free up a register and to enable 130df8f3188SJeenu Viswambharan * branching 131df8f3188SJeenu Viswambharan */ 132df8f3188SJeenu Viswambharan str x30, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_LR] 133df8f3188SJeenu Viswambharan 134e290a8fcSAlexei Fedorov /* 135ed108b56SAlexei Fedorov * Save general purpose and ARMv8.3-PAuth registers (if enabled). 136ed108b56SAlexei Fedorov * If Secure Cycle Counter is not disabled in MDCR_EL3 when 137ed108b56SAlexei Fedorov * ARMv8.5-PMU is implemented, save PMCR_EL0 and disable Cycle Counter. 138e290a8fcSAlexei Fedorov */ 139ed108b56SAlexei Fedorov bl save_gp_pmcr_pauth_regs 140e290a8fcSAlexei Fedorov 141b86048c4SAntonio Nino Diaz#if ENABLE_PAUTH 142ed108b56SAlexei Fedorov /* Load and program APIAKey firmware key */ 143ed108b56SAlexei Fedorov bl pauth_load_bl31_apiakey 144b86048c4SAntonio Nino Diaz#endif 1455283962eSAntonio Nino Diaz 146df8f3188SJeenu Viswambharan /* Setup exception class and syndrome arguments for platform handler */ 147df8f3188SJeenu Viswambharan mov x0, #ERROR_EA_ASYNC 148df8f3188SJeenu Viswambharan mrs x1, esr_el3 149df8f3188SJeenu Viswambharan adr x30, el3_exit 150b56dc2a9SJeenu Viswambharan b delegate_async_ea 151df8f3188SJeenu Viswambharanendfunc enter_lower_el_async_ea 152df8f3188SJeenu Viswambharan 153df8f3188SJeenu Viswambharan 154df8f3188SJeenu Viswambharan/* 155b56dc2a9SJeenu Viswambharan * Prelude for Synchronous External Abort handling. This function assumes that 156b56dc2a9SJeenu Viswambharan * all GP registers have been saved by the caller. 157b56dc2a9SJeenu Viswambharan * 158b56dc2a9SJeenu Viswambharan * x0: EA reason 159b56dc2a9SJeenu Viswambharan * x1: EA syndrome 160b56dc2a9SJeenu Viswambharan */ 161b56dc2a9SJeenu Viswambharanfunc delegate_sync_ea 162b56dc2a9SJeenu Viswambharan#if RAS_EXTENSION 163b56dc2a9SJeenu Viswambharan /* 164b56dc2a9SJeenu Viswambharan * Check for Uncontainable error type. If so, route to the platform 165b56dc2a9SJeenu Viswambharan * fatal error handler rather than the generic EA one. 166b56dc2a9SJeenu Viswambharan */ 167b56dc2a9SJeenu Viswambharan ubfx x2, x1, #EABORT_SET_SHIFT, #EABORT_SET_WIDTH 168b56dc2a9SJeenu Viswambharan cmp x2, #ERROR_STATUS_SET_UC 169b56dc2a9SJeenu Viswambharan b.ne 1f 170b56dc2a9SJeenu Viswambharan 171b56dc2a9SJeenu Viswambharan /* Check fault status code */ 172b56dc2a9SJeenu Viswambharan ubfx x3, x1, #EABORT_DFSC_SHIFT, #EABORT_DFSC_WIDTH 173b56dc2a9SJeenu Viswambharan cmp x3, #SYNC_EA_FSC 174b56dc2a9SJeenu Viswambharan b.ne 1f 175b56dc2a9SJeenu Viswambharan 176b56dc2a9SJeenu Viswambharan no_ret plat_handle_uncontainable_ea 177b56dc2a9SJeenu Viswambharan1: 178b56dc2a9SJeenu Viswambharan#endif 179b56dc2a9SJeenu Viswambharan 180b56dc2a9SJeenu Viswambharan b ea_proceed 181b56dc2a9SJeenu Viswambharanendfunc delegate_sync_ea 182b56dc2a9SJeenu Viswambharan 183b56dc2a9SJeenu Viswambharan 184b56dc2a9SJeenu Viswambharan/* 185b56dc2a9SJeenu Viswambharan * Prelude for Asynchronous External Abort handling. This function assumes that 186b56dc2a9SJeenu Viswambharan * all GP registers have been saved by the caller. 187b56dc2a9SJeenu Viswambharan * 188b56dc2a9SJeenu Viswambharan * x0: EA reason 189b56dc2a9SJeenu Viswambharan * x1: EA syndrome 190b56dc2a9SJeenu Viswambharan */ 191b56dc2a9SJeenu Viswambharanfunc delegate_async_ea 192b56dc2a9SJeenu Viswambharan#if RAS_EXTENSION 193b56dc2a9SJeenu Viswambharan /* 194b56dc2a9SJeenu Viswambharan * Check for Implementation Defined Syndrome. If so, skip checking 195b56dc2a9SJeenu Viswambharan * Uncontainable error type from the syndrome as the format is unknown. 196b56dc2a9SJeenu Viswambharan */ 197b56dc2a9SJeenu Viswambharan tbnz x1, #SERROR_IDS_BIT, 1f 198b56dc2a9SJeenu Viswambharan 199b56dc2a9SJeenu Viswambharan /* 200b56dc2a9SJeenu Viswambharan * Check for Uncontainable error type. If so, route to the platform 201b56dc2a9SJeenu Viswambharan * fatal error handler rather than the generic EA one. 202b56dc2a9SJeenu Viswambharan */ 203b56dc2a9SJeenu Viswambharan ubfx x2, x1, #EABORT_AET_SHIFT, #EABORT_AET_WIDTH 204b56dc2a9SJeenu Viswambharan cmp x2, #ERROR_STATUS_UET_UC 205b56dc2a9SJeenu Viswambharan b.ne 1f 206b56dc2a9SJeenu Viswambharan 207b56dc2a9SJeenu Viswambharan /* Check DFSC for SError type */ 208b56dc2a9SJeenu Viswambharan ubfx x3, x1, #EABORT_DFSC_SHIFT, #EABORT_DFSC_WIDTH 209b56dc2a9SJeenu Viswambharan cmp x3, #DFSC_SERROR 210b56dc2a9SJeenu Viswambharan b.ne 1f 211b56dc2a9SJeenu Viswambharan 212b56dc2a9SJeenu Viswambharan no_ret plat_handle_uncontainable_ea 213b56dc2a9SJeenu Viswambharan1: 214b56dc2a9SJeenu Viswambharan#endif 215b56dc2a9SJeenu Viswambharan 216b56dc2a9SJeenu Viswambharan b ea_proceed 217b56dc2a9SJeenu Viswambharanendfunc delegate_async_ea 218b56dc2a9SJeenu Viswambharan 219b56dc2a9SJeenu Viswambharan 220b56dc2a9SJeenu Viswambharan/* 221df8f3188SJeenu Viswambharan * Delegate External Abort handling to platform's EA handler. This function 222df8f3188SJeenu Viswambharan * assumes that all GP registers have been saved by the caller. 223df8f3188SJeenu Viswambharan * 224df8f3188SJeenu Viswambharan * x0: EA reason 225df8f3188SJeenu Viswambharan * x1: EA syndrome 226df8f3188SJeenu Viswambharan */ 227df8f3188SJeenu Viswambharanfunc ea_proceed 228d5a23af5SJeenu Viswambharan /* 229d5a23af5SJeenu Viswambharan * If the ESR loaded earlier is not zero, we were processing an EA 230d5a23af5SJeenu Viswambharan * already, and this is a double fault. 231d5a23af5SJeenu Viswambharan */ 232d5a23af5SJeenu Viswambharan ldr x5, [sp, #CTX_EL3STATE_OFFSET + CTX_ESR_EL3] 233d5a23af5SJeenu Viswambharan cbz x5, 1f 234d5a23af5SJeenu Viswambharan no_ret plat_handle_double_fault 235d5a23af5SJeenu Viswambharan 236d5a23af5SJeenu Viswambharan1: 237df8f3188SJeenu Viswambharan /* Save EL3 state */ 238df8f3188SJeenu Viswambharan mrs x2, spsr_el3 239df8f3188SJeenu Viswambharan mrs x3, elr_el3 240df8f3188SJeenu Viswambharan stp x2, x3, [sp, #CTX_EL3STATE_OFFSET + CTX_SPSR_EL3] 241df8f3188SJeenu Viswambharan 242df8f3188SJeenu Viswambharan /* 243df8f3188SJeenu Viswambharan * Save ESR as handling might involve lower ELs, and returning back to 244df8f3188SJeenu Viswambharan * EL3 from there would trample the original ESR. 245df8f3188SJeenu Viswambharan */ 246df8f3188SJeenu Viswambharan mrs x4, scr_el3 247df8f3188SJeenu Viswambharan mrs x5, esr_el3 248df8f3188SJeenu Viswambharan stp x4, x5, [sp, #CTX_EL3STATE_OFFSET + CTX_SCR_EL3] 249df8f3188SJeenu Viswambharan 250df8f3188SJeenu Viswambharan /* 251df8f3188SJeenu Viswambharan * Setup rest of arguments, and call platform External Abort handler. 252df8f3188SJeenu Viswambharan * 253df8f3188SJeenu Viswambharan * x0: EA reason (already in place) 254df8f3188SJeenu Viswambharan * x1: Exception syndrome (already in place). 255df8f3188SJeenu Viswambharan * x2: Cookie (unused for now). 256df8f3188SJeenu Viswambharan * x3: Context pointer. 257df8f3188SJeenu Viswambharan * x4: Flags (security state from SCR for now). 258df8f3188SJeenu Viswambharan */ 259df8f3188SJeenu Viswambharan mov x2, xzr 260df8f3188SJeenu Viswambharan mov x3, sp 261df8f3188SJeenu Viswambharan ubfx x4, x4, #0, #1 262df8f3188SJeenu Viswambharan 263df8f3188SJeenu Viswambharan /* Switch to runtime stack */ 264df8f3188SJeenu Viswambharan ldr x5, [sp, #CTX_EL3STATE_OFFSET + CTX_RUNTIME_SP] 265ed108b56SAlexei Fedorov msr spsel, #MODE_SP_EL0 266df8f3188SJeenu Viswambharan mov sp, x5 267df8f3188SJeenu Viswambharan 268df8f3188SJeenu Viswambharan mov x29, x30 269ee6ff1bbSJeenu Viswambharan#if ENABLE_ASSERTIONS 270ee6ff1bbSJeenu Viswambharan /* Stash the stack pointer */ 271ee6ff1bbSJeenu Viswambharan mov x28, sp 272ee6ff1bbSJeenu Viswambharan#endif 273df8f3188SJeenu Viswambharan bl plat_ea_handler 274df8f3188SJeenu Viswambharan 275ee6ff1bbSJeenu Viswambharan#if ENABLE_ASSERTIONS 276ee6ff1bbSJeenu Viswambharan /* 277ee6ff1bbSJeenu Viswambharan * Error handling flows might involve long jumps; so upon returning from 278ee6ff1bbSJeenu Viswambharan * the platform error handler, validate that the we've completely 279ee6ff1bbSJeenu Viswambharan * unwound the stack. 280ee6ff1bbSJeenu Viswambharan */ 281ee6ff1bbSJeenu Viswambharan mov x27, sp 282ee6ff1bbSJeenu Viswambharan cmp x28, x27 283ee6ff1bbSJeenu Viswambharan ASM_ASSERT(eq) 284ee6ff1bbSJeenu Viswambharan#endif 285ee6ff1bbSJeenu Viswambharan 286df8f3188SJeenu Viswambharan /* Make SP point to context */ 287ed108b56SAlexei Fedorov msr spsel, #MODE_SP_ELX 288df8f3188SJeenu Viswambharan 289d5a23af5SJeenu Viswambharan /* Restore EL3 state and ESR */ 290df8f3188SJeenu Viswambharan ldp x1, x2, [sp, #CTX_EL3STATE_OFFSET + CTX_SPSR_EL3] 291df8f3188SJeenu Viswambharan msr spsr_el3, x1 292df8f3188SJeenu Viswambharan msr elr_el3, x2 293df8f3188SJeenu Viswambharan 294df8f3188SJeenu Viswambharan /* Restore ESR_EL3 and SCR_EL3 */ 295df8f3188SJeenu Viswambharan ldp x3, x4, [sp, #CTX_EL3STATE_OFFSET + CTX_SCR_EL3] 296df8f3188SJeenu Viswambharan msr scr_el3, x3 297df8f3188SJeenu Viswambharan msr esr_el3, x4 298df8f3188SJeenu Viswambharan 299d5a23af5SJeenu Viswambharan#if ENABLE_ASSERTIONS 300d5a23af5SJeenu Viswambharan cmp x4, xzr 301d5a23af5SJeenu Viswambharan ASM_ASSERT(ne) 302d5a23af5SJeenu Viswambharan#endif 303d5a23af5SJeenu Viswambharan 304d5a23af5SJeenu Viswambharan /* Clear ESR storage */ 305d5a23af5SJeenu Viswambharan str xzr, [sp, #CTX_EL3STATE_OFFSET + CTX_ESR_EL3] 306d5a23af5SJeenu Viswambharan 307d5a23af5SJeenu Viswambharan ret x29 308df8f3188SJeenu Viswambharanendfunc ea_proceed 309