Merge "fix(sdei): ensure that interrupt ID is valid" into integration
diff --git a/Makefile b/Makefile
index 7f781a0..f55dfdd 100644
--- a/Makefile
+++ b/Makefile
@@ -9,7 +9,7 @@
#
VERSION_MAJOR := 2
VERSION_MINOR := 9
-VERSION_PATCH := 0
+VERSION_PATCH := 0 # Only used for LTS releases
VERSION := ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}
# Default goal is build all images
@@ -414,7 +414,6 @@
################################################################################
# Common sources and include directories
################################################################################
-include ${MAKE_HELPERS_DIRECTORY}arch_features.mk
include lib/compiler-rt/compiler-rt.mk
BL_COMMON_SOURCES += common/bl_common.c \
@@ -503,6 +502,12 @@
ifneq ($(SP_LAYOUT_FILE),)
BL2_ENABLE_SP_LOAD := 1
endif
+
+ ifeq ($(SPMC_AT_EL3_SEL0_SP),1)
+ ifneq ($(SPMC_AT_EL3),1)
+ $(error SEL0 SP cannot be enabled without SPMC at EL3)
+ endif
+ endif
else
# All other SPDs in spd directory
SPD_DIR := spd
@@ -651,111 +656,6 @@
endif #(FEAT_RME)
################################################################################
-# Generic definitions
-################################################################################
-include ${MAKE_HELPERS_DIRECTORY}plat_helpers.mk
-
-ifeq (${BUILD_BASE},)
- BUILD_BASE := ./build
-endif
-BUILD_PLAT := $(abspath ${BUILD_BASE})/${PLAT}/${BUILD_TYPE}
-
-SPDS := $(sort $(filter-out none, $(patsubst services/spd/%,%,$(wildcard services/spd/*))))
-
-# Platforms providing their own TBB makefile may override this value
-INCLUDE_TBBR_MK := 1
-
-################################################################################
-# Include SPD Makefile if one has been specified
-################################################################################
-
-ifneq (${SPD},none)
- ifeq (${ARCH},aarch32)
- $(error "Error: SPD is incompatible with AArch32.")
- endif
-
- ifdef EL3_PAYLOAD_BASE
- $(warning "SPD and EL3_PAYLOAD_BASE are incompatible build options.")
- $(warning "The SPD and its BL32 companion will be present but \
- ignored.")
- endif
-
- ifeq (${SPD},spmd)
- # SPMD is located in std_svc directory
- SPD_DIR := std_svc
-
- ifeq ($(SPMD_SPM_AT_SEL2),1)
- CTX_INCLUDE_EL2_REGS := 1
- ifeq ($(SPMC_AT_EL3),1)
- $(error SPM cannot be enabled in both S-EL2 and EL3.)
- endif
- endif
-
- ifeq ($(findstring optee_sp,$(ARM_SPMC_MANIFEST_DTS)),optee_sp)
- DTC_CPPFLAGS += -DOPTEE_SP_FW_CONFIG
- endif
-
- ifeq ($(TS_SP_FW_CONFIG),1)
- DTC_CPPFLAGS += -DTS_SP_FW_CONFIG
- endif
-
- ifneq ($(ARM_BL2_SP_LIST_DTS),)
- DTC_CPPFLAGS += -DARM_BL2_SP_LIST_DTS=$(ARM_BL2_SP_LIST_DTS)
- endif
-
- ifneq ($(SP_LAYOUT_FILE),)
- BL2_ENABLE_SP_LOAD := 1
- endif
-
- ifeq ($(SPMC_AT_EL3_SEL0_SP),1)
- ifneq ($(SPMC_AT_EL3),1)
- $(error SEL0 SP cannot be enabled without SPMC at EL3)
- endif
- endif
- else
- # All other SPDs in spd directory
- SPD_DIR := spd
- endif #(SPD)
-
- # We expect to locate an spd.mk under the specified SPD directory
- SPD_MAKE := $(wildcard services/${SPD_DIR}/${SPD}/${SPD}.mk)
-
- ifeq (${SPD_MAKE},)
- $(error Error: No services/${SPD_DIR}/${SPD}/${SPD}.mk located)
- endif
- $(info Including ${SPD_MAKE})
- include ${SPD_MAKE}
-
- # If there's BL32 companion for the chosen SPD, we expect that the SPD's
- # Makefile would set NEED_BL32 to "yes". In this case, the build system
- # supports two mutually exclusive options:
- # * BL32 is built from source: then BL32_SOURCES must contain the list
- # of source files to build BL32
- # * BL32 is a prebuilt binary: then BL32 must point to the image file
- # that will be included in the FIP
- # If both BL32_SOURCES and BL32 are defined, the binary takes precedence
- # over the sources.
-endif #(SPD=none)
-
-ifeq (${ENABLE_SPMD_LP}, 1)
-ifneq (${SPD},spmd)
- $(error Error: ENABLE_SPMD_LP requires SPD=spmd.)
-endif
-ifeq ($(SPMC_AT_EL3),1)
- $(error SPMC at EL3 not supported when enabling SPMD Logical partitions.)
-endif
-endif
-
-ifeq (${CTX_INCLUDE_EL2_REGS}, 1)
- ifeq (${SPD},none)
- ifeq (${ENABLE_RME},0)
- $(error CTX_INCLUDE_EL2_REGS is available only when SPD \
- or RME is enabled)
- endif
- endif
-endif
-
-################################################################################
# Include rmmd Makefile if RME is enabled
################################################################################
ifneq (${ENABLE_RME},0)
@@ -809,6 +709,14 @@
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 +878,9 @@
# 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 +1182,8 @@
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 +1238,6 @@
ERRATA_ABI_SUPPORT \
ERRATA_NON_ARM_INTERCONNECT \
CONDITIONAL_CMO \
- RAS_FFH_SUPPORT \
PSA_CRYPTO \
ENABLE_CONSOLE_GETC \
)))
@@ -1360,7 +1260,6 @@
ENABLE_FEAT_AMU \
ENABLE_FEAT_AMUv1p1 \
ENABLE_FEAT_CSV2_2 \
- ENABLE_FEAT_RAS \
ENABLE_FEAT_DIT \
ENABLE_FEAT_ECV \
ENABLE_FEAT_FGT \
@@ -1443,6 +1342,8 @@
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 +1361,6 @@
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 \
diff --git a/bl31/aarch64/ea_delegate.S b/bl31/aarch64/ea_delegate.S
index dd6b4dc..28d2187 100644
--- a/bl31/aarch64/ea_delegate.S
+++ b/bl31/aarch64/ea_delegate.S
@@ -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
-
-
-/*
- * 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
-
-
+ .globl handle_pending_async_ea
/*
- * 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 @@
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 @@
/* 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 @@
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 @@
* 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 @@
* 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.
diff --git a/bl31/aarch64/runtime_exceptions.S b/bl31/aarch64/runtime_exceptions.S
index 8298696..ed48311 100644
--- a/bl31/aarch64/runtime_exceptions.S
+++ b/bl31/aarch64/runtime_exceptions.S
@@ -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
-
- /*
- * Save general purpose and ARMv8.3-PAuth registers (if enabled).
- * Also save PMCR_EL0 and set the PSTATE to a known state.
- */
- 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.
- */
+ .macro restore_x30
+ ldr x30, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_LR]
+ .endm
/*
- * For SoCs which do not implement RAS, use DSB as a barrier to
- * synchronize pending external aborts.
+ * 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.
*/
- 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 @@
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 @@
*/
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
+ sync_and_handle_pending_serror
+ unmask_async_ea
+ b handle_lower_el_async_ea
#else
- check_and_unmask_ea
+ b report_unhandled_exception
#endif
- b handle_lower_el_async_ea
-
end_vector_entry serror_aarch64
/* ---------------------------------------------------------------------
@@ -291,34 +278,41 @@
*/
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
+ sync_and_handle_pending_serror
+ unmask_async_ea
+ b handle_lower_el_async_ea
#else
- check_and_unmask_ea
+ b report_unhandled_exception
#endif
- b handle_lower_el_async_ea
-
end_vector_entry serror_aarch32
#ifdef MONITOR_TRAPS
@@ -608,6 +602,114 @@
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
diff --git a/bl31/bl31.mk b/bl31/bl31.mk
index a1fc12b..3359526 100644
--- a/bl31/bl31.mk
+++ b/bl31/bl31.mk
@@ -39,7 +39,6 @@
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 @@
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)
diff --git a/docs/about/release-information.rst b/docs/about/release-information.rst
index 3d2783d..5e7f630 100644
--- a/docs/about/release-information.rst
+++ b/docs/about/release-information.rst
@@ -25,6 +25,18 @@
code freeze ver w.x code freeze ver y.z
+Version numbering
+~~~~~~~~~~~~~~~~~
+TF-A version is given in Makefile, through several macros:
+
+- VERSION_MAJOR
+- VERSION_MINOR
+- VERSION_PATCH
+
+For example, TF-A v2.10 has VERSION_MAJOR=2, VERSION_MINOR=10 and VERSION_PATCH=0.
+
+This VERSION_PATCH macro is only increased for LTS releases.
+
Upcoming Releases
~~~~~~~~~~~~~~~~~
diff --git a/docs/components/ras.rst b/docs/components/ras.rst
index 8d00345..747367a 100644
--- a/docs/components/ras.rst
+++ b/docs/components/ras.rst
@@ -10,6 +10,9 @@
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 @@
EA's originating/attributed to NS world are handled first in NS and Kernel navigates
the std error records directly.
+- 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).
+
-**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**
+|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 @@
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 @@
*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
diff --git a/docs/design/cpu-specific-build-macros.rst b/docs/design/cpu-specific-build-macros.rst
index 146026b..d03daf8 100644
--- a/docs/design/cpu-specific-build-macros.rst
+++ b/docs/design/cpu-specific-build-macros.rst
@@ -612,6 +612,10 @@
interconnect IP. This needs to be enabled for r0p0, r1p0, r2p0 and r2p1 and
is still open.
+- ``ERRATA_A710_2742423``: This applies errata 2742423 workaround to
+ Cortex-A710 CPU. This needs to be enabled for revisions r0p0, r1p0, r2p0 and
+ r2p1 of the CPU and is still open.
+
- ``ERRATA_A710_2768515``: This applies errata 2768515 workaround to
Cortex-A710 CPU. This needs to be enabled for revisions r0p0, r1p0, r2p0 and
r2p1 of the CPU and is still open.
@@ -655,6 +659,14 @@
CPU. This needs to be enabled for revision r0p0 of the CPU, it is fixed in
r0p1.
+- ``ERRATA_N2_2340933``: This applies errata 2340933 workaround to Neoverse-N2
+ CPU. This needs to be enabled for revision r0p0 of the CPU, it is fixed in
+ r0p1.
+
+- ``ERRATA_N2_2346952``: This applies errata 2346952 workaround to Neoverse-N2
+ CPU. This needs to be enabled for revisions r0p0, r0p1 and r0p2 of the CPU,
+ it is fixed in r0p3.
+
- ``ERRATA_N2_2376738``: This applies errata 2376738 workaround to Neoverse-N2
CPU. This needs to be enabled for revision r0p0, r0p1, r0p2, r0p3 and is still open.
@@ -721,6 +733,10 @@
This needs to be enabled for revisions r0p0, r1p0, r2p0 and r2p1 and is
still open.
+- ``ERRATA_X2_2742423``: This applies errata 2742423 workaround to Cortex-X2
+ CPU. This needs to be enabled for revisions r0p0, r1p0, r2p0 and r2p1 of the
+ CPU and is still open.
+
- ``ERRATA_X2_2768515``: This applies errata 2768515 workaround to Cortex-X2
CPU. This needs to be enabled for revisions r0p0, r1p0, r2p0 and r2p1 of the
CPU and is still open.
diff --git a/docs/design/firmware-design.rst b/docs/design/firmware-design.rst
index 879ddda..ff69b43 100644
--- a/docs/design/firmware-design.rst
+++ b/docs/design/firmware-design.rst
@@ -1118,6 +1118,65 @@
``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 @@
.. _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
diff --git a/docs/getting_started/build-internals.rst b/docs/getting_started/build-internals.rst
index a015d71..390c367 100644
--- a/docs/getting_started/build-internals.rst
+++ b/docs/getting_started/build-internals.rst
@@ -12,3 +12,10 @@
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.
diff --git a/docs/getting_started/build-options.rst b/docs/getting_started/build-options.rst
index 347cf20..43b13d6 100644
--- a/docs/getting_started/build-options.rst
+++ b/docs/getting_started/build-options.rst
@@ -811,14 +811,12 @@
- ``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
diff --git a/docs/plat/index.rst b/docs/plat/index.rst
index fc3effd..f135ca2 100644
--- a/docs/plat/index.rst
+++ b/docs/plat/index.rst
@@ -73,9 +73,9 @@
+----------------+----------------+--------------------+--------------------+
| mt6795 | MTK | 2.5 | 2.7 |
+----------------+----------------+--------------------+--------------------+
-| sgi575 | Arm | 2.8 | 2.10 |
+| sgi575 | Arm | 2.8 | TBD |
+----------------+----------------+--------------------+--------------------+
-| rdn1edge | Arm | 2.8 | 2.10 |
+| rdn1edge | Arm | 2.8 | TBD |
+----------------+----------------+--------------------+--------------------+
| tc0 | Arm | 2.8 | 2.10 |
+----------------+----------------+--------------------+--------------------+
diff --git a/docs/plat/xilinx-versal-net.rst b/docs/plat/xilinx-versal-net.rst
index 5d04639..1db7695 100644
--- a/docs/plat/xilinx-versal-net.rst
+++ b/docs/plat/xilinx-versal-net.rst
@@ -14,6 +14,11 @@
make RESET_TO_BL31=1 CROSS_COMPILE=aarch64-none-elf- PLAT=versal_net bl31
```
+To build bl32 TSP you have to rebuild bl31 too
+```bash
+make CROSS_COMPILE=aarch64-none-elf- PLAT=versal_net SPD=tspd RESET_TO_BL31=1 bl31 bl32
+```
+
To build TF-A for JTAG DCC console:
```bash
make RESET_TO_BL31=1 CROSS_COMPILE=aarch64-none-elf- PLAT=versal_net VERSAL_NET_CONSOLE=dcc bl31
diff --git a/docs/plat/xilinx-versal.rst b/docs/plat/xilinx-versal.rst
index 09a6ee2..b71776d 100644
--- a/docs/plat/xilinx-versal.rst
+++ b/docs/plat/xilinx-versal.rst
@@ -19,6 +19,11 @@
make RESET_TO_BL31=1 CROSS_COMPILE=aarch64-none-elf- PLAT=versal VERSAL_PLATFORM=versal_virt bl31
```
+To build bl32 TSP you have to rebuild bl31 too
+```bash
+make CROSS_COMPILE=aarch64-none-elf- PLAT=versal SPD=tspd RESET_TO_BL31=1 bl31 bl32
+```
+
To build TF-A for JTAG DCC console
```bash
make RESET_TO_BL31=1 CROSS_COMPILE=aarch64-none-elf- PLAT=versal bl31 VERSAL_CONSOLE=dcc
diff --git a/docs/porting-guide.rst b/docs/porting-guide.rst
index f612e1c..082497c 100644
--- a/docs/porting-guide.rst
+++ b/docs/porting-guide.rst
@@ -3298,10 +3298,10 @@
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 @@
(``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
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
diff --git a/docs/resources/diagrams/bl31-exception-entry-error-synchronization.png b/docs/resources/diagrams/bl31-exception-entry-error-synchronization.png
new file mode 100644
index 0000000..cdfdcb9
--- /dev/null
+++ b/docs/resources/diagrams/bl31-exception-entry-error-synchronization.png
Binary files differ
diff --git a/include/arch/aarch32/asm_macros.S b/include/arch/aarch32/asm_macros.S
index 83e94ca..3ba86e9 100644
--- a/include/arch/aarch32/asm_macros.S
+++ b/include/arch/aarch32/asm_macros.S
@@ -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
diff --git a/include/arch/aarch64/arch.h b/include/arch/aarch64/arch.h
index 13927bd..e9d22b6 100644
--- a/include/arch/aarch64/arch.h
+++ b/include/arch/aarch64/arch.h
@@ -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)
diff --git a/include/arch/aarch64/asm_macros.S b/include/arch/aarch64/asm_macros.S
index 6091f62..d09ad0f 100644
--- a/include/arch/aarch64/asm_macros.S
+++ b/include/arch/aarch64/asm_macros.S
@@ -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 */
diff --git a/include/arch/aarch64/el3_common_macros.S b/include/arch/aarch64/el3_common_macros.S
index 9c9c00f..a78837f 100644
--- a/include/arch/aarch64/el3_common_macros.S
+++ b/include/arch/aarch64/el3_common_macros.S
@@ -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 */
diff --git a/include/bl31/ea_handle.h b/include/bl31/ea_handle.h
index 68f012c..7cd7b6a 100644
--- a/include/bl31/ea_handle.h
+++ b/include/bl31/ea_handle.h
@@ -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 */
diff --git a/include/lib/cpus/aarch64/neoverse_n2.h b/include/lib/cpus/aarch64/neoverse_n2.h
index 0d50854..b379fab 100644
--- a/include/lib/cpus/aarch64/neoverse_n2.h
+++ b/include/lib/cpus/aarch64/neoverse_n2.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2020-2022, Arm Limited. All rights reserved.
+ * Copyright (c) 2020-2023, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -65,5 +65,8 @@
#define NEOVERSE_N2_CPUECTLR2_EL1_PF_MODE_CNSRV ULL(9)
#define CPUECTLR2_EL1_PF_MODE_LSB U(11)
#define CPUECTLR2_EL1_PF_MODE_WIDTH U(4)
+#define CPUECTLR2_EL1_TXREQ_STATIC_FULL ULL(0)
+#define CPUECTLR2_EL1_TXREQ_LSB U(0)
+#define CPUECTLR2_EL1_TXREQ_WIDTH U(3)
#endif /* NEOVERSE_N2_H */
diff --git a/include/lib/el3_runtime/aarch64/context.h b/include/lib/el3_runtime/aarch64/context.h
index 470d113..47d91de 100644
--- a/include/lib/el3_runtime/aarch64/context.h
+++ b/include/lib/el3_runtime/aarch64/context.h
@@ -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
diff --git a/include/plat/arm/common/arm_def.h b/include/plat/arm/common/arm_def.h
index 314eb93..9176e88 100644
--- a/include/plat/arm/common/arm_def.h
+++ b/include/plat/arm/common/arm_def.h
@@ -774,7 +774,7 @@
#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
diff --git a/lib/cpus/aarch64/cortex_a710.S b/lib/cpus/aarch64/cortex_a710.S
index c618d98..f3931d7 100644
--- a/lib/cpus/aarch64/cortex_a710.S
+++ b/lib/cpus/aarch64/cortex_a710.S
@@ -178,6 +178,14 @@
check_erratum_ls cortex_a710, ERRATUM(2371105), CPU_REV(2, 0)
+workaround_reset_start cortex_a710, ERRATUM(2742423), ERRATA_A710_2742423
+ /* Set CPUACTLR5_EL1[56:55] to 2'b01 */
+ sysreg_bit_set CORTEX_A710_CPUACTLR5_EL1, BIT(55)
+ sysreg_bit_clear CORTEX_A710_CPUACTLR5_EL1, BIT(56)
+workaround_reset_end cortex_a710, ERRATUM(2742423)
+
+check_erratum_ls cortex_a710, ERRATUM(2742423), CPU_REV(2, 1)
+
workaround_runtime_start cortex_a710, ERRATUM(2768515), ERRATA_A710_2768515
/* dsb before isb of power down sequence */
dsb sy
diff --git a/lib/cpus/aarch64/cortex_x2.S b/lib/cpus/aarch64/cortex_x2.S
index 855d196..258288c 100644
--- a/lib/cpus/aarch64/cortex_x2.S
+++ b/lib/cpus/aarch64/cortex_x2.S
@@ -118,6 +118,14 @@
check_erratum_ls cortex_x2, ERRATUM(2371105), CPU_REV(2, 0)
+workaround_reset_start cortex_x2, ERRATUM(2742423), ERRATA_X2_2742423
+ /* Set CPUACTLR5_EL1[56:55] to 2'b01 */
+ sysreg_bit_set CORTEX_X2_CPUACTLR5_EL1, BIT(55)
+ sysreg_bit_clear CORTEX_X2_CPUACTLR5_EL1, BIT(56)
+workaround_reset_end cortex_x2, ERRATUM(2742423)
+
+check_erratum_ls cortex_x2, ERRATUM(2742423), CPU_REV(2, 1)
+
workaround_reset_start cortex_x2, ERRATUM(2768515), ERRATA_X2_2768515
/* dsb before isb of power down sequence */
dsb sy
diff --git a/lib/cpus/aarch64/neoverse_n2.S b/lib/cpus/aarch64/neoverse_n2.S
index ead3908..477522f 100644
--- a/lib/cpus/aarch64/neoverse_n2.S
+++ b/lib/cpus/aarch64/neoverse_n2.S
@@ -165,6 +165,23 @@
check_erratum_ls neoverse_n2, ERRATUM(2326639), CPU_REV(0, 0)
+workaround_runtime_start neoverse_n2, ERRATUM(2340933), ERRATA_N2_2340933
+ /* Set bit 61 in CPUACTLR5_EL1 */
+ sysreg_bit_set NEOVERSE_N2_CPUACTLR5_EL1, BIT(61)
+workaround_runtime_end neoverse_n2, ERRATUM(2340933)
+
+check_erratum_ls neoverse_n2, ERRATUM(2340933), CPU_REV(0, 0)
+
+workaround_runtime_start neoverse_n2, ERRATUM(2346952), ERRATA_N2_2346952
+ /* Set TXREQ to STATIC and full L2 TQ size */
+ mrs x1, NEOVERSE_N2_CPUECTLR2_EL1
+ mov x0, #CPUECTLR2_EL1_TXREQ_STATIC_FULL
+ bfi x1, x0, #CPUECTLR2_EL1_TXREQ_LSB, #CPUECTLR2_EL1_TXREQ_WIDTH
+ msr NEOVERSE_N2_CPUECTLR2_EL1, x1
+workaround_runtime_end neoverse_n2, ERRATUM(2346952)
+
+check_erratum_ls neoverse_n2, ERRATUM(2346952), CPU_REV(0, 2)
+
workaround_reset_start neoverse_n2, ERRATUM(2376738), ERRATA_N2_2376738
/* Set CPUACTLR2_EL1[0] to 1 to force PLDW/PFRM
* ST to behave like PLD/PFRM LD and not cause
diff --git a/lib/cpus/cpu-ops.mk b/lib/cpus/cpu-ops.mk
index ea29047..434ee08 100644
--- a/lib/cpus/cpu-ops.mk
+++ b/lib/cpus/cpu-ops.mk
@@ -607,6 +607,11 @@
# and is still open.
CPU_FLAG_LIST += ERRATA_A710_2701952
+# Flag to apply erratum 2742423 workaround during reset. This erratum applies
+# to revision r0p0, r1p0, r2p0 and r2p1 of the Cortex-A710 cpu and is still
+# open.
+CPU_FLAG_LIST += ERRATA_A710_2742423
+
# Flag to apply erratum 2768515 workaround during power down. This erratum
# applies to revision r0p0, r1p0, r2p0 and r2p1 of the Cortex-A710 cpu and is
# still open.
@@ -656,10 +661,18 @@
# to revision r0p0 of the Neoverse N2 cpu and is fixed in r0p1.
CPU_FLAG_LIST += ERRATA_N2_2280757
-# Flag to apply erraturm 2326639 workaroud during powerdown. This erratum
+# Flag to apply erratum 2326639 workaroud during powerdown. This erratum
# applies to revision r0p0 of the Neoverse N2 cpu and is fixed in r0p1.
CPU_FLAG_LIST += ERRATA_N2_2326639
+# Flag to apply erratum 2340933 workaroud during reset. This erratum
+# applies to revision r0p0 of the Neoverse N2 cpu and is fixed in r0p1.
+CPU_FLAG_LIST += ERRATA_N2_2340933
+
+# Flag to apply erratum 2346952 workaround during reset. This erratum applies
+# to r0p0, r0p1, r0p2 of the Neoverse N2 cpu, it is fixed in r0p3.
+CPU_FLAG_LIST += ERRATA_N2_2346952
+
# Flag to apply erratum 2376738 workaround during reset. This erratum applies
# to revision r0p0, r0p1, r0p2, r0p3 of the Neoverse N2 cpu and is still open.
CPU_FLAG_LIST += ERRATA_N2_2376738
@@ -730,6 +743,10 @@
# and is still open.
CPU_FLAG_LIST += ERRATA_X2_2701952
+# Flag to apply erratum 2742423 workaround during reset. This erratum applies
+# to revisions r0p0, r1p0, r2p0 and r2p1 of the Cortex-X2 cpu and is still open.
+CPU_FLAG_LIST += ERRATA_X2_2742423
+
# Flag to apply erratum 2768515 workaround during power down. This erratum
# applies to revision r0p0, r1p0, r2p0 and r2p1 of the Cortex-X2 cpu and is
# still open.
diff --git a/lib/el3_runtime/aarch64/context.S b/lib/el3_runtime/aarch64/context.S
index 41b25d6..631094f 100644
--- a/lib/el3_runtime/aarch64/context.S
+++ b/lib/el3_runtime/aarch64/context.S
@@ -649,23 +649,9 @@
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 @@
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
diff --git a/make_helpers/defaults.mk b/make_helpers/defaults.mk
index ea22655..e02917c 100644
--- a/make_helpers/defaults.mk
+++ b/make_helpers/defaults.mk
@@ -191,9 +191,6 @@
# 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
diff --git a/plat/arm/board/fvp/platform.mk b/plat/arm/board/fvp/platform.mk
index f7c174f..2fdff34 100644
--- a/plat/arm/board/fvp/platform.mk
+++ b/plat/arm/board/fvp/platform.mk
@@ -56,7 +56,6 @@
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 @@
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 @@
# 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
diff --git a/plat/arm/board/morello/fdts/morello_nt_fw_config.dts b/plat/arm/board/morello/fdts/morello_nt_fw_config.dts
index e730d34..6ec282d 100644
--- a/plat/arm/board/morello/fdts/morello_nt_fw_config.dts
+++ b/plat/arm/board/morello/fdts/morello_nt_fw_config.dts
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2021, Arm Limited. All rights reserved.
+ * Copyright (c) 2021-2023, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -23,4 +23,19 @@
scc-config = <0x0>;
#endif
};
+
+ /*
+ * Placeholder for firmware-version node with default values.
+ * The value will be set to the correct values during
+ * the BL2 stage of boot.
+ */
+ firmware-version {
+#ifdef TARGET_PLATFORM_SOC
+ mcc-fw-version = <0x0>;
+ pcc-fw-version = <0x0>;
+#endif
+ scp-fw-version = <0x0>;
+ scp-fw-commit = <0x0>;
+ tfa-fw-version = "unknown-dirty_00000000";
+ };
};
diff --git a/plat/arm/board/morello/morello_def.h b/plat/arm/board/morello/morello_def.h
index e42a03c..25122e6 100644
--- a/plat/arm/board/morello/morello_def.h
+++ b/plat/arm/board/morello/morello_def.h
@@ -15,6 +15,15 @@
MORELLO_NS_SRAM_SIZE, \
MT_DEVICE | MT_RW | MT_SECURE)
+/* SDS Firmware version defines */
+#define MORELLO_SDS_FIRMWARE_VERSION_STRUCT_ID U(2)
+#define MORELLO_SDS_FIRMWARE_VERSION_OFFSET U(0)
+#ifdef TARGET_PLATFORM_FVP
+# define MORELLO_SDS_FIRMWARE_VERSION_SIZE U(8)
+#else
+# define MORELLO_SDS_FIRMWARE_VERSION_SIZE U(16)
+#endif
+
/* SDS Platform information defines */
#define MORELLO_SDS_PLATFORM_INFO_STRUCT_ID U(8)
#define MORELLO_SDS_PLATFORM_INFO_OFFSET U(0)
@@ -122,8 +131,40 @@
} __packed;
#endif
-/* Compile time assertion to ensure the size of structure is of the required bytes */
+/* SDS Firmware revision struct definition */
+#ifdef TARGET_PLATFORM_FVP
+/*
+ * Firmware revision structure stored in SDS.
+ * This structure holds information about firmware versions.
+ * - SCP firmware version
+ * - SCP firmware commit
+ */
+struct morello_firmware_version {
+ uint32_t scp_fw_ver;
+ uint32_t scp_fw_commit;
+} __packed;
+#else
+/*
+ * Firmware revision structure stored in SDS.
+ * This structure holds information about firmware versions.
+ * - SCP firmware version
+ * - SCP firmware commit
+ * - MCC firmware version
+ * - PCC firmware version
+ */
+struct morello_firmware_version {
+ uint32_t scp_fw_ver;
+ uint32_t scp_fw_commit;
+ uint32_t mcc_fw_ver;
+ uint32_t pcc_fw_ver;
+} __packed;
+#endif
+
+/* Compile time assertions to ensure the size of structures are of the required bytes */
CASSERT(sizeof(struct morello_plat_info) == MORELLO_SDS_PLATFORM_INFO_SIZE,
assert_invalid_plat_info_size);
+CASSERT(sizeof(struct morello_firmware_version) == MORELLO_SDS_FIRMWARE_VERSION_SIZE,
+ assert_invalid_firmware_version_size);
+
#endif /* MORELLO_DEF_H */
diff --git a/plat/arm/board/morello/morello_image_load.c b/plat/arm/board/morello/morello_image_load.c
index b5d9bd5..4ea2bb3 100644
--- a/plat/arm/board/morello/morello_image_load.c
+++ b/plat/arm/board/morello/morello_image_load.c
@@ -23,7 +23,8 @@
}
/*******************************************************************************
- * This function inserts Platform information via device tree nodes as,
+ * This function inserts Platform information and firmware versions
+ * via device tree nodes as,
* platform-info {
* local-ddr-size = <0x0 0x0>;
*#ifdef TARGET_PLATFORM_SOC
@@ -33,12 +34,22 @@
* scc-config = <0x0>;
*#endif
* };
+ * firmware-version {
+ *#ifdef TARGET_PLATFORM_SOC
+ * mcc-fw-version = <0x0>;
+ * pcc-fw-version = <0x0>;
+ *#endif
+ * scp-fw-version = <0x0>;
+ * scp-fw-commit = <0x0>;
+ * tfa-fw-version = "unknown-dirty_00000000";
+ * };
******************************************************************************/
-static int plat_morello_append_config_node(struct morello_plat_info *plat_info)
+static int plat_morello_append_config_node(struct morello_plat_info *plat_info,
+ struct morello_firmware_version *fw_version)
{
bl_mem_params_node_t *mem_params;
void *fdt;
- int nodeoffset, err;
+ int nodeoffset_plat, nodeoffset_fw, err;
uint64_t usable_mem_size;
usable_mem_size = plat_info->local_ddr_size;
@@ -57,35 +68,41 @@
return -1;
}
- nodeoffset = fdt_subnode_offset(fdt, 0, "platform-info");
- if (nodeoffset < 0) {
+ nodeoffset_plat = fdt_subnode_offset(fdt, 0, "platform-info");
+ if (nodeoffset_plat < 0) {
ERROR("NT_FW_CONFIG: Failed to get platform-info node offset\n");
return -1;
}
+ nodeoffset_fw = fdt_subnode_offset(fdt, 0, "firmware-version");
+ if (nodeoffset_fw < 0) {
+ ERROR("NT_FW_CONFIG: Failed to get firmware-version node offset\n");
+ return -1;
+ }
+
#ifdef TARGET_PLATFORM_SOC
- err = fdt_setprop_u64(fdt, nodeoffset, "remote-ddr-size",
+ err = fdt_setprop_u64(fdt, nodeoffset_plat, "remote-ddr-size",
plat_info->remote_ddr_size);
if (err < 0) {
ERROR("NT_FW_CONFIG: Failed to set remote-ddr-size\n");
return -1;
}
- err = fdt_setprop_u32(fdt, nodeoffset, "remote-chip-count",
+ err = fdt_setprop_u32(fdt, nodeoffset_plat, "remote-chip-count",
plat_info->remote_chip_count);
if (err < 0) {
ERROR("NT_FW_CONFIG: Failed to set remote-chip-count\n");
return -1;
}
- err = fdt_setprop_u32(fdt, nodeoffset, "multichip-mode",
+ err = fdt_setprop_u32(fdt, nodeoffset_plat, "multichip-mode",
plat_info->multichip_mode);
if (err < 0) {
ERROR("NT_FW_CONFIG: Failed to set multichip-mode\n");
return -1;
}
- err = fdt_setprop_u32(fdt, nodeoffset, "scc-config",
+ err = fdt_setprop_u32(fdt, nodeoffset_plat, "scc-config",
plat_info->scc_config);
if (err < 0) {
ERROR("NT_FW_CONFIG: Failed to set scc-config\n");
@@ -95,8 +112,41 @@
if (plat_info->scc_config & MORELLO_SCC_CLIENT_MODE_MASK) {
usable_mem_size = get_mem_client_mode(plat_info->local_ddr_size);
}
+
+ err = fdt_setprop_u32(fdt, nodeoffset_fw, "mcc-fw-version",
+ fw_version->mcc_fw_ver);
+ if (err < 0) {
+ ERROR("NT_FW_CONFIG: Failed to set mcc-fw-version\n");
+ return -1;
+ }
+
+ err = fdt_setprop_u32(fdt, nodeoffset_fw, "pcc-fw-version",
+ fw_version->pcc_fw_ver);
+ if (err < 0) {
+ ERROR("NT_FW_CONFIG: Failed to set pcc-fw-version\n");
+ return -1;
+ }
#endif
- err = fdt_setprop_u64(fdt, nodeoffset, "local-ddr-size",
+ err = fdt_setprop_u32(fdt, nodeoffset_fw, "scp-fw-version",
+ fw_version->scp_fw_ver);
+ if (err < 0) {
+ ERROR("NT_FW_CONFIG: Failed to set scp-fw-version\n");
+ return -1;
+ }
+
+ err = fdt_setprop_u32(fdt, nodeoffset_fw, "scp-fw-commit",
+ fw_version->scp_fw_commit);
+ if (err < 0) {
+ ERROR("NT_FW_CONFIG: Failed to set scp-fw-commit\n");
+ return -1;
+ }
+
+ err = fdt_setprop_string(fdt, nodeoffset_fw, "tfa-fw-version", version_string);
+ if (err < 0) {
+ WARN("NT_FW_CONFIG: Unable to set tfa-fw-version\n");
+ }
+
+ err = fdt_setprop_u64(fdt, nodeoffset_plat, "local-ddr-size",
usable_mem_size);
if (err < 0) {
ERROR("NT_FW_CONFIG: Failed to set local-ddr-size\n");
@@ -115,6 +165,7 @@
{
int ret;
struct morello_plat_info plat_info;
+ struct morello_firmware_version fw_version;
ret = sds_init();
if (ret != SDS_OK) {
@@ -132,6 +183,16 @@
panic();
}
+ ret = sds_struct_read(MORELLO_SDS_FIRMWARE_VERSION_STRUCT_ID,
+ MORELLO_SDS_FIRMWARE_VERSION_OFFSET,
+ &fw_version,
+ MORELLO_SDS_FIRMWARE_VERSION_SIZE,
+ SDS_ACCESS_MODE_NON_CACHED);
+ if (ret != SDS_OK) {
+ ERROR("Error getting firmware version from SDS. ret:%d\n", ret);
+ panic();
+ }
+
/* Validate plat_info SDS */
#ifdef TARGET_PLATFORM_FVP
if (plat_info.local_ddr_size == 0U) {
@@ -146,7 +207,7 @@
panic();
}
- ret = plat_morello_append_config_node(&plat_info);
+ ret = plat_morello_append_config_node(&plat_info, &fw_version);
if (ret != 0) {
panic();
}
diff --git a/plat/arm/board/rdn2/platform.mk b/plat/arm/board/rdn2/platform.mk
index 1506714..ef8f3d4 100644
--- a/plat/arm/board/rdn2/platform.mk
+++ b/plat/arm/board/rdn2/platform.mk
@@ -69,7 +69,7 @@
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 \
diff --git a/plat/arm/board/rdn2/rdn2_plat.c b/plat/arm/board/rdn2/rdn2_plat.c
index f117456..2a6c658 100644
--- a/plat/arm/board/rdn2/rdn2_plat.c
+++ b/plat/arm/board/rdn2/rdn2_plat.c
@@ -137,7 +137,7 @@
sgi_bl31_common_platform_setup();
-#if RAS_FFH_SUPPORT
+#if ENABLE_FEAT_RAS && FFH_SUPPORT
sgi_ras_platform_setup(&ras_config);
#endif
}
diff --git a/plat/arm/board/rdn2/rdn2_security.c b/plat/arm/board/rdn2/rdn2_security.c
index b836a7f..7cd4a1c 100644
--- a/plat/arm/board/rdn2/rdn2_security.c
+++ b/plat/arm/board/rdn2/rdn2_security.c
@@ -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
{}
diff --git a/plat/arm/board/tc/platform.mk b/plat/arm/board/tc/platform.mk
index 8ca33ca..8db6f1d 100644
--- a/plat/arm/board/tc/platform.mk
+++ b/plat/arm/board/tc/platform.mk
@@ -21,8 +21,6 @@
ENABLE_FEAT_RAS := 1
-RAS_FFH_SUPPORT := 0
-
SDEI_SUPPORT := 0
EL3_EXCEPTION_HANDLING := 0
diff --git a/plat/arm/common/arm_bl31_setup.c b/plat/arm/common/arm_bl31_setup.c
index cfd1aac..f47bc3e 100644
--- a/plat/arm/common/arm_bl31_setup.c
+++ b/plat/arm/common/arm_bl31_setup.c
@@ -295,7 +295,7 @@
/* Initialize power controller before setting up topology */
plat_arm_pwrc_setup();
-#if RAS_FFH_SUPPORT
+#if ENABLE_FEAT_RAS && FFH_SUPPORT
ras_init();
#endif
diff --git a/plat/arm/common/arm_common.mk b/plat/arm/common/arm_common.mk
index 421c8e9..bbb39d5 100644
--- a/plat/arm/common/arm_common.mk
+++ b/plat/arm/common/arm_common.mk
@@ -352,7 +352,7 @@
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
diff --git a/plat/arm/common/arm_gicv3.c b/plat/arm/common/arm_gicv3.c
index 8c16877..5becbcd 100644
--- a/plat/arm/common/arm_gicv3.c
+++ b/plat/arm/common/arm_gicv3.c
@@ -41,7 +41,7 @@
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
diff --git a/plat/arm/css/sgi/include/sgi_base_platform_def.h b/plat/arm/css/sgi/include/sgi_base_platform_def.h
index 8a13bf3..9dfe040 100644
--- a/plat/arm/css/sgi/include/sgi_base_platform_def.h
+++ b/plat/arm/css/sgi/include/sgi_base_platform_def.h
@@ -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)
diff --git a/plat/arm/css/sgi/sgi-common.mk b/plat/arm/css/sgi/sgi-common.mk
index 358316c..2cd7034 100644
--- a/plat/arm/css/sgi/sgi-common.mk
+++ b/plat/arm/css/sgi/sgi-common.mk
@@ -10,8 +10,6 @@
ENABLE_FEAT_RAS := 1
-RAS_FFH_SUPPORT := 0
-
SDEI_SUPPORT := 0
EL3_EXCEPTION_HANDLING := 0
diff --git a/plat/arm/css/sgi/sgi_plat.c b/plat/arm/css/sgi/sgi_plat.c
index 7f79d54..01b426e 100644
--- a/plat/arm/css/sgi/sgi_plat.c
+++ b/plat/arm/css/sgi/sgi_plat.c
@@ -93,7 +93,7 @@
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,
diff --git a/plat/arm/css/sgi/sgi_plat_v2.c b/plat/arm/css/sgi/sgi_plat_v2.c
index 85f99d4..624fed3 100644
--- a/plat/arm/css/sgi/sgi_plat_v2.c
+++ b/plat/arm/css/sgi/sgi_plat_v2.c
@@ -87,7 +87,7 @@
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,
diff --git a/plat/common/aarch64/plat_common.c b/plat/common/aarch64/plat_common.c
index eca81b1..ab99b15 100644
--- a/plat/common/aarch64/plat_common.c
+++ b/plat/common/aarch64/plat_common.c
@@ -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 @@
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 @@
*/
lower_el_panic();
}
+#endif
diff --git a/plat/common/aarch64/plat_ehf.c b/plat/common/aarch64/plat_ehf.c
index 41b175d..6100a20 100644
--- a/plat/common/aarch64/plat_ehf.c
+++ b/plat/common/aarch64/plat_ehf.c
@@ -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 @@
#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
diff --git a/plat/nvidia/tegra/include/tegra_private.h b/plat/nvidia/tegra/include/tegra_private.h
index f93585d..ad80596 100644
--- a/plat/nvidia/tegra/include/tegra_private.h
+++ b/plat/nvidia/tegra/include/tegra_private.h
@@ -154,7 +154,7 @@
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
diff --git a/plat/nvidia/tegra/soc/t186/plat_setup.c b/plat/nvidia/tegra/soc/t186/plat_setup.c
index d6d090a..b21faa3 100644
--- a/plat/nvidia/tegra/soc/t186/plat_setup.c
+++ b/plat/nvidia/tegra/soc/t186/plat_setup.c
@@ -302,14 +302,14 @@
*/
if ((cluster_id >= (u_register_t)PLATFORM_CLUSTER_COUNT) ||
(cpu_id >= (u_register_t)PLATFORM_MAX_CPUS_PER_CLUSTER)) {
- ret = PSCI_E_NOT_PRESENT;
+ ret = -1;
} else {
/* calculate the core position */
pos = cpu_id + (cluster_id << 2U);
/* check for non-existent CPUs */
if ((pos == TEGRA186_CLUSTER0_CORE2) || (pos == TEGRA186_CLUSTER0_CORE3)) {
- ret = PSCI_E_NOT_PRESENT;
+ ret = -1;
} else {
ret = (int32_t)pos;
}
diff --git a/plat/nvidia/tegra/soc/t194/plat_ras.c b/plat/nvidia/tegra/soc/t194/plat_ras.c
index 2f438c3..841d70b 100644
--- a/plat/nvidia/tegra/soc/t194/plat_ras.c
+++ b/plat/nvidia/tegra/soc/t194/plat_ras.c
@@ -484,7 +484,7 @@
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);
diff --git a/plat/nvidia/tegra/soc/t194/plat_setup.c b/plat/nvidia/tegra/soc/t194/plat_setup.c
index d3d09d3..6850330 100644
--- a/plat/nvidia/tegra/soc/t194/plat_setup.c
+++ b/plat/nvidia/tegra/soc/t194/plat_setup.c
@@ -254,7 +254,7 @@
/* 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
diff --git a/plat/nvidia/tegra/soc/t194/plat_sip_calls.c b/plat/nvidia/tegra/soc/t194/plat_sip_calls.c
index f0704ed..6e42e64 100644
--- a/plat/nvidia/tegra/soc/t194/plat_sip_calls.c
+++ b/plat/nvidia/tegra/soc/t194/plat_sip_calls.c
@@ -71,7 +71,7 @@
break;
-#if RAS_FFH_SUPPORT
+#if ENABLE_FEAT_RAS
case TEGRA_SIP_CLEAR_RAS_CORRECTED_ERRORS:
{
/*
diff --git a/plat/nvidia/tegra/soc/t194/platform_t194.mk b/plat/nvidia/tegra/soc/t194/platform_t194.mk
index 289e921..e6e0b5e 100644
--- a/plat/nvidia/tegra/soc/t194/platform_t194.mk
+++ b/plat/nvidia/tegra/soc/t194/platform_t194.mk
@@ -37,7 +37,7 @@
# 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 @@
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
diff --git a/plat/ti/k3/board/generic/include/board_def.h b/plat/ti/k3/board/generic/include/board_def.h
index edfa73f..ade6d7a 100644
--- a/plat/ti/k3/board/generic/include/board_def.h
+++ b/plat/ti/k3/board/generic/include/board_def.h
@@ -12,8 +12,8 @@
/* The ports must be in order and contiguous */
#define K3_CLUSTER0_CORE_COUNT U(2)
#define K3_CLUSTER1_CORE_COUNT U(2)
-#define K3_CLUSTER2_CORE_COUNT U(2)
-#define K3_CLUSTER3_CORE_COUNT U(2)
+#define K3_CLUSTER2_CORE_COUNT U(0)
+#define K3_CLUSTER3_CORE_COUNT U(0)
#define PLAT_PROC_START_ID U(32)
#define PLAT_PROC_DEVICE_START_ID U(202)
diff --git a/plat/ti/k3/common/drivers/ti_sci/ti_sci.c b/plat/ti/k3/common/drivers/ti_sci/ti_sci.c
index 495f0c7..d04d805 100644
--- a/plat/ti/k3/common/drivers/ti_sci/ti_sci.c
+++ b/plat/ti/k3/common/drivers/ti_sci/ti_sci.c
@@ -155,14 +155,14 @@
ret = k3_sec_proxy_clear_rx_thread(SP_RESPONSE);
if (ret) {
ERROR("Could not clear response queue (%d)\n", ret);
- return ret;
+ goto unlock;
}
/* Send the message */
ret = k3_sec_proxy_send(SP_HIGH_PRIORITY, tx_msg);
if (ret) {
ERROR("Message sending failed (%d)\n", ret);
- return ret;
+ goto unlock;
}
/* Get the response if requested */
@@ -170,13 +170,14 @@
ret = ti_sci_get_response(rx_msg, SP_RESPONSE);
if (ret != 0U) {
ERROR("Failed to get response (%d)\n", ret);
- return ret;
+ goto unlock;
}
}
+unlock:
bakery_lock_release(&ti_sci_xfer_lock);
- return 0;
+ return ret;
}
/**
@@ -211,6 +212,42 @@
}
/**
+ * ti_sci_query_fw_caps() - Get the FW/SoC capabilities
+ * @handle: Pointer to TI SCI handle
+ * @fw_caps: Each bit in fw_caps indicating one FW/SOC capability
+ *
+ * Return: 0 if all went well, else returns appropriate error value.
+ */
+int ti_sci_query_fw_caps(uint64_t *fw_caps)
+{
+ struct ti_sci_msg_hdr req;
+ struct ti_sci_msg_resp_query_fw_caps resp;
+
+ struct ti_sci_xfer xfer;
+ int ret;
+
+ ret = ti_sci_setup_one_xfer(TI_SCI_MSG_QUERY_FW_CAPS, 0,
+ &req, sizeof(req),
+ &resp, sizeof(resp),
+ &xfer);
+ if (ret != 0U) {
+ ERROR("Message alloc failed (%d)\n", ret);
+ return ret;
+ }
+
+ ret = ti_sci_do_xfer(&xfer);
+ if (ret != 0U) {
+ ERROR("Transfer send failed (%d)\n", ret);
+ return ret;
+ }
+
+ if (fw_caps)
+ *fw_caps = resp.fw_caps;
+
+ return 0;
+}
+
+/**
* ti_sci_device_set_state() - Set device state
*
* @id: Device identifier
diff --git a/plat/ti/k3/common/drivers/ti_sci/ti_sci.h b/plat/ti/k3/common/drivers/ti_sci/ti_sci.h
index 06944a7..c702a71 100644
--- a/plat/ti/k3/common/drivers/ti_sci/ti_sci.h
+++ b/plat/ti/k3/common/drivers/ti_sci/ti_sci.h
@@ -141,10 +141,13 @@
* Core control operations
*
* - ti_sci_core_reboot() - Command to request system reset
+ * - ti_sci_query_fw_caps() - Get the FW/SoC capabilities
+ * @fw_caps: Each bit in fw_caps indicating one FW/SOC capability
*
* Return: 0 if all went well, else returns appropriate error value.
*/
int ti_sci_core_reboot(void);
+int ti_sci_query_fw_caps(uint64_t *fw_caps);
/**
* Processor control operations
diff --git a/plat/ti/k3/common/drivers/ti_sci/ti_sci_protocol.h b/plat/ti/k3/common/drivers/ti_sci/ti_sci_protocol.h
index 36909f5..7f1c368 100644
--- a/plat/ti/k3/common/drivers/ti_sci/ti_sci_protocol.h
+++ b/plat/ti/k3/common/drivers/ti_sci/ti_sci_protocol.h
@@ -22,6 +22,7 @@
#define TI_SCI_MSG_WAKE_REASON 0x0003
#define TI_SCI_MSG_GOODBYE 0x0004
#define TI_SCI_MSG_SYS_RESET 0x0005
+#define TI_SCI_MSG_QUERY_FW_CAPS 0x0022
/* Device requests */
#define TI_SCI_MSG_SET_DEVICE_STATE 0x0200
@@ -124,6 +125,30 @@
} __packed;
/**
+ * struct ti_sci_msg_resp_query_fw_caps - Response for query firmware caps
+ * @hdr: Generic header
+ * @fw_caps: Each bit in fw_caps indicating one FW/SOC capability
+ * MSG_FLAG_CAPS_GENERIC: Generic capability (LPM not supported)
+ * MSG_FLAG_CAPS_LPM_DEEP_SLEEP: Deep Sleep LPM
+ * MSG_FLAG_CAPS_LPM_MCU_ONLY: MCU only LPM
+ * MSG_FLAG_CAPS_LPM_STANDBY: Standby LPM
+ * MSG_FLAG_CAPS_LPM_PARTIAL_IO: Partial IO in LPM
+ *
+ * Response to a generic message with message type TI_SCI_MSG_QUERY_FW_CAPS
+ * providing currently available SOC/firmware capabilities. SoC that don't
+ * support low power modes return only MSG_FLAG_CAPS_GENERIC capability.
+ */
+struct ti_sci_msg_resp_query_fw_caps {
+ struct ti_sci_msg_hdr hdr;
+#define MSG_FLAG_CAPS_GENERIC TI_SCI_MSG_FLAG(0)
+#define MSG_FLAG_CAPS_LPM_DEEP_SLEEP TI_SCI_MSG_FLAG(1)
+#define MSG_FLAG_CAPS_LPM_MCU_ONLY TI_SCI_MSG_FLAG(2)
+#define MSG_FLAG_CAPS_LPM_STANDBY TI_SCI_MSG_FLAG(3)
+#define MSG_FLAG_CAPS_LPM_PARTIAL_IO TI_SCI_MSG_FLAG(4)
+ uint64_t fw_caps;
+} __packed;
+
+/**
* struct ti_sci_msg_req_set_device_state - Set the desired state of the device
* @hdr: Generic header
* @id: Indicates which device to modify
diff --git a/plat/ti/k3/common/k3_gicv3.c b/plat/ti/k3/common/k3_gicv3.c
index 0199822..eda9430 100644
--- a/plat/ti/k3/common/k3_gicv3.c
+++ b/plat/ti/k3/common/k3_gicv3.c
@@ -19,10 +19,8 @@
/* The GICv3 driver only needs to be initialized in EL3 */
uintptr_t rdistif_base_addrs[PLATFORM_CORE_COUNT];
-#if K3_PM_SYSTEM_SUSPEND
static gicv3_redist_ctx_t rdist_ctx[PLATFORM_CORE_COUNT];
static gicv3_dist_ctx_t dist_ctx;
-#endif
static const interrupt_prop_t k3_interrupt_props[] = {
PLAT_ARM_G1S_IRQ_PROPS(INTR_GROUP1S),
@@ -94,7 +92,6 @@
gicv3_rdistif_init(plat_my_core_pos());
}
-#if K3_PM_SYSTEM_SUSPEND
void k3_gic_save_context(void)
{
for (unsigned int i = 0U; i < PLATFORM_CORE_COUNT; i++) {
@@ -110,4 +107,3 @@
gicv3_rdistif_init_restore(i, &rdist_ctx[i]);
}
}
-#endif
diff --git a/plat/ti/k3/common/k3_psci.c b/plat/ti/k3/common/k3_psci.c
index d846495..e8d73db 100644
--- a/plat/ti/k3/common/k3_psci.c
+++ b/plat/ti/k3/common/k3_psci.c
@@ -234,7 +234,6 @@
return PSCI_E_SUCCESS;
}
-#if K3_PM_SYSTEM_SUSPEND
static void k3_pwr_domain_suspend(const psci_power_state_t *target_state)
{
unsigned int core, proc_id;
@@ -266,18 +265,15 @@
req_state->pwr_domain_state[i] = PLAT_MAX_OFF_STATE;
}
}
-#endif
-static const plat_psci_ops_t k3_plat_psci_ops = {
+static plat_psci_ops_t k3_plat_psci_ops = {
.cpu_standby = k3_cpu_standby,
.pwr_domain_on = k3_pwr_domain_on,
.pwr_domain_off = k3_pwr_domain_off,
.pwr_domain_on_finish = k3_pwr_domain_on_finish,
-#if K3_PM_SYSTEM_SUSPEND
.pwr_domain_suspend = k3_pwr_domain_suspend,
.pwr_domain_suspend_finish = k3_pwr_domain_suspend_finish,
.get_sys_suspend_power_state = k3_get_sys_suspend_power_state,
-#endif
.system_off = k3_system_off,
.system_reset = k3_system_reset,
.validate_power_state = k3_validate_power_state,
@@ -286,8 +282,27 @@
int plat_setup_psci_ops(uintptr_t sec_entrypoint,
const plat_psci_ops_t **psci_ops)
{
+ uint64_t fw_caps = 0;
+ int ret;
+
k3_sec_entrypoint = sec_entrypoint;
+ ret = ti_sci_query_fw_caps(&fw_caps);
+ if (ret) {
+ ERROR("Unable to query firmware capabilities (%d)\n", ret);
+ }
+
+ /* If firmware does not support any known suspend mode */
+ if (!(fw_caps & (MSG_FLAG_CAPS_LPM_DEEP_SLEEP |
+ MSG_FLAG_CAPS_LPM_MCU_ONLY |
+ MSG_FLAG_CAPS_LPM_STANDBY |
+ MSG_FLAG_CAPS_LPM_PARTIAL_IO))) {
+ /* Disable PSCI suspend support */
+ k3_plat_psci_ops.pwr_domain_suspend = NULL;
+ k3_plat_psci_ops.pwr_domain_suspend_finish = NULL;
+ k3_plat_psci_ops.get_sys_suspend_power_state = NULL;
+ }
+
*psci_ops = &k3_plat_psci_ops;
return 0;
diff --git a/plat/ti/k3/common/plat_common.mk b/plat/ti/k3/common/plat_common.mk
index fb633a8..23efa31 100644
--- a/plat/ti/k3/common/plat_common.mk
+++ b/plat/ti/k3/common/plat_common.mk
@@ -44,10 +44,6 @@
K3_USART_BAUD := 115200
$(eval $(call add_define,K3_USART_BAUD))
-# Enable system suspend modes
-K3_PM_SYSTEM_SUSPEND := 0
-$(eval $(call add_define,K3_PM_SYSTEM_SUSPEND))
-
# Libraries
include lib/xlat_tables_v2/xlat_tables.mk
diff --git a/plat/xilinx/common/include/pm_defs.h b/plat/xilinx/common/include/pm_defs.h
index 72ba107..9cdb0ba 100644
--- a/plat/xilinx/common/include/pm_defs.h
+++ b/plat/xilinx/common/include/pm_defs.h
@@ -68,7 +68,6 @@
IOCTL_RPU_BOOT_ADDR_CONFIG = 2,
IOCTL_TCM_COMB_CONFIG = 3,
IOCTL_SET_TAPDELAY_BYPASS = 4,
- IOCTL_SET_SGMII_MODE = 5,
IOCTL_SD_DLL_RESET = 6,
IOCTL_SET_SD_TAPDELAY = 7,
/* Ioctl for clock driver */
diff --git a/plat/xilinx/common/tsp/tsp.mk b/plat/xilinx/common/tsp/tsp.mk
new file mode 100644
index 0000000..b80f531
--- /dev/null
+++ b/plat/xilinx/common/tsp/tsp.mk
@@ -0,0 +1,8 @@
+#
+# Copyright (c) 2023, Advanced Micro Devices, Inc. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+
+# TSP source files for AMD-Xilinx platforms
+BL32_SOURCES += plat/common/aarch64/platform_mp_stack.S \
+ plat/xilinx/common/tsp/tsp_plat_setup.c
diff --git a/plat/xilinx/zynqmp/tsp/tsp_plat_setup.c b/plat/xilinx/common/tsp/tsp_plat_setup.c
similarity index 67%
rename from plat/xilinx/zynqmp/tsp/tsp_plat_setup.c
rename to plat/xilinx/common/tsp/tsp_plat_setup.c
index a9f2dbd..21c29c3 100644
--- a/plat/xilinx/zynqmp/tsp/tsp_plat_setup.c
+++ b/plat/xilinx/common/tsp/tsp_plat_setup.c
@@ -1,11 +1,13 @@
/*
* Copyright (c) 2014-2019, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2023, Advanced Micro Devices. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <common/bl_common.h>
#include <common/debug.h>
+#include <drivers/arm/pl011.h>
#include <drivers/console.h>
#include <plat/arm/common/plat_arm.h>
#include <platform_tsp.h>
@@ -22,10 +24,24 @@
* messages from TSP
*/
static console_t tsp_boot_console;
- (void)console_cdns_register(UART_BASE,
- get_uart_clk(),
- UART_BAUDRATE,
- &tsp_boot_console);
+ int32_t rc;
+
+#if defined(PLAT_zynqmp)
+ rc = console_cdns_register((uintptr_t)UART_BASE,
+ (uint32_t)get_uart_clk(),
+ (uint32_t)UART_BAUDRATE,
+ &tsp_boot_console);
+#else
+ rc = console_pl011_register((uintptr_t)UART_BASE,
+ (uint32_t)get_uart_clk(),
+ (uint32_t)UART_BAUDRATE,
+ &tsp_boot_console);
+#endif
+
+ if (rc == 0) {
+ panic();
+ }
+
console_set_scope(&tsp_boot_console,
CONSOLE_FLAG_RUNTIME | CONSOLE_FLAG_BOOT);
}
@@ -35,8 +51,16 @@
******************************************************************************/
void tsp_platform_setup(void)
{
+/*
+ * For ZynqMP, the GICv2 driver needs to be initialized in S-EL1,
+ * and for other platforms, the GICv3 driver is initialized in EL3.
+ * This is because S-EL1 can use GIC system registers to manage
+ * interrupts and does not need to be initialized again in SEL1.
+ */
+#if defined(PLAT_zynqmp)
plat_arm_gic_driver_init();
plat_arm_gic_init();
+#endif
}
/*******************************************************************************
@@ -52,12 +76,14 @@
MT_CODE | MT_SECURE),
MAP_REGION_FLAT(BL_RO_DATA_BASE, BL_RO_DATA_END - BL_RO_DATA_BASE,
MT_RO_DATA | MT_SECURE),
+#if defined(PLAT_zynqmp) || defined(PLAT_versal)
MAP_REGION_FLAT(BL_COHERENT_RAM_BASE,
BL_COHERENT_RAM_END - BL_COHERENT_RAM_BASE,
MT_DEVICE | MT_RW | MT_SECURE),
+#endif
{0}
};
- setup_page_tables(bl_regions, plat_arm_get_mmap());
+ setup_page_tables(bl_regions, plat_get_mmap());
enable_mmu_el1(0);
}
diff --git a/plat/xilinx/versal/aarch64/versal_common.c b/plat/xilinx/versal/aarch64/versal_common.c
index 6541f27..aba190d 100644
--- a/plat/xilinx/versal/aarch64/versal_common.c
+++ b/plat/xilinx/versal/aarch64/versal_common.c
@@ -33,7 +33,7 @@
{ 0 }
};
-const mmap_region_t *plat_versal_get_mmap(void)
+const mmap_region_t *plat_get_mmap(void)
{
return plat_versal_mmap;
}
diff --git a/plat/xilinx/versal/bl31_versal_setup.c b/plat/xilinx/versal/bl31_versal_setup.c
index 48f774d..cd105c6 100644
--- a/plat/xilinx/versal/bl31_versal_setup.c
+++ b/plat/xilinx/versal/bl31_versal_setup.c
@@ -115,6 +115,19 @@
panic();
} else {
INFO("BL31: PLM to TF-A handover success %u\n", ret);
+
+ /*
+ * The BL32 load address is indicated as 0x0 in the handoff
+ * parameters, which is different from the default/user-provided
+ * load address of 0x60000000 but the flags are correctly
+ * configured. Consequently, in this scenario, set the PC
+ * to the requested BL32_BASE address.
+ */
+
+ /* TODO: Remove the following check once this is fixed from PLM */
+ if (bl32_image_ep_info.pc == 0 && bl32_image_ep_info.spsr != 0) {
+ bl32_image_ep_info.pc = (uintptr_t)BL32_BASE;
+ }
}
NOTICE("BL31: Secure code at 0x%lx\n", bl32_image_ep_info.pc);
@@ -190,6 +203,8 @@
if (rc != 0) {
panic();
}
+
+ console_switch_state(CONSOLE_FLAG_RUNTIME);
}
/*
@@ -218,6 +233,6 @@
{0}
};
- setup_page_tables(bl_regions, plat_versal_get_mmap());
+ setup_page_tables(bl_regions, plat_get_mmap());
enable_mmu(0);
}
diff --git a/plat/xilinx/versal/include/plat_private.h b/plat/xilinx/versal/include/plat_private.h
index 26545ba..a4210cd 100644
--- a/plat/xilinx/versal/include/plat_private.h
+++ b/plat/xilinx/versal/include/plat_private.h
@@ -20,7 +20,7 @@
uint32_t get_uart_clk(void);
void versal_config_setup(void);
-const mmap_region_t *plat_versal_get_mmap(void);
+const mmap_region_t *plat_get_mmap(void);
extern uint32_t platform_id, platform_version;
diff --git a/plat/xilinx/versal/include/versal_def.h b/plat/xilinx/versal/include/versal_def.h
index 0ac76b5..92c0ba6 100644
--- a/plat/xilinx/versal/include/versal_def.h
+++ b/plat/xilinx/versal/include/versal_def.h
@@ -48,6 +48,7 @@
* IRQ constants
******************************************************************************/
#define VERSAL_IRQ_SEC_PHY_TIMER U(29)
+#define ARM_IRQ_SEC_PHY_TIMER 29
/*******************************************************************************
* CCI-400 related constants
diff --git a/plat/xilinx/versal/platform.mk b/plat/xilinx/versal/platform.mk
index 494c30d..7c53daa 100644
--- a/plat/xilinx/versal/platform.mk
+++ b/plat/xilinx/versal/platform.mk
@@ -54,6 +54,9 @@
$(eval $(call add_define,PLAT_XLAT_TABLES_DYNAMIC))
endif
+# enable assert() for release/debug builds
+ENABLE_ASSERTIONS := 1
+
PLAT_INCLUDES := -Iinclude/plat/arm/common/ \
-Iplat/xilinx/common/include/ \
-Iplat/xilinx/common/ipi_mailbox_service/ \
diff --git a/plat/xilinx/versal/tsp/tsp-versal.mk b/plat/xilinx/versal/tsp/tsp-versal.mk
new file mode 100644
index 0000000..bf32de3
--- /dev/null
+++ b/plat/xilinx/versal/tsp/tsp-versal.mk
@@ -0,0 +1,10 @@
+#
+# Copyright (c) 2023, Advanced Micro Devices, Inc. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+
+# TSP source files specific to Versal platform
+
+PLAT_XILINX_COMMON := plat/xilinx/common/
+
+include ${PLAT_XILINX_COMMON}/tsp/tsp.mk
diff --git a/plat/xilinx/versal_net/aarch64/versal_net_common.c b/plat/xilinx/versal_net/aarch64/versal_net_common.c
index df18814..69c5c87 100644
--- a/plat/xilinx/versal_net/aarch64/versal_net_common.c
+++ b/plat/xilinx/versal_net/aarch64/versal_net_common.c
@@ -34,7 +34,7 @@
{ 0 }
};
-const mmap_region_t *plat_versal_net_get_mmap(void)
+const mmap_region_t *plat_get_mmap(void)
{
return plat_versal_net_mmap;
}
diff --git a/plat/xilinx/versal_net/bl31_versal_net_setup.c b/plat/xilinx/versal_net/bl31_versal_net_setup.c
index 08f79de..56ef27b 100644
--- a/plat/xilinx/versal_net/bl31_versal_net_setup.c
+++ b/plat/xilinx/versal_net/bl31_versal_net_setup.c
@@ -131,6 +131,19 @@
}
INFO("BL31: PLM to TF-A handover success\n");
+
+ /*
+ * The BL32 load address is indicated as 0x0 in the handoff
+ * parameters, which is different from the default/user-provided
+ * load address of 0x60000000 but the flags are correctly
+ * configured. Consequently, in this scenario, set the PC
+ * to the requested BL32_BASE address.
+ */
+
+ /* TODO: Remove the following check once this is fixed from PLM */
+ if (bl32_image_ep_info.pc == 0 && bl32_image_ep_info.spsr != 0) {
+ bl32_image_ep_info.pc = (uintptr_t)BL32_BASE;
+ }
} else {
INFO("BL31: setting up default configs\n");
@@ -213,6 +226,8 @@
if (rc != 0) {
panic();
}
+
+ console_switch_state(CONSOLE_FLAG_RUNTIME);
}
/*
@@ -234,6 +249,6 @@
{0}
};
- setup_page_tables(bl_regions, plat_versal_net_get_mmap());
+ setup_page_tables(bl_regions, plat_get_mmap());
enable_mmu(0);
}
diff --git a/plat/xilinx/versal_net/include/plat_private.h b/plat/xilinx/versal_net/include/plat_private.h
index 3eb8052..9cd8636 100644
--- a/plat/xilinx/versal_net/include/plat_private.h
+++ b/plat/xilinx/versal_net/include/plat_private.h
@@ -20,7 +20,7 @@
void versal_net_config_setup(void);
uint32_t get_uart_clk(void);
-const mmap_region_t *plat_versal_net_get_mmap(void);
+const mmap_region_t *plat_get_mmap(void);
void plat_versal_net_gic_driver_init(void);
void plat_versal_net_gic_init(void);
diff --git a/plat/xilinx/versal_net/include/versal_net_def.h b/plat/xilinx/versal_net/include/versal_net_def.h
index a53cad9..dd20faa 100644
--- a/plat/xilinx/versal_net/include/versal_net_def.h
+++ b/plat/xilinx/versal_net/include/versal_net_def.h
@@ -128,6 +128,7 @@
* IRQ constants
******************************************************************************/
#define VERSAL_NET_IRQ_SEC_PHY_TIMER U(29)
+#define ARM_IRQ_SEC_PHY_TIMER 29
/*******************************************************************************
* UART related constants
diff --git a/plat/xilinx/versal_net/platform.mk b/plat/xilinx/versal_net/platform.mk
index fb229bb..f299189 100644
--- a/plat/xilinx/versal_net/platform.mk
+++ b/plat/xilinx/versal_net/platform.mk
@@ -69,6 +69,9 @@
$(eval $(call add_define,XILINX_OF_BOARD_DTB_ADDR))
endif
+# enable assert() for release/debug builds
+ENABLE_ASSERTIONS := 1
+
PLAT_INCLUDES := -Iinclude/plat/arm/common/ \
-Iplat/xilinx/common/include/ \
-Iplat/xilinx/common/ipi_mailbox_service/ \
diff --git a/plat/xilinx/versal_net/tsp/tsp-versal_net.mk b/plat/xilinx/versal_net/tsp/tsp-versal_net.mk
new file mode 100644
index 0000000..87638ab
--- /dev/null
+++ b/plat/xilinx/versal_net/tsp/tsp-versal_net.mk
@@ -0,0 +1,13 @@
+#
+# Copyright (c) 2023, Advanced Micro Devices, Inc. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+
+# TSP source files specific to Versal NET platform
+
+PLAT_XILINX_COMMON := plat/xilinx/common/
+
+include ${PLAT_XILINX_COMMON}/tsp/tsp.mk
+
+BL32_SOURCES += plat/xilinx/versal_net/plat_topology.c \
+ ${XLAT_TABLES_LIB_SRCS}
diff --git a/plat/xilinx/zynqmp/aarch64/zynqmp_common.c b/plat/xilinx/zynqmp/aarch64/zynqmp_common.c
index e1c8ee8..dba1734 100644
--- a/plat/xilinx/zynqmp/aarch64/zynqmp_common.c
+++ b/plat/xilinx/zynqmp/aarch64/zynqmp_common.c
@@ -27,13 +27,18 @@
* This doesn't include TZRAM as the 'mem_layout' argument passed to
* configure_mmu_elx() will give the available subset of that,
*/
-const mmap_region_t plat_arm_mmap[] = {
+const mmap_region_t plat_zynqmp_mmap[] = {
{ DEVICE0_BASE, DEVICE0_BASE, DEVICE0_SIZE, MT_DEVICE | MT_RW | MT_SECURE },
{ DEVICE1_BASE, DEVICE1_BASE, DEVICE1_SIZE, MT_DEVICE | MT_RW | MT_SECURE },
{ CRF_APB_BASE, CRF_APB_BASE, CRF_APB_SIZE, MT_DEVICE | MT_RW | MT_SECURE },
{0}
};
+const mmap_region_t *plat_get_mmap(void)
+{
+ return plat_zynqmp_mmap;
+}
+
static uint32_t zynqmp_get_silicon_ver(void)
{
static unsigned int ver;
diff --git a/plat/xilinx/zynqmp/bl31_zynqmp_setup.c b/plat/xilinx/zynqmp/bl31_zynqmp_setup.c
index 8018535..baf6717 100644
--- a/plat/xilinx/zynqmp/bl31_zynqmp_setup.c
+++ b/plat/xilinx/zynqmp/bl31_zynqmp_setup.c
@@ -190,6 +190,8 @@
#endif
custom_runtime_setup();
+
+ console_switch_state(CONSOLE_FLAG_RUNTIME);
}
/*
@@ -219,6 +221,6 @@
custom_mmap_add();
- setup_page_tables(bl_regions, plat_arm_get_mmap());
+ setup_page_tables(bl_regions, plat_get_mmap());
enable_mmu_el3(0);
}
diff --git a/plat/xilinx/zynqmp/include/plat_private.h b/plat/xilinx/zynqmp/include/plat_private.h
index dda005a..afa102d 100644
--- a/plat/xilinx/zynqmp/include/plat_private.h
+++ b/plat/xilinx/zynqmp/include/plat_private.h
@@ -13,9 +13,12 @@
#include <bl31/interrupt_mgmt.h>
#include <common/bl_common.h>
#include <drivers/cadence/cdns_uart.h>
+#include <lib/xlat_tables/xlat_tables.h>
void zynqmp_config_setup(void);
+const mmap_region_t *plat_get_mmap(void);
+
uint32_t zynqmp_calc_core_pos(u_register_t mpidr);
/* ZynqMP specific functions */
diff --git a/plat/xilinx/zynqmp/include/zynqmp_def.h b/plat/xilinx/zynqmp/include/zynqmp_def.h
index 38f2d9b..d715ce2 100644
--- a/plat/xilinx/zynqmp/include/zynqmp_def.h
+++ b/plat/xilinx/zynqmp/include/zynqmp_def.h
@@ -221,20 +221,6 @@
#define IOU_TAPDLY_BYPASS U(0XFF180390)
#define TAP_DELAY_MASK U(0x7)
-/* SGMII mode */
-#define IOU_GEM_CTRL U(0xFF180360)
-#define IOU_GEM_CLK_CTRL U(0xFF180308)
-#define SGMII_SD_MASK U(0x3)
-#define SGMII_SD_OFFSET U(2)
-#define SGMII_PCS_SD_0 U(0x0)
-#define SGMII_PCS_SD_1 U(0x1)
-#define SGMII_PCS_SD_PHY U(0x2)
-#define GEM_SGMII_MASK U(0x4)
-#define GEM_CLK_CTRL_MASK U(0xF)
-#define GEM_CLK_CTRL_OFFSET U(5)
-#define GEM_RX_SRC_SEL_GTR U(0x1)
-#define GEM_SGMII_MODE U(0x4)
-
/* SD DLL reset */
#define ZYNQMP_SD_DLL_CTRL U(0xFF180358)
#define ZYNQMP_SD0_DLL_RST_MASK U(0x00000004)
diff --git a/plat/xilinx/zynqmp/platform.mk b/plat/xilinx/zynqmp/platform.mk
index b778932..e266615 100644
--- a/plat/xilinx/zynqmp/platform.mk
+++ b/plat/xilinx/zynqmp/platform.mk
@@ -49,6 +49,10 @@
ifdef ZYNQMP_ATF_MEM_PROGBITS_SIZE
$(eval $(call add_define,ZYNQMP_ATF_MEM_PROGBITS_SIZE))
endif
+
+ # enable assert() when TF-A runs from DDR memory.
+ ENABLE_ASSERTIONS := 1
+
endif
ifdef ZYNQMP_BL32_MEM_BASE
diff --git a/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.c b/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.c
index e812ad6..dd21499 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.c
+++ b/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.c
@@ -174,67 +174,6 @@
}
/**
- * pm_ioctl_set_sgmii_mode() - Set SGMII mode for the GEM device.
- * @nid: Node ID of the device.
- * @value: Enable/Disable.
- *
- * This function enable/disable SGMII mode for the GEM device.
- * While enabling SGMII mode, it also ties the GEM PCS Signal
- * Detect to 1 and selects EMIO for RX clock generation.
- *
- * Return: Returns status, either success or error+reason.
- *
- */
-static enum pm_ret_status pm_ioctl_set_sgmii_mode(enum pm_node_id nid,
- uint32_t value)
-{
- uint32_t val, mask, shift;
- enum pm_ret_status ret;
-
- if (value != PM_SGMII_DISABLE && value != PM_SGMII_ENABLE) {
- return PM_RET_ERROR_ARGS;
- }
-
- switch (nid) {
- case NODE_ETH_0:
- shift = 0;
- break;
- case NODE_ETH_1:
- shift = 1;
- break;
- case NODE_ETH_2:
- shift = 2;
- break;
- case NODE_ETH_3:
- shift = 3;
- break;
- default:
- return PM_RET_ERROR_ARGS;
- }
-
- if (value == PM_SGMII_DISABLE) {
- mask = GEM_SGMII_MASK << GEM_CLK_CTRL_OFFSET * shift;
- ret = pm_mmio_write(IOU_GEM_CLK_CTRL, mask, 0U);
- } else {
- /* Tie the GEM PCS Signal Detect to 1 */
- mask = SGMII_SD_MASK << SGMII_SD_OFFSET * shift;
- val = SGMII_PCS_SD_1 << SGMII_SD_OFFSET * shift;
- ret = pm_mmio_write(IOU_GEM_CTRL, mask, val);
- if (ret != PM_RET_SUCCESS) {
- return ret;
- }
-
- /* Set the GEM to SGMII mode */
- mask = GEM_CLK_CTRL_MASK << GEM_CLK_CTRL_OFFSET * shift;
- val = GEM_RX_SRC_SEL_GTR | GEM_SGMII_MODE;
- val <<= GEM_CLK_CTRL_OFFSET * shift;
- ret = pm_mmio_write(IOU_GEM_CLK_CTRL, mask, val);
- }
-
- return ret;
-}
-
-/**
* pm_ioctl_sd_dll_reset() - Reset DLL logic.
* @nid: Node ID of the device.
* @type: Reset type.
@@ -684,9 +623,6 @@
case IOCTL_SET_TAPDELAY_BYPASS:
ret = pm_ioctl_set_tapdelay_bypass(arg1, arg2);
break;
- case IOCTL_SET_SGMII_MODE:
- ret = pm_ioctl_set_sgmii_mode(nid, arg1);
- break;
case IOCTL_SD_DLL_RESET:
ret = pm_ioctl_sd_dll_reset(nid, arg1);
break;
@@ -752,7 +688,6 @@
IOCTL_RPU_BOOT_ADDR_CONFIG,
IOCTL_TCM_COMB_CONFIG,
IOCTL_SET_TAPDELAY_BYPASS,
- IOCTL_SET_SGMII_MODE,
IOCTL_SD_DLL_RESET,
IOCTL_SET_SD_TAPDELAY,
IOCTL_SET_PLL_FRAC_MODE,
diff --git a/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.h b/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.h
index 6b094db..bf94b7c 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.h
+++ b/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.h
@@ -36,10 +36,6 @@
#define PM_TAPDELAY_BYPASS_DISABLE 0U
#define PM_TAPDELAY_BYPASS_ENABLE 1U
-//sgmii mode
-#define PM_SGMII_DISABLE 0U
-#define PM_SGMII_ENABLE 1U
-
enum tap_delay_type {
PM_TAPDELAY_INPUT,
PM_TAPDELAY_OUTPUT,
diff --git a/plat/xilinx/zynqmp/pm_service/zynqmp_pm_api_sys.c b/plat/xilinx/zynqmp/pm_service/zynqmp_pm_api_sys.c
index 0199597..6b42055 100644
--- a/plat/xilinx/zynqmp/pm_service/zynqmp_pm_api_sys.c
+++ b/plat/xilinx/zynqmp/pm_service/zynqmp_pm_api_sys.c
@@ -163,10 +163,6 @@
.api_id = PM_MMIO_WRITE,
},
{
- .id = IOCTL_SET_SGMII_MODE,
- .api_id = PM_MMIO_WRITE,
- },
- {
.id = IOCTL_SD_DLL_RESET,
.api_id = PM_MMIO_WRITE,
},
diff --git a/plat/xilinx/zynqmp/tsp/tsp-zynqmp.mk b/plat/xilinx/zynqmp/tsp/tsp-zynqmp.mk
index f91a04c..1d6366f 100644
--- a/plat/xilinx/zynqmp/tsp/tsp-zynqmp.mk
+++ b/plat/xilinx/zynqmp/tsp/tsp-zynqmp.mk
@@ -4,5 +4,7 @@
# SPDX-License-Identifier: BSD-3-Clause
# TSP source files specific to ZynqMP platform
-BL32_SOURCES += plat/common/aarch64/platform_mp_stack.S \
- plat/xilinx/zynqmp/tsp/tsp_plat_setup.c
+
+PLAT_XILINX_COMMON := plat/xilinx/common/
+
+include ${PLAT_XILINX_COMMON}/tsp/tsp.mk
diff --git a/services/std_svc/errata_abi/errata_abi_main.c b/services/std_svc/errata_abi/errata_abi_main.c
index 38ba638..0b263e5 100644
--- a/services/std_svc/errata_abi/errata_abi_main.c
+++ b/services/std_svc/errata_abi/errata_abi_main.c
@@ -328,8 +328,9 @@
[13] = {2371105, 0x00, 0x20, ERRATA_A710_2371105},
[14] = {2701952, 0x00, 0x21, ERRATA_A710_2701952, \
ERRATA_NON_ARM_INTERCONNECT},
- [15] = {2768515, 0x00, 0x21, ERRATA_A710_2768515},
- [16 ... ERRATA_LIST_END] = UNDEF_ERRATA,
+ [15] = {2742423, 0x00, 0x21, ERRATA_A710_2742423},
+ [16] = {2768515, 0x00, 0x21, ERRATA_A710_2768515},
+ [17 ... ERRATA_LIST_END] = UNDEF_ERRATA,
}
},
#endif /* CORTEX_A710_H_INC */
@@ -350,14 +351,16 @@
[9] = {2242415, 0x00, 0x00, ERRATA_N2_2242415},
[10] = {2280757, 0x00, 0x00, ERRATA_N2_2280757},
[11] = {2326639, 0x00, 0x00, ERRATA_N2_2326639},
- [12] = {2376738, 0x00, 0x03, ERRATA_N2_2376738},
- [13] = {2388450, 0x00, 0x00, ERRATA_N2_2388450},
- [14] = {2728475, 0x00, 0x02, ERRATA_N2_2728475, \
+ [12] = {2340933, 0x00, 0x00, ERRATA_N2_2340933},
+ [13] = {2346952, 0x00, 0x02, ERRATA_N2_2346952},
+ [14] = {2376738, 0x00, 0x00, ERRATA_N2_2376738},
+ [15] = {2388450, 0x00, 0x00, ERRATA_N2_2388450},
+ [16] = {2728475, 0x00, 0x02, ERRATA_N2_2728475, \
ERRATA_NON_ARM_INTERCONNECT},
- [15] = {2743014, 0x00, 0x02, ERRATA_N2_2743014},
- [16] = {2743089, 0x00, 0x02, ERRATA_N2_2743089},
- [17] = {2779511, 0x00, 0x02, ERRATA_N2_2779511},
- [18 ... ERRATA_LIST_END] = UNDEF_ERRATA,
+ [17] = {2743014, 0x00, 0x02, ERRATA_N2_2743014},
+ [18] = {2743089, 0x00, 0x02, ERRATA_N2_2743089},
+ [19] = {2779511, 0x00, 0x02, ERRATA_N2_2779511},
+ [20 ... ERRATA_LIST_END] = UNDEF_ERRATA,
}
},
#endif /* NEOVERSE_N2_H_INC */
@@ -377,8 +380,9 @@
[8] = {2371105, 0x00, 0x20, ERRATA_X2_2371105},
[9] = {2701952, 0x00, 0x21, ERRATA_X2_2701952, \
ERRATA_NON_ARM_INTERCONNECT},
- [10] = {2768515, 0x00, 0x21, ERRATA_X2_2768515},
- [11 ... ERRATA_LIST_END] = UNDEF_ERRATA,
+ [10] = {2742423, 0x00, 0x21, ERRATA_X2_2742423},
+ [11] = {2768515, 0x00, 0x21, ERRATA_X2_2768515},
+ [12 ... ERRATA_LIST_END] = UNDEF_ERRATA,
}
},
#endif /* CORTEX_X2_H_INC */
diff --git a/services/std_svc/rmmd/rmmd_main.c b/services/std_svc/rmmd/rmmd_main.c
index d6d25d8..8b78b13 100644
--- a/services/std_svc/rmmd/rmmd_main.c
+++ b/services/std_svc/rmmd/rmmd_main.c
@@ -125,17 +125,13 @@
pmuv3_enable(ctx);
/*
- * If SME/SME2 is supported and enabled for NS world, then enables SME
- * for Realm world. RMM will save/restore required registers that are
- * shared with SVE/FPU so that Realm can use FPU or SVE.
+ * Enable access to TPIDR2_EL0 if SME/SME2 is enabled for Non Secure world.
*/
if (is_feat_sme_supported()) {
- /* sme_enable() also enables SME2 if supported by hardware */
sme_enable(ctx);
}
}
-#if IMAGE_BL31
static void manage_extensions_realm_per_world(void)
{
if (is_feat_sve_supported()) {
@@ -152,8 +148,15 @@
sys_reg_trace_disable_per_world(&per_world_context[CPU_CONTEXT_REALM]);
}
+ /*
+ * If SME/SME2 is supported and enabled for NS world, then disable trapping
+ * of SME instructions for Realm world. RMM will save/restore required
+ * registers that are shared with SVE/FPU so that Realm can use FPU or SVE.
+ */
+ if (is_feat_sme_supported()) {
+ sme_enable_per_world(&per_world_context[CPU_CONTEXT_REALM]);
+ }
}
-#endif /* IMAGE_BL31 */
/*******************************************************************************
* Jump to the RMM for the first time.
diff --git a/services/std_svc/spmd/spmd.mk b/services/std_svc/spmd/spmd.mk
index 72376f7..e567b53 100644
--- a/services/std_svc/spmd/spmd.mk
+++ b/services/std_svc/spmd/spmd.mk
@@ -4,14 +4,6 @@
# SPDX-License-Identifier: BSD-3-Clause
#
-ifneq (${ARCH},aarch64)
- $(error "Error: SPMD is only supported on aarch64.")
-endif
-
-ifneq (${ENABLE_SME_FOR_NS},0)
- $(error "Error: SPMD is not compatible with ENABLE_SME_FOR_NS")
-endif
-
SPMD_SOURCES += $(addprefix services/std_svc/spmd/, \
${ARCH}/spmd_helpers.S \
spmd_pm.c \