feat(sme): enable SME functionality

This patch adds two new compile time options to enable SME in TF-A:
ENABLE_SME_FOR_NS and ENABLE_SME_FOR_SWD for use in non-secure and
secure worlds respectively. Setting ENABLE_SME_FOR_NS=1 will enable
SME for non-secure worlds and trap SME, SVE, and FPU/SIMD instructions
in secure context. Setting ENABLE_SME_FOR_SWD=1 will disable these
traps, but support for SME context management does not yet exist in
SPM so building with SPD=spmd will fail.

The existing ENABLE_SVE_FOR_NS and ENABLE_SVE_FOR_SWD options cannot
be used with SME as it is a superset of SVE and will enable SVE and
FPU/SIMD along with SME.

Signed-off-by: John Powell <john.powell@arm.com>
Change-Id: Iaaac9d22fe37b4a92315207891da848a8fd0ed73
diff --git a/include/arch/aarch64/arch.h b/include/arch/aarch64/arch.h
index 5408acf..0fb4e74 100644
--- a/include/arch/aarch64/arch.h
+++ b/include/arch/aarch64/arch.h
@@ -218,8 +218,8 @@
 #define ID_AA64DFR0_MTPMU_SUPPORTED	ULL(1)
 
 /* ID_AA64ISAR0_EL1 definitions */
-#define ID_AA64ISAR0_RNDR_SHIFT U(60)
-#define ID_AA64ISAR0_RNDR_MASK  ULL(0xf)
+#define ID_AA64ISAR0_RNDR_SHIFT	U(60)
+#define ID_AA64ISAR0_RNDR_MASK	ULL(0xf)
 
 /* ID_AA64ISAR1_EL1 definitions */
 #define ID_AA64ISAR1_EL1	S3_0_C0_C6_1
@@ -286,10 +286,10 @@
 #define ID_AA64MMFR1_EL1_VHE_SHIFT		U(8)
 #define ID_AA64MMFR1_EL1_VHE_MASK		ULL(0xf)
 
-#define ID_AA64MMFR1_EL1_HCX_SHIFT              U(40)
-#define ID_AA64MMFR1_EL1_HCX_MASK               ULL(0xf)
-#define ID_AA64MMFR1_EL1_HCX_SUPPORTED          ULL(0x1)
-#define ID_AA64MMFR1_EL1_HCX_NOT_SUPPORTED      ULL(0x0)
+#define ID_AA64MMFR1_EL1_HCX_SHIFT		U(40)
+#define ID_AA64MMFR1_EL1_HCX_MASK		ULL(0xf)
+#define ID_AA64MMFR1_EL1_HCX_SUPPORTED		ULL(0x1)
+#define ID_AA64MMFR1_EL1_HCX_NOT_SUPPORTED	ULL(0x0)
 
 /* ID_AA64MMFR2_EL1 definitions */
 #define ID_AA64MMFR2_EL1		S3_0_C0_C7_2
@@ -329,6 +329,9 @@
 #define ID_AA64PFR1_MPAM_FRAC_SHIFT	ULL(16)
 #define ID_AA64PFR1_MPAM_FRAC_MASK	ULL(0xf)
 
+#define ID_AA64PFR1_EL1_SME_SHIFT	U(24)
+#define ID_AA64PFR1_EL1_SME_MASK	ULL(0xf)
+
 /* ID_PFR1_EL1 definitions */
 #define ID_PFR1_VIRTEXT_SHIFT	U(12)
 #define ID_PFR1_VIRTEXT_MASK	U(0xf)
@@ -388,6 +391,7 @@
 #define SCTLR_ITFSB_BIT		(ULL(1) << 37)
 #define SCTLR_TCF0_SHIFT	U(38)
 #define SCTLR_TCF0_MASK		ULL(3)
+#define SCTLR_ENTP2_BIT		(ULL(1) << 60)
 
 /* Tag Check Faults in EL0 have no effect on the PE */
 #define	SCTLR_TCF0_NO_EFFECT	U(0)
@@ -442,7 +446,9 @@
 #define SCR_GPF_BIT		(UL(1) << 48)
 #define SCR_TWEDEL_SHIFT	U(30)
 #define SCR_TWEDEL_MASK		ULL(0xf)
