refactor(cm): move mpam registers into el2 context

* FEAT_MPAM related EL2 registers are placed explicitly outside
  the EL2 context in the cpu_context_t structure.

* With EL2 registers now coupled with dependent features, this
  patch moves them to the el2_context structure "el2_sysregs_t".

* Further, converting the assembly context-offset entries into a
  c structure. It relies on garbage collection of the linker
  removing unreferenced structures from memory, as well as aiding
  in readability and future maintenance.

Change-Id: Ib784bc8d2fbe35a8a47a569426d8663282ec06aa
Signed-off-by: Jayanth Dodderi Chidanand <jayanthdodderi.chidanand@arm.com>
diff --git a/include/lib/el3_runtime/aarch64/context.h b/include/lib/el3_runtime/aarch64/context.h
index 4f11ad2..6f97bed 100644
--- a/include/lib/el3_runtime/aarch64/context.h
+++ b/include/lib/el3_runtime/aarch64/context.h
@@ -299,27 +299,6 @@
 #endif /* CTX_INCLUDE_PAUTH_REGS */
 
 /*******************************************************************************
- * Registers related to ARMv8.2-MPAM.
- ******************************************************************************/
-#define CTX_MPAM_REGS_OFFSET	(CTX_PAUTH_REGS_OFFSET + CTX_PAUTH_REGS_END)
-#if CTX_INCLUDE_MPAM_REGS
-#define CTX_MPAM2_EL2		U(0x0)
-#define CTX_MPAMHCR_EL2		U(0x8)
-#define CTX_MPAMVPM0_EL2	U(0x10)
-#define CTX_MPAMVPM1_EL2	U(0x18)
-#define CTX_MPAMVPM2_EL2	U(0x20)
-#define CTX_MPAMVPM3_EL2	U(0x28)
-#define CTX_MPAMVPM4_EL2	U(0x30)
-#define CTX_MPAMVPM5_EL2	U(0x38)
-#define CTX_MPAMVPM6_EL2	U(0x40)
-#define CTX_MPAMVPM7_EL2	U(0x48)
-#define CTX_MPAMVPMV_EL2	U(0x50)
-#define CTX_MPAM_REGS_END	U(0x60)
-#else
-#define CTX_MPAM_REGS_END	U(0x0)
-#endif /* CTX_INCLUDE_MPAM_REGS */
-
-/*******************************************************************************
  * Registers initialised in a per-world context.
  ******************************************************************************/
 #define CTX_CPTR_EL3			U(0x0)
@@ -355,9 +334,6 @@
 #if CTX_INCLUDE_PAUTH_REGS
 # define CTX_PAUTH_REGS_ALL	(CTX_PAUTH_REGS_END >> DWORD_SHIFT)
 #endif
-#if CTX_INCLUDE_MPAM_REGS
-# define CTX_MPAM_REGS_ALL	(CTX_MPAM_REGS_END >> DWORD_SHIFT)
-#endif
 
 /*
  * AArch64 general purpose register context structure. Usually x0-x18,
@@ -397,11 +373,6 @@
 DEFINE_REG_STRUCT(pauth, CTX_PAUTH_REGS_ALL);
 #endif
 
-/* Registers associated to ARMv8.2 MPAM */
-#if CTX_INCLUDE_MPAM_REGS
-DEFINE_REG_STRUCT(mpam, CTX_MPAM_REGS_ALL);
-#endif
-
 /*
  * Macros to access members of any of the above structures using their
  * offsets
@@ -432,10 +403,6 @@
 	pauth_t pauth_ctx;
 #endif
 
-#if CTX_INCLUDE_MPAM_REGS
-	mpam_t	mpam_ctx;
-#endif
-
 #if CTX_INCLUDE_EL2_REGS
 	el2_sysregs_t el2_sysregs_ctx;
 #endif
@@ -468,9 +435,6 @@
 #if CTX_INCLUDE_PAUTH_REGS
 # define get_pauth_ctx(h)	(&((cpu_context_t *) h)->pauth_ctx)
 #endif
-#if CTX_INCLUDE_MPAM_REGS
-# define get_mpam_ctx(h)	(&((cpu_context_t *) h)->mpam_ctx)
-#endif
 
 /*
  * Compile time assertions related to the 'cpu_context' structure to
@@ -499,11 +463,6 @@
 	assert_core_context_pauth_offset_mismatch);
 #endif /* CTX_INCLUDE_PAUTH_REGS */
 
