feat(rmmd): add FEAT_MEC support

This patch provides architectural support for further use of
Memory Encryption Contexts (MEC) by declaring the necessary
registers, bits, masks, helpers and values and modifying the
necessary registers to enable FEAT_MEC.

Signed-off-by: Tushar Khandelwal <tushar.khandelwal@arm.com>
Signed-off-by: Juan Pablo Conde <juanpablo.conde@arm.com>
Change-Id: I670dbfcef46e131dcbf3a0b927467ebf6f438fa4
diff --git a/Makefile b/Makefile
index 4cba2b0..d70a8b8 100644
--- a/Makefile
+++ b/Makefile
@@ -615,6 +615,22 @@
 endif
 
 ################################################################################
+# Verify FEAT_RME, FEAT_SCTLR2 and FEAT_TCR2 are enabled if FEAT_MEC is enabled.
+################################################################################
+
+ifneq (${ENABLE_FEAT_MEC},0)
+    ifeq (${ENABLE_RME},0)
+        $(error FEAT_RME must be enabled when FEAT_MEC is enabled.)
+    endif
+    ifeq (${ENABLE_FEAT_TCR2},0)
+        $(error FEAT_TCR2 must be enabled when FEAT_MEC is enabled.)
+    endif
+    ifeq (${ENABLE_FEAT_SCTLR2},0)
+        $(error FEAT_SCTLR2 must be enabled when FEAT_MEC is enabled.)
+    endif
+endif
+
+################################################################################
 # Make 128-Bit sysreg read/writes availabe when FEAT_D128 is enabled.
 ################################################################################
 ifneq (${ENABLE_FEAT_D128}, 0)
@@ -1297,6 +1313,7 @@
 	ENABLE_FEAT_FPMR \
 	ENABLE_FEAT_HCX \
 	ENABLE_FEAT_LS64_ACCDATA \
+	ENABLE_FEAT_MEC \
 	ENABLE_FEAT_MOPS \
 	ENABLE_FEAT_MTE2 \
 	ENABLE_FEAT_PAN \
@@ -1466,6 +1483,7 @@
 	ENABLE_FEAT_CSV2_2 \
 	ENABLE_FEAT_CSV2_3 \
 	ENABLE_FEAT_LS64_ACCDATA \
+	ENABLE_FEAT_MEC \
 	ENABLE_FEAT_PAN \
 	ENABLE_FEAT_TCR2 \
 	ENABLE_FEAT_THE \
diff --git a/docs/getting_started/build-options.rst b/docs/getting_started/build-options.rst
index 2b36fda..740f3a6 100644
--- a/docs/getting_started/build-options.rst
+++ b/docs/getting_started/build-options.rst
@@ -1382,6 +1382,12 @@
    Management Extension. This flag can take the values 0 to 2, to align with
    the ``ENABLE_FEAT`` mechanism. Default value is 0.
 
+-  ``ENABLE_FEAT_MEC``: Numeric value to enable support for the ARMv9.2 Memory
+   Encryption Contexts (MEC). This flag can take the values 0 to 2, to align
+   with the ``ENABLE_FEAT`` mechanism. MEC supports multiple encryption
+   contexts for Realm security state and only one encryption context for the
+   rest of the security states. Default value is 0.
+
 -  ``RMMD_ENABLE_EL3_TOKEN_SIGN``: Numeric value to enable support for singing
    realm attestation token signing requests in EL3. This flag can take the
    values 0 and 1. The default value is ``0``. When set to ``1``, this option
diff --git a/include/arch/aarch64/arch.h b/include/arch/aarch64/arch.h
index 85b33aa..627416f 100644
--- a/include/arch/aarch64/arch.h
+++ b/include/arch/aarch64/arch.h
@@ -410,6 +410,9 @@
 #define ID_AA64MMFR3_EL1_D128_MASK		ULL(0xf)
 #define D128_IMPLEMENTED			ULL(0x1)
 
+#define ID_AA64MMFR3_EL1_MEC_SHIFT		U(28)
+#define ID_AA64MMFR3_EL1_MEC_MASK		ULL(0xf)
+
 #define ID_AA64MMFR3_EL1_S2POE_SHIFT		U(20)
 #define ID_AA64MMFR3_EL1_S2POE_MASK		ULL(0xf)
 
@@ -617,6 +620,7 @@
 #define SCR_FGTEN2_BIT		(UL(1) << 59)
 #define SCR_NSE_BIT		(ULL(1) << SCR_NSE_SHIFT)
 #define SCR_EnFPM_BIT		(ULL(1) << 50)
