feat(mops): enable FEAT_MOPS in EL3 when INIT_UNUSED_NS_EL2=1
FEAT_MOPS, mandatory from Arm v8.8, is typically managed in EL2.
However, in configurations where NS_EL2 is not enabled,
EL3 must set the HCRX_EL2.MSCEn bit to 1 to enable the feature.
This patch ensures FEAT_MOPS is enabled by setting HCRX_EL2.MSCEn to 1.
Change-Id: Ic4960e0cc14a44279156b79ded50de475b3b21c5
Signed-off-by: Arvind Ram Prakash <arvind.ramprakash@arm.com>
diff --git a/Makefile b/Makefile
index a286a4a..de1d71e 100644
--- a/Makefile
+++ b/Makefile
@@ -958,6 +958,10 @@
ifeq (${ARCH_FEATURE_AVAILABILITY},1)
$(error "ARCH_FEATURE_AVAILABILITY cannot be used with ARCH=aarch32")
endif
+ # FEAT_MOPS is only supported on AArch64
+ ifneq (${ENABLE_FEAT_MOPS},0)
+ $(error "ENABLE_FEAT_MOPS cannot be used with ARCH=aarch32")
+ endif
endif #(ARCH=aarch32)
ifneq (${ENABLE_FEAT_FPMR},0)
@@ -1284,6 +1288,7 @@
ENABLE_FEAT_FPMR \
ENABLE_FEAT_HCX \
ENABLE_FEAT_LS64_ACCDATA \
+ ENABLE_FEAT_MOPS \
ENABLE_FEAT_MTE2 \
ENABLE_FEAT_PAN \
ENABLE_FEAT_RNG \
@@ -1462,6 +1467,7 @@
ENABLE_FEAT_SCTLR2 \
ENABLE_FEAT_D128 \
ENABLE_FEAT_GCS \
+ ENABLE_FEAT_MOPS \
ENABLE_FEAT_MTE2 \
FEATURE_DETECTION \
TWED_DELAY \
diff --git a/common/feat_detect.c b/common/feat_detect.c
index 0f6be9f..821ccb8 100644
--- a/common/feat_detect.c
+++ b/common/feat_detect.c
@@ -286,6 +286,12 @@
ID_AA64PFR2_EL1_FPMR_MASK);
}
+static unsigned int read_feat_mops_id_field(void)
+{
+ return ISOLATE_FIELD(read_id_aa64isar2_el1(), ID_AA64ISAR2_EL1_MOPS_SHIFT,
+ ID_AA64ISAR2_EL1_MOPS_MASK);
+}
+
/***********************************************************************************
* TF-A supports many Arm architectural features starting from arch version
* (8.0 till 8.7+). These features are mostly enabled through build flags. This
@@ -343,6 +349,8 @@
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_FEAT_MOPS, read_feat_mops_id_field(),
+ "MOPS", 1, 1);
check_feature(ENABLE_FEAT_MPAM, read_feat_mpam_version(),
"MPAM", 1, 17);
check_feature(CTX_INCLUDE_NEVE_REGS, read_feat_nv_id_field(),
diff --git a/docs/getting_started/build-options.rst b/docs/getting_started/build-options.rst
index a8184e6..58321e7 100644
--- a/docs/getting_started/build-options.rst
+++ b/docs/getting_started/build-options.rst
@@ -378,6 +378,16 @@
flag can take the values 0 to 2, to align with the ``ENABLE_FEAT``
mechanism. Default value is ``0``.
+- ``ENABLE_FEAT_MOPS``: Numeric value to enable FEAT_MOPS (Standardization
+ of memory operations) when INIT_UNUSED_NS_EL2=1.
+ This feature is mandatory from v8.8 and enabling of FEAT_MOPS does not
+ require any settings from EL3 as the controls are present in EL2 registers
+ (HCRX_EL2.{MSCEn,MCE2} and SCTLR_EL2.MSCEn) and in most configurations
+ we expect EL2 to be present. But in case of INIT_UNUSED_NS_EL2=1 ,
+ EL3 should configure the EL2 registers. This flag
+ can take values 0 to 2, to align with the ``ENABLE_FEAT`` mechanism.
+ Default value is ``0``.
+
- ``ENABLE_FEAT_MTE2``: Numeric value to enable Memory Tagging Extension2
if the platform wants to use this feature and MTE2 is enabled at ELX.
This flag can take values 0 to 2, to align with the ``ENABLE_FEAT``
diff --git a/include/arch/aarch64/arch.h b/include/arch/aarch64/arch.h
index fefee4a..4d26153 100644
--- a/include/arch/aarch64/arch.h
+++ b/include/arch/aarch64/arch.h
@@ -317,6 +317,10 @@
/* ID_AA64ISAR2_EL1 definitions */
#define ID_AA64ISAR2_EL1 S3_0_C0_C6_2
+#define ID_AA64ISAR2_EL1_MOPS_SHIFT U(16)
+#define ID_AA64ISAR2_EL1_MOPS_MASK ULL(0xf)
+
+#define MOPS_IMPLEMENTED ULL(0x1)
/* ID_AA64PFR2_EL1 definitions */
#define ID_AA64PFR2_EL1 S3_0_C0_C4_2
diff --git a/include/arch/aarch64/arch_features.h b/include/arch/aarch64/arch_features.h
index 99c2cdf..1d0a2e0 100644
--- a/include/arch/aarch64/arch_features.h
+++ b/include/arch/aarch64/arch_features.h
@@ -144,6 +144,8 @@
* +----------------------------+
* | FEAT_FPMR |
* +----------------------------+
+ * | FEAT_MOPS |
+ * +----------------------------+
*/
__attribute__((always_inline))
@@ -290,7 +292,10 @@
CREATE_FEATURE_FUNCS(feat_fpmr, id_aa64pfr2_el1, ID_AA64PFR2_EL1_FPMR_SHIFT,
ID_AA64PFR2_EL1_FPMR_MASK, FPMR_IMPLEMENTED,
ENABLE_FEAT_FPMR)
-
+/* FEAT_MOPS */
+CREATE_FEATURE_FUNCS(feat_mops, id_aa64isar2_el1, ID_AA64ISAR2_EL1_MOPS_SHIFT,
+ ID_AA64ISAR2_EL1_MOPS_MASK, MOPS_IMPLEMENTED,
+ ENABLE_FEAT_MOPS)
__attribute__((always_inline))
static inline bool is_feat_sxpie_supported(void)
diff --git a/lib/el3_runtime/aarch64/context_mgmt.c b/lib/el3_runtime/aarch64/context_mgmt.c
index f220d8a..9b97685 100644
--- a/lib/el3_runtime/aarch64/context_mgmt.c
+++ b/lib/el3_runtime/aarch64/context_mgmt.c
@@ -883,6 +883,10 @@
sme_init_el2_unused();
}
+ if (is_feat_mops_supported()) {
+ write_hcrx_el2(read_hcrx_el2() | HCRX_EL2_MSCEn_BIT);
+ }
+
#if ENABLE_PAUTH
enable_pauth_el2();
#endif /* ENABLE_PAUTH */
diff --git a/make_helpers/arch_features.mk b/make_helpers/arch_features.mk
index a1db0b8..3c9e136 100644
--- a/make_helpers/arch_features.mk
+++ b/make_helpers/arch_features.mk
@@ -83,6 +83,7 @@
# Enable the features which are mandatory from ARCH version 8.8 and upwards.
ifeq "8.8" "$(word 1, $(sort 8.8 $(ARM_ARCH_MAJOR).$(ARM_ARCH_MINOR)))"
+armv8-8-a-feats := ENABLE_FEAT_MOPS
# 8.7 Compliant
armv8-8-a-feats += ${armv8-7-a-feats}
FEAT_LIST := ${armv8-8-a-feats}
@@ -213,6 +214,14 @@
ENABLE_FEAT_HCX ?= 0
#----
+# 8.8
+#----
+
+# Flag to enable FEAT_MOPS (Standardization of Memory operations)
+# when INIT_UNUSED_NS_EL2 = 1
+ENABLE_FEAT_MOPS ?= 0
+
+#----
# 8.9
#----
diff --git a/plat/arm/board/fvp/platform.mk b/plat/arm/board/fvp/platform.mk
index 08fbfee..241003a 100644
--- a/plat/arm/board/fvp/platform.mk
+++ b/plat/arm/board/fvp/platform.mk
@@ -58,6 +58,7 @@
ENABLE_TRBE_FOR_NS := 2
ENABLE_FEAT_D128 := 2
ENABLE_FEAT_FPMR := 2
+ ENABLE_FEAT_MOPS := 2
endif
ENABLE_SYS_REG_TRACE_FOR_NS := 2