refactor(cm): gather per-world context management to the same place
The per-world calls are disparate - they get called in different places,
are guarded in different ways, and the code is apart.
Since they just need to be called once at boot, add a function that we
can call from BL31 and be done with it.
Change-Id: Id0ade302e35f2b00ca37c552a53038942ab7b58e
Signed-off-by: Boyan Karatotev <boyan.karatotev@arm.com>
diff --git a/lib/el3_runtime/aarch64/context_mgmt.c b/lib/el3_runtime/aarch64/context_mgmt.c
index 7795fcf..50e9565 100644
--- a/lib/el3_runtime/aarch64/context_mgmt.c
+++ b/lib/el3_runtime/aarch64/context_mgmt.c
@@ -48,11 +48,9 @@
#endif /* ENABLE_FEAT_TWED */
per_world_context_t per_world_context[CPU_DATA_CONTEXT_NUM];
-static bool has_secure_perworld_init;
static void manage_extensions_nonsecure(cpu_context_t *ctx);
static void manage_extensions_secure(cpu_context_t *ctx);
-static void manage_extensions_secure_per_world(void);
#if ((IMAGE_BL1) || (IMAGE_BL31 && (!CTX_INCLUDE_EL2_REGS)))
static void setup_el1_context(cpu_context_t *ctx, const struct entry_point_info *ep)
@@ -150,17 +148,6 @@
#endif
manage_extensions_secure(ctx);
-
- /**
- * manage_extensions_secure_per_world api has to be executed once,
- * as the registers getting initialised, maintain constant value across
- * all the cpus for the secure world.
- * Henceforth, this check ensures that the registers are initialised once
- * and avoids re-initialization from multiple cores.
- */
- if (!has_secure_perworld_init) {
- manage_extensions_secure_per_world();
- }
}
#if ENABLE_RME
@@ -686,14 +673,12 @@
pmuv3_init_el3();
}
-#endif /* IMAGE_BL31 */
/******************************************************************************
* Function to initialise the registers with the RESET values in the context
* memory, which are maintained per world.
******************************************************************************/
-#if IMAGE_BL31
-void cm_el3_arch_init_per_world(per_world_context_t *per_world_ctx)
+static void cm_el3_arch_init_per_world(per_world_context_t *per_world_ctx)
{
/*
* Initialise CPTR_EL3, setting all fields rather than relying on hw.
@@ -718,15 +703,13 @@
per_world_ctx->ctx_mpam3_el3 = MPAM3_EL3_RESET_VAL;
}
-#endif /* IMAGE_BL31 */
/*******************************************************************************
* Initialise per_world_context for Non-Secure world.
* This function enables the architecture extensions, which have same value
* across the cores for the non-secure world.
******************************************************************************/
-#if IMAGE_BL31
-void manage_extensions_nonsecure_per_world(void)
+static void manage_extensions_nonsecure_per_world(void)
{
cm_el3_arch_init_per_world(&per_world_context[CPU_CONTEXT_NS]);
@@ -754,7 +737,6 @@
fpmr_enable_per_world(&per_world_context[CPU_CONTEXT_NS]);
}
}
-#endif /* IMAGE_BL31 */
/*******************************************************************************
* Initialise per_world_context for Secure world.
@@ -763,7 +745,6 @@
******************************************************************************/
static void manage_extensions_secure_per_world(void)
{
-#if IMAGE_BL31
cm_el3_arch_init_per_world(&per_world_context[CPU_CONTEXT_SECURE]);
if (is_feat_sme_supported()) {
@@ -802,11 +783,56 @@
if (is_feat_sys_reg_trace_supported()) {
sys_reg_trace_disable_per_world(&per_world_context[CPU_CONTEXT_SECURE]);
}
+}
- has_secure_perworld_init = true;
-#endif /* IMAGE_BL31 */
+static void manage_extensions_realm_per_world(void)
+{
+#if ENABLE_RME
+ cm_el3_arch_init_per_world(&per_world_context[CPU_CONTEXT_REALM]);
+
+ if (is_feat_sve_supported()) {
+ /*
+ * Enable SVE and FPU in realm context when it is enabled for NS.
+ * Realm manager must ensure that the SVE and FPU register
+ * contexts are properly managed.
+ */
+ sve_enable_per_world(&per_world_context[CPU_CONTEXT_REALM]);
+ }
+
+ /* NS can access this but Realm shouldn't */
+ if (is_feat_sys_reg_trace_supported()) {
+ sys_reg_trace_disable_per_world(&per_world_context[CPU_CONTEXT_REALM]);
+ }
+
+ /*
+ * If SME/SME2 is supported and enabled for NS world, then disable trapping
+ * of SME instructions for Realm world. RMM will save/restore required
+ * registers that are shared with SVE/FPU so that Realm can use FPU or SVE.
+ */
+ if (is_feat_sme_supported()) {
+ sme_enable_per_world(&per_world_context[CPU_CONTEXT_REALM]);
+ }
+
+ /*
+ * If FEAT_MPAM is supported and enabled, then disable trapping access
+ * to the MPAM registers for Realm world. Instead, RMM will configure
+ * the access to be trapped by itself so it can inject undefined aborts
+ * back to the Realm.
+ */
+ if (is_feat_mpam_supported()) {
+ mpam_enable_per_world(&per_world_context[CPU_CONTEXT_REALM]);
+ }
+#endif /* ENABLE_RME */
}
+void cm_manage_extensions_per_world(void)
+{
+ manage_extensions_nonsecure_per_world();
+ manage_extensions_secure_per_world();
+ manage_extensions_realm_per_world();
+}
+#endif /* IMAGE_BL31 */
+
/*******************************************************************************
* Enable architecture extensions on first entry to Non-secure world.
******************************************************************************/