feat(mte): adds feature detection for MTE_PERM

Adds feature detection for v8.9 feature FEAT_MTE_PERM. Adds respective
ID_AA64PFR2_EL1 definitions and ENABLE_FEAT_MTE_PERM define.

Change-Id: If24b42f1207154e639016b0b840b2d91c6ee13d4
Signed-off-by: Maksims Svecovs <maksims.svecovs@arm.com>
Signed-off-by: Harrison Mutai <harrison.mutai@arm.com>
diff --git a/Makefile b/Makefile
index f33a12e..4b96be1 100644
--- a/Makefile
+++ b/Makefile
@@ -1245,6 +1245,7 @@
 	ENABLE_FEAT_S1POE \
 	ENABLE_FEAT_GCS \
 	ENABLE_FEAT_VHE \
+	ENABLE_FEAT_MTE_PERM \
 	ENABLE_MPAM_FOR_LOWER_ELS \
 	ENABLE_RME \
 	ENABLE_SPE_FOR_NS \
@@ -1389,6 +1390,7 @@
 	ENABLE_FEAT_S2POE \
 	ENABLE_FEAT_S1POE \
 	ENABLE_FEAT_GCS \
+	ENABLE_FEAT_MTE_PERM \
 	FEATURE_DETECTION \
 	TWED_DELAY \
 	ENABLE_FEAT_TWED \
diff --git a/common/feat_detect.c b/common/feat_detect.c
index d2e94e9..2aa0c5c 100644
--- a/common/feat_detect.c
+++ b/common/feat_detect.c
@@ -213,6 +213,8 @@
 		      "S2POE", 1, 1);
 	check_feature(ENABLE_FEAT_S1POE, read_feat_s1poe_id_field(),
 		      "S1POE", 1, 1);
+	check_feature(ENABLE_FEAT_MTE_PERM, read_feat_mte_perm_id_field(),
+		      "MTE_PERM", 1, 1);
 
 	/* v9.0 features */
 	check_feature(ENABLE_BRBE_FOR_NS, read_feat_brbe_id_field(),
diff --git a/docs/getting_started/build-options.rst b/docs/getting_started/build-options.rst
index 276daa4..47fd450 100644
--- a/docs/getting_started/build-options.rst
+++ b/docs/getting_started/build-options.rst
@@ -308,6 +308,13 @@
    flag can take the values 0 to 2, to align  with the ``FEATURE_DETECTION``
    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
+   memory region attributes. ``FEAT_MTE_PERM`` is a optional architectural
+   feature available from v8.9 and upwards.  This flag can take the values 0 to
+   2, to align  with the ``FEATURE_DETECTION`` mechanism. Default value is
+   ``0``.
+
 -  ``ENABLE_FEAT_PAN``: Numeric value to enable the ``FEAT_PAN`` (Privileged
    Access Never) extension. ``FEAT_PAN`` adds a bit to PSTATE, generating a
    permission fault for any privileged data access from EL1/EL2 to virtual
diff --git a/include/arch/aarch64/arch.h b/include/arch/aarch64/arch.h
index 5dbcd0a..698fad4 100644
--- a/include/arch/aarch64/arch.h
+++ b/include/arch/aarch64/arch.h
@@ -275,6 +275,9 @@
 /* ID_AA64ISAR2_EL1 definitions */
 #define ID_AA64ISAR2_EL1		S3_0_C0_C6_2
 
+/* ID_AA64PFR2_EL1 definitions */
+#define ID_AA64PFR2_EL1			S3_0_C0_C4_2
+
 #define ID_AA64ISAR2_GPA3_SHIFT		U(8)
 #define ID_AA64ISAR2_GPA3_MASK		ULL(0xf)
 
@@ -402,6 +405,16 @@
 #define ID_AA64PFR1_EL1_RNG_TRAP_SUPPORTED	ULL(0x1)
 #define ID_AA64PFR1_EL1_RNG_TRAP_NOT_SUPPORTED	ULL(0x0)
 
+/* ID_AA64PFR2_EL1 definitions */
+#define ID_AA64PFR2_EL1_MTEPERM_SHIFT		U(0)
+#define ID_AA64PFR2_EL1_MTEPERM_MASK		ULL(0xf)
+
+#define ID_AA64PFR2_EL1_MTESTOREONLY_SHIFT	U(4)
+#define ID_AA64PFR2_EL1_MTESTOREONLY_MASK	ULL(0xf)
+
+#define ID_AA64PFR2_EL1_MTEFAR_SHIFT		U(8)
+#define ID_AA64PFR2_EL1_MTEFAR_MASK		ULL(0xf)
+
 #define VDISR_EL2				S3_4_C12_C1_1
 #define VSESR_EL2				S3_4_C5_C2_3
 
diff --git a/include/arch/aarch64/arch_features.h b/include/arch/aarch64/arch_features.h
index 9d71987..9f11f15 100644
--- a/include/arch/aarch64/arch_features.h
+++ b/include/arch/aarch64/arch_features.h
@@ -148,6 +148,11 @@
 	return ISOLATE_FIELD(read_id_aa64mmfr0_el1(), ID_AA64MMFR0_EL1_FGT);
 }
 
