Merge changes from topic "mp/exceptions" into integration

* changes:
  docs(ras): update RAS documentation
  docs(el3-runtime): update BL31 exception vector handling
  fix(el3-runtime): restrict lower el EA handlers in FFH mode
  fix(ras): remove RAS_FFH_SUPPORT and introduce FFH_SUPPORT
  fix(ras): restrict ENABLE_FEAT_RAS to have only two states
  feat(ras): use FEAT_IESB for error synchronization
  feat(el3-runtime): modify vector entry paths
This commit is contained in:
Manish Pandey 2023-11-02 14:34:53 +01:00 committed by TrustedFirmware Code Review
commit 6f802c44e9
38 changed files with 536 additions and 240 deletions

View file

@ -809,6 +809,14 @@ else
BL2_RUNS_AT_EL3 := 0
endif
# This internal flag is set to 1 when Firmware First handling of External aborts
# is required by lowe ELs. Currently only NS requires this support.
ifeq ($(HANDLE_EA_EL3_FIRST_NS),1)
FFH_SUPPORT := 1
else
FFH_SUPPORT := 0
endif
$(eval $(call MAKE_PREREQ_DIR,${BUILD_PLAT}))
ifeq (${ARM_ARCH_MAJOR},7)
@ -970,18 +978,9 @@ endif
# RAS_EXTENSION is deprecated, provide alternate build options
ifeq ($(RAS_EXTENSION),1)
$(error "RAS_EXTENSION is now deprecated, please use ENABLE_FEAT_RAS \
and RAS_FFH_SUPPORT instead")
and HANDLE_EA_EL3_FIRST_NS instead")
endif
# RAS firmware first handling requires that EAs are handled in EL3 first
ifeq ($(RAS_FFH_SUPPORT),1)
ifneq ($(ENABLE_FEAT_RAS),1)
$(error For RAS_FFH_SUPPORT, ENABLE_FEAT_RAS must also be 1)
endif
ifneq ($(HANDLE_EA_EL3_FIRST_NS),1)
$(error For RAS_FFH_SUPPORT, HANDLE_EA_EL3_FIRST_NS must also be 1)
endif
endif #(RAS_FFH_SUPPORT)
# When FAULT_INJECTION_SUPPORT is used, require that FEAT_RAS is enabled
ifeq ($(FAULT_INJECTION_SUPPORT),1)
@ -1283,6 +1282,8 @@ $(eval $(call assert_booleans,\
ENABLE_RUNTIME_INSTRUMENTATION \
ENABLE_SME_FOR_SWD \
ENABLE_SVE_FOR_SWD \
ENABLE_FEAT_RAS \
FFH_SUPPORT \
ERROR_DEPRECATED \
FAULT_INJECTION_SUPPORT \
GENERATE_COT \
@ -1337,7 +1338,6 @@ $(eval $(call assert_booleans,\
ERRATA_ABI_SUPPORT \
ERRATA_NON_ARM_INTERCONNECT \
CONDITIONAL_CMO \
RAS_FFH_SUPPORT \
PSA_CRYPTO \
ENABLE_CONSOLE_GETC \
)))
@ -1360,7 +1360,6 @@ $(eval $(call assert_numerics,\
ENABLE_FEAT_AMU \
ENABLE_FEAT_AMUv1p1 \
ENABLE_FEAT_CSV2_2 \
ENABLE_FEAT_RAS \
ENABLE_FEAT_DIT \
ENABLE_FEAT_ECV \
ENABLE_FEAT_FGT \
@ -1443,6 +1442,8 @@ $(eval $(call add_defines,\
ENABLE_SPE_FOR_NS \
ENABLE_SVE_FOR_NS \
ENABLE_SVE_FOR_SWD \
ENABLE_FEAT_RAS \
FFH_SUPPORT \
ENCRYPT_BL31 \
ENCRYPT_BL32 \
ERROR_DEPRECATED \
@ -1460,8 +1461,6 @@ $(eval $(call add_defines,\
PROGRAMMABLE_RESET_ADDRESS \
PSCI_EXTENDED_STATE_ID \
PSCI_OS_INIT_MODE \
ENABLE_FEAT_RAS \
RAS_FFH_SUPPORT \
RESET_TO_BL31 \
SEPARATE_CODE_AND_RODATA \
SEPARATE_BL2_NOLOAD_REGION \

View file

@ -15,31 +15,11 @@
#include <cpu_macros.S>
#include <context.h>
.globl handle_lower_el_ea_esb
.globl handle_lower_el_sync_ea
.globl handle_lower_el_async_ea
.globl handle_pending_async_ea
/*
* Function to delegate External Aborts synchronized by ESB instruction at EL3
* vector entry. This function assumes GP registers x0-x29 have been saved, and
* are available for use. It delegates the handling of the EA to platform
* handler, and returns only upon successfully handling the EA; otherwise
* panics. On return from this function, the original exception handler is
* expected to resume.
*/
func handle_lower_el_ea_esb
mov x0, #ERROR_EA_ESB
mrs x1, DISR_EL1
b ea_proceed
endfunc handle_lower_el_ea_esb
/*
* This function forms the tail end of Synchronous Exception entry from lower
* EL, and expects to handle Synchronous External Aborts from lower EL and CPU
* Implementation Defined Exceptions. If any other kind of exception is detected,
* then this function reports unhandled exception.
* This function handles Synchronous External Aborts from lower EL.
*
* It delegates the handling of the EA to platform handler, and upon successfully
* handling the EA, exits EL3; otherwise panics.
@ -57,27 +37,8 @@ func handle_lower_el_sync_ea
cmp x30, #EC_DABORT_LOWER_EL
b.eq 1f
/* Save GP registers */
stp x0, x1, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X0]
stp x2, x3, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X2]
stp x4, x5, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X4]
/* Get the cpu_ops pointer */
bl get_cpu_ops_ptr
/* Get the cpu_ops exception handler */
ldr x0, [x0, #CPU_E_HANDLER_FUNC]
/*
* If the reserved function pointer is NULL, this CPU does not have an
* implementation defined exception handler function
*/
cbz x0, 2f
mrs x1, esr_el3
ubfx x1, x1, #ESR_EC_SHIFT, #ESR_EC_LENGTH
blr x0
b 2f
/* EA other than above are unhandled exceptions */
no_ret report_unhandled_exception
1:
/*
* Save general purpose and ARMv8.3-PAuth registers (if enabled).
@ -98,14 +59,6 @@ func handle_lower_el_sync_ea
/* el3_exit assumes SP_EL0 on entry */
msr spsel, #MODE_SP_EL0
b el3_exit
2:
ldp x0, x1, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X0]
ldp x2, x3, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X2]
ldp x4, x5, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X4]
/* Synchronous exceptions other than the above are assumed to be EA */
ldr x30, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_LR]
no_ret report_unhandled_exception
endfunc handle_lower_el_sync_ea
@ -140,6 +93,73 @@ func handle_lower_el_async_ea
b el3_exit
endfunc handle_lower_el_async_ea
/*
* Handler for async EA from lower EL synchronized at EL3 entry in FFH mode.
*
* This scenario may arise when there is an error (EA) in the system which is not
* yet signaled to PE while executing in lower EL. During entry into EL3, the errors
* are synchronized either implicitly or explicitly causing async EA to pend at EL3.
*
* On detecting the pending EA (via ISR_EL1.A), if the EA routing model is Firmware
* First handling (FFH, SCR_EL3.EA = 1) this handler first handles the pending EA
* and then handles the original exception.
*
* This function assumes x30 has been saved.
*/
func handle_pending_async_ea
/*
* Prepare for nested handling of EA. Stash sysregs clobbered by nested
* exception and handler
*/
str x30, [sp, #CTX_EL3STATE_OFFSET + CTX_SAVED_GPREG_LR]
mrs x30, esr_el3
str x30, [sp, #CTX_EL3STATE_OFFSET + CTX_SAVED_ESR_EL3]
mrs x30, spsr_el3
str x30, [sp, #CTX_EL3STATE_OFFSET + CTX_SAVED_SPSR_EL3]
mrs x30, elr_el3
str x30, [sp, #CTX_EL3STATE_OFFSET + CTX_SAVED_ELR_EL3]
mov x30, #1
str x30, [sp, #CTX_EL3STATE_OFFSET + CTX_NESTED_EA_FLAG]
/*
* Restore the original x30 saved as part of entering EL3. This is not
* required for the current function but for EL3 SError vector entry
* once PSTATE.A bit is unmasked. We restore x30 and then the same
* value is stored in EL3 SError vector entry.
*/
ldr x30, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_LR]
/*
* After clearing PSTATE.A bit pending SError will trigger at current EL.
* Put explicit synchronization event to ensure newly unmasked interrupt
* is taken immediately.
*/
unmask_async_ea
/* Restore the original exception information along with zeroing the storage */
ldr x30, [sp, #CTX_EL3STATE_OFFSET + CTX_SAVED_ELR_EL3]
msr elr_el3, x30
str xzr, [sp, #CTX_EL3STATE_OFFSET + CTX_SAVED_ELR_EL3]
ldr x30, [sp, #CTX_EL3STATE_OFFSET + CTX_SAVED_SPSR_EL3]
msr spsr_el3, x30
str xzr, [sp, #CTX_EL3STATE_OFFSET + CTX_SAVED_SPSR_EL3]
ldr x30, [sp, #CTX_EL3STATE_OFFSET + CTX_SAVED_ESR_EL3]
msr esr_el3, x30
str xzr, [sp, #CTX_EL3STATE_OFFSET + CTX_SAVED_ESR_EL3]
/*
* If the original exception corresponds to SError from lower El, eret back
* to lower EL, otherwise return to vector table for original exception handling.
*/
ubfx x30, x30, #ESR_EC_SHIFT, #ESR_EC_LENGTH
cmp x30, #EC_SERROR
ldr x30, [sp, #CTX_EL3STATE_OFFSET + CTX_SAVED_GPREG_LR]
str xzr, [sp, #CTX_EL3STATE_OFFSET + CTX_SAVED_GPREG_LR]
b.eq 1f
ret
1:
exception_return
endfunc handle_pending_async_ea
/*
* Prelude for Synchronous External Abort handling. This function assumes that
@ -149,7 +169,7 @@ endfunc handle_lower_el_async_ea
* x1: EA syndrome
*/
func delegate_sync_ea
#if RAS_FFH_SUPPORT
#if ENABLE_FEAT_RAS
/*
* Check for Uncontainable error type. If so, route to the platform
* fatal error handler rather than the generic EA one.
@ -179,7 +199,7 @@ endfunc delegate_sync_ea
* x1: EA syndrome
*/
func delegate_async_ea
#if RAS_FFH_SUPPORT
#if ENABLE_FEAT_RAS
/* Check Exception Class to ensure SError, as this function should
* only be invoked for SError. If that is not the case, which implies
* either an HW error or programming error, panic.

View file

@ -13,6 +13,7 @@
#include <bl31/sync_handle.h>
#include <common/runtime_svc.h>
#include <context.h>
#include <cpu_macros.S>
#include <el3_common_macros.S>
#include <lib/el3_runtime/cpu_data.h>
#include <lib/smccc.h>
@ -47,72 +48,30 @@
str x30, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_LR]
.endm
/*
* Macro that prepares entry to EL3 upon taking an exception.
*
* With RAS_FFH_SUPPORT, this macro synchronizes pending errors with an
* ESB instruction. When an error is thus synchronized, the handling is
* delegated to platform EA handler.
*
* Without RAS_FFH_SUPPORT, this macro synchronizes pending errors using
* a DSB, unmasks Asynchronous External Aborts and saves X30 before
* setting the flag CTX_IS_IN_EL3.
*/
.macro check_and_unmask_ea
#if RAS_FFH_SUPPORT
/* Synchronize pending External Aborts */
esb
/* Unmask the SError interrupt */
msr daifclr, #DAIF_ABT_BIT
/* Check for SErrors synchronized by the ESB instruction */
mrs x30, DISR_EL1
tbz x30, #DISR_A_BIT, 1f
.macro restore_x30
ldr x30, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_LR]
.endm
/*
* Save general purpose and ARMv8.3-PAuth registers (if enabled).
* Also save PMCR_EL0 and set the PSTATE to a known state.
* Macro that synchronizes errors (EA) and checks for pending SError.
* On detecting a pending SError it either reflects it back to lower
* EL (KFH) or handles it in EL3 (FFH) based on EA routing model.
*/
bl prepare_el3_entry
bl handle_lower_el_ea_esb
/* Restore general purpose, PMCR_EL0 and ARMv8.3-PAuth registers */
bl restore_gp_pmcr_pauth_regs
1:
#else
/*
* Note 1: The explicit DSB at the entry of various exception vectors
* for handling exceptions from lower ELs can inadvertently trigger an
* SError exception in EL3 due to pending asynchronous aborts in lower
* ELs. This will end up being handled by serror_sp_elx which will
* ultimately panic and die.
* The way to workaround is to update a flag to indicate if the exception
* truly came from EL3. This flag is allocated in the cpu_context
* structure and located at offset "CTX_EL3STATE_OFFSET + CTX_IS_IN_EL3"
* This is not a bullet proof solution to the problem at hand because
* we assume the instructions following "isb" that help to update the
* flag execute without causing further exceptions.
*/
/*
* For SoCs which do not implement RAS, use DSB as a barrier to
* synchronize pending external aborts.
*/
dsb sy
/* Unmask the SError interrupt */
msr daifclr, #DAIF_ABT_BIT
/* Use ISB for the above unmask operation to take effect immediately */
isb
/* Refer Note 1. */
mov x30, #1
str x30, [sp, #CTX_EL3STATE_OFFSET + CTX_IS_IN_EL3]
dmb sy
.macro sync_and_handle_pending_serror
synchronize_errors
mrs x30, ISR_EL1
tbz x30, #ISR_A_SHIFT, 2f
#if FFH_SUPPORT
mrs x30, scr_el3
tst x30, #SCR_EA_BIT
b.eq 1f
bl handle_pending_async_ea
b 2f
#endif
1:
/* This function never returns, but need LR for decision making */
bl reflect_pending_async_ea_to_lower_el
2:
.endm
/* ---------------------------------------------------------------------
@ -147,9 +106,19 @@
cmp x30, #EC_AARCH64_SYS
b.eq sync_handler64
/* Synchronous exceptions other than the above are assumed to be EA */
ldr x30, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_LR]
cmp x30, #EC_IMP_DEF_EL3
b.eq imp_def_el3_handler
/* If FFH Support then try to handle lower EL EA exceptions. */
#if FFH_SUPPORT
mrs x30, scr_el3
tst x30, #SCR_EA_BIT
b.eq 1f
b handle_lower_el_sync_ea
#endif
1:
/* Synchronous exceptions other than the above are unhandled */
b report_unhandled_exception
.endm
vector_base runtime_exceptions
@ -217,22 +186,33 @@ vector_entry fiq_sp_elx
end_vector_entry fiq_sp_elx
vector_entry serror_sp_elx
#if !RAS_FFH_SUPPORT
#if FFH_SUPPORT
/*
* This will trigger if the exception was taken due to SError in EL3 or
* because of pending asynchronous external aborts from lower EL that got
* triggered due to explicit synchronization in EL3. Refer Note 1.
* triggered due to implicit/explicit synchronization in EL3 (SCR_EL3.EA=1)
* during EL3 entry. For the former case we continue with "plat_handle_el3_ea".
* The later case will occur when PSTATE.A bit is cleared in
* "handle_pending_async_ea". This means we are doing a nested
* exception in EL3. Call the handler for async EA which will eret back to
* original el3 handler if it is nested exception. Also, unmask EA so that we
* catch any further EA arise when handling this nested exception at EL3.
*/
/* Assumes SP_EL3 on entry */
save_x30
ldr x30, [sp, #CTX_EL3STATE_OFFSET + CTX_IS_IN_EL3]
cbnz x30, 1f
/* Handle asynchronous external abort from lower EL */
ldr x30, [sp, #CTX_EL3STATE_OFFSET + CTX_NESTED_EA_FLAG]
cbz x30, 1f
/*
* This is nested exception handling, clear the flag to avoid taking this
* path for further exceptions caused by EA handling
*/
str xzr, [sp, #CTX_EL3STATE_OFFSET + CTX_NESTED_EA_FLAG]
unmask_async_ea
b handle_lower_el_async_ea
1:
restore_x30
#endif
no_ret plat_handle_el3_ea
end_vector_entry serror_sp_elx
/* ---------------------------------------------------------------------
@ -248,34 +228,41 @@ vector_entry sync_exception_aarch64
*/
save_x30
apply_at_speculative_wa
check_and_unmask_ea
sync_and_handle_pending_serror
unmask_async_ea
handle_sync_exception
end_vector_entry sync_exception_aarch64
vector_entry irq_aarch64
save_x30
apply_at_speculative_wa
check_and_unmask_ea
sync_and_handle_pending_serror
unmask_async_ea
b handle_interrupt_exception
end_vector_entry irq_aarch64
vector_entry fiq_aarch64
save_x30
apply_at_speculative_wa
check_and_unmask_ea
sync_and_handle_pending_serror
unmask_async_ea
b handle_interrupt_exception
end_vector_entry fiq_aarch64
/*
* Need to synchronize any outstanding SError since we can get a burst of errors.
* So reuse the sync mechanism to catch any further errors which are pending.
*/
vector_entry serror_aarch64
#if FFH_SUPPORT
save_x30
apply_at_speculative_wa
#if RAS_FFH_SUPPORT
msr daifclr, #DAIF_ABT_BIT
#else
check_and_unmask_ea
#endif
sync_and_handle_pending_serror
unmask_async_ea
b handle_lower_el_async_ea
#else
b report_unhandled_exception
#endif
end_vector_entry serror_aarch64
/* ---------------------------------------------------------------------
@ -291,34 +278,41 @@ vector_entry sync_exception_aarch32
*/
save_x30
apply_at_speculative_wa
check_and_unmask_ea
sync_and_handle_pending_serror
unmask_async_ea
handle_sync_exception
end_vector_entry sync_exception_aarch32
vector_entry irq_aarch32
save_x30
apply_at_speculative_wa
check_and_unmask_ea
sync_and_handle_pending_serror
unmask_async_ea
b handle_interrupt_exception
end_vector_entry irq_aarch32
vector_entry fiq_aarch32
save_x30
apply_at_speculative_wa
check_and_unmask_ea
sync_and_handle_pending_serror
unmask_async_ea
b handle_interrupt_exception
end_vector_entry fiq_aarch32
/*
* Need to synchronize any outstanding SError since we can get a burst of errors.
* So reuse the sync mechanism to catch any further errors which are pending.
*/
vector_entry serror_aarch32
#if FFH_SUPPORT
save_x30
apply_at_speculative_wa
#if RAS_FFH_SUPPORT
msr daifclr, #DAIF_ABT_BIT
#else
check_and_unmask_ea
#endif
sync_and_handle_pending_serror
unmask_async_ea
b handle_lower_el_async_ea
#else
b report_unhandled_exception
#endif
end_vector_entry serror_aarch32
#ifdef MONITOR_TRAPS
@ -608,6 +602,114 @@ interrupt_exit:
b el3_exit
endfunc handle_interrupt_exception
func imp_def_el3_handler
/* Save GP registers */
stp x0, x1, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X0]
stp x2, x3, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X2]
stp x4, x5, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X4]
/* Get the cpu_ops pointer */
bl get_cpu_ops_ptr
/* Get the cpu_ops exception handler */
ldr x0, [x0, #CPU_E_HANDLER_FUNC]
/*
* If the reserved function pointer is NULL, this CPU does not have an
* implementation defined exception handler function
*/
cbz x0, el3_handler_exit
mrs x1, esr_el3
ubfx x1, x1, #ESR_EC_SHIFT, #ESR_EC_LENGTH
blr x0
el3_handler_exit:
ldp x0, x1, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X0]
ldp x2, x3, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X2]
ldp x4, x5, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X4]
restore_x30
no_ret report_unhandled_exception
endfunc imp_def_el3_handler
/*
* Handler for async EA from lower EL synchronized at EL3 entry in KFH mode.
*
* This scenario may arise when there is an error (EA) in the system which is not
* yet signaled to PE while executing in lower EL. During entry into EL3, the errors
* are synchronized either implicitly or explicitly causing async EA to pend at EL3.
*
* On detecting the pending EA (via ISR_EL1.A) and if the EA routing model is
* KFH (SCR_EL3.EA = 1) this handler reflects ther error back to lower EL.
*
* This function assumes x30 has been saved.
*/
func reflect_pending_async_ea_to_lower_el
/*
* As the original exception was not handled we need to ensure that we return
* back to the instruction which caused the exception. To acheive that, eret
* to "elr-4" (Label "subtract_elr_el3") for SMC or simply eret otherwise
* (Label "skip_smc_check").
*
* LIMITATION: It could be that async EA is masked at the target exception level
* or the priority of async EA wrt to the EL3/secure interrupt is lower, which
* causes back and forth between lower EL and EL3. In case of back and forth between
* lower EL and EL3, we can track the loop count in "CTX_NESTED_EA_FLAG" and leverage
* previous ELR in "CTX_SAVED_ELR_EL3" to detect this cycle and further panic
* to indicate a problem here (Label "check_loop_ctr"). If we are in this cycle, loop
* counter retains its value but if we do a normal el3_exit this flag gets cleared.
* However, setting SCR_EL3.IESB = 1, should give priority to SError handling
* as per AArch64.TakeException pseudo code in Arm ARM.
*
* TODO: In future if EL3 gets a capability to inject a virtual SError to lower
* ELs, we can remove the el3_panic and handle the original exception first and
* inject SError to lower EL before ereting back.
*/
stp x28, x29, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X28]
ldr x29, [sp, #CTX_EL3STATE_OFFSET + CTX_SAVED_ELR_EL3]
mrs x28, elr_el3
cmp x29, x28
b.eq check_loop_ctr
str x28, [sp, #CTX_EL3STATE_OFFSET + CTX_SAVED_ELR_EL3]
/* Zero the loop counter */
str xzr, [sp, #CTX_EL3STATE_OFFSET + CTX_NESTED_EA_FLAG]
b skip_loop_ctr
check_loop_ctr:
ldr x29, [sp, #CTX_EL3STATE_OFFSET + CTX_NESTED_EA_FLAG]
add x29, x29, #1
str x29, [sp, #CTX_EL3STATE_OFFSET + CTX_NESTED_EA_FLAG]
cmp x29, #ASYNC_EA_REPLAY_COUNTER
b.ge el3_panic
skip_loop_ctr:
/*
* Logic to distinguish if we came from SMC or any other exception.
* Use offsets in vector entry to get which exception we are handling.
* In each vector entry of size 0x200, address "0x0-0x80" is for sync
* exception and "0x80-0x200" is for async exceptions.
* Use vector base address (vbar_el3) and exception offset (LR) to
* calculate whether the address we came from is any of the following
* "0x0-0x80", "0x200-0x280", "0x400-0x480" or "0x600-0x680"
*/
mrs x29, vbar_el3
sub x30, x30, x29
and x30, x30, #0x1ff
cmp x30, #0x80
b.ge skip_smc_check
/* Its a synchronous exception, Now check if it is SMC or not? */
mrs x30, esr_el3
ubfx x30, x30, #ESR_EC_SHIFT, #ESR_EC_LENGTH
cmp x30, #EC_AARCH32_SMC
b.eq subtract_elr_el3
cmp x30, #EC_AARCH64_SMC
b.eq subtract_elr_el3
b skip_smc_check
subtract_elr_el3:
sub x28, x28, #4
skip_smc_check:
msr elr_el3, x28
ldp x28, x29, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X28]
ldr x30, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_LR]
exception_return
endfunc reflect_pending_async_ea_to_lower_el
/* ---------------------------------------------------------------------
* The following code handles exceptions caused by BRK instructions.
* Following a BRK instruction, the only real valid cause of action is

View file

@ -39,7 +39,6 @@ BL31_SOURCES += bl31/bl31_main.c \
bl31/interrupt_mgmt.c \
bl31/aarch64/bl31_entrypoint.S \
bl31/aarch64/crash_reporting.S \
bl31/aarch64/ea_delegate.S \
bl31/aarch64/runtime_exceptions.S \
bl31/bl31_context_mgmt.c \
bl31/bl31_traps.c \
@ -67,6 +66,10 @@ ifeq (${EL3_EXCEPTION_HANDLING},1)
BL31_SOURCES += bl31/ehf.c
endif
ifeq (${FFH_SUPPORT},1)
BL31_SOURCES += bl31/aarch64/ea_delegate.S
endif
ifeq (${SDEI_SUPPORT},1)
ifeq (${EL3_EXCEPTION_HANDLING},0)
$(error EL3_EXCEPTION_HANDLING must be 1 for SDEI support)

View file

@ -10,6 +10,9 @@ precise definition of RAS terminology, please refer to the Arm Architecture
Reference Manual and `RAS Supplement`_. The rest of this document assumes
familiarity with architecture and terminology.
**IMPORTANT NOTE**: TF-A implementation assumes that if RAS extension is present
then FEAT_IESB is also implmented.
There are two philosophies for handling RAS errors from Non-secure world point
of view.
@ -56,26 +59,87 @@ Introduction
EA's originating/attributed to NS world are handled first in NS and Kernel navigates
the std error records directly.
**KFH can be supported in a platform without TF-A being aware of it but there are few
corner cases where TF-A needs to have special handling, which is currently missing and
will be added in future**
- KFH is the default handling mode if platform does not explicitly enable FFH mode.
- KFH mode does not need any EL3 involvement except for the reflection of errors back
to lower EL. This happens when there is an error (EA) in the system which is not yet
signaled to PE while executing at lower EL. During entry into EL3 the errors (EA) are
synchronized causing async EA to pend at EL3.
Error Syncronization at EL3 entry
=================================
During entry to EL3 from lower EL, if there is any pending async EAs they are either
reflected back to lower EL (KFH) or handled in EL3 itself (FFH).
|Image 1|
TF-A build options
==================
- **ENABLE_FEAT_RAS**: Manage FEAT_RAS extension when switching the world.
- **RAS_FFH_SUPPORT**: Pull in necessary framework and platform hooks for Firmware first
handling(FFH) of RAS errors.
- **ENABLE_FEAT_RAS**: Enable RAS extension feature at EL3.
- **HANDLE_EA_EL3_FIRST_NS**: Required for FFH
- **RAS_TRAP_NS_ERR_REC_ACCESS**: Trap Non-secure access of RAS error record registers.
- **RAS_EXTENSION**: Deprecated macro, equivalent to ENABLE_FEAT_RAS and RAS_FFH_SUPPORT
put together.
- **RAS_EXTENSION**: Deprecated macro, equivalent to ENABLE_FEAT_RAS and
HANDLE_EA_EL3_FIRST_NS put together.
RAS internal macros
- **FFH_SUPPORT**: Gets enabled if **HANDLE_EA_EL3_FIRST_NS** is enabled.
RAS feature has dependency on some other TF-A build flags
- **EL3_EXCEPTION_HANDLING**: Required for FFH
- **HANDLE_EA_EL3_FIRST_NS**: Required for FFH
- **FAULT_INJECTION_SUPPORT**: Required for testing RAS feature on fvp platform
TF-A Tests
==========
RAS functionality is regularly tested in TF-A CI using `RAS test group`_ which has multiple
configurations for testing lower EL External aborts.
All the tests are written in TF-A tests which runs as NS-EL2 payload.
- **FFH without RAS extension**
*fvp-ea-ffh,fvp-ea-ffh:fvp-tftf-fip.tftf-aemv8a-debug*
Couple of tests, one each for sync EA and async EA from lower EL which gets handled in El3.
Inject External aborts(sync/async) which traps in EL3, FVP has a handler which gracefully
handles these errors and returns back to TF-A Tests
Build Configs : **HANDLE_EA_EL3_FIRST_NS** , **PLATFORM_TEST_EA_FFH**
- **FFH with RAS extension**
Three Tests :
- *fvp-ras-ffh,fvp-single-fault:fvp-tftf-fip.tftf-aemv8a.fi-debug*
Inject an unrecoverable RAS error, which gets handled in EL3.
- *fvp-ras-ffh,fvp-uncontainable:fvp-tftf.fault-fip.tftf-aemv8a.fi-debug*
Inject uncontainable RAS errors which causes platform to panic.
- *fvp-ras-ffh,fvp-ras-ffh-nested:fvp-tftf-fip.tftf-ras_ffh_nested-aemv8a.fi-debug*
Test nested exception handling at El3 for synchronized async EAs. Inject an SError in lower EL
which remain pending until we enter EL3 through SMC call. At EL3 entry on encountering a pending
async EA it will handle the async EA first (nested exception) before handling the original SMC call.
- **KFH with RAS extension**
Couple of tests in the group :
- *fvp-ras-kfh,fvp-ras-kfh:fvp-tftf-fip.tftf-aemv8a.fi-debug*
Inject and handle RAS errors in TF-A tests (no El3 involvement)
- *fvp-ras-kfh,fvp-ras-kfh-reflect:fvp-tftf-fip.tftf-ras_kfh_reflection-aemv8a.fi-debug*
Reflection of synchronized errors from EL3 to TF-A tests, two tests one each for reflecting
in IRQ and SMC path.
RAS Framework
=============
@ -238,7 +302,7 @@ Engaging the RAS framework
Enabling RAS support is a platform choice
The RAS support in |TF-A| introduces a default implementation of
``plat_ea_handler``, the External Abort handler in EL3. When ``RAS_FFH_SUPPORT``
``plat_ea_handler``, the External Abort handler in EL3. When ``ENABLE_FEAT_RAS``
is set to ``1``, it'll first call ``ras_ea_handler()`` function, which is the
top-level RAS exception handler. ``ras_ea_handler`` is responsible for iterating
to through platform-supplied error records, probe them, and when an error is
@ -277,3 +341,6 @@ for non-interrupt exceptions, they're explicit using :ref:`EHF APIs
*Copyright (c) 2018-2023, Arm Limited and Contributors. All rights reserved.*
.. _RAS Supplement: https://developer.arm.com/documentation/ddi0587/latest
.. _RAS Test group: https://git.trustedfirmware.org/ci/tf-a-ci-scripts.git/tree/group/tf-l3-boot-tests-ras?h=refs/heads/master
.. |Image 1| image:: ../resources/diagrams/bl31-exception-entry-error-synchronization.png

View file

@ -1118,6 +1118,65 @@ returning through EL3 and running the non-trusted firmware (BL33):
``bl31_main()`` will set up the return to the normal world firmware BL33 and
continue the boot process in the normal world.
Exception handling in BL31
--------------------------
When exception occurs, PE must execute handler corresponding to exception. The
location in memory where the handler is stored is called the exception vector.
For ARM architecture, exception vectors are stored in a table, called the exception
vector table.
Each EL (except EL0) has its own vector table, VBAR_ELn register stores the base
of vector table. Refer to `AArch64 exception vector table`_
Current EL with SP_EL0
~~~~~~~~~~~~~~~~~~~~~~
- Sync exception : Not expected except for BRK instruction, its debugging tool which
a programmer may place at specific points in a program, to check the state of
processor flags at these points in the code.
- IRQ/FIQ : Unexpected exception, panic
- SError : "plat_handle_el3_ea", defaults to panic
Current EL with SP_ELx
~~~~~~~~~~~~~~~~~~~~~~
- Sync exception : Unexpected exception, panic
- IRQ/FIQ : Unexpected exception, panic
- SError : "plat_handle_el3_ea" Except for special handling of lower EL's SError exception
which gets triggered in EL3 when PSTATE.A is unmasked. Its only applicable when lower
EL's EA is routed to EL3 (FFH_SUPPORT=1).
Lower EL Exceptions
~~~~~~~~~~~~~~~~~~~
Applies to all the exceptions in both AArch64/AArch32 mode of lower EL.
Before handling any lower EL exception, we synchronize the errors at EL3 entry to ensure
that any errors pertaining to lower EL is isolated/identified. If we continue without
identifying these errors early on then these errors will trigger in EL3 (as SError from
current EL) any time after PSTATE.A is unmasked. This is wrong because the error originated
in lower EL but exception happened in EL3.
To solve this problem, synchronize the errors at EL3 entry and check for any pending
errors (async EA). If there is no pending error then continue with original exception.
If there is a pending error then, handle them based on routing model of EA's. Refer to
:ref:`Reliability, Availability, and Serviceability (RAS) Extensions` for details about
routing models.
- KFH : Reflect it back to lower EL using **reflect_pending_async_ea_to_lower_el()**
- FFH : Handle the synchronized error first using **handle_pending_async_ea()** after
that continue with original exception. It is the only scenario where EL3 is capable
of doing nested exception handling.
After synchronizing and handling lower EL SErrors, unmask EA (PSTATE.A) to ensure
that any further EA's caused by EL3 are caught.
Crash Reporting in BL31
-----------------------
@ -2803,5 +2862,6 @@ kernel at boot time. These can be found in the ``fdts`` directory.
.. _SMC Calling Convention: https://developer.arm.com/docs/den0028/latest
.. _Trusted Board Boot Requirements CLIENT (TBBR-CLIENT) Armv8-A (ARM DEN0006D): https://developer.arm.com/docs/den0006/latest/trusted-board-boot-requirements-client-tbbr-client-armv8-a
.. _Arm Confidential Compute Architecture (Arm CCA): https://www.arm.com/why-arm/architecture/security-features/arm-confidential-compute-architecture
.. _AArch64 exception vector table: https://developer.arm.com/documentation/100933/0100/AArch64-exception-vector-table
.. |Image 1| image:: ../resources/diagrams/rt-svc-descs-layout.png

View file

@ -12,3 +12,10 @@ depends on certain options to be enabled or disabled.
interest when Armv8.4-SecEL2 or RME extension is implemented.
Default is 0 (disabled). This option will be set to 1 (enabled) when ``SPD=spmd``
and ``SPMD_SPM_AT_SEL2`` is set or when ``ENABLE_RME`` is set to 1 (enabled).
- ``FFH_SUPPORT``: This boolean option provides support to enable Firmware First
handling (FFH) of External aborts and SError interrupts originating from lower
ELs which gets trapped in EL3. This option will be set to 1 (enabled) if
``HANDLE_EA_EL3_FIRST_NS`` is set. Currently only NS world routes EA to EL3 but
in future when Secure/Realm wants to use FFH then they can introduce new macros
which will enable this option implicitly.

View file

@ -811,14 +811,12 @@ Common build options
- ``PSCI_OS_INIT_MODE``: Boolean flag to enable support for optional PSCI
OS-initiated mode. This option defaults to 0.
- ``ENABLE_FEAT_RAS``: Numeric value to enable Armv8.2 RAS features. RAS features
- ``ENABLE_FEAT_RAS``: Boolean flag to enable Armv8.2 RAS features. RAS features
are an optional extension for pre-Armv8.2 CPUs, but are mandatory for Armv8.2
or later CPUs. This flag can take the values 0 to 2, to align with the
``FEATURE_DETECTION`` mechanism.
- ``RAS_FFH_SUPPORT``: Support to enable Firmware first handling of RAS errors
originating from NS world. When ``RAS_FFH_SUPPORT`` is set to ``1``,
``HANDLE_EA_EL3_FIRST_NS`` and ``ENABLE_FEAT_RAS`` must also be set to ``1``.
or later CPUs. This flag can take the values 0 or 1. The default value is 0.
NOTE: This flag enables use of IESB capability to reduce entry latency into
EL3 even when RAS error handling is not performed on the platform. Hence this
flag is recommended to be turned on Armv8.2 and later CPUs.
- ``RESET_TO_BL31``: Enable BL31 entrypoint as the CPU reset vector instead
of the BL1 entrypoint. It can take the value 0 (CPU reset to BL1

View file

@ -3298,10 +3298,10 @@ Function : plat_ea_handler
Argument : uint64_t
Return : void
This function is invoked by the RAS framework for the platform to handle an
External Abort received at EL3. The intention of the function is to attempt to
resolve the cause of External Abort and return; if that's not possible, to
initiate orderly shutdown of the system.
This function is invoked by the runtime exception handling framework for the
platform to handle an External Abort received at EL3. The intention of the
function is to attempt to resolve the cause of External Abort and return;
if that's not possible then an orderly shutdown of the system is initiated.
The first parameter (``int ea_reason``) indicates the reason for External Abort.
Its value is one of ``ERROR_EA_*`` constants defined in ``ea_handle.h``.
@ -3316,13 +3316,8 @@ The third parameter (``void *cookie``) is unused for now. The fourth parameter
(``uint64_t flags``) indicates the preempted security state. These parameters
are received from the top-level exception handler.
If ``RAS_FFH_SUPPORT`` is set to ``1``, the default implementation of this
function iterates through RAS handlers registered by the platform. If any of the
RAS handlers resolve the External Abort, no further action is taken.
If ``RAS_FFH_SUPPORT`` is set to ``0``, or if none of the platform RAS handlers
could resolve the External Abort, the default implementation prints an error
message, and panics.
This function must be implemented if a platform expects Firmware First handling
of External Aborts.
Function : plat_handle_uncontainable_ea
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Binary file not shown.

After

Width:  |  Height:  |  Size: 82 KiB

View file

@ -120,6 +120,14 @@
.endm
#endif
/* Macro for error synchronization */
.macro synchronize_errors
/* Complete any stores that may return an abort */
dsb sy
/* Synchronise the CPU context with the completion of the dsb */
isb
.endm
#if (ARM_ARCH_MAJOR == 7)
/* ARMv7 does not support stl instruction */
.macro stl _reg, _write_lock

View file

@ -962,6 +962,7 @@
#define EC_AARCH64_HVC U(0x16)
#define EC_AARCH64_SMC U(0x17)
#define EC_AARCH64_SYS U(0x18)
#define EC_IMP_DEF_EL3 U(0x1f)
#define EC_IABORT_LOWER_EL U(0x20)
#define EC_IABORT_CUR_EL U(0x21)
#define EC_PC_ALIGN U(0x22)

View file

@ -292,4 +292,29 @@
#endif
.endm
/*
* Macro to unmask External Aborts by changing PSTATE.A bit.
* Put explicit synchronization event to ensure newly unmasked interrupt
* is taken immediately.
*/
.macro unmask_async_ea
msr daifclr, #DAIF_ABT_BIT
isb
.endm
/* Macro for error synchronization on exception boundries.
* With FEAT_RAS enabled, it is assumed that FEAT_IESB is also present
* and enabled.
* FEAT_IESB provides an implicit error synchronization event at exception
* entry and exception return, so there is no need for any explicit instruction.
*/
.macro synchronize_errors
#if !ENABLE_FEAT_RAS
/* Complete any stores that may return an abort */
dsb sy
/* Synchronise the CPU context with the completion of the dsb */
isb
#endif
.endm
#endif /* ASM_MACROS_S */

View file

@ -208,6 +208,10 @@
*/
mov_imm x0, (SCTLR_RESET_VAL & ~(SCTLR_EE_BIT | SCTLR_WXN_BIT \
| SCTLR_SA_BIT | SCTLR_A_BIT | SCTLR_DSSBS_BIT))
#if ENABLE_FEAT_RAS
/* If FEAT_RAS is present assume FEAT_IESB is also present */
orr x0, x0, #SCTLR_IESB_BIT
#endif
msr sctlr_el3, x0
isb
.endif /* _init_sctlr */

View file

@ -21,4 +21,6 @@
/* RAS event signalled as peripheral interrupt */
#define ERROR_INTERRUPT 3
#define ASYNC_EA_REPLAY_COUNTER U(100)
#endif /* EA_HANDLE_H */

View file

@ -63,7 +63,22 @@
#define CTX_PMCR_EL0 U(0x28)
#define CTX_IS_IN_EL3 U(0x30)
#define CTX_MPAM3_EL3 U(0x38)
#define CTX_EL3STATE_END U(0x40) /* Align to the next 16 byte boundary */
/* Constants required in supporting nested exception in EL3 */
#define CTX_SAVED_ELR_EL3 U(0x40)
/*
* General purpose flag, to save various EL3 states
* FFH mode : Used to identify if handling nested exception
* KFH mode : Used as counter value
*/
#define CTX_NESTED_EA_FLAG U(0x48)
#if FFH_SUPPORT
#define CTX_SAVED_ESR_EL3 U(0x50)
#define CTX_SAVED_SPSR_EL3 U(0x58)
#define CTX_SAVED_GPREG_LR U(0x60)
#define CTX_EL3STATE_END U(0x70) /* Align to the next 16 byte boundary */
#else
#define CTX_EL3STATE_END U(0x50) /* Align to the next 16 byte boundary */
#endif
/*******************************************************************************
* Constants that allow assembler code to access members of and the

View file

@ -774,7 +774,7 @@ MEASURED_BOOT
#define PLAT_PERCPU_BAKERY_LOCK_SIZE (1 * CACHE_WRITEBACK_GRANULE)
/* Priority levels for ARM platforms */
#if RAS_FFH_SUPPORT
#if ENABLE_FEAT_RAS && FFH_SUPPORT
#define PLAT_RAS_PRI 0x10
#endif
#define PLAT_SDEI_CRITICAL_PRI 0x60

View file

@ -649,23 +649,9 @@ sve_not_enabled:
1:
#endif /* IMAGE_BL31 && DYNAMIC_WORKAROUND_CVE_2018_3639 */
/*
* This is a hot path, so we don't want to do some actual FEAT_RAS runtime
* detection here. The "esb" is a cheaper variant, so using "dsb" in the
* ENABLE_FEAT_RAS==2 case is not ideal, but won't hurt.
*/
#if IMAGE_BL31 && ENABLE_FEAT_RAS == 1
/* ----------------------------------------------------------
* Issue Error Synchronization Barrier to synchronize SErrors
* before exiting EL3. We're running with EAs unmasked, so
* any synchronized errors would be taken immediately;
* therefore no need to inspect DISR_EL1 register.
* ----------------------------------------------------------
*/
esb
#else
dsb sy
#endif /* IMAGE_BL31 && ENABLE_FEAT_RAS */
#if IMAGE_BL31
synchronize_errors
#endif /* IMAGE_BL31 */
/* ----------------------------------------------------------
* Restore SPSR_EL3, ELR_EL3 and SCR_EL3 prior to ERET
@ -689,7 +675,8 @@ sve_not_enabled:
ldr x30, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_LR]
#ifdef IMAGE_BL31
str xzr, [sp, #CTX_EL3STATE_OFFSET + CTX_IS_IN_EL3]
/* Clear the EL3 flag as we are exiting el3 */
str xzr, [sp, #CTX_EL3STATE_OFFSET + CTX_NESTED_EA_FLAG]
#endif /* IMAGE_BL31 */
exception_return

View file

@ -191,9 +191,6 @@ PSCI_EXTENDED_STATE_ID := 0
# Enable PSCI OS-initiated mode support
PSCI_OS_INIT_MODE := 0
# Enable RAS Firmware First Handling Support
RAS_FFH_SUPPORT := 0
# By default, BL1 acts as the reset handler, not BL31
RESET_TO_BL31 := 0

View file

@ -56,7 +56,6 @@ ifneq (${SPD}, tspd)
ENABLE_FEAT_RNG := 2
ENABLE_FEAT_TWED := 2
ENABLE_FEAT_GCS := 2
ENABLE_FEAT_RAS := 2
ifeq (${ARCH}, aarch64)
ifneq (${SPD}, spmd)
ifeq (${SPM_MM}, 0)
@ -398,8 +397,12 @@ BL31_SOURCES += lib/cpus/aarch64/cortex_a75_pubsub.c \
endif
endif
ifeq (${RAS_FFH_SUPPORT},1)
ifeq (${HANDLE_EA_EL3_FIRST_NS},1)
ifeq (${ENABLE_FEAT_RAS},1)
BL31_SOURCES += plat/arm/board/fvp/aarch64/fvp_ras.c
else
BL31_SOURCES += plat/arm/board/fvp/aarch64/fvp_ea.c
endif
endif
ifneq (${ENABLE_STACK_PROTECTOR},0)
@ -519,16 +522,19 @@ endif
# Test specific macros, keep them at bottom of this file
$(eval $(call add_define,PLATFORM_TEST_EA_FFH))
ifeq (${PLATFORM_TEST_EA_FFH}, 1)
ifeq (${HANDLE_EA_EL3_FIRST_NS}, 0)
$(error "PLATFORM_TEST_EA_FFH expects HANDLE_EA_EL3_FIRST_NS to be 1")
ifeq (${FFH_SUPPORT}, 0)
$(error "PLATFORM_TEST_EA_FFH expects FFH_SUPPORT to be 1")
endif
BL31_SOURCES += plat/arm/board/fvp/aarch64/fvp_ea.c
endif
$(eval $(call add_define,PLATFORM_TEST_RAS_FFH))
ifeq (${PLATFORM_TEST_RAS_FFH}, 1)
ifeq (${RAS_EXTENSION}, 0)
$(error "PLATFORM_TEST_RAS_FFH expects RAS_EXTENSION to be 1")
ifeq (${ENABLE_FEAT_RAS}, 0)
$(error "PLATFORM_TEST_RAS_FFH expects ENABLE_FEAT_RAS to be 1")
endif
ifeq (${HANDLE_EA_EL3_FIRST_NS}, 0)
$(error "PLATFORM_TEST_RAS_FFH expects HANDLE_EA_EL3_FIRST_NS to be 1")
endif
endif

View file

@ -69,7 +69,7 @@ BL31_SOURCES += drivers/arm/gic/v3/gic600_multichip.c
BL31_CFLAGS += -DPLAT_XLAT_TABLES_DYNAMIC
endif
ifeq (${RAS_FFH_SUPPORT},1)
ifeq (${ENABLE_FEAT_RAS}-${HANDLE_EA_EL3_FIRST_NS},1-1)
BL31_SOURCES += ${RDN2_BASE}/rdn2_ras.c \
${CSS_ENT_BASE}/ras/sgi_ras_common.c \
${CSS_ENT_BASE}/ras/sgi_ras_sram.c \

View file

@ -137,7 +137,7 @@ void bl31_platform_setup(void)
sgi_bl31_common_platform_setup();
#if RAS_FFH_SUPPORT
#if ENABLE_FEAT_RAS && FFH_SUPPORT
sgi_ras_platform_setup(&ras_config);
#endif
}

View file

@ -15,7 +15,7 @@
static const arm_tzc_regions_info_t tzc_regions[] = {
ARM_TZC_REGIONS_DEF,
#if RAS_FFH_SUPPORT
#if ENABLE_FEAT_RAS && FFH_SUPPORT
RDN2_TZC_CPER_REGION,
#endif
{}

View file

@ -21,8 +21,6 @@ CSS_USE_SCMI_SDS_DRIVER := 1
ENABLE_FEAT_RAS := 1
RAS_FFH_SUPPORT := 0
SDEI_SUPPORT := 0
EL3_EXCEPTION_HANDLING := 0

View file

@ -295,7 +295,7 @@ void arm_bl31_platform_setup(void)
/* Initialize power controller before setting up topology */
plat_arm_pwrc_setup();
#if RAS_FFH_SUPPORT
#if ENABLE_FEAT_RAS && FFH_SUPPORT
ras_init();
#endif

View file

@ -352,7 +352,7 @@ endif
endif
# RAS sources
ifeq (${RAS_FFH_SUPPORT},1)
ifeq (${ENABLE_FEAT_RAS}-${HANDLE_EA_EL3_FIRST_NS},1-1)
BL31_SOURCES += lib/extensions/ras/std_err_record.c \
lib/extensions/ras/ras_common.c
endif

View file

@ -41,7 +41,7 @@ static const uintptr_t *gicr_frames = gicr_base_addrs;
static const interrupt_prop_t arm_interrupt_props[] = {
PLAT_ARM_G1S_IRQ_PROPS(INTR_GROUP1S),
PLAT_ARM_G0_IRQ_PROPS(INTR_GROUP0),
#if RAS_FFH_SUPPORT
#if ENABLE_FEAT_RAS && FFH_SUPPORT
INTR_PROP_DESC(PLAT_CORE_FAULT_IRQ, PLAT_RAS_PRI, INTR_GROUP0,
GIC_INTR_CFG_LEVEL)
#endif

View file

@ -204,13 +204,13 @@
SOC_CSS_DEVICE_SIZE, \
MT_DEVICE | MT_RW | MT_SECURE | MT_USER)
#if RAS_FFH_SUPPORT
#if ENABLE_FEAT_RAS && FFH_SUPPORT
#define PLAT_SP_PRI PLAT_RAS_PRI
#else
#define PLAT_SP_PRI 0x10
#endif
#if (SPM_MM || (SPMC_AT_EL3 && SPMC_AT_EL3_SEL0_SP)) && RAS_FFH_SUPPORT
#if (SPM_MM || (SPMC_AT_EL3 && SPMC_AT_EL3_SEL0_SP)) && ENABLE_FEAT_RAS && FFH_SUPPORT
/*
* CPER buffer memory of 128KB is reserved and it is placed adjacent to the
* memory shared between EL3 and S-EL0.
@ -239,7 +239,7 @@
*/
#define PLAT_ARM_SP_IMAGE_STACK_BASE (PLAT_SP_IMAGE_NS_BUF_BASE + \
PLAT_SP_IMAGE_NS_BUF_SIZE)
#endif /* SPM_MM && RAS_FFH_SUPPORT */
#endif /* SPM_MM && ENABLE_FEAT_RAS && FFH_SUPPORT */
/* Platform ID address */
#define SSC_VERSION (SSC_REG_BASE + SSC_VERSION_OFFSET)

View file

@ -10,8 +10,6 @@ CSS_ENT_BASE := plat/arm/css/sgi
ENABLE_FEAT_RAS := 1
RAS_FFH_SUPPORT := 0
SDEI_SUPPORT := 0
EL3_EXCEPTION_HANDLING := 0

View file

@ -93,7 +93,7 @@ const mmap_region_t plat_arm_secure_partition_mmap[] = {
PLAT_ARM_SECURE_MAP_DEVICE,
ARM_SP_IMAGE_MMAP,
ARM_SP_IMAGE_NS_BUF_MMAP,
#if RAS_FFH_SUPPORT
#if ENABLE_FEAT_RAS && FFH_SUPPORT
CSS_SGI_SP_CPER_BUF_MMAP,
#endif
ARM_SP_IMAGE_RW_MMAP,

View file

@ -87,7 +87,7 @@ const mmap_region_t plat_arm_secure_partition_mmap[] = {
SOC_PLATFORM_PERIPH_MAP_DEVICE_USER,
ARM_SP_IMAGE_MMAP,
ARM_SP_IMAGE_NS_BUF_MMAP,
#if RAS_FFH_SUPPORT
#if ENABLE_FEAT_RAS && FFH_SUPPORT
CSS_SGI_SP_CPER_BUF_MMAP,
#endif
ARM_SP_IMAGE_RW_MMAP,

View file

@ -11,7 +11,7 @@
#include <arch_helpers.h>
#include <common/debug.h>
#include <drivers/console.h>
#if RAS_FFH_SUPPORT
#if ENABLE_FEAT_RAS
#include <lib/extensions/ras.h>
#endif
#include <lib/xlat_tables/xlat_mmu_helpers.h>
@ -29,7 +29,9 @@
#pragma weak plat_sdei_validate_entry_point
#endif
#if FFH_SUPPORT
#pragma weak plat_ea_handler = plat_default_ea_handler
#endif
void bl31_plat_runtime_setup(void)
{
@ -77,11 +79,12 @@ const char *get_el_str(unsigned int el)
return "EL1";
}
#if FFH_SUPPORT
/* Handler for External Aborts from lower EL including RAS errors */
void plat_default_ea_handler(unsigned int ea_reason, uint64_t syndrome, void *cookie,
void *handle, uint64_t flags)
{
#if RAS_FFH_SUPPORT
#if ENABLE_FEAT_RAS
/* Call RAS EA handler */
int handled = ras_ea_handler(ea_reason, syndrome, cookie, handle, flags);
if (handled != 0)
@ -99,3 +102,4 @@ void plat_default_ea_handler(unsigned int ea_reason, uint64_t syndrome, void *co
*/
lower_el_panic();
}
#endif

View file

@ -12,7 +12,7 @@
* Enumeration of priority levels on ARM platforms.
*/
ehf_pri_desc_t plat_exceptions[] = {
#if RAS_FFH_SUPPORT
#if ENABLE_FEAT_RAS && FFH_SUPPORT
/* RAS Priority */
EHF_PRI_DESC(PLAT_PRI_BITS, PLAT_RAS_PRI),
#endif
@ -26,7 +26,7 @@ ehf_pri_desc_t plat_exceptions[] = {
#endif
#if SPM_MM || (SPMC_AT_EL3 && SPMC_AT_EL3_SEL0_SP)
#if RAS_FFH_SUPPORT
#if ENABLE_FEAT_RAS && FFH_SUPPORT
#if (PLAT_SP_PRI != PLAT_RAS_PRI)
EHF_PRI_DESC(PLAT_PRI_BITS, PLAT_SP_PRI),
#endif

View file

@ -154,7 +154,7 @@ int plat_sip_handler(uint32_t smc_fid,
void *handle,
uint64_t flags);
#if RAS_FFH_SUPPORT
#if ENABLE_FEAT_RAS && FFH_SUPPORT
void tegra194_ras_enable(void);
void tegra194_ras_corrected_err_clear(uint64_t *cookie);
#endif

View file

@ -484,7 +484,7 @@ REGISTER_RAS_INTERRUPTS(carmel_ras_interrupts);
void plat_ea_handler(unsigned int ea_reason, uint64_t syndrome, void *cookie,
void *handle, uint64_t flags)
{
#if RAS_FFH_SUPPORT
#if ENABLE_FEAT_RAS
tegra194_ea_handler(ea_reason, syndrome, cookie, handle, flags);
#else
plat_default_ea_handler(ea_reason, syndrome, cookie, handle, flags);

View file

@ -254,7 +254,7 @@ void plat_early_platform_setup(void)
/* sanity check MCE firmware compatibility */
mce_verify_firmware_version();
#if RAS_FFH_SUPPORT
#if ENABLE_FEAT_RAS
/* Enable Uncorrectable RAS error */
tegra194_ras_enable();
#endif

View file

@ -71,7 +71,7 @@ int32_t plat_sip_handler(uint32_t smc_fid,
break;
#if RAS_FFH_SUPPORT
#if ENABLE_FEAT_RAS
case TEGRA_SIP_CLEAR_RAS_CORRECTED_ERRORS:
{
/*

View file

@ -37,7 +37,7 @@ $(eval $(call add_define,MAX_MMAP_REGIONS))
# enable RAS handling
HANDLE_EA_EL3_FIRST_NS := 1
RAS_FFH_SUPPORT := 1
ENABLE_FEAT_RAS := 1
# platform files
PLAT_INCLUDES += -Iplat/nvidia/tegra/include/t194 \
@ -71,7 +71,7 @@ BL31_SOURCES += ${TEGRA_DRIVERS}/spe/shared_console.S
endif
# RAS sources
ifeq (${RAS_FFH_SUPPORT},1)
ifeq (${ENABLE_FEAT_RAS}-${HANDLE_EA_EL3_FIRST_NS},1-1)
BL31_SOURCES += lib/extensions/ras/std_err_record.c \
lib/extensions/ras/ras_common.c \
${SOC_DIR}/plat_ras.c