feat(cm): support for asymmetric feature among cores

TF-A assumes that all the cores in a platform has architecture feature
parity, this is evident by the fact that primary sets up the
Non-secure context of secondary cores.

With changing landscape of platforms (e.g. big/little/mid cores), we are
seeing more and more platforms which has feature asymmetry among cores.
There is also a scenario where certain CPU erratum only applies to one
type of cores and requires a feature to be disabled even it supports
the feature.

To handle these scenarios, introduce a hook in warmboot path which would
be called on the running CPU to override any feature disparity in the
NS context stashed up by primary. Note that, re-checking of feature for
Secure/Realm context is not required as the context is created on
running core itself.

Signed-off-by: Manish Pandey <manish.pandey2@arm.com>
Change-Id: I5a01dbda528fa8481a00fdd098b58a7463ed0e22
diff --git a/include/lib/el3_runtime/context_mgmt.h b/include/lib/el3_runtime/context_mgmt.h
index 7451b85..b7b73e6 100644
--- a/include/lib/el3_runtime/context_mgmt.h
+++ b/include/lib/el3_runtime/context_mgmt.h
@@ -44,6 +44,7 @@
 void cm_manage_extensions_el3(void);
 void manage_extensions_nonsecure_per_world(void);
 void cm_el3_arch_init_per_world(per_world_context_t *per_world_ctx);
+void cm_handle_asymmetric_features(void);
 #endif
 
 #if CTX_INCLUDE_EL2_REGS
@@ -95,6 +96,7 @@
 void cm_set_next_context(void *context);
 static inline void cm_manage_extensions_el3(void) {}
 static inline void manage_extensions_nonsecure_per_world(void) {}
+static inline void cm_handle_asymmetric_features(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 15db9e5..22f5d93 100644
--- a/lib/el3_runtime/aarch64/context_mgmt.c
+++ b/lib/el3_runtime/aarch64/context_mgmt.c
@@ -1523,6 +1523,23 @@
 }
 #endif /* CTX_INCLUDE_EL2_REGS */
 
+#if IMAGE_BL31
+/*********************************************************************************
+* This function allows Architecture features asymmetry among cores.
+* TF-A assumes that all the cores in the platform has architecture feature parity
+* and hence the context is setup on different core (e.g. primary sets up the
+* context for secondary cores).This assumption may not be true for systems where
+* cores are not conforming to same Arch version or there is CPU Erratum which
+* requires certain feature to be be disabled only on a given core.
+*
+* This function is called on secondary cores to override any disparity in context
+* setup by primary, this would be called during warmboot path.
+*********************************************************************************/
+void cm_handle_asymmetric_features(void)
+{
+}
+#endif
+
 /*******************************************************************************
  * This function is used to exit to Non-secure world. If CTX_INCLUDE_EL2_REGS
  * is enabled, it restores EL1 and EL2 sysreg contexts instead of directly
@@ -1531,6 +1548,18 @@
  ******************************************************************************/
 void cm_prepare_el3_exit_ns(void)
 {
+#if IMAGE_BL31
+	/*
+	 * Check and handle Architecture feature asymmetry among cores.
+	 *
+	 * In warmboot path secondary cores context is initialized on core which
+	 * did CPU_ON SMC call, if there is feature asymmetry in these cores handle
+	 * it in this function call.
+	 * For Symmetric cores this is an empty function.
+	 */
+	cm_handle_asymmetric_features();
+#endif
+
 #if CTX_INCLUDE_EL2_REGS
 #if ENABLE_ASSERTIONS
 	cpu_context_t *ctx = cm_get_context(NON_SECURE);