aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--bl31/aarch64/ea_delegate.S71
-rw-r--r--include/lib/extensions/ras_arch.h57
-rw-r--r--plat/common/aarch64/platform_helpers.S14
3 files changed, 129 insertions, 13 deletions
diff --git a/bl31/aarch64/ea_delegate.S b/bl31/aarch64/ea_delegate.S
index d18f9e575..9faa503ff 100644
--- a/bl31/aarch64/ea_delegate.S
+++ b/bl31/aarch64/ea_delegate.S
@@ -9,6 +9,7 @@
#include <assert_macros.S>
#include <context.h>
#include <ea_handle.h>
+#include <ras_arch.h>
.globl handle_lower_el_ea_esb
@@ -70,7 +71,7 @@ func enter_lower_el_sync_ea
mov x0, #ERROR_EA_SYNC
mrs x1, esr_el3
adr x30, el3_exit
- b ea_proceed
+ b delegate_sync_ea
2:
/* Synchronous exceptions other than the above are assumed to be EA */
@@ -100,11 +101,77 @@ func enter_lower_el_async_ea
mov x0, #ERROR_EA_ASYNC
mrs x1, esr_el3
adr x30, el3_exit
- b ea_proceed
+ b delegate_async_ea
endfunc enter_lower_el_async_ea
/*
+ * Prelude for Synchronous External Abort handling. This function assumes that
+ * all GP registers have been saved by the caller.
+ *
+ * x0: EA reason
+ * x1: EA syndrome
+ */
+func delegate_sync_ea
+#if RAS_EXTENSION
+ /*
+ * Check for Uncontainable error type. If so, route to the platform
+ * fatal error handler rather than the generic EA one.
+ */
+ ubfx x2, x1, #EABORT_SET_SHIFT, #EABORT_SET_WIDTH
+ cmp x2, #ERROR_STATUS_SET_UC
+ b.ne 1f
+
+ /* Check fault status code */
+ ubfx x3, x1, #EABORT_DFSC_SHIFT, #EABORT_DFSC_WIDTH
+ cmp x3, #SYNC_EA_FSC
+ b.ne 1f
+
+ no_ret plat_handle_uncontainable_ea
+1:
+#endif
+
+ b ea_proceed
+endfunc delegate_sync_ea
+
+
+/*
+ * Prelude for Asynchronous External Abort handling. This function assumes that
+ * all GP registers have been saved by the caller.
+ *
+ * x0: EA reason
+ * x1: EA syndrome
+ */
+func delegate_async_ea
+#if RAS_EXTENSION
+ /*
+ * Check for Implementation Defined Syndrome. If so, skip checking
+ * Uncontainable error type from the syndrome as the format is unknown.
+ */
+ tbnz x1, #SERROR_IDS_BIT, 1f
+
+ /*
+ * Check for Uncontainable error type. If so, route to the platform
+ * fatal error handler rather than the generic EA one.
+ */
+ ubfx x2, x1, #EABORT_AET_SHIFT, #EABORT_AET_WIDTH
+ cmp x2, #ERROR_STATUS_UET_UC
+ b.ne 1f
+
+ /* Check DFSC for SError type */
+ ubfx x3, x1, #EABORT_DFSC_SHIFT, #EABORT_DFSC_WIDTH
+ cmp x3, #DFSC_SERROR
+ b.ne 1f
+
+ no_ret plat_handle_uncontainable_ea
+1:
+#endif
+
+ b ea_proceed
+endfunc delegate_async_ea
+
+
+/*
* Delegate External Abort handling to platform's EA handler. This function
* assumes that all GP registers have been saved by the caller.
*
diff --git a/include/lib/extensions/ras_arch.h b/include/lib/extensions/ras_arch.h
index 7d210531b..6ec4da80f 100644
--- a/include/lib/extensions/ras_arch.h
+++ b/include/lib/extensions/ras_arch.h
@@ -4,15 +4,8 @@
* SPDX-License-Identifier: BSD-3-Clause
*/
-#ifndef __RAS_H__
-#define __RAS_H__
-
-#include <arch.h>
-#include <arch_helpers.h>
-#include <assert.h>
-#include <context.h>
-#include <mmio.h>
-#include <stdint.h>
+#ifndef RAS_ARCH_H
+#define RAS_ARCH_H
/*
* Size of nodes implementing Standard Error Records - currently only 4k is
@@ -146,12 +139,53 @@
#define ERR_CTLR_ENABLE_FIELD(_ctlr, _field) \
ERR_CTLR_SET_FIELD(_ctlr, _field, ERR_CTLR_ ##_field ##_MASK)
-/* Uncorrected error types */
+/* Uncorrected error types for Asynchronous exceptions */
#define ERROR_STATUS_UET_UC 0x0 /* Uncontainable */
#define ERROR_STATUS_UET_UEU 0x1 /* Unrecoverable */
#define ERROR_STATUS_UET_UEO 0x2 /* Restable */
#define ERROR_STATUS_UET_UER 0x3 /* Recoverable */
+/* Error types for Synchronous exceptions */
+#define ERROR_STATUS_SET_UER 0x0 /* Recoverable */
+#define ERROR_STATUS_SET_UEO 0x1 /* Restable */
+#define ERROR_STATUS_SET_UC 0x2 /* Uncontainable */
+#define ERROR_STATUS_SET_CE 0x3 /* Corrected */
+
+/* Implementation Defined Syndrome bit in ESR */
+#define SERROR_IDS_BIT U(24)
+
+/*
+ * Asynchronous Error Type in exception syndrome. The field has same values in
+ * both DISR_EL1 and ESR_EL3 for SError.
+ */
+#define EABORT_AET_SHIFT U(10)
+#define EABORT_AET_WIDTH U(3)
+#define EABORT_AET_MASK U(0x7)
+
+/* DFSC field in Asynchronous exception syndrome */
+#define EABORT_DFSC_SHIFT U(0)
+#define EABORT_DFSC_WIDTH U(6)
+#define EABORT_DFSC_MASK U(0x3f)
+
+/* Synchronous Error Type in exception syndrome. */
+#define EABORT_SET_SHIFT U(11)
+#define EABORT_SET_WIDTH U(2)
+#define EABORT_SET_MASK U(0x3)
+
+/* DFSC code for SErrors */
+#define DFSC_SERROR 0x11
+
+/* I/DFSC code for synchronous external abort */
+#define SYNC_EA_FSC 0x10
+
+#ifndef __ASSEMBLY__
+
+#include <arch.h>
+#include <arch_helpers.h>
+#include <assert.h>
+#include <context.h>
+#include <mmio.h>
+#include <stdint.h>
/*
* Standard Error Record accessors for memory-mapped registers.
@@ -221,5 +255,6 @@ static inline void ser_sys_select_record(unsigned int idx)
/* Library functions to probe Standard Error Record */
int ser_probe_memmap(uintptr_t base, unsigned int size_num_k, int *probe_data);
int ser_probe_sysreg(unsigned int idx_start, unsigned int num_idx, int *probe_data);
+#endif /* __ASSEMBLY__ */
-#endif /* __RAS_H__ */
+#endif /* RAS_ARCH_H */
diff --git a/plat/common/aarch64/platform_helpers.S b/plat/common/aarch64/platform_helpers.S
index a413f5fd1..13dfac84b 100644
--- a/plat/common/aarch64/platform_helpers.S
+++ b/plat/common/aarch64/platform_helpers.S
@@ -20,6 +20,8 @@
.weak bl31_plat_enable_mmu
.weak bl32_plat_enable_mmu
+ .weak plat_handle_uncontainable_ea
+
#if !ENABLE_PLAT_COMPAT
.globl platform_get_core_pos
@@ -186,3 +188,15 @@ endfunc bl31_plat_enable_mmu
func bl32_plat_enable_mmu
b enable_mmu_direct_el1
endfunc bl32_plat_enable_mmu
+
+
+ /* -----------------------------------------------------
+ * Platform handler for Uncontainable External Abort.
+ *
+ * x0: EA reason
+ * x1: EA syndrome
+ * -----------------------------------------------------
+ */
+func plat_handle_uncontainable_ea
+ b report_unhandled_exception
+endfunc plat_handle_uncontainable_ea