-#if CTX_INCLUDE_MPAM_REGS
-CASSERT(CTX_MPAM_REGS_OFFSET == __builtin_offsetof(cpu_context_t, mpam_ctx),
-	assert_core_context_mpam_offset_mismatch);
-#endif /* CTX_INCLUDE_MPAM_REGS */
-
 /*
  * Helper macro to set the general purpose registers that correspond to
  * parameters in an aapcs_64 call i.e. x0-x7
diff --git a/include/lib/el3_runtime/context_el2.h b/include/lib/el3_runtime/context_el2.h
index 04f6587..d25ab81 100644
--- a/include/lib/el3_runtime/context_el2.h
+++ b/include/lib/el3_runtime/context_el2.h
@@ -114,6 +114,20 @@
 	uint64_t gcspr_el2;
 } el2_gcs_regs_t;
 
+typedef struct el2_mpam_regs {
+	uint64_t mpam2_el2;
+	uint64_t mpamhcr_el2;
+	uint64_t mpamvpm0_el2;
+	uint64_t mpamvpm1_el2;
+	uint64_t mpamvpm2_el2;
+	uint64_t mpamvpm3_el2;
+	uint64_t mpamvpm4_el2;
+	uint64_t mpamvpm5_el2;
+	uint64_t mpamvpm6_el2;
+	uint64_t mpamvpm7_el2;
+	uint64_t mpamvpmv_el2;
+} el2_mpam_regs_t;
+
 typedef struct el2_sysregs {
 
 	el2_common_regs_t common;
@@ -174,6 +188,10 @@
 	el2_gcs_regs_t gcs;
 #endif
 
+#if CTX_INCLUDE_MPAM_REGS
+	el2_mpam_regs_t mpam;
+#endif
+
 } el2_sysregs_t;
 
 /*
@@ -311,6 +329,15 @@
 #define write_el2_ctx_gcs(ctx, reg, val)
 #endif /* ENABLE_FEAT_GCS */
 
+#if CTX_INCLUDE_MPAM_REGS
+#define read_el2_ctx_mpam(ctx, reg)		(((ctx)->mpam).reg)
+#define write_el2_ctx_mpam(ctx, reg, val)	((((ctx)->mpam).reg)	\
+							= (uint64_t) (val))
+#else
+#define read_el2_ctx_mpam(ctx, reg)		ULL(0)
+#define write_el2_ctx_mpam(ctx, reg, val)
+#endif /* CTX_INCLUDE_MPAM_REGS */
+
 #endif /* CTX_INCLUDE_EL2_REGS */
 /******************************************************************************/
 
diff --git a/lib/el3_runtime/aarch64/context_mgmt.c b/lib/el3_runtime/aarch64/context_mgmt.c
index 35c98f5..1937c30 100644
--- a/lib/el3_runtime/aarch64/context_mgmt.c
+++ b/lib/el3_runtime/aarch64/context_mgmt.c
@@ -1046,13 +1046,11 @@
 	write_hfgwtr_el2(read_el2_ctx_fgt(ctx, hfgwtr_el2));
 }
 
