feat(mte): add mte2 feat

Add support for feat mte2. tfsr_el2 is available only with mte2,
however currently its context_save/restore is done with mte rather than
mte2, so introduce 'is_feat_mte2_supported' to check mte2.

Change-Id: I108d9989a8f5b4d1d2f3b9865a914056fa566cf2
Signed-off-by: Govindraj Raja <govindraj.raja@arm.com>
diff --git a/Makefile b/Makefile
index c1448fa..f324ebc 100644
--- a/Makefile
+++ b/Makefile
@@ -1246,6 +1246,7 @@
 	ENABLE_FEAT_FGT \
 	ENABLE_FEAT_HCX \
 	ENABLE_FEAT_MTE \
+	ENABLE_FEAT_MTE2 \
 	ENABLE_FEAT_PAN \
 	ENABLE_FEAT_RNG \
 	ENABLE_FEAT_RNG_TRAP \
@@ -1406,6 +1407,7 @@
 	ENABLE_FEAT_S1POE \
 	ENABLE_FEAT_GCS \
 	ENABLE_FEAT_MTE \
+	ENABLE_FEAT_MTE2 \
 	ENABLE_FEAT_MTE_PERM \
 	FEATURE_DETECTION \
 	TWED_DELAY \
diff --git a/bl32/tsp/tsp_main.c b/bl32/tsp/tsp_main.c
index b8d336f..d8031f9 100644
--- a/bl32/tsp/tsp_main.c
+++ b/bl32/tsp/tsp_main.c
@@ -238,13 +238,13 @@
 	service_arg0 = (uint64_t)service_args;
 	service_arg1 = (uint64_t)(service_args >> 64U);
 
-#if ENABLE_FEAT_MTE
 	/*
 	 * Write a dummy value to an MTE register, to simulate usage in the
 	 * secure world
 	 */