-#define SCR_HXEn_BIT            (UL(1) << 38)
+#define SCR_HXEn_BIT		(UL(1) << 38)
+#define SCR_ENTP2_SHIFT		U(41)
+#define SCR_ENTP2_BIT		(UL(1) << SCR_ENTP2_SHIFT)
 #define SCR_AMVOFFEN_BIT	(UL(1) << 35)
 #define SCR_TWEDEn_BIT		(UL(1) << 29)
 #define SCR_ECVEN_BIT		(UL(1) << 28)
@@ -465,7 +471,7 @@
 #define SCR_FIQ_BIT		(UL(1) << 2)
 #define SCR_IRQ_BIT		(UL(1) << 1)
 #define SCR_NS_BIT		(UL(1) << 0)
-#define SCR_VALID_BIT_MASK	U(0x2f8f)
+#define SCR_VALID_BIT_MASK	U(0x24000002F8F)
 #define SCR_RESET_VAL		SCR_RES1_BITS
 
 /* MDCR_EL3 definitions */
@@ -574,23 +580,28 @@
 #define TAM_SHIFT		U(30)
 #define TAM_BIT			(U(1) << TAM_SHIFT)
 #define TTA_BIT			(U(1) << 20)
+#define ESM_BIT			(U(1) << 12)
 #define TFP_BIT			(U(1) << 10)
 #define CPTR_EZ_BIT		(U(1) << 8)
-#define CPTR_EL3_RESET_VAL	(TCPAC_BIT | TAM_BIT | TTA_BIT | TFP_BIT & ~(CPTR_EZ_BIT))
+#define CPTR_EL3_RESET_VAL	((TCPAC_BIT | TAM_BIT | TTA_BIT | TFP_BIT) & \
+				~(CPTR_EZ_BIT | ESM_BIT))
 
 /* CPTR_EL2 definitions */
 #define CPTR_EL2_RES1		((U(1) << 13) | (U(1) << 12) | (U(0x3ff)))
 #define CPTR_EL2_TCPAC_BIT	(U(1) << 31)
 #define CPTR_EL2_TAM_SHIFT	U(30)
 #define CPTR_EL2_TAM_BIT	(U(1) << CPTR_EL2_TAM_SHIFT)
+#define CPTR_EL2_SMEN_MASK	ULL(0x3)
+#define CPTR_EL2_SMEN_SHIFT	U(24)
 #define CPTR_EL2_TTA_BIT	(U(1) << 20)
+#define CPTR_EL2_TSM_BIT	(U(1) << 12)
 #define CPTR_EL2_TFP_BIT	(U(1) << 10)
 #define CPTR_EL2_TZ_BIT		(U(1) << 8)
 #define CPTR_EL2_RESET_VAL	CPTR_EL2_RES1
 
 /* VTCR_EL2 definitions */
-#define VTCR_RESET_VAL         U(0x0)
-#define VTCR_EL2_MSA           (U(1) << 31)
+#define VTCR_RESET_VAL		U(0x0)
+#define VTCR_EL2_MSA		(U(1) << 31)
 
 /* CPSR/SPSR definitions */
 #define DAIF_FIQ_BIT		(U(1) << 0)
@@ -918,6 +929,20 @@
 #define ZCR_EL2_LEN_MASK	U(0xf)
 
 /*******************************************************************************
+ * Definitions for system register interface to SME as needed in EL3
+ ******************************************************************************/
+#define ID_AA64SMFR0_EL1		S3_0_C0_C4_5
+#define SMCR_EL3			S3_6_C1_C2_6
+
+/* ID_AA64SMFR0_EL1 definitions */
+#define ID_AA64SMFR0_EL1_FA64_BIT	(UL(1) << 63)
+
+/* SMCR_ELx definitions */
+#define SMCR_ELX_LEN_SHIFT		U(0)
+#define SMCR_ELX_LEN_MASK		U(0x1ff)
+#define SMCR_ELX_FA64_BIT		(U(1) << 31)
+
+/*******************************************************************************
  * Definitions of MAIR encodings for device and normal memory
  ******************************************************************************/
 /*
@@ -1199,12 +1224,12 @@
 /*******************************************************************************
  * FEAT_HCX - Extended Hypervisor Configuration Register
  ******************************************************************************/
