fix(errata): workaround for Cortex-A710 erratum 2147715

Cortex-A710 erratum 2147715 is a Cat B erratum that applies
to revision r2p0 of the CPU, and is fixed in r2p1. The work-
around is to set CPUACTLR_EL1[22]=1. Setting this will cause
the CFP instruction to invalidate all branch predictor resources
regardless of the context.

SDEN can be found here:
https://developer.arm.com/documentation/SDEN1775101/latest

Signed-off-by: Akram Ahmad <Akram.Ahmad@arm.com>
Change-Id: I94771bc1fc9b65a0c17d75200ec2b1df8a3279c6
diff --git a/docs/design/cpu-specific-build-macros.rst b/docs/design/cpu-specific-build-macros.rst
index e15c82e..e02cd1d 100644
--- a/docs/design/cpu-specific-build-macros.rst
+++ b/docs/design/cpu-specific-build-macros.rst
@@ -472,6 +472,10 @@
    Cortex-A710 CPU. This needs to be enabled for revisions r0p0, r1p0 and r2p0
    of the CPU and is fixed in r2p1.
 
+-  ``ERRATA_A710_2147715``: This applies errata 2147715 workaround to
+   Cortex-A710 CPU. This needs to be enabled for revision r2p0 of the CPU
+   and is fixed in r2p1.
+
 -  ``ERRATA_A710_2282622``: This applies errata 2282622 workaround to
    Cortex-A710 CPU. This needs to be enabled for revisions r0p0, r1p0 and r2p0
    of the CPU and is fixed in r2p1.
diff --git a/lib/cpus/aarch64/cortex_a710.S b/lib/cpus/aarch64/cortex_a710.S
index 8d02e7b..0b06169 100644
--- a/lib/cpus/aarch64/cortex_a710.S
+++ b/lib/cpus/aarch64/cortex_a710.S
@@ -280,6 +280,37 @@
 	b       cpu_rev_var_ls
 endfunc check_errata_2136059
 
+/* ----------------------------------------------------------------
+ * Errata workaround for Cortex-A710 Erratum 2147715.
+ * This applies to revision r2p0, and is fixed in r2p1.
+ * Inputs:
+ * x0: variant[4:7] and revision[0:3] of current cpu.
+ * Shall clobber: x0, x1, x17
+ * ----------------------------------------------------------------
+ */
+func errata_a710_2147715_wa
+	mov 	x17, x30
+	bl 	check_errata_2147715
+	cbz	x0, 1f
+
+	/* Apply workaround; set CPUACTLR_EL1[22]
+	 * to 1, which will cause the CFP instruction
+	 * to invalidate all branch predictor resources
+	 * regardless of context.
+	 */
+	mrs 	x1, CORTEX_A710_CPUACTLR_EL1
+	orr	x1, x1, CORTEX_A710_CPUACTLR_EL1_BIT_22
+	msr 	CORTEX_A710_CPUACTLR_EL1, x1
+1:
+	ret	x17
+endfunc errata_a710_2147715_wa
+
+func check_errata_2147715
+	mov 	x1, #0x20
+	mov 	x2, #0x20
+	b 	cpu_rev_var_range
+endfunc check_errata_2147715
+
 /* ---------------------------------------------------------------
  * Errata Workaround for Cortex-A710 Erratum 2282622.
  * This applies to revision r0p0, r1p0 and r2p0.
@@ -438,6 +469,7 @@
 	report_errata ERRATA_A710_2136059, cortex_a710, 2136059
 	report_errata ERRATA_A710_2282622, cortex_a710, 2282622
 	report_errata ERRATA_A710_2008768, cortex_a710, 2008768
+	report_errata ERRATA_A710_2147715, cortex_a710, 2147715
 	report_errata ERRATA_A710_2371105, cortex_a710, 2371105
 	report_errata WORKAROUND_CVE_2022_23960, cortex_a710, cve_2022_23960
 	report_errata ERRATA_DSU_2313941, cortex_a710, dsu_2313941
@@ -500,6 +532,11 @@
 	bl	errata_a710_2136059_wa
 #endif
 
+#if ERRATA_A710_2147715
+	mov	x0, x18
+	bl 	errata_a710_2147715_wa
+#endif
+
 #if ERRATA_A710_2282622
 	mov	x0, x18
 	bl	errata_a710_2282622_wa
diff --git a/lib/cpus/cpu-ops.mk b/lib/cpus/cpu-ops.mk
index 3e5e92a..b382012 100644
--- a/lib/cpus/cpu-ops.mk
+++ b/lib/cpus/cpu-ops.mk
@@ -524,6 +524,10 @@
 # to revision r0p0, r1p0 and r2p0 of the Cortex-A710 cpu and is fixed in r2p1.
 ERRATA_A710_2136059	?=0
 
+# Flag to apply erratum 2147715 workaround during reset. This erratum applies
+# to revision r2p0 of the Cortex-A710 CPU and is fixed in revision r2p1.
+ERRATA_A710_2147715	?=0
+
 # Flag to apply erratum 2282622 workaround during reset. This erratum applies
 # to revision r0p0, r1p0 and r2p0 of the Cortex-A710 cpu and is fixed in r2p1.
 ERRATA_A710_2282622	?=0
@@ -1099,6 +1103,10 @@
 $(eval $(call assert_boolean,ERRATA_A710_2136059))
 $(eval $(call add_define,ERRATA_A710_2136059))
 
+# Process ERRATA_A710_2147715 flag
+$(eval $(call assert_boolean,ERRATA_A710_2147715))
+$(eval $(call add_define,ERRATA_A710_2147715))
+
 # Process ERRATA_A710_2282622 flag
 $(eval $(call assert_boolean,ERRATA_A710_2282622))
 $(eval $(call add_define,ERRATA_A710_2282622))