-#if CTX_INCLUDE_MPAM_REGS
-
-static void el2_sysregs_context_save_mpam(mpam_t *ctx)
+static void el2_sysregs_context_save_mpam(el2_sysregs_t *ctx)
 {
 	u_register_t mpam_idr = read_mpamidr_el1();
 
-	write_ctx_reg(ctx, CTX_MPAM2_EL2, read_mpam2_el2());
+	write_el2_ctx_mpam(ctx, mpam2_el2, read_mpam2_el2());
 
 	/*
 	 * The context registers that we intend to save would be part of the
@@ -1066,9 +1064,9 @@
 	 * MPAMHCR_EL2, MPAMVPMV_EL2 and MPAMVPM0_EL2 are always present if
 	 * MPAMIDR_HAS_HCR_BIT == 1.
 	 */
-	write_ctx_reg(ctx, CTX_MPAMHCR_EL2, read_mpamhcr_el2());
-	write_ctx_reg(ctx, CTX_MPAMVPM0_EL2, read_mpamvpm0_el2());
-	write_ctx_reg(ctx, CTX_MPAMVPMV_EL2, read_mpamvpmv_el2());
+	write_el2_ctx_mpam(ctx, mpamhcr_el2, read_mpamhcr_el2());
+	write_el2_ctx_mpam(ctx, mpamvpm0_el2, read_mpamvpm0_el2());
+	write_el2_ctx_mpam(ctx, mpamvpmv_el2, read_mpamvpmv_el2());
 
 	/*
 	 * The number of MPAMVPM registers is implementation defined, their
@@ -1076,71 +1074,67 @@
 	 */
 	switch ((mpam_idr >> MPAMIDR_EL1_VPMR_MAX_SHIFT) & MPAMIDR_EL1_VPMR_MAX_MASK) {
 	case 7:
-		write_ctx_reg(ctx, CTX_MPAMVPM7_EL2, read_mpamvpm7_el2());
+		write_el2_ctx_mpam(ctx, mpamvpm7_el2, read_mpamvpm7_el2());
 		__fallthrough;
 	case 6:
-		write_ctx_reg(ctx, CTX_MPAMVPM6_EL2, read_mpamvpm6_el2());
+		write_el2_ctx_mpam(ctx, mpamvpm6_el2, read_mpamvpm6_el2());
 		__fallthrough;
 	case 5:
-		write_ctx_reg(ctx, CTX_MPAMVPM5_EL2, read_mpamvpm5_el2());
+		write_el2_ctx_mpam(ctx, mpamvpm5_el2, read_mpamvpm5_el2());
 		__fallthrough;
 	case 4:
-		write_ctx_reg(ctx, CTX_MPAMVPM4_EL2, read_mpamvpm4_el2());
+		write_el2_ctx_mpam(ctx, mpamvpm4_el2, read_mpamvpm4_el2());
 		__fallthrough;
 	case 3:
-		write_ctx_reg(ctx, CTX_MPAMVPM3_EL2, read_mpamvpm3_el2());
+		write_el2_ctx_mpam(ctx, mpamvpm3_el2, read_mpamvpm3_el2());
 		__fallthrough;
 	case 2:
-		write_ctx_reg(ctx, CTX_MPAMVPM2_EL2, read_mpamvpm2_el2());
+		write_el2_ctx_mpam(ctx, mpamvpm2_el2, read_mpamvpm2_el2());
 		__fallthrough;
 	case 1:
-		write_ctx_reg(ctx, CTX_MPAMVPM1_EL2, read_mpamvpm1_el2());
+		write_el2_ctx_mpam(ctx, mpamvpm1_el2, read_mpamvpm1_el2());
 		break;
 	}
 }
 
