Merge "feat(psci): remove cpu context init by index" into integration
diff --git a/docs/components/context-management-library.rst b/docs/components/context-management-library.rst
index 8cb1ace..cef6fba 100644
--- a/docs/components/context-management-library.rst
+++ b/docs/components/context-management-library.rst
@@ -106,7 +106,6 @@
 	#define FEAT_STATE_DISABLED     	0
 	#define FEAT_STATE_ENABLED      	1
 	#define FEAT_STATE_CHECK        	2
-	#define FEAT_STATE_CHECK_ASYMMETRIC	3
 
 A pattern is established for feature enablement behavior.
 Each feature must support the 3 possible values with rigid semantics.
@@ -120,15 +119,15 @@
 - **FEAT_STATE_CHECK** - same as ``FEAT_STATE_ALWAYS`` except that the feature's
   existence will be checked at runtime. Default on dynamic platforms (example: FVP).
 
-- **FEAT_STATE_CHECK_ASYMMETRIC** - same as ``FEAT_STATE_CHECK`` except that the feature's
-  existence is asymmetric across cores, which requires the feature existence is checked
-  during warmboot path also. Note that only limited number of features can be asymmetric.
-
  .. note::
-   Only limited number of features can be ``FEAT_STATE_CHECK_ASYMMETRIC`` this is due to
-   the fact that Operating systems are designed for SMP systems.
-   There are no clear guidelines what kind of mismatch is allowed but following pointers
-   can help making a decision
+
+   In general, it is assumed that all cores will support the same set of
+   architectural features (features will be symmetrical). However, there are
+   cases where this is impractical to achieve. Only some features can be
+   mismatched among cores and this is the exception rather than the rule. This
+   is due to the fact that Operating systems are designed for SMP systems. There
+   are no clear guidelines what kind of mismatch is allowed but following
+   pointers can help in making a decision:
 
     - All mandatory features must be symmetric.
     - Any feature that impacts the generation of page tables must be symmetric.
@@ -136,8 +135,9 @@
     - Features related with profiling, debug and trace could be asymmetric
     - Migration of vCPU/tasks between CPUs should not cause an error
 
-    Whenever there is asymmetric feature support is added for a feature TF-A need to add
-    feature specific code in context management code.
+   TF-A caters for mismatched features, however, this is not regularly tested
+   for all features and may not work as expected, even without considering OS
+   support.
 
  .. note::
    ``FEAT_RAS`` is an exception here, as it impacts the execution of EL3 and
@@ -345,9 +345,9 @@
 
 |Context Init WarmBoot|
 
-The primary CPU initializes the Non-Secure context for the secondary CPU while
-restoring re-entry information for the Non-Secure world.
-It initialises via ``cm_init_context_by_index(target_idx, ep )``.
+The primary CPU writes the entrypoint for the secondary CPU. When the secondary
+wakes up it initialises its own context via ``cm_init_my_context( ep )`` using
+the provided entrypoint.
 
 ``psci_warmboot_entrypoint()`` is the warm boot entrypoint procedure.
 During the warm bootup process, secondary CPUs have their secure context
diff --git a/include/common/feat_detect.h b/include/common/feat_detect.h
index b85e1ce..18e6c42 100644
--- a/include/common/feat_detect.h
+++ b/include/common/feat_detect.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2022-2025, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -14,6 +14,5 @@
 #define FEAT_STATE_DISABLED		0
 #define FEAT_STATE_ALWAYS		1
 #define FEAT_STATE_CHECK		2
-#define FEAT_STATE_CHECK_ASYMMETRIC	3
 
 #endif /* FEAT_DETECT_H */
diff --git a/include/lib/cpus/errata.h b/include/lib/cpus/errata.h
index 8e28d46..1f5f5ea 100644
--- a/include/lib/cpus/errata.h
+++ b/include/lib/cpus/errata.h
@@ -67,7 +67,6 @@
 }
 #endif
 
-
 bool check_if_trbe_disable_affected_core(void);
 int check_wa_cve_2024_7881(void);
 bool errata_ich_vmcr_el2_applies(void);
diff --git a/include/lib/el3_runtime/context_mgmt.h b/include/lib/el3_runtime/context_mgmt.h
index a48ed96..72a8ea2 100644
--- a/include/lib/el3_runtime/context_mgmt.h
+++ b/include/lib/el3_runtime/context_mgmt.h
@@ -34,17 +34,11 @@
 void cm_prepare_el3_exit(uint32_t security_state);
 void cm_prepare_el3_exit_ns(void);
 
