feat(cpufeat): add feature detection for FEAT_CSV2_3

This feature provides support to context save the
SCXTNUM_ELx register. FEAT_CSV2_3 implies the implementation
of FEAT_CSV2_2. FEAT_CSV2_3 is supported in AArch64 state only
and is an optional feature in Arm v8.0 implementations.

This patch adds feature detection for v8.9 feature FEAT_CSV2_3,
adds macros for ID_AA64PFR0_EL1.CSV2 bits [59:56] for detecting
FEAT_CSV2_3 and macro for ENABLE_FEAT_CSV2_3.

Change-Id: Ida9f31e832b5f11bd89eebd6cc9f10ddad755c14
Signed-off-by: Sona Mathew <sonarebecca.mathew@arm.com>
diff --git a/Makefile b/Makefile
index 87ff22e..3536763 100644
--- a/Makefile
+++ b/Makefile
@@ -1256,6 +1256,7 @@
 	ENABLE_FEAT_AMU \
 	ENABLE_FEAT_AMUv1p1 \
 	ENABLE_FEAT_CSV2_2 \
+	ENABLE_FEAT_CSV2_3 \
 	ENABLE_FEAT_DIT \
 	ENABLE_FEAT_ECV \
 	ENABLE_FEAT_FGT \
@@ -1411,6 +1412,7 @@
 	ENABLE_FEAT_SEL2 \
 	ENABLE_FEAT_VHE \
 	ENABLE_FEAT_CSV2_2 \
+	ENABLE_FEAT_CSV2_3 \
 	ENABLE_FEAT_PAN \
 	ENABLE_FEAT_TCR2 \
 	ENABLE_FEAT_S2PIE \
diff --git a/common/feat_detect.c b/common/feat_detect.c
index 49b5360..57d6ae0 100644
--- a/common/feat_detect.c
+++ b/common/feat_detect.c
@@ -204,6 +204,8 @@
 		      "S1POE", 1, 1);
 	check_feature(ENABLE_FEAT_MTE_PERM, read_feat_mte_perm_id_field(),
 		      "MTE_PERM", 1, 1);
+	check_feature(ENABLE_FEAT_CSV2_3, read_feat_csv2_id_field(),
+		      "CSV2_3", 3, 3);
 
 	/* 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 077f598..cc20261 100644
--- a/docs/getting_started/build-options.rst
+++ b/docs/getting_started/build-options.rst
@@ -306,6 +306,13 @@
    0 to 2, to align with the ``ENABLE_FEAT`` mechanism.
    Default value is ``0``.
 
+-  ``ENABLE_FEAT_CSV2_3``: Numeric value to enable support for ``FEAT_CSV2_3``
+   extension. This feature is supported in AArch64 state only and is an optional
+   feature available in Arm v8.0 implementations.
+   ``FEAT_CSV2_3`` implies the implementation of ``FEAT_CSV2_2``.
+   The flag can take values 0 to 2, to align with the ``ENABLE_FEAT``
+   mechanism. Default value is ``0``.
+
 -  ``ENABLE_FEAT_DIT``: Numeric value to enable ``FEAT_DIT`` (Data Independent
    Timing) extension. It allows setting the ``DIT`` bit of PSTATE in EL3.
    ``FEAT_DIT`` is a mandatory  architectural feature and is enabled from v8.4
diff --git a/include/arch/aarch32/arch_features.h b/include/arch/aarch32/arch_features.h
index acc1751..a2063f1 100644
--- a/include/arch/aarch32/arch_features.h
+++ b/include/arch/aarch32/arch_features.h
@@ -137,6 +137,7 @@
 static inline bool is_feat_ecv_supported(void) { return false; }
 static inline bool is_feat_ecv_v2_supported(void) { return false; }
 static inline bool is_feat_csv2_2_supported(void) { return false; }
+static inline bool is_feat_csv2_3_supported(void) { return false; }
 static inline bool is_feat_ras_supported(void) { return false; }
 
 /* The following features are supported in AArch64 only. */
diff --git a/include/arch/aarch64/arch.h b/include/arch/aarch64/arch.h
index e9d22b6..b88d6c6 100644
--- a/include/arch/aarch64/arch.h
+++ b/include/arch/aarch64/arch.h
@@ -197,6 +197,7 @@
 #define ID_AA64PFR0_CSV2_MASK			ULL(0xf)
 #define ID_AA64PFR0_CSV2_LENGTH			U(4)
 #define ID_AA64PFR0_CSV2_2_SUPPORTED		ULL(0x2)
+#define ID_AA64PFR0_CSV2_3_SUPPORTED		ULL(0x3)
 
 #define ID_AA64PFR0_FEAT_RME_SHIFT		U(52)
 #define ID_AA64PFR0_FEAT_RME_MASK		ULL(0xf)
diff --git a/include/arch/aarch64/arch_features.h b/include/arch/aarch64/arch_features.h
index deea6d4..c053c4d 100644
--- a/include/arch/aarch64/arch_features.h
+++ b/include/arch/aarch64/arch_features.h
@@ -187,10 +187,28 @@
 	return ISOLATE_FIELD(read_id_aa64isar1_el1(), ID_AA64ISAR1_SB_SHIFT);
 }
 
