feat(tcr2): add asymmetric feature testing for FEAT_TCR2

Change-Id: I07b27ff58ccf471ccc43643141e2dfe70083fd13
Signed-off-by: Jayanth Dodderi Chidanand <jayanthdodderi.chidanand@arm.com>
diff --git a/include/lib/aarch64/arch.h b/include/lib/aarch64/arch.h
index 8081ff4..a1dca21 100644
--- a/include/lib/aarch64/arch.h
+++ b/include/lib/aarch64/arch.h
@@ -395,6 +395,12 @@
 #define ID_AA64MMFR2_EL1_CNP_SHIFT	U(0)
 #define ID_AA64MMFR2_EL1_CNP_MASK	ULL(0xf)
 
+/* ID_AA64MMFR3_EL1 definitions */
+#define ID_AA64MMFR3_EL1		S3_0_C0_C7_3
+
+#define ID_AA64MMFR3_TCR2_SHIFT		U(0)
+#define ID_AA64MMFR3_TCR2_MASK		ULL(0xf)
+
 /* ID_AA64PFR1_EL1 definitions */
 #define ID_AA64PFR1_EL1_SSBS_SHIFT	U(4)
 #define ID_AA64PFR1_EL1_SSBS_MASK	ULL(0xf)
@@ -1347,6 +1353,12 @@
 #define BRBIDR0_EL1	S2_1_C9_C2_0
 
 /*******************************************************************************
+ * FEAT_TCR2 - Extended Translation Control Registers
+ ******************************************************************************/
+#define TCR2_EL1		S3_0_C2_C0_3
+#define TCR2_EL2		S3_4_C2_C0_3
+
+/*******************************************************************************
  * Armv8.4 - Trace Filter System Registers
  ******************************************************************************/
 #define TRFCR_EL1	S3_0_C1_C2_1
diff --git a/include/lib/aarch64/arch_features.h b/include/lib/aarch64/arch_features.h
index 5822dc4..8a6e4b7 100644
--- a/include/lib/aarch64/arch_features.h
+++ b/include/lib/aarch64/arch_features.h
@@ -256,6 +256,12 @@
 	return spe_get_version() >= ID_AA64DFR0_SPE;
 }
 
+static inline bool is_feat_tcr2_supported(void)
+{
+	return (((read_id_aa64mmfr3_el1() >> ID_AA64MMFR3_TCR2_SHIFT) &
+		ID_AA64MMFR3_TCR2_MASK) != 0);
+}
+
 static inline bool get_feat_pmuv3_supported(void)
 {
 	return (((read_id_aa64dfr0_el1() >> ID_AA64DFR0_PMUVER_SHIFT) &
diff --git a/include/lib/aarch64/arch_helpers.h b/include/lib/aarch64/arch_helpers.h
index 076a9cd..455ae27 100644
--- a/include/lib/aarch64/arch_helpers.h
+++ b/include/lib/aarch64/arch_helpers.h
@@ -623,6 +623,10 @@
 /* FEAT_HCX HCRX_EL2 */
 DEFINE_RENAME_SYSREG_RW_FUNCS(hcrx_el2, HCRX_EL2)
 
+/* FEAT_TCR2 TCR2_EL1, TCR2_EL2 */
+DEFINE_RENAME_SYSREG_RW_FUNCS(tcr2_el1, TCR2_EL1)
+DEFINE_RENAME_SYSREG_RW_FUNCS(tcr2_el2, TCR2_EL2)
+
 /* Floating point control and status register */
 DEFINE_RENAME_SYSREG_RW_FUNCS(fpcr, FPCR)
 DEFINE_RENAME_SYSREG_RW_FUNCS(fpsr, FPSR)
@@ -633,6 +637,9 @@
 /* ID_PFR2_EL1 */
 DEFINE_RENAME_SYSREG_READ_FUNC(id_pfr2_el1, ID_PFR2_EL1)
 
+/* ID_AA64MMFR3_EL1 */
+DEFINE_RENAME_SYSREG_READ_FUNC(id_aa64mmfr3_el1, ID_AA64MMFR3_EL1)
+
 #define IS_IN_EL(x) \
 	(GET_EL(read_CurrentEl()) == MODE_EL##x)
 
diff --git a/tftf/tests/misc_tests/test_asymmetric_features.c b/tftf/tests/misc_tests/test_asymmetric_features.c
index 630cc69..cf84122 100644
--- a/tftf/tests/misc_tests/test_asymmetric_features.c
+++ b/tftf/tests/misc_tests/test_asymmetric_features.c
@@ -112,6 +112,21 @@
 	return TEST_RESULT_SUCCESS;
 }
 
+static test_result_t test_tcr2(void)
+{
+	unsigned int mpid = read_mpidr_el1() & MPID_MASK;
+	unsigned int core_pos = platform_get_core_pos(mpid);
+
+	if (!is_feat_tcr2_supported()) {
+		test_skipped[core_pos] = true;
+		return TEST_RESULT_SUCCESS;
+	}
+
+	read_tcr2_el1();
+
+	return TEST_RESULT_SUCCESS;
+}
+
 /*
  * Runs on one CPU, and runs asymmetric_test_function.
  */
@@ -251,3 +266,8 @@
 {
 	return run_asymmetric_test(test_spe);
 }
+
+test_result_t test_tcr2_asymmetric(void)
+{
+	return run_asymmetric_test(test_tcr2);
+}
diff --git a/tftf/tests/tests-asymmetric-features.xml b/tftf/tests/tests-asymmetric-features.xml
index 29dfd7a..5be3176 100644
--- a/tftf/tests/tests-asymmetric-features.xml
+++ b/tftf/tests/tests-asymmetric-features.xml
@@ -12,5 +12,7 @@
                 function="test_trbe_errata_asymmetric" />
       <testcase name="Asymmetric SPE Test"
                 function="test_spe_asymmetric" />
+      <testcase name="Asymmetric TCR2 Test"
+                function="test_tcr2_asymmetric" />
   </testsuite>
 </testsuites>