-#if !IMAGE_BL1
-void cm_init_context_by_index(unsigned int cpu_idx,
-			      const struct entry_point_info *ep);
-#endif /* !IMAGE_BL1 */
-
 #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_handle_asymmetric_features(void);
 #endif
 
 #if (CTX_INCLUDE_EL2_REGS && IMAGE_BL31)
@@ -97,7 +91,6 @@
 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) {}
-static inline void cm_handle_asymmetric_features(void) {}
 #endif /* __aarch64__ */
 
 #endif /* CONTEXT_MGMT_H */
diff --git a/include/lib/el3_runtime/cpu_data.h b/include/lib/el3_runtime/cpu_data.h
index e417f45..3dc156a 100644
--- a/include/lib/el3_runtime/cpu_data.h
+++ b/include/lib/el3_runtime/cpu_data.h
@@ -23,10 +23,10 @@
 /* Size of cpu_context array */
 #define CPU_DATA_CONTEXT_NUM		3
 /* Offset of cpu_ops_ptr, size 8 bytes */
-#define CPU_DATA_CPU_OPS_PTR		0x18
+#define CPU_DATA_CPU_OPS_PTR		0x20
 #else /* ENABLE_RME */
 #define CPU_DATA_CONTEXT_NUM		2
-#define CPU_DATA_CPU_OPS_PTR		0x10
+#define CPU_DATA_CPU_OPS_PTR		0x18
 #endif /* ENABLE_RME */
 
 #if ENABLE_PAUTH
@@ -47,8 +47,9 @@
 #if CRASH_REPORTING
 #error "Crash reporting is not supported in AArch32"
 #endif
-#define CPU_DATA_CPU_OPS_PTR		0x0
-#define CPU_DATA_CRASH_BUF_OFFSET	(0x4 + PSCI_CPU_DATA_SIZE)
+#define WARMBOOT_EP_INFO		0x0
+#define CPU_DATA_CPU_OPS_PTR		0x4
+#define CPU_DATA_CRASH_BUF_OFFSET	(CPU_DATA_CPU_OPS_PTR + PSCI_CPU_DATA_SIZE)
 
 #endif	/* __aarch64__ */
 
@@ -79,7 +80,12 @@
 #if ENABLE_RUNTIME_INSTRUMENTATION
 /* Temporary space to store PMF timestamps from assembly code */
 #define CPU_DATA_PMF_TS_COUNT		1
+#if __aarch64__
 #define CPU_DATA_PMF_TS0_OFFSET		CPU_DATA_EHF_DATA_BUF_END
+#else
+/* alignment */
+#define CPU_DATA_PMF_TS0_OFFSET		(CPU_DATA_EHF_DATA_BUF_END + 8)
+#endif
 #define CPU_DATA_PMF_TS0_IDX		0
 #endif
 
@@ -131,6 +137,7 @@
 #ifdef __aarch64__
 	void *cpu_context[CPU_DATA_CONTEXT_NUM];
 #endif /* __aarch64__ */
+	entry_point_info_t *warmboot_ep_info;
 	uintptr_t cpu_ops_ptr;
 	struct psci_cpu_data psci_svc_cpu_data;
 #if ENABLE_PAUTH
diff --git a/lib/el3_runtime/aarch32/context_mgmt.c b/lib/el3_runtime/aarch32/context_mgmt.c
index 132888c..00d9c01 100644
--- a/lib/el3_runtime/aarch32/context_mgmt.c
+++ b/lib/el3_runtime/aarch32/context_mgmt.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2024, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2025, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -155,21 +155,6 @@
 #endif /*  IMAGE_BL32 */
 }
 
