mirror of
https://github.com/ARM-software/arm-trusted-firmware.git
synced 2025-04-19 02:54:24 +00:00
RAS: Introduce handler for Uncontainable errors
Uncontainable errors are the most severe form of errors, which typically mean that the system state can't be trusted any more. This further means that normal error recovery process can't be followed, and an orderly shutdown of the system is often desirable. This patch allows for the platform to define a handler for Uncontainable errors received. Due to the nature of Uncontainable error, the handler is expected to initiate an orderly shutdown of the system, and therefore is not expected to return. A default implementation is added which falls back to platform unhandled exception. Also fix ras_arch.h header guards. Change-Id: I072e336a391a0b382e77e627eb9e40729d488b55 Signed-off-by: Jeenu Viswambharan <jeenu.viswambharan@arm.com>
This commit is contained in:
parent
ee6ff1bb37
commit
b56dc2a98c
3 changed files with 129 additions and 13 deletions
|
@ -9,6 +9,7 @@
|
||||||
#include <assert_macros.S>
|
#include <assert_macros.S>
|
||||||
#include <context.h>
|
#include <context.h>
|
||||||
#include <ea_handle.h>
|
#include <ea_handle.h>
|
||||||
|
#include <ras_arch.h>
|
||||||
|
|
||||||
|
|
||||||
.globl handle_lower_el_ea_esb
|
.globl handle_lower_el_ea_esb
|
||||||
|
@ -70,7 +71,7 @@ func enter_lower_el_sync_ea
|
||||||
mov x0, #ERROR_EA_SYNC
|
mov x0, #ERROR_EA_SYNC
|
||||||
mrs x1, esr_el3
|
mrs x1, esr_el3
|
||||||
adr x30, el3_exit
|
adr x30, el3_exit
|
||||||
b ea_proceed
|
b delegate_sync_ea
|
||||||
|
|
||||||
2:
|
2:
|
||||||
/* Synchronous exceptions other than the above are assumed to be EA */
|
/* Synchronous exceptions other than the above are assumed to be EA */
|
||||||
|
@ -100,10 +101,76 @@ func enter_lower_el_async_ea
|
||||||
mov x0, #ERROR_EA_ASYNC
|
mov x0, #ERROR_EA_ASYNC
|
||||||
mrs x1, esr_el3
|
mrs x1, esr_el3
|
||||||
adr x30, el3_exit
|
adr x30, el3_exit
|
||||||
b ea_proceed
|
b delegate_async_ea
|
||||||
endfunc enter_lower_el_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
|
* Delegate External Abort handling to platform's EA handler. This function
|
||||||
* assumes that all GP registers have been saved by the caller.
|
* assumes that all GP registers have been saved by the caller.
|
||||||
|
|
|
@ -4,15 +4,8 @@
|
||||||
* SPDX-License-Identifier: BSD-3-Clause
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __RAS_H__
|
#ifndef RAS_ARCH_H
|
||||||
#define __RAS_H__
|
#define RAS_ARCH_H
|
||||||
|
|
||||||
#include <arch.h>
|
|
||||||
#include <arch_helpers.h>
|
|
||||||
#include <assert.h>
|
|
||||||
#include <context.h>
|
|
||||||
#include <mmio.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Size of nodes implementing Standard Error Records - currently only 4k is
|
* Size of nodes implementing Standard Error Records - currently only 4k is
|
||||||
|
@ -146,12 +139,53 @@
|
||||||
#define ERR_CTLR_ENABLE_FIELD(_ctlr, _field) \
|
#define ERR_CTLR_ENABLE_FIELD(_ctlr, _field) \
|
||||||
ERR_CTLR_SET_FIELD(_ctlr, _field, ERR_CTLR_ ##_field ##_MASK)
|
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_UC 0x0 /* Uncontainable */
|
||||||
#define ERROR_STATUS_UET_UEU 0x1 /* Unrecoverable */
|
#define ERROR_STATUS_UET_UEU 0x1 /* Unrecoverable */
|
||||||
#define ERROR_STATUS_UET_UEO 0x2 /* Restable */
|
#define ERROR_STATUS_UET_UEO 0x2 /* Restable */
|
||||||
#define ERROR_STATUS_UET_UER 0x3 /* Recoverable */
|
#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.
|
* 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 */
|
/* 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_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);
|
int ser_probe_sysreg(unsigned int idx_start, unsigned int num_idx, int *probe_data);
|
||||||
|
#endif /* __ASSEMBLY__ */
|
||||||
|
|
||||||
#endif /* __RAS_H__ */
|
#endif /* RAS_ARCH_H */
|
||||||
|
|
|
@ -20,6 +20,8 @@
|
||||||
.weak bl31_plat_enable_mmu
|
.weak bl31_plat_enable_mmu
|
||||||
.weak bl32_plat_enable_mmu
|
.weak bl32_plat_enable_mmu
|
||||||
|
|
||||||
|
.weak plat_handle_uncontainable_ea
|
||||||
|
|
||||||
#if !ENABLE_PLAT_COMPAT
|
#if !ENABLE_PLAT_COMPAT
|
||||||
.globl platform_get_core_pos
|
.globl platform_get_core_pos
|
||||||
|
|
||||||
|
@ -186,3 +188,15 @@ endfunc bl31_plat_enable_mmu
|
||||||
func bl32_plat_enable_mmu
|
func bl32_plat_enable_mmu
|
||||||
b enable_mmu_direct_el1
|
b enable_mmu_direct_el1
|
||||||
endfunc bl32_plat_enable_mmu
|
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
|
||||||
|
|
Loading…
Add table
Reference in a new issue