summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile9
-rw-r--r--bl31/aarch64/runtime_exceptions.S60
-rw-r--r--docs/user-guide.rst9
-rw-r--r--include/bl31/ea_handle.h3
-rw-r--r--include/common/aarch64/asm_macros.S8
-rw-r--r--include/lib/aarch64/arch.h6
-rw-r--r--lib/el3_runtime/aarch64/context.S10
-rw-r--r--make_helpers/defaults.mk3
8 files changed, 97 insertions, 11 deletions
diff --git a/Makefile b/Makefile
index 23b48e8f..c588931f 100644
--- a/Makefile
+++ b/Makefile
@@ -388,6 +388,13 @@ ifneq (${SMCCC_MAJOR_VERSION},1)
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
################################################################################
@@ -525,6 +532,7 @@ $(eval $(call assert_boolean,NS_TIMER_SWITCH))
$(eval $(call assert_boolean,PL011_GENERIC_UART))
$(eval $(call assert_boolean,PROGRAMMABLE_RESET_ADDRESS))
$(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,SAVE_KEYS))
$(eval $(call assert_boolean,SEPARATE_CODE_AND_RODATA))
@@ -574,6 +582,7 @@ $(eval $(call add_define,PL011_GENERIC_UART))
$(eval $(call add_define,PLAT_${PLAT}))
$(eval $(call add_define,PROGRAMMABLE_RESET_ADDRESS))
$(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,SEPARATE_CODE_AND_RODATA))
$(eval $(call add_define,SMCCC_MAJOR_VERSION))
diff --git a/bl31/aarch64/runtime_exceptions.S b/bl31/aarch64/runtime_exceptions.S
index 494ccd79..346cd3b3 100644
--- a/bl31/aarch64/runtime_exceptions.S
+++ b/bl31/aarch64/runtime_exceptions.S
@@ -37,6 +37,50 @@
.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.
* Once the platform handler returns, the macro exits EL3 and returns to
* where the abort was taken from.
@@ -63,11 +107,6 @@
* ---------------------------------------------------------------------
*/
.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
/*
* Read the timestamp value and store it in per-cpu data. The value
@@ -117,12 +156,7 @@
* ---------------------------------------------------------------------
*/
.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
-
/* Save the EL3 system registers needed to return from this exception */
mrs x0, spsr_el3
mrs x1, elr_el3
@@ -256,14 +290,17 @@ vector_entry sync_exception_aarch64
* to a valid cpu context where the general purpose and system register
* state can be saved.
*/
+ check_and_unmask_ea
handle_sync_exception
check_vector_size sync_exception_aarch64
vector_entry irq_aarch64
+ check_and_unmask_ea
handle_interrupt_exception irq_aarch64
check_vector_size irq_aarch64
vector_entry fiq_aarch64
+ check_and_unmask_ea
handle_interrupt_exception fiq_aarch64
check_vector_size fiq_aarch64
@@ -289,14 +326,17 @@ vector_entry sync_exception_aarch32
* to a valid cpu context where the general purpose and system register
* state can be saved.
*/
+ check_and_unmask_ea
handle_sync_exception
check_vector_size sync_exception_aarch32
vector_entry irq_aarch32
+ check_and_unmask_ea
handle_interrupt_exception irq_aarch32
check_vector_size irq_aarch32
vector_entry fiq_aarch32
+ check_and_unmask_ea
handle_interrupt_exception fiq_aarch32
check_vector_size fiq_aarch32
diff --git a/docs/user-guide.rst b/docs/user-guide.rst
index aed54a63..880fe7d9 100644
--- a/docs/user-guide.rst
+++ b/docs/user-guide.rst
@@ -531,6 +531,15 @@ Common build options
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.
+- ``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
of the BL1 entrypoint. It can take the value 0 (CPU reset to BL1
entrypoint) or 1 (CPU reset to BL31 entrypoint).
diff --git a/include/bl31/ea_handle.h b/include/bl31/ea_handle.h
index 285132b7..9dfe3e0a 100644
--- a/include/bl31/ea_handle.h
+++ b/include/bl31/ea_handle.h
@@ -15,4 +15,7 @@
/* Synchronous External Abort received at Synchronous exception vector */
#define ERROR_EA_SYNC 1
+/* External Abort synchronized by ESB instruction */
+#define ERROR_EA_ESB 2
+
#endif /* __EA_HANDLE_H__ */
diff --git a/include/common/aarch64/asm_macros.S b/include/common/aarch64/asm_macros.S
index 94a9df92..7c8e643d 100644
--- a/include/common/aarch64/asm_macros.S
+++ b/include/common/aarch64/asm_macros.S
@@ -1,5 +1,5 @@
/*
- * 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
*/
@@ -192,4 +192,10 @@
.space SPINLOCK_ASM_SIZE
.endm
+#if RAS_EXTENSION
+ .macro esb
+ .inst 0xd503221f
+ .endm
+#endif
+
#endif /* __ASM_MACROS_S__ */
diff --git a/include/lib/aarch64/arch.h b/include/lib/aarch64/arch.h
index a4469412..5be4b4e9 100644
--- a/include/lib/aarch64/arch.h
+++ b/include/lib/aarch64/arch.h
@@ -711,4 +711,10 @@
#define AMCGCR_EL0_CG1NC_LENGTH U(8)
#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__ */
diff --git a/lib/el3_runtime/aarch64/context.S b/lib/el3_runtime/aarch64/context.S
index 9a53b76c..121ca4d3 100644
--- a/lib/el3_runtime/aarch64/context.S
+++ b/lib/el3_runtime/aarch64/context.S
@@ -364,6 +364,16 @@ endfunc restore_gp_registers
func restore_gp_registers_eret
bl restore_gp_registers
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
endfunc restore_gp_registers_eret
diff --git a/make_helpers/defaults.mk b/make_helpers/defaults.mk
index 00ac1268..791a9c08 100644
--- a/make_helpers/defaults.mk
+++ b/make_helpers/defaults.mk
@@ -124,6 +124,9 @@ PROGRAMMABLE_RESET_ADDRESS := 0
# Original format.
PSCI_EXTENDED_STATE_ID := 0
+# Enable RAS support
+RAS_EXTENSION := 0
+
# By default, BL1 acts as the reset handler, not BL31
RESET_TO_BL31 := 0