Commit 14c6016a authored by Jeenu Viswambharan's avatar Jeenu Viswambharan
Browse files

AArch64: Introduce RAS handling



RAS extensions are mandatory for ARMv8.2 CPUs, but are also optional
extensions to base ARMv8.0 architecture.

This patch adds build system support to enable RAS features in ARM
Trusted Firmware. A boolean build option RAS_EXTENSION is introduced for
this.

With RAS_EXTENSION, an Exception Synchronization Barrier (ESB) is
inserted at all EL3 vector entry and exit. ESBs will synchronize pending
external aborts before entering EL3, and therefore will contain and
attribute errors to lower EL execution. Any errors thus synchronized are
detected via. DISR_EL1 register.

When RAS_EXTENSION is set to 1, HANDLE_EL3_EA_FIRST must also be set to 1.

Change-Id: I38a19d84014d4d8af688bd81d61ba582c039383a
Signed-off-by: default avatarJeenu Viswambharan <jeenu.viswambharan@arm.com>
parent 76454abf
...@@ -388,6 +388,13 @@ ifneq (${SMCCC_MAJOR_VERSION},1) ...@@ -388,6 +388,13 @@ ifneq (${SMCCC_MAJOR_VERSION},1)
endif endif
endif endif
# For RAS_EXTENSION, require that EAs are handled in EL3 first
ifeq ($(RAS_EXTENSION),1)
ifneq ($(HANDLE_EA_EL3_FIRST),1)
$(error For RAS_EXTENSION, HANDLE_EA_EL3_FIRST must also be 1)
endif
endif
################################################################################ ################################################################################
# Process platform overrideable behaviour # Process platform overrideable behaviour
################################################################################ ################################################################################
...@@ -525,6 +532,7 @@ $(eval $(call assert_boolean,NS_TIMER_SWITCH)) ...@@ -525,6 +532,7 @@ $(eval $(call assert_boolean,NS_TIMER_SWITCH))
$(eval $(call assert_boolean,PL011_GENERIC_UART)) $(eval $(call assert_boolean,PL011_GENERIC_UART))
$(eval $(call assert_boolean,PROGRAMMABLE_RESET_ADDRESS)) $(eval $(call assert_boolean,PROGRAMMABLE_RESET_ADDRESS))
$(eval $(call assert_boolean,PSCI_EXTENDED_STATE_ID)) $(eval $(call assert_boolean,PSCI_EXTENDED_STATE_ID))
$(eval $(call assert_boolean,RAS_EXTENSION))
$(eval $(call assert_boolean,RESET_TO_BL31)) $(eval $(call assert_boolean,RESET_TO_BL31))
$(eval $(call assert_boolean,SAVE_KEYS)) $(eval $(call assert_boolean,SAVE_KEYS))
$(eval $(call assert_boolean,SEPARATE_CODE_AND_RODATA)) $(eval $(call assert_boolean,SEPARATE_CODE_AND_RODATA))
...@@ -574,6 +582,7 @@ $(eval $(call add_define,PL011_GENERIC_UART)) ...@@ -574,6 +582,7 @@ $(eval $(call add_define,PL011_GENERIC_UART))
$(eval $(call add_define,PLAT_${PLAT})) $(eval $(call add_define,PLAT_${PLAT}))
$(eval $(call add_define,PROGRAMMABLE_RESET_ADDRESS)) $(eval $(call add_define,PROGRAMMABLE_RESET_ADDRESS))
$(eval $(call add_define,PSCI_EXTENDED_STATE_ID)) $(eval $(call add_define,PSCI_EXTENDED_STATE_ID))
$(eval $(call add_define,RAS_EXTENSION))
$(eval $(call add_define,RESET_TO_BL31)) $(eval $(call add_define,RESET_TO_BL31))
$(eval $(call add_define,SEPARATE_CODE_AND_RODATA)) $(eval $(call add_define,SEPARATE_CODE_AND_RODATA))
$(eval $(call add_define,SMCCC_MAJOR_VERSION)) $(eval $(call add_define,SMCCC_MAJOR_VERSION))
......
...@@ -36,6 +36,50 @@ ...@@ -36,6 +36,50 @@
.globl fiq_aarch32 .globl fiq_aarch32
.globl serror_aarch32 .globl serror_aarch32
/*
* Macro that prepares entry to EL3 upon taking an exception.
*
* With RAS_EXTENSION, 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_EXTENSION, this macro just saves x30, and unmasks
* Asynchronous External Aborts.
*/
.macro check_and_unmask_ea
#if RAS_EXTENSION
/* Synchronize pending External Aborts */
esb
/* Unmask the SError interrupt */
msr daifclr, #DAIF_ABT_BIT
/*
* Explicitly save x30 so as to free up a register and to enable
* branching
*/
str x30, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_LR]
/* Check for SErrors synchronized by the ESB instruction */
mrs x30, DISR_EL1
tbz x30, #DISR_A_BIT, 1f
/* Save GP registers and restore them afterwards */
bl save_gp_registers
mov x0, #ERROR_EA_ESB
mrs x1, DISR_EL1
bl delegate_ea
bl restore_gp_registers
1:
#else
/* Unmask the SError interrupt */
msr daifclr, #DAIF_ABT_BIT
str x30, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_LR]
#endif
.endm
/* /*
* Handle External Abort by delegating to the platform's EA handler. * Handle External Abort by delegating to the platform's EA handler.
* Once the platform handler returns, the macro exits EL3 and returns to * Once the platform handler returns, the macro exits EL3 and returns to
...@@ -63,11 +107,6 @@ ...@@ -63,11 +107,6 @@
* --------------------------------------------------------------------- * ---------------------------------------------------------------------
*/ */
.macro handle_sync_exception .macro handle_sync_exception
/* Enable the SError interrupt */
msr daifclr, #DAIF_ABT_BIT
str x30, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_LR]
#if ENABLE_RUNTIME_INSTRUMENTATION #if ENABLE_RUNTIME_INSTRUMENTATION
/* /*
* Read the timestamp value and store it in per-cpu data. The value * Read the timestamp value and store it in per-cpu data. The value
...@@ -117,12 +156,7 @@ ...@@ -117,12 +156,7 @@
* --------------------------------------------------------------------- * ---------------------------------------------------------------------
*/ */
.macro handle_interrupt_exception label .macro handle_interrupt_exception label
/* Enable the SError interrupt */
msr daifclr, #DAIF_ABT_BIT
str x30, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_LR]
bl save_gp_registers bl save_gp_registers
/* Save the EL3 system registers needed to return from this exception */ /* Save the EL3 system registers needed to return from this exception */
mrs x0, spsr_el3 mrs x0, spsr_el3
mrs x1, elr_el3 mrs x1, elr_el3
...@@ -256,14 +290,17 @@ vector_entry sync_exception_aarch64 ...@@ -256,14 +290,17 @@ vector_entry sync_exception_aarch64
* to a valid cpu context where the general purpose and system register * to a valid cpu context where the general purpose and system register
* state can be saved. * state can be saved.
*/ */
check_and_unmask_ea
handle_sync_exception handle_sync_exception
check_vector_size sync_exception_aarch64 check_vector_size sync_exception_aarch64
vector_entry irq_aarch64 vector_entry irq_aarch64
check_and_unmask_ea
handle_interrupt_exception irq_aarch64 handle_interrupt_exception irq_aarch64
check_vector_size irq_aarch64 check_vector_size irq_aarch64
vector_entry fiq_aarch64 vector_entry fiq_aarch64
check_and_unmask_ea
handle_interrupt_exception fiq_aarch64 handle_interrupt_exception fiq_aarch64
check_vector_size fiq_aarch64 check_vector_size fiq_aarch64
...@@ -289,14 +326,17 @@ vector_entry sync_exception_aarch32 ...@@ -289,14 +326,17 @@ vector_entry sync_exception_aarch32
* to a valid cpu context where the general purpose and system register * to a valid cpu context where the general purpose and system register
* state can be saved. * state can be saved.
*/ */
check_and_unmask_ea
handle_sync_exception handle_sync_exception
check_vector_size sync_exception_aarch32 check_vector_size sync_exception_aarch32
vector_entry irq_aarch32 vector_entry irq_aarch32
check_and_unmask_ea
handle_interrupt_exception irq_aarch32 handle_interrupt_exception irq_aarch32
check_vector_size irq_aarch32 check_vector_size irq_aarch32
vector_entry fiq_aarch32 vector_entry fiq_aarch32
check_and_unmask_ea
handle_interrupt_exception fiq_aarch32 handle_interrupt_exception fiq_aarch32
check_vector_size fiq_aarch32 check_vector_size fiq_aarch32
......
...@@ -531,6 +531,15 @@ Common build options ...@@ -531,6 +531,15 @@ Common build options
smc function id. When this option is enabled on Arm platforms, the smc function id. When this option is enabled on Arm platforms, the
option ``ARM_RECOM_STATE_ID_ENC`` needs to be set to 1 as well. option ``ARM_RECOM_STATE_ID_ENC`` needs to be set to 1 as well.
- ``RAS_EXTENSION``: When set to ``1``, 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.
When ``RAS_EXTENSION`` is set to ``1``, ``HANDLE_EA_EL3_FIRST`` must also be
set to ``1``.
This option is disabled by default.
- ``RESET_TO_BL31``: Enable BL31 entrypoint as the CPU reset vector instead - ``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 of the BL1 entrypoint. It can take the value 0 (CPU reset to BL1
entrypoint) or 1 (CPU reset to BL31 entrypoint). entrypoint) or 1 (CPU reset to BL31 entrypoint).
......
...@@ -15,4 +15,7 @@ ...@@ -15,4 +15,7 @@
/* Synchronous External Abort received at Synchronous exception vector */ /* Synchronous External Abort received at Synchronous exception vector */
#define ERROR_EA_SYNC 1 #define ERROR_EA_SYNC 1
/* External Abort synchronized by ESB instruction */
#define ERROR_EA_ESB 2
#endif /* __EA_HANDLE_H__ */ #endif /* __EA_HANDLE_H__ */
/* /*
* Copyright (c) 2013-2017, ARM Limited and Contributors. All rights reserved. * Copyright (c) 2013-2018, ARM Limited and Contributors. All rights reserved.
* *
* SPDX-License-Identifier: BSD-3-Clause * SPDX-License-Identifier: BSD-3-Clause
*/ */
...@@ -192,4 +192,10 @@ ...@@ -192,4 +192,10 @@
.space SPINLOCK_ASM_SIZE .space SPINLOCK_ASM_SIZE
.endm .endm
#if RAS_EXTENSION
.macro esb
.inst 0xd503221f
.endm
#endif
#endif /* __ASM_MACROS_S__ */ #endif /* __ASM_MACROS_S__ */
...@@ -711,4 +711,10 @@ ...@@ -711,4 +711,10 @@
#define AMCGCR_EL0_CG1NC_LENGTH U(8) #define AMCGCR_EL0_CG1NC_LENGTH U(8)
#define AMCGCR_EL0_CG1NC_MASK U(0xff) #define AMCGCR_EL0_CG1NC_MASK U(0xff)
/*******************************************************************************
* RAS system registers
*******************************************************************************/
#define DISR_EL1 S3_0_C12_C1_1
#define DISR_A_BIT 31
#endif /* __ARCH_H__ */ #endif /* __ARCH_H__ */
...@@ -364,6 +364,16 @@ endfunc restore_gp_registers ...@@ -364,6 +364,16 @@ endfunc restore_gp_registers
func restore_gp_registers_eret func restore_gp_registers_eret
bl restore_gp_registers bl restore_gp_registers
ldr x30, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_LR] ldr x30, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_LR]
#if IMAGE_BL31 && RAS_EXTENSION
/*
* 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
#endif
eret eret
endfunc restore_gp_registers_eret endfunc restore_gp_registers_eret
......
...@@ -124,6 +124,9 @@ PROGRAMMABLE_RESET_ADDRESS := 0 ...@@ -124,6 +124,9 @@ PROGRAMMABLE_RESET_ADDRESS := 0
# Original format. # Original format.
PSCI_EXTENDED_STATE_ID := 0 PSCI_EXTENDED_STATE_ID := 0
# Enable RAS support
RAS_EXTENSION := 0
# By default, BL1 acts as the reset handler, not BL31 # By default, BL1 acts as the reset handler, not BL31
RESET_TO_BL31 := 0 RESET_TO_BL31 := 0
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment