summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndre Przywara <andre.przywara@arm.com>2022-11-17 16:42:09 +0000
committerAndre Przywara <andre.przywara@arm.com>2023-03-20 13:37:36 +0000
commit6437a09a2db5774438fb1a95c508ed6b0a9f0ef2 (patch)
tree831ab1562452ab1700c3e40684dd871fb4deb083
parent90118bb5c180198db3386c3e1f5be8e32707c2cc (diff)
refactor(spe): enable FEAT_SPE for FEAT_STATE_CHECKED
At the moment we only support FEAT_SPE to be either unconditionally compiled in, or to be not supported at all. Add support for runtime detection (ENABLE_SPE_FOR_NS=2), by splitting is_armv8_2_feat_spe_present() into an ID register reading function and a second function to report the support status. That function considers both build time settings and runtime information (if needed), and is used before we access SPE related registers. Previously SPE was enabled unconditionally for all platforms, change this now to the runtime detection version. Change-Id: I830c094107ce6a398bf1f4aef7ffcb79d4f36552 Signed-off-by: Andre Przywara <andre.przywara@arm.com>
-rw-r--r--Makefile2
-rw-r--r--bl31/bl31.mk2
-rw-r--r--docs/getting_started/build-options.rst7
-rw-r--r--include/arch/aarch32/arch_features.h6
-rw-r--r--include/arch/aarch64/arch_features.h18
-rw-r--r--include/lib/extensions/spe.h10
-rw-r--r--lib/el3_runtime/aarch64/context_mgmt.c6
-rw-r--r--lib/extensions/spe/spe.c17
-rw-r--r--make_helpers/defaults.mk2
-rw-r--r--plat/arm/board/arm_fpga/fpga_bl31_setup.c2
-rw-r--r--plat/arm/board/fvp/fvp_pm.c7
11 files changed, 47 insertions, 32 deletions
diff --git a/Makefile b/Makefile
index 16279b603..797b2cfeb 100644
--- a/Makefile
+++ b/Makefile
@@ -1096,7 +1096,6 @@ $(eval $(call assert_booleans,\
ENABLE_RUNTIME_INSTRUMENTATION \
ENABLE_SME_FOR_NS \
ENABLE_SME_FOR_SWD \
- ENABLE_SPE_FOR_NS \
ENABLE_SVE_FOR_NS \
ENABLE_SVE_FOR_SWD \
ERROR_DEPRECATED \
@@ -1182,6 +1181,7 @@ $(eval $(call assert_numerics,\
ENABLE_FEAT_VHE \
ENABLE_MPAM_FOR_LOWER_ELS \
ENABLE_RME \
+ ENABLE_SPE_FOR_NS \
ENABLE_TRF_FOR_NS \
FW_ENC_STATUS \
NR_OF_FW_BANKS \
diff --git a/bl31/bl31.mk b/bl31/bl31.mk
index b639920e5..e000f4f7b 100644
--- a/bl31/bl31.mk
+++ b/bl31/bl31.mk
@@ -87,7 +87,7 @@ BL31_SOURCES += services/std_svc/trng/trng_main.c \
services/std_svc/trng/trng_entropy_pool.c
endif
-ifeq (${ENABLE_SPE_FOR_NS},1)
+ifneq (${ENABLE_SPE_FOR_NS},0)
BL31_SOURCES += lib/extensions/spe/spe.c
endif
diff --git a/docs/getting_started/build-options.rst b/docs/getting_started/build-options.rst
index 9241c3912..9415871df 100644
--- a/docs/getting_started/build-options.rst
+++ b/docs/getting_started/build-options.rst
@@ -428,10 +428,11 @@ Common build options
handle context switching for SME, SVE, and FPU/SIMD registers to ensure that
no data is leaked to non-secure world. This is experimental. Default is 0.
-- ``ENABLE_SPE_FOR_NS`` : Boolean option to enable Statistical Profiling
+- ``ENABLE_SPE_FOR_NS`` : Numeric value to enable Statistical Profiling
extensions. This is an optional architectural feature for AArch64.
- The default is 1 but is automatically disabled when the target architecture
- is AArch32.
+ This flag can take the values 0 to 2, to align with the ``FEATURE_DETECTION``
+ mechanism. The default is 2 but is automatically disabled when the target
+ architecture is AArch32.
- ``ENABLE_SVE_FOR_NS``: Boolean option to enable Scalable Vector Extension
(SVE) for the Non-secure world only. SVE is an optional architectural feature
diff --git a/include/arch/aarch32/arch_features.h b/include/arch/aarch32/arch_features.h
index a5a5e278b..12df6da4b 100644
--- a/include/arch/aarch32/arch_features.h
+++ b/include/arch/aarch32/arch_features.h
@@ -43,4 +43,10 @@ static inline bool is_feat_trf_supported(void)
return read_feat_trf_id_field() != 0U;
}
+static inline bool is_feat_spe_supported(void)
+{
+ /* FEAT_SPE is AArch64 only */
+ return false;
+}
+
#endif /* ARCH_FEATURES_H */
diff --git a/include/arch/aarch64/arch_features.h b/include/arch/aarch64/arch_features.h
index 582aed12f..58b37521b 100644
--- a/include/arch/aarch64/arch_features.h
+++ b/include/arch/aarch64/arch_features.h
@@ -249,10 +249,22 @@ static inline bool is_armv8_0_feat_csv2_2_present(void)
/**********************************************************************************
* Function to identify the presence of FEAT_SPE (Statistical Profiling Extension)
*********************************************************************************/
-static inline bool is_armv8_2_feat_spe_present(void)
+static inline unsigned int read_feat_spe_id_field(void)
{
- return (((read_id_aa64dfr0_el1() >> ID_AA64DFR0_PMS_SHIFT) &
- ID_AA64DFR0_PMS_MASK) != ID_AA64DFR0_SPE_NOT_SUPPORTED);
+ return ISOLATE_FIELD(read_id_aa64dfr0_el1(), ID_AA64DFR0_PMS);
+}
+
+static inline bool is_feat_spe_supported(void)
+{
+ if (ENABLE_SPE_FOR_NS == FEAT_STATE_DISABLED) {
+ return false;
+ }
+
+ if (ENABLE_SPE_FOR_NS == FEAT_STATE_ALWAYS) {
+ return true;
+ }
+
+ return read_feat_spe_id_field() != 0U;
}
/*******************************************************************************
diff --git a/include/lib/extensions/spe.h b/include/lib/extensions/spe.h
index d4b925fe4..d443f18fb 100644
--- a/include/lib/extensions/spe.h
+++ b/include/lib/extensions/spe.h
@@ -9,8 +9,16 @@
#include <stdbool.h>
-bool spe_supported(void);
+#if ENABLE_SPE_FOR_NS
void spe_enable(bool el2_unused);
void spe_disable(void);
+#else
+void spe_enable(bool el2_unused)
+{
+}
+void spe_disable(void)
+{
+}
+#endif
#endif /* SPE_H */
diff --git a/lib/el3_runtime/aarch64/context_mgmt.c b/lib/el3_runtime/aarch64/context_mgmt.c
index 50fddc502..c5f20ad35 100644
--- a/lib/el3_runtime/aarch64/context_mgmt.c
+++ b/lib/el3_runtime/aarch64/context_mgmt.c
@@ -482,9 +482,9 @@ void cm_setup_context(cpu_context_t *ctx, const entry_point_info_t *ep)
static void manage_extensions_nonsecure(bool el2_unused, cpu_context_t *ctx)
{
#if IMAGE_BL31
-#if ENABLE_SPE_FOR_NS
- spe_enable(el2_unused);
-#endif
+ if (is_feat_spe_supported()) {
+ spe_enable(el2_unused);
+ }
#if ENABLE_AMU
amu_enable(el2_unused, ctx);
diff --git a/lib/extensions/spe/spe.c b/lib/extensions/spe/spe.c
index d747efcd7..b1fe39f58 100644
--- a/lib/extensions/spe/spe.c
+++ b/lib/extensions/spe/spe.c
@@ -7,6 +7,7 @@
#include <stdbool.h>
#include <arch.h>
+#include <arch_features.h>
#include <arch_helpers.h>
#include <lib/el3_runtime/pubsub.h>
#include <lib/extensions/spe.h>
@@ -20,21 +21,10 @@ static inline void psb_csync(void)
__asm__ volatile("hint #17");
}
-bool spe_supported(void)
-{
- uint64_t features;
-
- features = read_id_aa64dfr0_el1() >> ID_AA64DFR0_PMS_SHIFT;
- return (features & ID_AA64DFR0_PMS_MASK) > 0ULL;
-}
-
void spe_enable(bool el2_unused)
{
uint64_t v;
- if (!spe_supported())
- return;
-
if (el2_unused) {
/*
* MDCR_EL2.TPMS (ARM v8.2): Do not trap statistical
@@ -69,9 +59,6 @@ void spe_disable(void)
{
uint64_t v;
- if (!spe_supported())
- return;
-
/* Drain buffered data */
psb_csync();
dsbnsh();
@@ -85,7 +72,7 @@ void spe_disable(void)
static void *spe_drain_buffers_hook(const void *arg)
{
- if (!spe_supported())
+ if (!is_feat_spe_supported())
return (void *)-1;
/* Drain buffered data */
diff --git a/make_helpers/defaults.mk b/make_helpers/defaults.mk
index 63ac82e6d..b928fcf98 100644
--- a/make_helpers/defaults.mk
+++ b/make_helpers/defaults.mk
@@ -355,7 +355,7 @@ V := 0
WARMBOOT_ENABLE_DCACHE_EARLY := 0
# Build option to enable/disable the Statistical Profiling Extensions
-ENABLE_SPE_FOR_NS := 1
+ENABLE_SPE_FOR_NS := 2
# SPE is only supported on AArch64 so disable it on AArch32.
ifeq (${ARCH},aarch32)
diff --git a/plat/arm/board/arm_fpga/fpga_bl31_setup.c b/plat/arm/board/arm_fpga/fpga_bl31_setup.c
index e1b3abb28..5cc1e7645 100644
--- a/plat/arm/board/arm_fpga/fpga_bl31_setup.c
+++ b/plat/arm/board/arm_fpga/fpga_bl31_setup.c
@@ -364,7 +364,7 @@ static void fpga_prepare_dtb(void)
fpga_dtb_update_clock(fdt, system_freq);
/* Check whether we support the SPE PMU. Remove the DT node if not. */
- if (!spe_supported()) {
+ if (!is_feat_spe_supported()) {
int node = fdt_node_offset_by_compatible(fdt, 0,
"arm,statistical-profiling-extension-v1");
diff --git a/plat/arm/board/fvp/fvp_pm.c b/plat/arm/board/fvp/fvp_pm.c
index 9d9386230..3d53388e4 100644
--- a/plat/arm/board/fvp/fvp_pm.c
+++ b/plat/arm/board/fvp/fvp_pm.c
@@ -6,6 +6,7 @@
#include <assert.h>
+#include <arch_features.h>
#include <arch_helpers.h>
#include <common/debug.h>
#include <drivers/arm/gicv3.h>
@@ -53,13 +54,13 @@ static void fvp_cluster_pwrdwn_common(void)
{
uint64_t mpidr = read_mpidr_el1();
-#if ENABLE_SPE_FOR_NS
/*
* On power down we need to disable statistical profiling extensions
* before exiting coherency.
*/
- spe_disable();
-#endif
+ if (is_feat_spe_supported()) {
+ spe_disable();
+ }
/* Disable coherency if this cluster is to be turned off */
fvp_interconnect_disable();