Merge "fix(errata): workaround for Cortex-A510 erratum 2971420" into integration
diff --git a/docs/design/cpu-specific-build-macros.rst b/docs/design/cpu-specific-build-macros.rst
index 9e06fe0..6562139 100644
--- a/docs/design/cpu-specific-build-macros.rst
+++ b/docs/design/cpu-specific-build-macros.rst
@@ -956,6 +956,10 @@
    Cortex-A510 CPU. This needs to be applied to revision r0p0, r0p1, r0p2,
    r0p3, r1p0, r1p1 and r1p2. It is fixed in r1p3.
 
+-  ``ERRATA_A510_2971420``: This applies erratum 2971420 workaround to
+   Cortex-A510 CPU. This needs to be applied to revisions r0p1, r0p2, r0p3,
+   r1p0, r1p1, r1p2 and r1p3 and is still open.
+
 For Cortex-A520, the following errata build flags are defined :
 
 -  ``ERRATA_A520_2630792``: This applies errata 2630792 workaround to
diff --git a/include/lib/cpus/aarch64/cortex_a510.h b/include/lib/cpus/aarch64/cortex_a510.h
index 337aac3..fb09411 100644
--- a/include/lib/cpus/aarch64/cortex_a510.h
+++ b/include/lib/cpus/aarch64/cortex_a510.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022-2023, Arm Limited. All rights reserved.
+ * Copyright (c) 2022-2025, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -52,4 +52,12 @@
 #define CORTEX_A510_CPUACTLR_EL1_DATA_CORRUPT_SHIFT		U(18)
 #define CORTEX_A510_CPUACTLR_EL1_DATA_CORRUPT_WIDTH		U(1)
 
+#ifndef __ASSEMBLER__
+
+#if ERRATA_A510_2971420
+long check_erratum_cortex_a510_2971420(long cpu_rev);
+#endif
+
+#endif /* __ASSEMBLER__ */
+
 #endif /* CORTEX_A510_H */
diff --git a/include/lib/cpus/errata.h b/include/lib/cpus/errata.h
index 9eae276..8e28d46 100644
--- a/include/lib/cpus/errata.h
+++ b/include/lib/cpus/errata.h
@@ -67,10 +67,8 @@
 }
 #endif
 
-#if ERRATA_A520_2938996 || ERRATA_X4_2726228
-unsigned int check_if_affected_core(void);
-#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/lib/cpus/aarch64/cortex_a510.S b/lib/cpus/aarch64/cortex_a510.S
index 81a227b..6ec6742 100644
--- a/lib/cpus/aarch64/cortex_a510.S
+++ b/lib/cpus/aarch64/cortex_a510.S
@@ -178,6 +178,10 @@
 	ret
 check_erratum_custom_end cortex_a510, ERRATUM(2313941)
 
+.global check_erratum_cortex_a510_2971420
+add_erratum_entry cortex_a510, ERRATUM(2971420), ERRATA_A510_2971420
+check_erratum_range cortex_a510, ERRATUM(2971420), CPU_REV(0, 1), CPU_REV(1, 3)
+
 	/* ----------------------------------------------------
 	 * HW will do the cache maintenance while powering down
 	 * ----------------------------------------------------
diff --git a/lib/cpus/cpu-ops.mk b/lib/cpus/cpu-ops.mk
index b04d617..4cfa765 100644
--- a/lib/cpus/cpu-ops.mk
+++ b/lib/cpus/cpu-ops.mk
@@ -966,6 +966,11 @@
 # Cortex-A510 cpu and is fixed in r1p3.
 CPU_FLAG_LIST += ERRATA_A510_2684597
 
+# Flag to apply erratum 2971420 workaround during context switch. This erratum
+# applies to revisions r0p1, r0p2, r0p3, r1p0, r1p1, r1p2 and r1p3 of the
+# Cortex-A510 cpu and is still open.
+CPU_FLAG_LIST += ERRATA_A510_2971420
+
 # Flag to apply erratum 2630792 workaround during reset. This erratum applies
 # to revisions r0p0, r0p1 of the Cortex-A520 cpu and is still open.
 CPU_FLAG_LIST += ERRATA_A520_2630792
diff --git a/lib/cpus/errata_common.c b/lib/cpus/errata_common.c
index a391430..0530647 100644
--- a/lib/cpus/errata_common.c
+++ b/lib/cpus/errata_common.c
@@ -9,6 +9,7 @@
 #include <arch.h>
 #include <arch_helpers.h>
 #include <cortex_a75.h>
+#include <cortex_a510.h>
 #include <cortex_a520.h>
 #include <cortex_a710.h>
 #include <cortex_a715.h>
@@ -25,21 +26,26 @@
 #include <neoverse_n3.h>
 #include <neoverse_v3.h>
 
-#if ERRATA_A520_2938996 || ERRATA_X4_2726228
-unsigned int check_if_affected_core(void)
+bool check_if_trbe_disable_affected_core(void)
 {
-	uint32_t midr_val = read_midr();
-	long rev_var  = cpu_get_rev_var();
-
-	if (EXTRACT_PARTNUM(midr_val) == EXTRACT_PARTNUM(CORTEX_A520_MIDR)) {
-		return check_erratum_cortex_a520_2938996(rev_var);
-	} else if (EXTRACT_PARTNUM(midr_val) == EXTRACT_PARTNUM(CORTEX_X4_MIDR)) {
-		return check_erratum_cortex_x4_2726228(rev_var);
-	}
-
-	return ERRATA_NOT_APPLIES;
-}
+	switch (EXTRACT_PARTNUM(read_midr())) {
+#if ERRATA_A520_2938996
+	case EXTRACT_PARTNUM(CORTEX_A520_MIDR):
+		return check_erratum_cortex_a520_2938996(cpu_get_rev_var()) == ERRATA_APPLIES;
 #endif
+#if ERRATA_X4_2726228
+	case EXTRACT_PARTNUM(CORTEX_X4_MIDR):
+		return check_erratum_cortex_x4_2726228(cpu_get_rev_var()) == ERRATA_APPLIES;
+#endif
+#if ERRATA_A510_2971420
+	case EXTRACT_PARTNUM(CORTEX_A510_MIDR):
+		return check_erratum_cortex_a510_2971420(cpu_get_rev_var()) == ERRATA_APPLIES;
+#endif
+	default:
+		break;
+	}
+	return false;
+}
 
 #if ERRATA_A75_764081
 bool errata_a75_764081_applies(void)
diff --git a/lib/el3_runtime/aarch64/context_mgmt.c b/lib/el3_runtime/aarch64/context_mgmt.c
index d870da4..f4fec42 100644
--- a/lib/el3_runtime/aarch64/context_mgmt.c
+++ b/lib/el3_runtime/aarch64/context_mgmt.c
@@ -1673,13 +1673,11 @@
 	}
 #endif
 
-#if ERRATA_A520_2938996 || ERRATA_X4_2726228
-	if (check_if_affected_core() == ERRATA_APPLIES) {
+	if (check_if_trbe_disable_affected_core()) {
 		if (is_feat_trbe_supported()) {
 			trbe_disable(ctx);
 		}
 	}
-#endif
 
 #if ENABLE_FEAT_TCR2 == FEAT_STATE_CHECK_ASYMMETRIC
 	el3_state_t *el3_state = get_el3state_ctx(ctx);