Add MEC support

Signed-off-by: Tushar Khandelwal <tushar.khandelwal@arm.com>
Signed-off-by: Jean-Philippe Brucker <jean-philippe@linaro.org>
Change-Id: I670dbfcef46e131dcbf3a0b927467ebf6f438fa4
diff --git a/Makefile b/Makefile
index 51c7b2e..73b18f5 100644
--- a/Makefile
+++ b/Makefile
@@ -610,6 +610,9 @@
 
 	# RME enables CSV2_2 extension by default.
 	ENABLE_FEAT_CSV2_2 = 1
+
+	# RME uses MEC when available
+	ENABLE_FEAT_MEC = 2
 endif #(FEAT_RME)
 
 ################################################################################
@@ -1302,6 +1305,7 @@
 	ENABLE_FEAT_S1POE \
 	ENABLE_FEAT_SCTLR2 \
 	ENABLE_FEAT_D128 \
+	ENABLE_FEAT_MEC \
 	ENABLE_FEAT_GCS \
 	ENABLE_FEAT_VHE \
 	ENABLE_FEAT_MPAM \
@@ -1465,6 +1469,7 @@
 	ENABLE_FEAT_S1POE \
 	ENABLE_FEAT_SCTLR2 \
 	ENABLE_FEAT_D128 \
+	ENABLE_FEAT_MEC \
 	ENABLE_FEAT_GCS \
 	ENABLE_FEAT_MOPS \
 	ENABLE_FEAT_MTE2 \
diff --git a/include/arch/aarch64/arch.h b/include/arch/aarch64/arch.h
index 4d26153..40c7b40 100644
--- a/include/arch/aarch64/arch.h
+++ b/include/arch/aarch64/arch.h
@@ -410,6 +410,10 @@
 #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 MEC_IMPLEMENTED				ULL(0x1)
+
 #define ID_AA64MMFR3_EL1_S2POE_SHIFT		U(20)
 #define ID_AA64MMFR3_EL1_S2POE_MASK		ULL(0xf)
 
@@ -521,6 +525,13 @@
 			(U(1) << 22) | (U(1) << 18) | (U(1) << 16) | \
 			(U(1) << 11) | (U(1) << 5) | (U(1) << 4))
 
+#define SCTLR2_EL2   	S3_4_C1_C0_3
+#define SCTLR2_EL3   	S3_6_C1_C0_3
+
+#define SCTLR2_EMEC_BIT		(ULL(1) << 1)
+#define TCR2_EL2_AMEC0		(ULL(1) << 12)
+#define TCR2_EL2_AMEC1		(ULL(1) << 13)
+
 #define SCTLR_M_BIT		(ULL(1) << 0)
 #define SCTLR_A_BIT		(ULL(1) << 1)
 #define SCTLR_C_BIT		(ULL(1) << 2)
@@ -615,6 +626,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)
@@ -1575,4 +1587,12 @@
 #define CLUSTERPMCR_N_SHIFT		U(11)
 #define CLUSTERPMCR_N_MASK		U(0x1f)
 
+/* RME MECID Registers */
+#define MECID_P0_EL2			S3_4_C10_C8_0
+#define MECID_P1_EL2			S3_4_C10_C8_2
+#define MECIDR_EL2			S3_4_C10_C8_7
+#define MECID_RL_A_EL3			S3_6_C10_C10_1
+
+#define MECIDR_MECIDWIDTHM1_MASK	UINT64_C(0xf)
+
 #endif /* ARCH_H */
diff --git a/include/arch/aarch64/arch_features.h b/include/arch/aarch64/arch_features.h
index 1d0a2e0..9bbf558 100644
--- a/include/arch/aarch64/arch_features.h
+++ b/include/arch/aarch64/arch_features.h
@@ -288,6 +288,11 @@
 		     ID_AA64MMFR3_EL1_D128_MASK, D128_IMPLEMENTED,
 		     ENABLE_FEAT_D128)
 