-	write_gcr_el1(0x99);
-#endif
+	if (is_feat_mte_supported()) {
+		write_gcr_el1(0x99);
+	}
 
 	/* Determine the function to perform based on the function ID */
 	switch (TSP_BARE_FID(func)) {
diff --git a/common/feat_detect.c b/common/feat_detect.c
index 57d6ae0..7a2f0d7 100644
--- a/common/feat_detect.c
+++ b/common/feat_detect.c
@@ -169,6 +169,8 @@
 	/* v8.5 features */
 	check_feature(ENABLE_FEAT_MTE, read_feat_mte_id_field(), "MTE",
 		      MTE_IMPLEMENTED_EL0, MTE_IMPLEMENTED_ASY);
+	check_feature(ENABLE_FEAT_MTE2, read_feat_mte_id_field(), "MTE2",
+		      MTE_IMPLEMENTED_ELX, MTE_IMPLEMENTED_ASY);
 	check_feature(ENABLE_FEAT_RNG, read_feat_rng_id_field(), "RNG", 1, 1);
 	read_feat_bti();
 	read_feat_rng_trap();
diff --git a/docs/design/firmware-design.rst b/docs/design/firmware-design.rst
index bddff16..ba97264 100644
--- a/docs/design/firmware-design.rst
+++ b/docs/design/firmware-design.rst
@@ -2767,13 +2767,9 @@
 -  Branch Target Identification feature is selected by ``BRANCH_PROTECTION``
    option set to 1. This option defaults to 0.
 
--  Memory Tagging Extension feature is unconditionally enabled for both worlds
-   (at EL0 and S-EL0) if it is only supported at EL0. If instead it is
-   implemented at all ELs, it is unconditionally enabled for only the normal
-   world. To enable it for the secure world as well, the build option
-   ``ENABLE_FEAT_MTE`` is required. If the hardware does not implement
-   MTE support at all, it is always disabled, no matter what build options
-   are used.
+-  Memory Tagging Extension feature is unconditionally enabled for both worlds.
+   To enable MTE at EL0 use ``ENABLE_FEAT_MTE`` is required and to enable MTE at
+   ELX ``ENABLE_FEAT_MTE2`` is required.
 
 Armv7-A
 ~~~~~~~
diff --git a/docs/getting_started/build-options.rst b/docs/getting_started/build-options.rst
index cc20261..16522bd 100644
--- a/docs/getting_started/build-options.rst
+++ b/docs/getting_started/build-options.rst
@@ -341,9 +341,14 @@
    mechanism. Default value is ``0``.
 
 -  ``ENABLE_FEAT_MTE``: Numeric value to enable Memory Tagging Extension
-   if the platform wants to use this feature in the Secure world and MTE is
-   enabled at ELX. This flag can take values 0 to 2, to align with the
-   ``ENABLE_FEAT`` mechanism. Default value is ``0``.
+   if the platform wants to use this feature at EL0 ``ENABLE_FEAT_MTE`` is
+   required. This flag can take values 0 to 2, to align with the ``ENABLE_FEAT``
+   feature detection 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``
+   mechanism. Default value is ``0``.
 
 -  ``ENABLE_FEAT_MTE_PERM``: Numeric value to enable support for
    ``FEAT_MTE_PERM``, which introduces Allocation tag access permission to
diff --git a/include/arch/aarch32/arch_features.h b/include/arch/aarch32/arch_features.h
index a2063f1..dd9b7ad 100644
--- a/include/arch/aarch32/arch_features.h
+++ b/include/arch/aarch32/arch_features.h
@@ -149,6 +149,7 @@
 static inline bool is_feat_rng_supported(void) { return false; }
 static inline bool is_feat_gcs_supported(void) { return false; }
 static inline bool is_feat_mte_supported(void) { return false; }
+static inline bool is_feat_mte2_supported(void) { return false; }
 static inline bool is_feat_mpam_supported(void) { return false; }
 static inline bool is_feat_hcx_supported(void) { return false; }
 static inline bool is_feat_sve_supported(void) { return false; }
diff --git a/include/arch/aarch64/arch_features.h b/include/arch/aarch64/arch_features.h
index c053c4d..60fb522 100644
--- a/include/arch/aarch64/arch_features.h
+++ b/include/arch/aarch64/arch_features.h
@@ -91,6 +91,8 @@
 
 CREATE_FEATURE_FUNCS(feat_mte, id_aa64pfr1_el1, ID_AA64PFR1_EL1_MTE_SHIFT,
 		     ENABLE_FEAT_MTE)
+CREATE_FEATURE_FUNCS_VER(feat_mte2, read_feat_mte_id_field, MTE_IMPLEMENTED_ELX,
+		     ENABLE_FEAT_MTE2)
 CREATE_FEATURE_FUNCS(feat_sel2, id_aa64pfr0_el1, ID_AA64PFR0_SEL2_SHIFT,
 		     ENABLE_FEAT_SEL2)
 CREATE_FEATURE_FUNCS(feat_twed, id_aa64mmfr1_el1, ID_AA64MMFR1_EL1_TWED_SHIFT,
diff --git a/lib/el3_runtime/aarch64/context_mgmt.c b/lib/el3_runtime/aarch64/context_mgmt.c
index 00c6008..c3b7e78 100644
--- a/lib/el3_runtime/aarch64/context_mgmt.c
+++ b/lib/el3_runtime/aarch64/context_mgmt.c
@@ -1258,7 +1258,7 @@
 
 	el2_sysregs_context_save_common(el2_sysregs_ctx);
 
-	if (is_feat_mte_supported()) {
+	if (is_feat_mte2_supported()) {
 		write_ctx_reg(el2_sysregs_ctx, CTX_TFSR_EL2, read_tfsr_el2());
 	}
 
@@ -1337,7 +1337,7 @@
 
 	el2_sysregs_context_restore_common(el2_sysregs_ctx);
 
-	if (is_feat_mte_supported()) {
+	if (is_feat_mte2_supported()) {
 		write_tfsr_el2(read_ctx_reg(el2_sysregs_ctx, CTX_TFSR_EL2));
 	}
 
diff --git a/make_helpers/arch_features.mk b/make_helpers/arch_features.mk
index a346dac..643d550 100644
--- a/make_helpers/arch_features.mk
+++ b/make_helpers/arch_features.mk
@@ -319,6 +319,15 @@
         endif
 endif
 ENABLE_FEAT_MTE		                ?=	0
+ENABLE_FEAT_MTE2		        ?=	0
+
+
+# Add a error message to indicate incorrect MTE2 selection without MTE enabled.
+ifneq ($(ENABLE_FEAT_MTE2),0)
+        ifeq ($(ENABLE_FEAT_MTE),0)
+               $(error ENABLE_FEAT_MTE2 is not supported without enabling ENABLE_FEAT_MTE)
+        endif
+endif
 
 #----
 # 8.6