-#define HCRX_EL2                S3_4_C1_C2_2
-#define HCRX_EL2_FGTnXS_BIT     (UL(1) << 4)
-#define HCRX_EL2_FnXS_BIT       (UL(1) << 3)
-#define HCRX_EL2_EnASR_BIT      (UL(1) << 2)
-#define HCRX_EL2_EnALS_BIT      (UL(1) << 1)
-#define HCRX_EL2_EnAS0_BIT      (UL(1) << 0)
+#define HCRX_EL2		S3_4_C1_C2_2
+#define HCRX_EL2_FGTnXS_BIT	(UL(1) << 4)
+#define HCRX_EL2_FnXS_BIT	(UL(1) << 3)
+#define HCRX_EL2_EnASR_BIT	(UL(1) << 2)
+#define HCRX_EL2_EnALS_BIT	(UL(1) << 1)
+#define HCRX_EL2_EnAS0_BIT	(UL(1) << 0)
 
 /*******************************************************************************
  * Definitions for DynamicIQ Shared Unit registers
diff --git a/include/arch/aarch64/arch_helpers.h b/include/arch/aarch64/arch_helpers.h
index 37fa047..733bb23 100644
--- a/include/arch/aarch64/arch_helpers.h
+++ b/include/arch/aarch64/arch_helpers.h
@@ -509,6 +509,9 @@
 DEFINE_RENAME_SYSREG_WRITE_FUNC(zcr_el3, ZCR_EL3)
 DEFINE_RENAME_SYSREG_WRITE_FUNC(zcr_el2, ZCR_EL2)
 
+DEFINE_RENAME_SYSREG_READ_FUNC(id_aa64smfr0_el1, ID_AA64SMFR0_EL1)
+DEFINE_RENAME_SYSREG_RW_FUNCS(smcr_el3, SMCR_EL3)
+
 DEFINE_RENAME_SYSREG_READ_FUNC(erridr_el1, ERRIDR_EL1)
 DEFINE_RENAME_SYSREG_WRITE_FUNC(errselr_el1, ERRSELR_EL1)
 
diff --git a/include/arch/aarch64/el3_common_macros.S b/include/arch/aarch64/el3_common_macros.S
index 8e8d334..f29def7 100644
--- a/include/arch/aarch64/el3_common_macros.S
+++ b/include/arch/aarch64/el3_common_macros.S
@@ -222,6 +222,9 @@
 	 *
 	 * CPTR_EL3.EZ: Set to zero so that all SVE functionality is trapped
 	 *  to EL3 by default.
+	 *
+	 * CPTR_EL3.ESM: Set to zero so that all SME functionality is trapped
+	 *  to EL3 by default.
 	 */
 
 	mov_imm x0, (CPTR_EL3_RESET_VAL & ~(TCPAC_BIT | TTA_BIT | TFP_BIT))
diff --git a/include/lib/extensions/sme.h b/include/lib/extensions/sme.h
new file mode 100644
index 0000000..893f9f2
--- /dev/null
+++ b/include/lib/extensions/sme.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2021, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SME_H
+#define SME_H
+
+#include <stdbool.h>
+
+#include <context.h>
+
+/*
+ * Maximum value of LEN field in SMCR_ELx. This is different than the maximum
+ * supported value which is platform dependent. In the first version of SME the
+ * LEN field is limited to 4 bits but will be expanded in future iterations.
+ * To support different versions, the code that discovers the supported vector
+ * lengths will write the max value into SMCR_ELx then read it back to see how
+ * many bits are implemented.
+ */
+#define SME_SMCR_LEN_MAX	U(0x1FF)
+
+void sme_enable(cpu_context_t *context);
+void sme_disable(cpu_context_t *context);
+
+#endif /* SME_H */
diff --git a/include/lib/extensions/sve.h b/include/lib/extensions/sve.h
index c85e08c..4b66cdb 100644
--- a/include/lib/extensions/sve.h
+++ b/include/lib/extensions/sve.h
@@ -10,5 +10,6 @@
 #include <context.h>
 
 void sve_enable(cpu_context_t *context);
+void sve_disable(cpu_context_t *context);
 
 #endif /* SVE_H */