-#endif /* CTX_INCLUDE_MPAM_REGS */
-
-#if CTX_INCLUDE_MPAM_REGS
-static void el2_sysregs_context_restore_mpam(mpam_t *ctx)
+static void el2_sysregs_context_restore_mpam(el2_sysregs_t *ctx)
 {
 	u_register_t mpam_idr = read_mpamidr_el1();
 
-	write_mpam2_el2(read_ctx_reg(ctx, CTX_MPAM2_EL2));
+	write_mpam2_el2(read_el2_ctx_mpam(ctx, mpam2_el2));
 
 	if ((mpam_idr & MPAMIDR_HAS_HCR_BIT) == 0U) {
 		return;
 	}
 
-	write_mpamhcr_el2(read_ctx_reg(ctx, CTX_MPAMHCR_EL2));
-	write_mpamvpm0_el2(read_ctx_reg(ctx, CTX_MPAMVPM0_EL2));
-	write_mpamvpmv_el2(read_ctx_reg(ctx, CTX_MPAMVPMV_EL2));
+	write_mpamhcr_el2(read_el2_ctx_mpam(ctx, mpamhcr_el2));
+	write_mpamvpm0_el2(read_el2_ctx_mpam(ctx, mpamvpm0_el2));
+	write_mpamvpmv_el2(read_el2_ctx_mpam(ctx, mpamvpmv_el2));
 
 	switch ((mpam_idr >> MPAMIDR_EL1_VPMR_MAX_SHIFT) & MPAMIDR_EL1_VPMR_MAX_MASK) {
 	case 7:
-		write_mpamvpm7_el2(read_ctx_reg(ctx, CTX_MPAMVPM7_EL2));
+		write_mpamvpm7_el2(read_el2_ctx_mpam(ctx, mpamvpm7_el2));
 		__fallthrough;
 	case 6:
-		write_mpamvpm6_el2(read_ctx_reg(ctx, CTX_MPAMVPM6_EL2));
+		write_mpamvpm6_el2(read_el2_ctx_mpam(ctx, mpamvpm6_el2));
 		__fallthrough;
 	case 5:
-		write_mpamvpm5_el2(read_ctx_reg(ctx, CTX_MPAMVPM5_EL2));
+		write_mpamvpm5_el2(read_el2_ctx_mpam(ctx, mpamvpm5_el2));
 		__fallthrough;
 	case 4:
-		write_mpamvpm4_el2(read_ctx_reg(ctx, CTX_MPAMVPM4_EL2));
+		write_mpamvpm4_el2(read_el2_ctx_mpam(ctx, mpamvpm4_el2));
 		__fallthrough;
 	case 3:
-		write_mpamvpm3_el2(read_ctx_reg(ctx, CTX_MPAMVPM3_EL2));
+		write_mpamvpm3_el2(read_el2_ctx_mpam(ctx, mpamvpm3_el2));
 		__fallthrough;
 	case 2:
-		write_mpamvpm2_el2(read_ctx_reg(ctx, CTX_MPAMVPM2_EL2));
+		write_mpamvpm2_el2(read_el2_ctx_mpam(ctx, mpamvpm2_el2));
 		__fallthrough;
 	case 1:
-		write_mpamvpm1_el2(read_ctx_reg(ctx, CTX_MPAMVPM1_EL2));
+		write_mpamvpm1_el2(read_el2_ctx_mpam(ctx, mpamvpm1_el2));
 		break;
 	}
 }
-#endif /* CTX_INCLUDE_MPAM_REGS */
 
 /* ---------------------------------------------------------------------------
  * The following registers are not added:
@@ -1283,12 +1277,9 @@
 		write_el2_ctx_mte2(el2_sysregs_ctx, tfsr_el2, read_tfsr_el2());
 	}
 
-#if CTX_INCLUDE_MPAM_REGS
 	if (is_feat_mpam_supported()) {
-		mpam_t *mpam_ctx = get_mpam_ctx(ctx);
-		el2_sysregs_context_save_mpam(mpam_ctx);
+		el2_sysregs_context_save_mpam(el2_sysregs_ctx);
 	}
-#endif
 
 	if (is_feat_fgt_supported()) {
 		el2_sysregs_context_save_fgt(el2_sysregs_ctx);
@@ -1369,12 +1360,9 @@
 		write_tfsr_el2(read_el2_ctx_mte2(el2_sysregs_ctx, tfsr_el2));
 	}
 
-#if CTX_INCLUDE_MPAM_REGS
 	if (is_feat_mpam_supported()) {
-		mpam_t *mpam_ctx = get_mpam_ctx(ctx);
-		el2_sysregs_context_restore_mpam(mpam_ctx);
+		el2_sysregs_context_restore_mpam(el2_sysregs_ctx);
 	}
-#endif
 
 	if (is_feat_fgt_supported()) {
 		el2_sysregs_context_restore_fgt(el2_sysregs_ctx);