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);