+/* FEAT_MEC */
+CREATE_FEATURE_FUNCS(feat_mec, id_aa64mmfr3_el1, ID_AA64MMFR3_EL1_MEC_SHIFT,
+		     ID_AA64MMFR3_EL1_MEC_MASK, MEC_IMPLEMENTED,
+		     ENABLE_FEAT_MEC)
+
 /* FEAT_FPMR */
 CREATE_FEATURE_FUNCS(feat_fpmr, id_aa64pfr2_el1, ID_AA64PFR2_EL1_FPMR_SHIFT,
 		     ID_AA64PFR2_EL1_FPMR_MASK, FPMR_IMPLEMENTED,
diff --git a/include/arch/aarch64/arch_helpers.h b/include/arch/aarch64/arch_helpers.h
index 8b92f19..1a0869e 100644
--- a/include/arch/aarch64/arch_helpers.h
+++ b/include/arch/aarch64/arch_helpers.h
@@ -394,6 +394,7 @@
 /*******************************************************************************
  * System register accessor prototypes
  ******************************************************************************/
+
 DEFINE_IDREG_READ_FUNC(midr_el1)
 DEFINE_SYSREG_READ_FUNC(mpidr_el1)
 DEFINE_IDREG_READ_FUNC(id_aa64mmfr0_el1)
@@ -696,6 +697,7 @@
 /* FEAT_SCTLR2 Registers */
 DEFINE_RENAME_SYSREG_RW_FUNCS(sctlr2_el1, SCTLR2_EL1)
 DEFINE_RENAME_SYSREG_RW_FUNCS(sctlr2_el2, SCTLR2_EL2)
+DEFINE_RENAME_SYSREG_RW_FUNCS(sctlr2_el3, SCTLR2_EL3)
 
 /* FEAT_LS64_ACCDATA Registers */
 DEFINE_RENAME_SYSREG_RW_FUNCS(accdata_el1, ACCDATA_EL1)
@@ -721,6 +723,12 @@
 
 DEFINE_RENAME_SYSREG_RW_FUNCS(fpmr, FPMR)
 
+/* RME MEC Registers */
+DEFINE_RENAME_SYSREG_RW_FUNCS(mecid_el3, MECID_RL_A_EL3)
+DEFINE_RENAME_SYSREG_RW_FUNCS(mecid_p0_el2, MECID_P0_EL2)
+DEFINE_RENAME_SYSREG_RW_FUNCS(mecid_p1_el2, MECID_P1_EL2)
+DEFINE_RENAME_SYSREG_READ_FUNC(mecidr_el2, MECIDR_EL2)
+
 #define IS_IN_EL(x) \
 	(GET_EL(read_CurrentEl()) == MODE_EL##x)
 
diff --git a/lib/el3_runtime/aarch64/context_mgmt.c b/lib/el3_runtime/aarch64/context_mgmt.c
index 9b97685..9a64f07 100644
--- a/lib/el3_runtime/aarch64/context_mgmt.c
+++ b/lib/el3_runtime/aarch64/context_mgmt.c
@@ -138,6 +138,10 @@
 		scr_el3 |= SCR_ATA_BIT;
 	}
 
+	if (is_feat_mec_supported()) {
+		scr_el3 |= SCR_MECEn_BIT;
+		scr_el3 |= SCR_SCTLR2En_BIT;
+	}
 	write_ctx_reg(state, CTX_SCR_EL3, scr_el3);
 
 	/*
@@ -190,6 +194,10 @@
 		scr_el3 |= SCR_SCTLR2En_BIT;
 	}
 
+	if (is_feat_mec_supported()) {
+		scr_el3 |= SCR_MECEn_BIT;
+		scr_el3 |= SCR_SCTLR2En_BIT;
+	}
 	write_ctx_reg(state, CTX_SCR_EL3, scr_el3);
 }
 #endif /* ENABLE_RME */
@@ -660,6 +668,17 @@
 	}
 
 	pmuv3_init_el3();
+
+	if (is_feat_mec_supported()) {
+		u_register_t sctlr2_el3 = read_sctlr2_el3();
+
+		/* Use default MECID 0 for RMM code and data */
+		write_mecid_el3(0);
+
+		sctlr2_el3 |= SCTLR2_EMEC_BIT;
+		write_sctlr2_el3(sctlr2_el3);
+		isb();
+	}
 }
 #endif /* IMAGE_BL31 */
 
diff --git a/make_helpers/arch_features.mk b/make_helpers/arch_features.mk
index 3c9e136..1b29a99 100644
--- a/make_helpers/arch_features.mk
+++ b/make_helpers/arch_features.mk
@@ -420,6 +420,9 @@
 # Flag to enable Floating point exception Mode Register Feature (FEAT_FPMR)
 ENABLE_FEAT_FPMR			?=	0
 
+# Memory encryption extension to RME
+ENABLE_FEAT_MEC				?=	0
+
 #----
 # 9.3
 #----
diff --git a/plat/arm/board/fvp/fvp_security.c b/plat/arm/board/fvp/fvp_security.c
index 5b97034..4c4ff82 100644
--- a/plat/arm/board/fvp/fvp_security.c
+++ b/plat/arm/board/fvp/fvp_security.c
@@ -7,6 +7,7 @@
 #include <plat/arm/common/arm_config.h>
 #include <plat/arm/common/plat_arm.h>
 #include <platform_def.h>
+#include <arch_features.h>
 
 /*
  * We assume that all security programming is done by the primary core.