-#if !IMAGE_BL1
-/*******************************************************************************
- * The following function initializes the cpu_context for a CPU specified by
- * its `cpu_idx` for first use, and sets the initial entrypoint state as
- * specified by the entry_point_info structure.
- ******************************************************************************/
-void cm_init_context_by_index(unsigned int cpu_idx,
-			      const entry_point_info_t *ep)
-{
-	cpu_context_t *ctx;
-	ctx = cm_get_context_by_index(cpu_idx, GET_SECURITY_STATE(ep->h.attr));
-	cm_setup_context(ctx, ep);
-}
-#endif /* !IMAGE_BL1 */
-
 /*******************************************************************************
  * The following function initializes the cpu_context for the current CPU
  * for first use, and sets the initial entrypoint state as specified by the
diff --git a/lib/el3_runtime/aarch64/context_mgmt.c b/lib/el3_runtime/aarch64/context_mgmt.c
index 021d538..2d1b063 100644
--- a/lib/el3_runtime/aarch64/context_mgmt.c
+++ b/lib/el3_runtime/aarch64/context_mgmt.c
@@ -484,13 +484,6 @@
 #endif /* CTX_INCLUDE_PAUTH_REGS */
 
 	/*
-	 * SCR_EL3.TCR2EN: Enable access to TCR2_ELx for AArch64 if present.
-	 */
-	if (is_feat_tcr2_supported() && (GET_RW(ep->spsr) == MODE_RW_64)) {
-		scr_el3 |= SCR_TCR2EN_BIT;
-	}
-
-	/*
 	 * SCR_EL3.PIEN: Enable permission indirection and overlay
 	 * registers for AArch64 if present.
 	 */
@@ -591,6 +584,10 @@
 		trf_enable(ctx);
 	}
 
+	if (is_feat_tcr2_supported()) {
+		tcr2_enable(ctx);
+	}
+
 	pmuv3_enable(ctx);
 #endif /* IMAGE_BL31 */
 
@@ -839,8 +836,10 @@
 		spe_enable(ctx);
 	}
 
-	if (is_feat_trbe_supported()) {
-		trbe_enable(ctx);
+	if (!check_if_trbe_disable_affected_core()) {
+		if (is_feat_trbe_supported()) {
+			trbe_enable(ctx);
+		}
 	}
 
 	if (is_feat_brbe_supported()) {
@@ -955,21 +954,6 @@
 #endif /* IMAGE_BL31 */
 }
 
-#if !IMAGE_BL1
-/*******************************************************************************
- * The following function initializes the cpu_context for a CPU specified by
- * its `cpu_idx` for first use, and sets the initial entrypoint state as
- * specified by the entry_point_info structure.
- ******************************************************************************/
-void cm_init_context_by_index(unsigned int cpu_idx,
-			      const entry_point_info_t *ep)
-{
-	cpu_context_t *ctx;
-	ctx = cm_get_context_by_index(cpu_idx, GET_SECURITY_STATE(ep->h.attr));
-	cm_setup_context(ctx, ep);
-}
-#endif /* !IMAGE_BL1 */
-
 /*******************************************************************************
  * The following function initializes the cpu_context for the current CPU
  * for first use, and sets the initial entrypoint state as specified by the
@@ -1647,52 +1631,6 @@
 }
 #endif /* (CTX_INCLUDE_EL2_REGS && IMAGE_BL31) */
 
-#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)
-{
-	cpu_context_t *ctx __maybe_unused = cm_get_context(NON_SECURE);
-
-	assert(ctx != NULL);
-
-#if ENABLE_SPE_FOR_NS == FEAT_STATE_CHECK_ASYMMETRIC
-	if (is_feat_spe_supported()) {
-		spe_enable(ctx);
-	} else {
-		spe_disable(ctx);
-	}
-#endif
-
-	if (check_if_trbe_disable_affected_core()) {
-		if (is_feat_trbe_supported()) {
-			trbe_disable(ctx);
-		}
-	}
-
-#if ENABLE_FEAT_TCR2 == FEAT_STATE_CHECK_ASYMMETRIC
-	el3_state_t *el3_state = get_el3state_ctx(ctx);
-	u_register_t spsr = read_ctx_reg(el3_state, CTX_SPSR_EL3);
-
-	if (is_feat_tcr2_supported() && (GET_RW(spsr) == MODE_RW_64)) {
-		tcr2_enable(ctx);
-	} else {
-		tcr2_disable(ctx);
-	}
-#endif
-
-}
-#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
@@ -1701,18 +1639,6 @@
  ******************************************************************************/
 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 && IMAGE_BL31)
 #if ENABLE_ASSERTIONS
 	cpu_context_t *ctx = cm_get_context(NON_SECURE);