+static unsigned int read_feat_mte_perm_id_field(void)
+{
+	return ISOLATE_FIELD(read_id_aa64pfr2_el1(), ID_AA64PFR2_EL1_MTEPERM);
+}
+
 static inline bool is_feat_fgt_supported(void)
 {
 	if (ENABLE_FEAT_FGT == FEAT_STATE_DISABLED) {
@@ -161,6 +166,19 @@
 	return read_feat_fgt_id_field() != 0U;
 }
 
+static inline bool is_feat_mte_perm_supported(void)
+{
+	if (ENABLE_FEAT_MTE_PERM == FEAT_STATE_DISABLED) {
+		return false;
+	}
+
+	if (ENABLE_FEAT_MTE_PERM == FEAT_STATE_ALWAYS) {
+		return true;
+	}
+
+	return read_feat_mte_perm_id_field() != 0U;
+}
+
 static unsigned int read_feat_ecv_id_field(void)
 {
 	return ISOLATE_FIELD(read_id_aa64mmfr0_el1(), ID_AA64MMFR0_EL1_ECV);
diff --git a/include/arch/aarch64/arch_helpers.h b/include/arch/aarch64/arch_helpers.h
index 5b3d4c2..3121079 100644
--- a/include/arch/aarch64/arch_helpers.h
+++ b/include/arch/aarch64/arch_helpers.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2022, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2023, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -269,6 +269,7 @@
 DEFINE_RENAME_IDREG_READ_FUNC(id_aa64isar2_el1, ID_AA64ISAR2_EL1)
 DEFINE_IDREG_READ_FUNC(id_aa64pfr0_el1)
 DEFINE_IDREG_READ_FUNC(id_aa64pfr1_el1)
+DEFINE_RENAME_IDREG_READ_FUNC(id_aa64pfr2_el1, ID_AA64PFR2_EL1)
 DEFINE_IDREG_READ_FUNC(id_aa64dfr0_el1)
 DEFINE_IDREG_READ_FUNC(id_afr0_el1)
 DEFINE_SYSREG_READ_FUNC(CurrentEl)
diff --git a/make_helpers/defaults.mk b/make_helpers/defaults.mk
index f9077eb..a065039 100644
--- a/make_helpers/defaults.mk
+++ b/make_helpers/defaults.mk
@@ -191,6 +191,9 @@
 # Flag to enable access to Guarded Control Stack (FEAT_GCS)
 ENABLE_FEAT_GCS			:= 0
 
+# Flag to enable NoTagAccess memory region attribute for stage 2 of translation.
+ENABLE_FEAT_MTE_PERM		:= 0
+
 # By default BL31 encryption disabled
 ENCRYPT_BL31			:= 0
 
diff --git a/plat/arm/board/fvp/platform.mk b/plat/arm/board/fvp/platform.mk
index 436cab3..7df150e 100644
--- a/plat/arm/board/fvp/platform.mk
+++ b/plat/arm/board/fvp/platform.mk
@@ -80,6 +80,7 @@
 ENABLE_FEAT_CSV2_2		:= 2
 ENABLE_FEAT_DIT			:= 2
 ENABLE_FEAT_PAN			:= 2
+ENABLE_FEAT_MTE_PERM		:= 2
 ENABLE_FEAT_VHE			:= 2
 CTX_INCLUDE_NEVE_REGS		:= 2
 ENABLE_FEAT_SEL2		:= 2