]> git.baikalelectronics.ru Git - arm-tf.git/commitdiff
refactor(spe): enable FEAT_SPE for FEAT_STATE_CHECKED
authorAndre Przywara <andre.przywara@arm.com>
Thu, 17 Nov 2022 16:42:09 +0000 (16:42 +0000)
committerAndre Przywara <andre.przywara@arm.com>
Mon, 20 Mar 2023 13:37:36 +0000 (13:37 +0000)
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>
Makefile
bl31/bl31.mk
docs/getting_started/build-options.rst
include/arch/aarch32/arch_features.h
include/arch/aarch64/arch_features.h
include/lib/extensions/spe.h
lib/el3_runtime/aarch64/context_mgmt.c
lib/extensions/spe/spe.c
make_helpers/defaults.mk
plat/arm/board/arm_fpga/fpga_bl31_setup.c
plat/arm/board/fvp/fvp_pm.c

index 16279b603d08fde60fc9d97fc79715f95244dbd4..797b2cfeb21b0daa32c2afbae6f55b6d0bb7cb7c 100644 (file)
--- 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 \
index b639920e59970e0f8f5b9843e73bef05bce5348c..e000f4f7b4d55871397724b431b00fe178834adf 100644 (file)
@@ -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
 
index 9241c3912b477d0b069732721a06bec51151986c..9415871df09c216ddf084932ee2d935a68ffc2df 100644 (file)
@@ -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
index a5a5e278b5580331b7276fc5df9151288c8f1dbb..12df6da4b2c53403c2075494c8d16f5b0d0d86d7 100644 (file)
@@ -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 */
index 582aed12fbbd52646a8fd9f114cc38b8676becf3..58b37521b03b43cded5b1c258c6d5c1d15eb5c5f 100644 (file)
@@ -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;
 }
 
 /*******************************************************************************
index d4b925fe4fa199dad3c4caf31a85429c4bf82047..d443f18fb5e68964f2ea038ee9a557b8a6554cfb 100644 (file)
@@ -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 */
index 50fddc502245a6b922d618f9f60c9aeda94144df..c5f20ad350cd10a58baefbffa7034dbf4ee4c3f9 100644 (file)
@@ -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);
index d747efcd7643102d825eeb7f781142c367fcdead..b1fe39f5892fc4d56bbea21341201ce609f8bd5a 100644 (file)
@@ -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 */
index 63ac82e6d10e2ec4a08b112af603b770b0e8b21a..b928fcf9879635e6e9653442caeb231693e789bc 100644 (file)
@@ -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)
index e1b3abb2828e00bc16f42437eb874366e1a080fc..5cc1e764587a755e11726a7162481e0724890390 100644 (file)
@@ -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");
 
index 9d93862302709bd563233c08d76f342a0a475712..3d53388e4ccc162384ef458a29a123e6e6ab2ff0 100644 (file)
@@ -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();