diff --git a/lib/psci/psci_common.c b/lib/psci/psci_common.c
index 17ecab8..1c634e3 100644
--- a/lib/psci/psci_common.c
+++ b/lib/psci/psci_common.c
@@ -1032,6 +1032,13 @@
 	}
 
 	/*
+	 * Caches and (importantly) coherency are on so we can rely on seeing
+	 * whatever the primary gave us without explicit cache maintenance
+	 */
+	entry_point_info_t *ep = get_cpu_data(warmboot_ep_info);
+	cm_init_my_context(ep);
+
+	/*
 	 * Generic management: Now we just need to retrieve the
 	 * information that we had stashed away during the cpu_on
 	 * call to set this cpu on its way.
diff --git a/lib/psci/psci_main.c b/lib/psci/psci_main.c
index 34668ea..f126f49 100644
--- a/lib/psci/psci_main.c
+++ b/lib/psci/psci_main.c
@@ -28,15 +28,17 @@
 
 {
 	int rc;
-	entry_point_info_t ep;
+	entry_point_info_t *ep;
+	unsigned int target_idx = (unsigned int)plat_core_pos_by_mpidr(target_cpu);
 
 	/* Validate the target CPU */
 	if (!is_valid_mpidr(target_cpu)) {
 		return PSCI_E_INVALID_PARAMS;
 	}
 
-	/* Validate the entry point and get the entry_point_info */
-	rc = psci_validate_entry_point(&ep, entrypoint, context_id);
+	ep = get_cpu_data_by_index(target_idx, warmboot_ep_info);
+	/* Validate the lower EL entry point and put it in the entry_point_info */
+	rc = psci_validate_entry_point(ep, entrypoint, context_id);
 	if (rc != PSCI_E_SUCCESS) {
 		return rc;
 	}
@@ -45,7 +47,7 @@
 	 * To turn this cpu on, specify which power
 	 * levels need to be turned on
 	 */
-	return psci_cpu_on_start(target_cpu, &ep);
+	return psci_cpu_on_start(target_cpu, ep);
 }
 
 unsigned int psci_version(void)
