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/bl31/bl31_main.c b/bl31/bl31_main.c
index ba26366..4d641d3 100644
--- a/bl31/bl31_main.c
+++ b/bl31/bl31_main.c
@@ -123,8 +123,8 @@
/* Init registers that never change for the lifetime of TF-A */
cm_manage_extensions_el3(plat_my_core_pos());
- /* Init per-world context registers for non-secure world */
- manage_extensions_nonsecure_per_world();
+ /* Init per-world context registers */
+ cm_manage_extensions_per_world();
NOTICE("BL31: %s\n", build_version_string);
NOTICE("BL31: %s\n", build_message);
diff --git a/include/lib/el3_runtime/context_mgmt.h b/include/lib/el3_runtime/context_mgmt.h
index 72a8ea2..f71f33c 100644
--- a/include/lib/el3_runtime/context_mgmt.h
+++ b/include/lib/el3_runtime/context_mgmt.h
@@ -37,8 +37,7 @@
#ifdef __aarch64__
#if IMAGE_BL31
void cm_manage_extensions_el3(unsigned int my_idx);
-void manage_extensions_nonsecure_per_world(void);
-void cm_el3_arch_init_per_world(per_world_context_t *per_world_ctx);
+void cm_manage_extensions_per_world(void);
#endif
#if (CTX_INCLUDE_EL2_REGS && IMAGE_BL31)
@@ -90,7 +89,6 @@
void *cm_get_next_context(void);
void cm_set_next_context(void *context);
static inline void cm_manage_extensions_el3(unsigned int cpu_idx) {}
-static inline void manage_extensions_nonsecure_per_world(void) {}
#endif /* __aarch64__ */
#endif /* CONTEXT_MGMT_H */
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.
******************************************************************************/
diff --git a/services/std_svc/rmmd/rmmd_main.c b/services/std_svc/rmmd/rmmd_main.c
index 35582dc..7435130 100644
--- a/services/std_svc/rmmd/rmmd_main.c
+++ b/services/std_svc/rmmd/rmmd_main.c
@@ -144,44 +144,6 @@
}
}
-static void manage_extensions_realm_per_world(void)
-{
- 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]);
- }
-}
-
/*******************************************************************************
* Jump to the RMM for the first time.
******************************************************************************/
@@ -195,8 +157,6 @@
/* Enable architecture extensions */
manage_extensions_realm(&ctx->cpu_ctx);
- manage_extensions_realm_per_world();
-
/* Initialize RMM EL2 context. */
rmm_el2_context_init(&ctx->cpu_ctx.el2_sysregs_ctx);