]> git.baikalelectronics.ru Git - arm-tf.git/commitdiff
refactor(cpufeat): enable FEAT_DIT for FEAT_STATE_CHECKED
authorAndre Przywara <andre.przywara@arm.com>
Thu, 26 Jan 2023 16:47:52 +0000 (16:47 +0000)
committerAndre Przywara <andre.przywara@arm.com>
Tue, 25 Apr 2023 14:09:30 +0000 (15:09 +0100)
At the moment we only support FEAT_DIT to be either unconditionally
compiled in, or to be not supported at all.

Add support for runtime detection (ENABLE_DIT=2), by splitting
is_armv8_4_dit_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).

We use ENABLE_DIT in two occassions in assembly code, where we just set
the DIT bit in the DIT system register.
Protect those two cases by reading the CPU ID register when ENABLE_DIT
is set to 2.

Change the FVP platform default to the now supported dynamic
option (=2), so the right decision can be made by the code at runtime.

Change-Id: I506d352f18e23c60db8cdf08edb449f60adbe098
Signed-off-by: Andre Przywara <andre.przywara@arm.com>
bl32/tsp/tsp_main.c
common/feat_detect.c
include/arch/aarch32/arch_features.h
include/arch/aarch64/arch_features.h
include/arch/aarch64/el3_common_macros.S
lib/el3_runtime/aarch64/context.S
plat/arm/board/fvp/platform.mk

index df9903bb258473ebacd801edf966ca772759e29d..0878ea4d34b149bad7da26cd177def2060fdcca9 100644 (file)
@@ -263,7 +263,7 @@ smc_args_t *tsp_smc_handler(uint64_t func,
                results[1] /= service_arg1 ? service_arg1 : 1;
                break;
        case TSP_CHECK_DIT:
-               if (!is_armv8_4_dit_present()) {
+               if (!is_feat_dit_supported()) {
                        ERROR("DIT not supported\n");
                        results[0] = 0;
                        results[1] = 0xffff;
index 98b420a33da8d66b32076c442ad43a79270b5b7d..c8a070392b77623700883aee6e693c05e7b3286f 100644 (file)
@@ -80,16 +80,6 @@ static void read_feat_pauth(void)
 #endif
 }
 
-/************************************************************
- * Feature : FEAT_DIT (Data Independent Timing Instructions)
- ***********************************************************/
-static void read_feat_dit(void)
-{
-#if (ENABLE_FEAT_DIT == FEAT_STATE_ALWAYS)
-       feat_detect_panic(is_armv8_4_feat_dit_present(), "DIT");
-#endif
-}
-
 /************************************************
  * Feature : FEAT_MTE (Memory Tagging Extension)
  ***********************************************/
@@ -178,7 +168,7 @@ void detect_arch_features(void)
        read_feat_pauth();
 
        /* v8.4 features */
-       read_feat_dit();
+       check_feature(ENABLE_FEAT_DIT, read_feat_dit_id_field(), "DIT", 1, 1);
        check_feature(ENABLE_FEAT_AMU, read_feat_amu_id_field(),
                      "AMUv1", 1, 2);
        check_feature(ENABLE_MPAM_FOR_LOWER_ELS, read_feat_mpam_version(),
index 7c25b99ac001027f10e6ada66e35b23873070e2b..62a512b3e5d1051befc496bae6e6488487d5fe0b 100644 (file)
@@ -92,6 +92,24 @@ static inline bool is_feat_sys_reg_trace_supported(void)
        return read_feat_coptrc_id_field() != 0U;
 }
 
+static inline unsigned int read_feat_dit_id_field(void)
+{
+       return ISOLATE_FIELD(read_id_pfr0(), ID_PFR0_DIT);
+}
+
+static inline bool is_feat_dit_supported(void)
+{
+       if (ENABLE_FEAT_DIT == FEAT_STATE_DISABLED) {
+               return false;
+       }
+
+       if (ENABLE_FEAT_DIT == FEAT_STATE_ALWAYS) {
+               return true;
+       }
+
+       return read_feat_dit_id_field() != 0U;
+}
+
 static inline bool is_feat_spe_supported(void)
 {
        /* FEAT_SPE is AArch64 only */
index 16f4fb996e89c40975edfb1d7a8336ca9059565f..40ab82fb01f265b7fe40355f817f48b5b3247414 100644 (file)
@@ -89,12 +89,6 @@ static inline bool is_armv8_3_pauth_present(void)
                is_feat_pacqarma3_present());
 }
 
-static inline bool is_armv8_4_dit_present(void)
-{
-       return ((read_id_aa64pfr0_el1() >> ID_AA64PFR0_DIT_SHIFT) &
-               ID_AA64PFR0_DIT_MASK) == 1U;
-}
-
 static inline bool is_armv8_4_ttst_present(void)
 {
        return ((read_id_aa64mmfr2_el1() >> ID_AA64MMFR2_EL1_ST_SHIFT) &
@@ -515,13 +509,22 @@ static inline bool is_armv8_2_feat_ras_present(void)
                ID_AA64PFR0_RAS_MASK) != ID_AA64PFR0_RAS_NOT_SUPPORTED);
 }
 