@@ -59,7 +61,6 @@
 {
 	int rc;
 	unsigned int target_pwrlvl, is_power_down_state;
-	entry_point_info_t ep;
 	psci_power_state_t state_info = { {PSCI_LOCAL_STATE_RUN} };
 	plat_local_state_t cpu_pd_state;
 	unsigned int cpu_idx = plat_my_core_pos();
@@ -173,7 +174,9 @@
 	 * point and program entry information.
 	 */
 	if (is_power_down_state != 0U) {
-		rc = psci_validate_entry_point(&ep, entrypoint, context_id);
+		entry_point_info_t *ep = get_cpu_data_by_index(cpu_idx, warmboot_ep_info);
+
+		rc = psci_validate_entry_point(ep, entrypoint, context_id);
 		if (rc != PSCI_E_SUCCESS) {
 			return rc;
 		}
@@ -186,7 +189,6 @@
 	 * arrival of an interrupt
 	 */
 	rc = psci_cpu_suspend_start(cpu_idx,
-				    &ep,
 				    target_pwrlvl,
 				    &state_info,
 				    is_power_down_state);
@@ -199,8 +201,8 @@
 {
 	int rc;
 	psci_power_state_t state_info;
-	entry_point_info_t ep;
 	unsigned int cpu_idx = plat_my_core_pos();
+	entry_point_info_t *ep = get_cpu_data_by_index(cpu_idx, warmboot_ep_info);
 
 	/* Check if the current CPU is the last ON CPU in the system */
 	if (!psci_is_last_on_cpu(cpu_idx)) {
@@ -208,7 +210,7 @@
 	}
 
 	/* Validate the entry point and get the entry_point_info */
-	rc = psci_validate_entry_point(&ep, entrypoint, context_id);
+	rc = psci_validate_entry_point(ep, entrypoint, context_id);
 	if (rc != PSCI_E_SUCCESS) {
 		return rc;
 	}
@@ -235,7 +237,6 @@
 	 * arrival of an interrupt
 	 */
 	rc = psci_cpu_suspend_start(cpu_idx,
-				    &ep,
 				    PLAT_MAX_PWR_LVL,
 				    &state_info,
 				    PSTATE_TYPE_POWERDOWN);
diff --git a/lib/psci/psci_on.c b/lib/psci/psci_on.c
index 3eacb9c..1bbea7a 100644
--- a/lib/psci/psci_on.c
+++ b/lib/psci/psci_on.c
@@ -141,10 +141,7 @@
 	rc = psci_plat_pm_ops->pwr_domain_on(target_cpu);
 	assert((rc == PSCI_E_SUCCESS) || (rc == PSCI_E_INTERN_FAIL));
 
-	if (rc == PSCI_E_SUCCESS) {
-		/* Store the re-entry information for the non-secure world. */
-		cm_init_context_by_index(target_idx, ep);
-	} else {
+	if (rc != PSCI_E_SUCCESS) {
 		/* Restore the state on error. */
 		psci_set_aff_info_state_by_idx(target_idx, AFF_STATE_OFF);
 		flush_cpu_data_by_index(target_idx,
diff --git a/lib/psci/psci_private.h b/lib/psci/psci_private.h
index 49b19c9..f3f5a5c 100644
--- a/lib/psci/psci_private.h
+++ b/lib/psci/psci_private.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2024, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2025, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -344,7 +344,6 @@
 
 /* Private exported functions from psci_suspend.c */
 int psci_cpu_suspend_start(unsigned int idx,
-			   const entry_point_info_t *ep,
 			   unsigned int end_pwrlvl,
 			   psci_power_state_t *state_info,
 			   unsigned int is_power_down_state);
diff --git a/lib/psci/psci_setup.c b/lib/psci/psci_setup.c
index 3604549..e1b0ae8 100644
--- a/lib/psci/psci_setup.c
+++ b/lib/psci/psci_setup.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2024, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2025, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -30,6 +30,7 @@
  * of relying on platform defined constants.
  ******************************************************************************/
 static cpu_context_t psci_ns_context[PLATFORM_CORE_COUNT];
+static entry_point_info_t warmboot_ep_info[PLATFORM_CORE_COUNT];
 
 /******************************************************************************
  * Define the psci capability variable.
@@ -114,6 +115,13 @@
 	}
 }
 
+static void __init populate_cpu_data(void)
+{
+	for (unsigned int idx = 0; idx < psci_plat_core_count; idx++) {
+		set_cpu_data_by_index(idx, warmboot_ep_info, &warmboot_ep_info[idx]);
+	}
+}
+
 /*******************************************************************************
  * Core routine to populate the power domain tree. The tree descriptor passed by
  * the platform is populated breadth-first and the first entry in the map
@@ -218,6 +226,9 @@
 	/* Update the CPU limits for each node in psci_non_cpu_pd_nodes */
 	psci_update_pwrlvl_limits();
 
+	/* Initialise the warmboot entrypoints */
+	populate_cpu_data();
+
 	/* Populate the mpidr field of cpu node for this CPU */
 	psci_cpu_pd_nodes[cpu_idx].mpidr =
 		read_mpidr() & MPIDR_AFFINITY_MASK;
diff --git a/lib/psci/psci_suspend.c b/lib/psci/psci_suspend.c
index f690e49..39d4482 100644
--- a/lib/psci/psci_suspend.c
+++ b/lib/psci/psci_suspend.c
@@ -45,7 +45,6 @@
 static void psci_suspend_to_pwrdown_start(unsigned int idx,
 					  unsigned int end_pwrlvl,
 					  unsigned int max_off_lvl,
-					  const entry_point_info_t *ep,
 					  const psci_power_state_t *state_info)
 {
 	PUBLISH_EVENT_ARG(psci_suspend_pwrdown_start, &idx);
@@ -85,12 +84,6 @@
 	if (psci_plat_pm_ops->pwr_domain_suspend_pwrdown_early != NULL)
 		psci_plat_pm_ops->pwr_domain_suspend_pwrdown_early(state_info);
 #endif
-
-	/*
-	 * Store the re-entry information for the non-secure world.
-	 */
-	cm_init_my_context(ep);
-
 	/*
 	 * Arch. management. Initiate power down sequence.
 	 */
@@ -116,7 +109,6 @@
  * not possible to undo any of the actions taken beyond that point.
  ******************************************************************************/
 int psci_cpu_suspend_start(unsigned int idx,
-			   const entry_point_info_t *ep,
 			   unsigned int end_pwrlvl,
 			   psci_power_state_t *state_info,
 			   unsigned int is_power_down_state)
@@ -124,10 +116,6 @@
 	int rc = PSCI_E_SUCCESS;
 	unsigned int parent_nodes[PLAT_MAX_PWR_LVL] = {0};
 	unsigned int max_off_lvl = 0;
-#if FEAT_PABANDON
-	cpu_context_t *ctx = cm_get_context(NON_SECURE);
-	cpu_context_t old_ctx;
-#endif
 
 	/*
 	 * This function must only be called on platforms where the
@@ -205,26 +193,9 @@
 #if !CTX_INCLUDE_EL2_REGS
 		cm_el1_sysregs_context_save(NON_SECURE);
 #endif
-		/*
-		 * when the core wakes it expects its context to already be in
-		 * place so we must overwrite it before powerdown. But if
-		 * powerdown never happens we want the old context. Save it in
-		 * case we wake up. EL2/El1 will not be touched by PSCI so don't
-		 * copy */
-		memcpy(&ctx->gpregs_ctx, &old_ctx.gpregs_ctx, sizeof(gp_regs_t));
-		memcpy(&ctx->el3state_ctx, &old_ctx.el3state_ctx, sizeof(el3_state_t));
-#if DYNAMIC_WORKAROUND_CVE_2018_3639
-		memcpy(&ctx->cve_2018_3639_ctx, &old_ctx.cve_2018_3639_ctx, sizeof(cve_2018_3639_t));
-#endif
-#if ERRATA_SPECULATIVE_AT
-		memcpy(&ctx->errata_speculative_at_ctx, &old_ctx.errata_speculative_at_ctx, sizeof(errata_speculative_at_t));
-#endif
-#if CTX_INCLUDE_PAUTH_REGS
-		memcpy(&ctx->pauth_ctx, &old_ctx.pauth_ctx, sizeof(pauth_t));
-#endif
 #endif
 		max_off_lvl = psci_find_max_off_lvl(state_info);
-		psci_suspend_to_pwrdown_start(idx, end_pwrlvl, end_pwrlvl, ep, state_info);
+		psci_suspend_to_pwrdown_start(idx, end_pwrlvl, end_pwrlvl, state_info);
 	}
 
 	/*
@@ -301,18 +272,6 @@
 #if FEAT_PABANDON
 		psci_cpu_suspend_to_powerdown_finish(idx, max_off_lvl, state_info);
 
-		/* we overwrote context ourselves, put it back */
-		memcpy(&ctx->gpregs_ctx, &old_ctx.gpregs_ctx, sizeof(gp_regs_t));
-		memcpy(&ctx->el3state_ctx, &old_ctx.el3state_ctx, sizeof(el3_state_t));
-#if DYNAMIC_WORKAROUND_CVE_2018_3639
-		memcpy(&ctx->cve_2018_3639_ctx, &old_ctx.cve_2018_3639_ctx, sizeof(cve_2018_3639_t));
-#endif
-#if ERRATA_SPECULATIVE_AT
-		memcpy(&ctx->errata_speculative_at_ctx, &old_ctx.errata_speculative_at_ctx, sizeof(errata_speculative_at_t));
-#endif
-#if CTX_INCLUDE_PAUTH_REGS
-		memcpy(&ctx->pauth_ctx, &old_ctx.pauth_ctx, sizeof(pauth_t));
-#endif
 #if !CTX_INCLUDE_EL2_REGS
 		cm_el1_sysregs_context_restore(NON_SECURE);
 #endif
diff --git a/plat/arm/board/tc/platform.mk b/plat/arm/board/tc/platform.mk
index a056bc2..cf42243 100644
--- a/plat/arm/board/tc/platform.mk
+++ b/plat/arm/board/tc/platform.mk
@@ -35,8 +35,8 @@
 ENABLE_AMU_AUXILIARY_COUNTERS	:=	1
 ENABLE_MPMM			:=	1
 ENABLE_FEAT_MTE2		:=	2
-ENABLE_SPE_FOR_NS		:=	3
-ENABLE_FEAT_TCR2		:=	3
+ENABLE_SPE_FOR_NS		:=	2
+ENABLE_FEAT_TCR2		:=	2
 
 ifneq ($(filter ${TARGET_PLATFORM}, 3),)
 ENABLE_FEAT_RNG_TRAP		:=	0