+#define SCR_MECEn_BIT		(UL(1) << 49)
 #define SCR_GPF_BIT		(UL(1) << 48)
 #define SCR_D128En_BIT		(UL(1) << 47)
 #define SCR_TWEDEL_SHIFT	U(30)
diff --git a/include/arch/aarch64/arch_features.h b/include/arch/aarch64/arch_features.h
index a580213..43ff2cc 100644
--- a/include/arch/aarch64/arch_features.h
+++ b/include/arch/aarch64/arch_features.h
@@ -373,6 +373,10 @@
 CREATE_FEATURE_PRESENT(feat_sb, id_aa64isar1_el1, ID_AA64ISAR1_SB_SHIFT,
 		       ID_AA64ISAR1_SB_MASK, 1U)
 
+/* FEAT_MEC: Memory Encryption Contexts */
+CREATE_FEATURE_FUNCS(feat_mec, id_aa64mmfr3_el1, ID_AA64MMFR3_EL1_MEC_SHIFT,
+		ID_AA64MMFR3_EL1_MEC_MASK, 1U, ENABLE_FEAT_MEC)
+
 /*
  * 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:
diff --git a/include/services/arm_arch_svc.h b/include/services/arm_arch_svc.h
index ed9bc95..5a69ae8 100644
--- a/include/services/arm_arch_svc.h
+++ b/include/services/arm_arch_svc.h
@@ -125,6 +125,12 @@
 #define SCR_FEAT_RAS (0)
 #endif
 
+#if ENABLE_FEAT_MEC
+#define SCR_FEAT_MEC SCR_MECEn_BIT
+#else
+#define SCR_FEAT_MEC (0)
+#endif
+
 #ifndef SCR_PLAT_FEATS
 #define SCR_PLAT_FEATS (0)
 #endif
@@ -195,6 +201,7 @@
 	SCR_IRQ_BIT		|						\
 	SCR_NS_BIT		|						\
 	SCR_RES1_BITS		|						\
+	SCR_FEAT_MEC		|						\
 	SCR_PLAT_IGNORED)
 CASSERT((SCR_EL3_FEATS & SCR_EL3_IGNORED) == 0, scr_feat_is_ignored);
 CASSERT((SCR_EL3_FLIPPED & SCR_EL3_FEATS) == SCR_EL3_FLIPPED, scr_flipped_not_a_feat);
diff --git a/lib/el3_runtime/aarch64/context_mgmt.c b/lib/el3_runtime/aarch64/context_mgmt.c
index e28e1c3..531edcb 100644
--- a/lib/el3_runtime/aarch64/context_mgmt.c
+++ b/lib/el3_runtime/aarch64/context_mgmt.c
@@ -548,6 +548,10 @@
 	}
 #endif /* (IMAGE_BL31 && defined(SPD_spmd) && SPMD_SPM_AT_SEL2) */
 
+	if (is_feat_mec_supported()) {
+		scr_el3 |= SCR_MECEn_BIT;
+	}
+
 	/*
 	 * Populate EL3 state so that we've the right context
 	 * before doing ERET
diff --git a/make_helpers/arch_features.mk b/make_helpers/arch_features.mk
index 8dec522..56bfb64 100644
--- a/make_helpers/arch_features.mk
+++ b/make_helpers/arch_features.mk
@@ -419,6 +419,9 @@
 # Flag to enable Floating point exception Mode Register Feature (FEAT_FPMR)
 ENABLE_FEAT_FPMR			?=	0
 
+# Flag to enable Memory Encryption Contexts (FEAT_MEC).
+ENABLE_FEAT_MEC				?=	0
+
 #----
 # 9.3
 #----
diff --git a/plat/arm/board/fvp/platform.mk b/plat/arm/board/fvp/platform.mk
index 7bd2a1d..e43d025 100644
--- a/plat/arm/board/fvp/platform.mk
+++ b/plat/arm/board/fvp/platform.mk
@@ -93,6 +93,10 @@
 ENABLE_FEAT_MTE2		:= 2
 ENABLE_FEAT_LS64_ACCDATA	:= 2
 
+ifeq (${ENABLE_RME},1)
+    ENABLE_FEAT_MEC		:= 2
+endif
+
 # The FVP platform depends on this macro to build with correct GIC driver.
 $(eval $(call add_define,FVP_USE_GIC_DRIVER))