refactor(cm): move EL3 registers to global context
Currently, EL3 context registers are duplicated per-world per-cpu.
Some registers have the same value across all CPUs, so this patch
moves these registers out into a per-world context to reduce
memory usage.
Change-Id: I91294e3d5f4af21a58c23599af2bdbd2a747c54a
Signed-off-by: Elizabeth Ho <elizabeth.ho@arm.com>
Signed-off-by: Jayanth Dodderi Chidanand <jayanthdodderi.chidanand@arm.com>
diff --git a/lib/extensions/sme/sme.c b/lib/extensions/sme/sme.c
index d705b64..b1409b9 100644
--- a/lib/extensions/sme/sme.c
+++ b/lib/extensions/sme/sme.c
@@ -22,17 +22,22 @@
/* Get the context state. */
state = get_el3state_ctx(context);
- /* Enable SME in CPTR_EL3. */
- reg = read_ctx_reg(state, CTX_CPTR_EL3);
- reg |= ESM_BIT;
- write_ctx_reg(state, CTX_CPTR_EL3, reg);
-
/* Set the ENTP2 bit in SCR_EL3 to enable access to TPIDR2_EL0. */
reg = read_ctx_reg(state, CTX_SCR_EL3);
reg |= SCR_ENTP2_BIT;
write_ctx_reg(state, CTX_SCR_EL3, reg);
}
+void sme_enable_per_world(per_world_context_t *per_world_ctx)
+{
+ u_register_t reg;
+
+ /* Enable SME in CPTR_EL3. */
+ reg = per_world_ctx->ctx_cptr_el3;
+ reg |= ESM_BIT;
+ per_world_ctx->ctx_cptr_el3 = reg;
+}
+
void sme_init_el3(void)
{
u_register_t cptr_el3 = read_cptr_el3();
@@ -43,7 +48,7 @@
isb();
/*
- * Set the max LEN value and FA64 bit. This register is set up globally
+ * Set the max LEN value and FA64 bit. This register is set up per_world
* to be the least restrictive, then lower ELs can restrict as needed
* using SMCR_EL2 and SMCR_EL1.
*/
@@ -87,15 +92,20 @@
/* Get the context state. */
state = get_el3state_ctx(context);
- /* Disable SME, SVE, and FPU since they all share registers. */
- reg = read_ctx_reg(state, CTX_CPTR_EL3);
- reg &= ~ESM_BIT; /* Trap SME */
- reg &= ~CPTR_EZ_BIT; /* Trap SVE */
- reg |= TFP_BIT; /* Trap FPU/SIMD */
- write_ctx_reg(state, CTX_CPTR_EL3, reg);
-
/* Disable access to TPIDR2_EL0. */
reg = read_ctx_reg(state, CTX_SCR_EL3);
reg &= ~SCR_ENTP2_BIT;
write_ctx_reg(state, CTX_SCR_EL3, reg);
}
+
+void sme_disable_per_world(per_world_context_t *per_world_ctx)
+{
+ u_register_t reg;
+
+ /* Disable SME, SVE, and FPU since they all share registers. */
+ reg = per_world_ctx->ctx_cptr_el3;
+ reg &= ~ESM_BIT; /* Trap SME */
+ reg &= ~CPTR_EZ_BIT; /* Trap SVE */
+ reg |= TFP_BIT; /* Trap FPU/SIMD */
+ per_world_ctx->ctx_cptr_el3 = reg;
+}