blob: 3f1b3eac16794a132ea0fa2412df50927e15f0a9 [file] [log] [blame]
Jeenu Viswambharandf8f3182018-07-05 15:24:45 +01001/*
Boyan Karatotev51997e32025-04-02 11:09:02 +01002 * Copyright (c) 2018-2025, Arm Limited and Contributors. All rights reserved.
Varun Wadekardf56e9d2022-08-03 12:01:36 +01003 * Copyright (c) 2022, NVIDIA Corporation. All rights reserved.
Jeenu Viswambharandf8f3182018-07-05 15:24:45 +01004 *
5 * SPDX-License-Identifier: BSD-3-Clause
6 */
7
8
Jeenu Viswambharand5a23af2018-05-17 11:24:01 +01009#include <assert_macros.S>
Jeenu Viswambharandf8f3182018-07-05 15:24:45 +010010#include <asm_macros.S>
Jeenu Viswambharanee6ff1b2018-02-19 12:25:53 +000011#include <assert_macros.S>
Antonio Nino Diaz09d40e02018-12-14 00:18:21 +000012#include <bl31/ea_handle.h>
Jeenu Viswambharandf8f3182018-07-05 15:24:45 +010013#include <context.h>
Antonio Nino Diaz09d40e02018-12-14 00:18:21 +000014#include <lib/extensions/ras_arch.h>
laurenw-arm80942622019-08-20 15:51:24 -050015#include <cpu_macros.S>
16#include <context.h>
Jeenu Viswambharandf8f3182018-07-05 15:24:45 +010017
Manish Pandey6f7de9a2023-01-11 21:53:02 +000018 .globl handle_lower_el_sync_ea
19 .globl handle_lower_el_async_ea
Manish Pandeyd04c04a2023-05-25 13:46:14 +010020 .globl handle_pending_async_ea
Jeenu Viswambharandf8f3182018-07-05 15:24:45 +010021/*
Manish Pandey6d22b082023-10-11 11:52:24 +010022 * This function handles Synchronous External Aborts from lower EL.
Jeenu Viswambharandf8f3182018-07-05 15:24:45 +010023 *
Manish Pandey6f7de9a2023-01-11 21:53:02 +000024 * It delegates the handling of the EA to platform handler, and upon successfully
25 * handling the EA, exits EL3; otherwise panics.
26 *
27 * This function assumes x30 has been saved.
Jeenu Viswambharandf8f3182018-07-05 15:24:45 +010028 */
Manish Pandey6f7de9a2023-01-11 21:53:02 +000029func handle_lower_el_sync_ea
Jeenu Viswambharandf8f3182018-07-05 15:24:45 +010030 mrs x30, esr_el3
31 ubfx x30, x30, #ESR_EC_SHIFT, #ESR_EC_LENGTH
32
33 /* Check for I/D aborts from lower EL */
34 cmp x30, #EC_IABORT_LOWER_EL
35 b.eq 1f
36
37 cmp x30, #EC_DABORT_LOWER_EL
laurenw-arm80942622019-08-20 15:51:24 -050038 b.eq 1f
39
Manish Pandey6d22b082023-10-11 11:52:24 +010040 /* EA other than above are unhandled exceptions */
41 no_ret report_unhandled_exception
Jeenu Viswambharandf8f3182018-07-05 15:24:45 +0100421:
Alexei Fedorove290a8f2019-08-13 15:17:53 +010043 /*
Alexei Fedoroved108b52019-09-13 14:11:59 +010044 * Save general purpose and ARMv8.3-PAuth registers (if enabled).
Boyan Karatotev1d6d6802022-12-06 09:03:42 +000045 * Also save PMCR_EL0 and set the PSTATE to a known state.
Alexei Fedorove290a8f2019-08-13 15:17:53 +010046 */
Daniel Boulby97215e02022-01-19 11:20:05 +000047 bl prepare_el3_entry
Alexei Fedorove290a8f2019-08-13 15:17:53 +010048
Jeenu Viswambharandf8f3182018-07-05 15:24:45 +010049 /* Setup exception class and syndrome arguments for platform handler */
50 mov x0, #ERROR_EA_SYNC
51 mrs x1, esr_el3
Jan Dabrosbb9549b2019-12-02 13:30:03 +010052 bl delegate_sync_ea
Jeenu Viswambharandf8f3182018-07-05 15:24:45 +010053
Jan Dabrosbb9549b2019-12-02 13:30:03 +010054 /* el3_exit assumes SP_EL0 on entry */
55 msr spsel, #MODE_SP_EL0
56 b el3_exit
Manish Pandey6f7de9a2023-01-11 21:53:02 +000057endfunc handle_lower_el_sync_ea
Jeenu Viswambharandf8f3182018-07-05 15:24:45 +010058
59
60/*
61 * This function handles SErrors from lower ELs.
62 *
Manish Pandey6f7de9a2023-01-11 21:53:02 +000063 * It delegates the handling of the EA to platform handler, and upon successfully
64 * handling the EA, exits EL3; otherwise panics.
65 *
66 * This function assumes x30 has been saved.
Jeenu Viswambharandf8f3182018-07-05 15:24:45 +010067 */
Manish Pandey6f7de9a2023-01-11 21:53:02 +000068func handle_lower_el_async_ea
Jeenu Viswambharandf8f3182018-07-05 15:24:45 +010069
Alexei Fedorove290a8f2019-08-13 15:17:53 +010070 /*
Alexei Fedoroved108b52019-09-13 14:11:59 +010071 * Save general purpose and ARMv8.3-PAuth registers (if enabled).
Boyan Karatotev1d6d6802022-12-06 09:03:42 +000072 * Also save PMCR_EL0 and set the PSTATE to a known state.
Alexei Fedorove290a8f2019-08-13 15:17:53 +010073 */
Daniel Boulby97215e02022-01-19 11:20:05 +000074 bl prepare_el3_entry
Alexei Fedorove290a8f2019-08-13 15:17:53 +010075
Jeenu Viswambharandf8f3182018-07-05 15:24:45 +010076 /* Setup exception class and syndrome arguments for platform handler */
77 mov x0, #ERROR_EA_ASYNC
78 mrs x1, esr_el3
Jan Dabrosbb9549b2019-12-02 13:30:03 +010079 bl delegate_async_ea
80
81 /* el3_exit assumes SP_EL0 on entry */
82 msr spsel, #MODE_SP_EL0
83 b el3_exit
Manish Pandey6f7de9a2023-01-11 21:53:02 +000084endfunc handle_lower_el_async_ea
Jeenu Viswambharandf8f3182018-07-05 15:24:45 +010085
Manish Pandeyd04c04a2023-05-25 13:46:14 +010086/*
Manish Pandey6d22b082023-10-11 11:52:24 +010087 * Handler for async EA from lower EL synchronized at EL3 entry in FFH mode.
Manish Pandeyd04c04a2023-05-25 13:46:14 +010088 *
89 * This scenario may arise when there is an error (EA) in the system which is not
90 * yet signaled to PE while executing in lower EL. During entry into EL3, the errors
91 * are synchronized either implicitly or explicitly causing async EA to pend at EL3.
92 *
Manish Pandey6d22b082023-10-11 11:52:24 +010093 * On detecting the pending EA (via ISR_EL1.A), if the EA routing model is Firmware
94 * First handling (FFH, SCR_EL3.EA = 1) this handler first handles the pending EA
95 * and then handles the original exception.
Manish Pandeyd04c04a2023-05-25 13:46:14 +010096 *
97 * This function assumes x30 has been saved.
98 */
Manish Pandeyd04c04a2023-05-25 13:46:14 +010099func handle_pending_async_ea
100 /*
101 * Prepare for nested handling of EA. Stash sysregs clobbered by nested
102 * exception and handler
103 */
104 str x30, [sp, #CTX_EL3STATE_OFFSET + CTX_SAVED_GPREG_LR]
105 mrs x30, esr_el3
106 str x30, [sp, #CTX_EL3STATE_OFFSET + CTX_SAVED_ESR_EL3]
107 mrs x30, spsr_el3
108 str x30, [sp, #CTX_EL3STATE_OFFSET + CTX_SAVED_SPSR_EL3]
109 mrs x30, elr_el3
110 str x30, [sp, #CTX_EL3STATE_OFFSET + CTX_SAVED_ELR_EL3]
111
112 mov x30, #1
113 str x30, [sp, #CTX_EL3STATE_OFFSET + CTX_NESTED_EA_FLAG]
114 /*
115 * Restore the original x30 saved as part of entering EL3. This is not
116 * required for the current function but for EL3 SError vector entry
117 * once PSTATE.A bit is unmasked. We restore x30 and then the same
118 * value is stored in EL3 SError vector entry.
119 */
120 ldr x30, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_LR]
121
122 /*
123 * After clearing PSTATE.A bit pending SError will trigger at current EL.
124 * Put explicit synchronization event to ensure newly unmasked interrupt
125 * is taken immediately.
126 */
127 unmask_async_ea
128
129 /* Restore the original exception information along with zeroing the storage */
130 ldr x30, [sp, #CTX_EL3STATE_OFFSET + CTX_SAVED_ELR_EL3]
131 msr elr_el3, x30
132 str xzr, [sp, #CTX_EL3STATE_OFFSET + CTX_SAVED_ELR_EL3]
133 ldr x30, [sp, #CTX_EL3STATE_OFFSET + CTX_SAVED_SPSR_EL3]
134 msr spsr_el3, x30
135 str xzr, [sp, #CTX_EL3STATE_OFFSET + CTX_SAVED_SPSR_EL3]
136 ldr x30, [sp, #CTX_EL3STATE_OFFSET + CTX_SAVED_ESR_EL3]
137 msr esr_el3, x30
138 str xzr, [sp, #CTX_EL3STATE_OFFSET + CTX_SAVED_ESR_EL3]
139
140 /*
141 * If the original exception corresponds to SError from lower El, eret back
142 * to lower EL, otherwise return to vector table for original exception handling.
143 */
144 ubfx x30, x30, #ESR_EC_SHIFT, #ESR_EC_LENGTH
145 cmp x30, #EC_SERROR
146 ldr x30, [sp, #CTX_EL3STATE_OFFSET + CTX_SAVED_GPREG_LR]
147 str xzr, [sp, #CTX_EL3STATE_OFFSET + CTX_SAVED_GPREG_LR]
148 b.eq 1f
149 ret
1501:
Jaiprakash Singh0bc31152024-12-22 22:13:57 -0800151 ldr x30, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_LR]
152 str xzr, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_LR]
Manish Pandeyd04c04a2023-05-25 13:46:14 +0100153 exception_return
154endfunc handle_pending_async_ea
Jeenu Viswambharandf8f3182018-07-05 15:24:45 +0100155
156/*
Jeenu Viswambharanb56dc2a2018-05-17 09:52:36 +0100157 * Prelude for Synchronous External Abort handling. This function assumes that
158 * all GP registers have been saved by the caller.
159 *
160 * x0: EA reason
161 * x1: EA syndrome
162 */
163func delegate_sync_ea
Manish Pandeyf87e54f2023-10-10 15:42:19 +0100164#if ENABLE_FEAT_RAS
Jeenu Viswambharanb56dc2a2018-05-17 09:52:36 +0100165 /*
166 * Check for Uncontainable error type. If so, route to the platform
167 * fatal error handler rather than the generic EA one.
168 */
169 ubfx x2, x1, #EABORT_SET_SHIFT, #EABORT_SET_WIDTH
170 cmp x2, #ERROR_STATUS_SET_UC
171 b.ne 1f
172
173 /* Check fault status code */
174 ubfx x3, x1, #EABORT_DFSC_SHIFT, #EABORT_DFSC_WIDTH
175 cmp x3, #SYNC_EA_FSC
176 b.ne 1f
177
178 no_ret plat_handle_uncontainable_ea
1791:
180#endif
181
182 b ea_proceed
183endfunc delegate_sync_ea
184
185
186/*
187 * Prelude for Asynchronous External Abort handling. This function assumes that
188 * all GP registers have been saved by the caller.
189 *
190 * x0: EA reason
191 * x1: EA syndrome
192 */
193func delegate_async_ea
Manish Pandeyf87e54f2023-10-10 15:42:19 +0100194#if ENABLE_FEAT_RAS
Manish Pandeyd4352382022-10-11 17:28:14 +0100195 /* Check Exception Class to ensure SError, as this function should
196 * only be invoked for SError. If that is not the case, which implies
197 * either an HW error or programming error, panic.
198 */
199 ubfx x2, x1, #ESR_EC_SHIFT, #ESR_EC_LENGTH
200 cmp x2, EC_SERROR
Govindraj Rajabd62ce92023-01-16 17:35:07 +0000201 b.ne el3_panic
Jeenu Viswambharanb56dc2a2018-05-17 09:52:36 +0100202 /*
203 * Check for Implementation Defined Syndrome. If so, skip checking
204 * Uncontainable error type from the syndrome as the format is unknown.
205 */
206 tbnz x1, #SERROR_IDS_BIT, 1f
207
Manish Pandeyd4352382022-10-11 17:28:14 +0100208 /* AET only valid when DFSC is 0x11 */
209 ubfx x2, x1, #EABORT_DFSC_SHIFT, #EABORT_DFSC_WIDTH
210 cmp x2, #DFSC_SERROR
211 b.ne 1f
212
Jeenu Viswambharanb56dc2a2018-05-17 09:52:36 +0100213 /*
214 * Check for Uncontainable error type. If so, route to the platform
215 * fatal error handler rather than the generic EA one.
216 */
Manish Pandeyd4352382022-10-11 17:28:14 +0100217 ubfx x3, x1, #EABORT_AET_SHIFT, #EABORT_AET_WIDTH
218 cmp x3, #ERROR_STATUS_UET_UC
Jeenu Viswambharanb56dc2a2018-05-17 09:52:36 +0100219 b.ne 1f
220
221 no_ret plat_handle_uncontainable_ea
2221:
223#endif
224
225 b ea_proceed
226endfunc delegate_async_ea
227
228
229/*
Jeenu Viswambharandf8f3182018-07-05 15:24:45 +0100230 * Delegate External Abort handling to platform's EA handler. This function
231 * assumes that all GP registers have been saved by the caller.
232 *
233 * x0: EA reason
234 * x1: EA syndrome
235 */
236func ea_proceed
Jeenu Viswambharand5a23af2018-05-17 11:24:01 +0100237 /*
Manish Pandeyc7220032025-02-03 12:00:56 +0000238 * If it is a double fault invoke platform handler.
239 * Double fault scenario would arise when platform is handling a fault in
240 * lower EL using plat_ea_handler() and another fault happens which would
241 * trap into EL3 as FFH_SUPPORT is enabled for the platform.
Jeenu Viswambharand5a23af2018-05-17 11:24:01 +0100242 */
Manish Pandeyc7220032025-02-03 12:00:56 +0000243 ldr x5, [sp, #CTX_EL3STATE_OFFSET + CTX_DOUBLE_FAULT_ESR]
Jeenu Viswambharand5a23af2018-05-17 11:24:01 +0100244 cbz x5, 1f
245 no_ret plat_handle_double_fault
246
2471:
Manish Pandeyc7220032025-02-03 12:00:56 +0000248 /* Save EL3 state as handling might involve lower ELs */
Jeenu Viswambharandf8f3182018-07-05 15:24:45 +0100249 mrs x2, spsr_el3
250 mrs x3, elr_el3
251 stp x2, x3, [sp, #CTX_EL3STATE_OFFSET + CTX_SPSR_EL3]
Manish Pandeyc7220032025-02-03 12:00:56 +0000252 mrs x4, scr_el3
253 str x4, [sp, #CTX_EL3STATE_OFFSET + CTX_SCR_EL3]
Jeenu Viswambharandf8f3182018-07-05 15:24:45 +0100254
255 /*
Manish Pandeyc7220032025-02-03 12:00:56 +0000256 * Save CTX_DOUBLE_FAULT_ESR, so that if another fault happens in lower EL, we
257 * catch it as DoubleFault in next invocation of ea_proceed() along with
258 * preserving original ESR_EL3.
Jeenu Viswambharandf8f3182018-07-05 15:24:45 +0100259 */
Jeenu Viswambharandf8f3182018-07-05 15:24:45 +0100260 mrs x5, esr_el3
Manish Pandeyc7220032025-02-03 12:00:56 +0000261 str x5, [sp, #CTX_EL3STATE_OFFSET + CTX_DOUBLE_FAULT_ESR]
Jeenu Viswambharandf8f3182018-07-05 15:24:45 +0100262
263 /*
264 * Setup rest of arguments, and call platform External Abort handler.
265 *
266 * x0: EA reason (already in place)
267 * x1: Exception syndrome (already in place).
268 * x2: Cookie (unused for now).
269 * x3: Context pointer.
270 * x4: Flags (security state from SCR for now).
271 */
272 mov x2, xzr
273 mov x3, sp
274 ubfx x4, x4, #0, #1
275
276 /* Switch to runtime stack */
277 ldr x5, [sp, #CTX_EL3STATE_OFFSET + CTX_RUNTIME_SP]
Alexei Fedoroved108b52019-09-13 14:11:59 +0100278 msr spsel, #MODE_SP_EL0
Jeenu Viswambharandf8f3182018-07-05 15:24:45 +0100279 mov sp, x5
280
281 mov x29, x30
Jeenu Viswambharanee6ff1b2018-02-19 12:25:53 +0000282#if ENABLE_ASSERTIONS
283 /* Stash the stack pointer */
284 mov x28, sp
285#endif
Jeenu Viswambharandf8f3182018-07-05 15:24:45 +0100286 bl plat_ea_handler
Jeenu Viswambharandf8f3182018-07-05 15:24:45 +0100287
Jeenu Viswambharanee6ff1b2018-02-19 12:25:53 +0000288#if ENABLE_ASSERTIONS
289 /*
290 * Error handling flows might involve long jumps; so upon returning from
291 * the platform error handler, validate that the we've completely
292 * unwound the stack.
293 */
294 mov x27, sp
295 cmp x28, x27
296 ASM_ASSERT(eq)
297#endif
298
Jeenu Viswambharandf8f3182018-07-05 15:24:45 +0100299 /* Make SP point to context */
Alexei Fedoroved108b52019-09-13 14:11:59 +0100300 msr spsel, #MODE_SP_ELX
Jeenu Viswambharandf8f3182018-07-05 15:24:45 +0100301
Manish Pandeyc7220032025-02-03 12:00:56 +0000302 /* Clear Double Fault storage */
303 str xzr, [sp, #CTX_EL3STATE_OFFSET + CTX_DOUBLE_FAULT_ESR]
304
305 /* Restore EL3 state */
Jeenu Viswambharandf8f3182018-07-05 15:24:45 +0100306 ldp x1, x2, [sp, #CTX_EL3STATE_OFFSET + CTX_SPSR_EL3]
307 msr spsr_el3, x1
308 msr elr_el3, x2
Manish Pandeyc7220032025-02-03 12:00:56 +0000309 ldr x3, [sp, #CTX_EL3STATE_OFFSET + CTX_SCR_EL3]
Jeenu Viswambharandf8f3182018-07-05 15:24:45 +0100310 msr scr_el3, x3
Jeenu Viswambharand5a23af2018-05-17 11:24:01 +0100311
312 ret x29
Jeenu Viswambharandf8f3182018-07-05 15:24:45 +0100313endfunc ea_proceed