-/* FEAT_CSV2_2: Cache Speculation Variant 2 */
-CREATE_FEATURE_FUNCS(feat_csv2, id_aa64pfr0_el1, ID_AA64PFR0_CSV2_SHIFT, 0)
+/*
+ * FEAT_CSV2: Cache Speculation Variant 2. This checks bit fields[56-59]
+ * of id_aa64pfr0_el1 register and can be used to check for below features:
+ * FEAT_CSV2_2: Cache Speculation Variant CSV2_2.
+ * FEAT_CSV2_3: Cache Speculation Variant CSV2_3.
+ * 0b0000 - Feature FEAT_CSV2 is not implemented.
+ * 0b0001 - Feature FEAT_CSV2 is implemented, but FEAT_CSV2_2 and FEAT_CSV2_3
+ *          are not implemented.
+ * 0b0010 - Feature FEAT_CSV2_2 is implemented but FEAT_CSV2_3 is not
+ *          implemented.
+ * 0b0011 - Feature FEAT_CSV2_3 is implemented.
+ */
+static inline unsigned int read_feat_csv2_id_field(void)
+{
+	return (unsigned int)(read_id_aa64pfr0_el1() >>
+		ID_AA64PFR0_CSV2_SHIFT) & ID_AA64PFR0_CSV2_MASK;
+}
+
 CREATE_FEATURE_FUNCS_VER(feat_csv2_2, read_feat_csv2_id_field,
 			 ID_AA64PFR0_CSV2_2_SUPPORTED, ENABLE_FEAT_CSV2_2)
+CREATE_FEATURE_FUNCS_VER(feat_csv2_3, read_feat_csv2_id_field,
+			 ID_AA64PFR0_CSV2_3_SUPPORTED, ENABLE_FEAT_CSV2_3)
 
 /* FEAT_SPE: Statistical Profiling Extension */
 CREATE_FEATURE_FUNCS(feat_spe, id_aa64dfr0_el1, ID_AA64DFR0_PMS_SHIFT,
diff --git a/lib/el3_runtime/aarch64/context_mgmt.c b/lib/el3_runtime/aarch64/context_mgmt.c
index da53194..00c6008 100644
--- a/lib/el3_runtime/aarch64/context_mgmt.c
+++ b/lib/el3_runtime/aarch64/context_mgmt.c
@@ -168,6 +168,7 @@
 
 	scr_el3 |= SCR_NS_BIT | SCR_NSE_BIT;
 
+	/* CSV2 version 2 and above */
 	if (is_feat_csv2_2_supported()) {
 		/* Enable access to the SCXTNUM_ELx registers. */
 		scr_el3 |= SCR_EnSCXT_BIT;
@@ -236,6 +237,7 @@
 	scr_el3 |= SCR_TERR_BIT;
 #endif
 
+	/* CSV2 version 2 and above */
 	if (is_feat_csv2_2_supported()) {
 		/* Enable access to the SCXTNUM_ELx registers. */
 		scr_el3 |= SCR_EnSCXT_BIT;
@@ -1293,6 +1295,7 @@
 		write_ctx_reg(el2_sysregs_ctx, CTX_TRFCR_EL2, read_trfcr_el2());
 	}
 
+	/* CSV2 version 2 and above */
 	if (is_feat_csv2_2_supported()) {
 		write_ctx_reg(el2_sysregs_ctx, CTX_SCXTNUM_EL2, read_scxtnum_el2());
 	}
@@ -1370,6 +1373,7 @@
 		write_trfcr_el2(read_ctx_reg(el2_sysregs_ctx, CTX_TRFCR_EL2));
 	}
 
+	/* CSV2 version 2 and above */
 	if (is_feat_csv2_2_supported()) {
 		write_scxtnum_el2(read_ctx_reg(el2_sysregs_ctx, CTX_SCXTNUM_EL2));
 	}
diff --git a/make_helpers/arch_features.mk b/make_helpers/arch_features.mk
index 9ac9332..bb4e224 100644
--- a/make_helpers/arch_features.mk
+++ b/make_helpers/arch_features.mk
@@ -169,6 +169,10 @@
 # Flag to enable CSV2_2 extension.
 ENABLE_FEAT_CSV2_2			?=	0
 
+# Flag to enable CSV2_3 extension. FEAT_CSV2_3 enables access to the
+# SCXTNUM_ELx register.
+ENABLE_FEAT_CSV2_3			?=	0
+
 # By default, disable access of trace system registers from NS lower
 # ELs  i.e. NS-EL2, or NS-EL1 if NS-EL2 implemented but unused if
 # system register trace is implemented. This feature is available if
diff --git a/plat/arm/board/fvp/platform.mk b/plat/arm/board/fvp/platform.mk
index df26dd7..eef06d4 100644
--- a/plat/arm/board/fvp/platform.mk
+++ b/plat/arm/board/fvp/platform.mk
@@ -75,6 +75,7 @@
 endif
 ENABLE_SYS_REG_TRACE_FOR_NS	:= 2
 ENABLE_FEAT_CSV2_2		:= 2
+ENABLE_FEAT_CSV2_3		:= 2
 ENABLE_FEAT_DIT			:= 2
 ENABLE_FEAT_PAN			:= 2
 ENABLE_FEAT_MTE_PERM		:= 2