-/**************************************************************************
- * Function to identify the presence of FEAT_DIT (Data Independent Timing)
- *************************************************************************/
-static inline bool is_armv8_4_feat_dit_present(void)
+static unsigned int read_feat_dit_id_field(void)
+{
+       return ISOLATE_FIELD(read_id_aa64pfr0_el1(), ID_AA64PFR0_DIT);
+}
+
+static inline bool is_feat_dit_supported(void)
 {
-       return (((read_id_aa64pfr0_el1() >> ID_AA64PFR0_DIT_SHIFT) &
-               ID_AA64PFR0_DIT_MASK) == ID_AA64PFR0_DIT_SUPPORTED);
+       if (ENABLE_FEAT_DIT == FEAT_STATE_DISABLED) {
+               return false;
+       }
+
+       if (ENABLE_FEAT_DIT == FEAT_STATE_ALWAYS) {
+               return true;
+       }
+
+       return read_feat_dit_id_field() != 0U;
 }
 
 static inline unsigned int read_feat_tracever_id_field(void)
index 45a86c10e03ad982ffa6beb9f67377101747c2e8..2dee07d2acd9e0a582a76cee8dffcdcbc9dcddc4 100644 (file)
         * register value for DIT.
         */
 #if ENABLE_FEAT_DIT
-#if ENABLE_ASSERTIONS
+#if ENABLE_ASSERTIONS || ENABLE_FEAT_DIT > 1
        mrs     x0, id_aa64pfr0_el1
        ubfx    x0, x0, #ID_AA64PFR0_DIT_SHIFT, #ID_AA64PFR0_DIT_LENGTH
+#if ENABLE_FEAT_DIT > 1
+       cbz     x0, 1f
+#else
        cmp     x0, #ID_AA64PFR0_DIT_SUPPORTED
        ASM_ASSERT(eq)
+#endif
+
 #endif /* ENABLE_ASSERTIONS */
        mov     x0, #DIT_BIT
        msr     DIT, x0
+1:
 #endif
        .endm
 
index 013a505d448fd1c3027db2ad525933b2cb73a199..769117163e132dfc4ba0550c7a75a447140d31e0 100644 (file)
@@ -553,8 +553,14 @@ endfunc fpregs_context_restore
         * always enable DIT in EL3
         */
 #if ENABLE_FEAT_DIT
+#if ENABLE_FEAT_DIT == 2
+       mrs     x8, id_aa64pfr0_el1
+       and     x8, x8, #(ID_AA64PFR0_DIT_MASK << ID_AA64PFR0_DIT_SHIFT)
+       cbz     x8, 1f
+#endif
        mov     x8, #DIT_BIT
        msr     DIT, x8
+1:
 #endif /* ENABLE_FEAT_DIT */
        .endm /* set_unset_pstate_bits */
 
index e81f1eb6580c9d3e3c2d5ccbe68d06dd15c20b6c..214064bf146a7ae54254700c264649403366e43f 100644 (file)
@@ -70,6 +70,7 @@ endif
 ENABLE_TRBE_FOR_NS             := 2
 ENABLE_SYS_REG_TRACE_FOR_NS    := 2
 ENABLE_FEAT_CSV2_2             := 2
+ENABLE_FEAT_DIT                        := 2
 ENABLE_FEAT_PAN                        := 2
 ENABLE_FEAT_VHE                        := 2
 CTX_INCLUDE_NEVE_REGS          := 2