fix(cpus): workaround for Cortex-A715 erratum 2804830

Cortex-A715 erratum 2804830 applies to r0p0, r1p0, r1p1 and r1p2,
and is fixed in r1p3.

Under some conditions, writes of a 64B-aligned, 64B granule of
memory might cause data corruption without this workaround. See SDEN
for details.

Since this workaround disables write streaming, it is expected to
have a significant performance impact for code that is heavily
reliant on write streaming, such as memcpy or memset.

SDEN: https://developer.arm.com/documentation/SDEN-2148827/latest/

Change-Id: Ia12f6c7de7c92f6ea4aec3057b228b828d48724c
Signed-off-by: John Powell <john.powell@arm.com>
diff --git a/docs/design/cpu-specific-build-macros.rst b/docs/design/cpu-specific-build-macros.rst
index 67f29f0..9e06fe0 100644
--- a/docs/design/cpu-specific-build-macros.rst
+++ b/docs/design/cpu-specific-build-macros.rst
@@ -1001,9 +1001,13 @@
    Cortex-A715 CPU. This needs to be enabled for revisions r0p0, r1p0
    and r1p1. It is fixed in r1p2.
 
+-  ``ERRATA_A715_2804830``: This applies errata 2804830 workaround to
+   Cortex-A715 CPU. This needs to be enabled for revisions r0p0, r1p0,
+   r1p1 and r1p2. It is fixed in r1p3.
+
 -  ``ERRATA_A715_3699560``: This applies errata 3699560 workaround to
    Cortex-A715 CPU. This needs to be enabled for revisions r0p0, r1p0,
-   r1p2, r1p3. It is still open.
+   r1p2 and r1p3. It is still open.
 
 For Cortex-A720, the following errata build flags are defined :
 
diff --git a/include/lib/cpus/aarch64/cortex_a715.h b/include/lib/cpus/aarch64/cortex_a715.h
index e9bd886..9980214 100644
--- a/include/lib/cpus/aarch64/cortex_a715.h
+++ b/include/lib/cpus/aarch64/cortex_a715.h
@@ -13,20 +13,14 @@
 #define CORTEX_A715_BHB_LOOP_COUNT				U(38)
 
 /*******************************************************************************
- * CPU Auxiliary Control register 1 specific definitions.
+ * CPU Register Mappings
  ******************************************************************************/
+#define CORTEX_A715_CPUCFR_EL1					S3_0_C15_C0_0
 #define CORTEX_A715_CPUACTLR_EL1				S3_0_C15_C1_0
-
-/*******************************************************************************
- * CPU Auxiliary Control register 2 specific definitions.
- ******************************************************************************/
 #define CORTEX_A715_CPUACTLR2_EL1				S3_0_C15_C1_1
-
-/*******************************************************************************
- * CPU Extended Control register specific definitions
- ******************************************************************************/
+#define CORTEX_A715_CPUACTLR3_EL1				S3_0_C15_C1_2
 #define CORTEX_A715_CPUECTLR_EL1				S3_0_C15_C1_4
-
+#define CORTEX_A715_CPUECTLR2_EL1				S3_0_C15_C1_5
 #define CORTEX_A715_CPUPSELR_EL3				S3_6_C15_C8_0
 #define CORTEX_A715_CPUPCR_EL3					S3_6_C15_C8_1
 #define CORTEX_A715_CPUPOR_EL3					S3_6_C15_C8_2
diff --git a/lib/cpus/aarch64/cortex_a715.S b/lib/cpus/aarch64/cortex_a715.S
index d9c0df2..d863cc5 100644
--- a/lib/cpus/aarch64/cortex_a715.S
+++ b/lib/cpus/aarch64/cortex_a715.S
@@ -119,6 +119,29 @@
 
 check_erratum_ls cortex_a715, ERRATUM(2728106), CPU_REV(1, 1)
 
+workaround_reset_start cortex_a715, ERRATUM(2804830), ERRATA_A715_2804830
+	/* Workaround changes based on CORE_CACHE_PROTECTIONS field (bit 1) */
+	mrs x0, CORTEX_A715_CPUCFR_EL1
+	tbz x0, #1, wa_2804830_core_cache_prot_false
+
+	/* CORE_CACHE_PROTECTIONS==true */
+	sysreg_bit_set CORTEX_A715_CPUACTLR3_EL1, BIT(2)
+	sysreg_bit_set CORTEX_A715_CPUECTLR_EL1, BIT(23)
+	b wa_2804830_done
+
+	/* CORE_CACHE_PROTECTIONS==false */
+wa_2804830_core_cache_prot_false:
+	sysreg_bit_set CORTEX_A715_CPUECTLR2_EL1, BIT(7)
+
+wa_2804830_done:
+workaround_reset_end cortex_a715, ERRATUM(2804830)
+
+check_erratum_ls cortex_a715, ERRATUM(2804830), CPU_REV(1, 2)
+
+add_erratum_entry cortex_a715, ERRATUM(3699560), ERRATA_A715_3699560
+
+check_erratum_ls cortex_a715, ERRATUM(3699560), CPU_REV(1, 3)
+
 workaround_reset_start cortex_a715, CVE(2022, 23960), WORKAROUND_CVE_2022_23960
 #if IMAGE_BL31
 	/*
@@ -131,10 +154,6 @@
 
 check_erratum_chosen cortex_a715, CVE(2022, 23960), WORKAROUND_CVE_2022_23960
 
-add_erratum_entry cortex_a715, ERRATUM(3699560), ERRATA_A715_3699560
-
-check_erratum_ls cortex_a715, ERRATUM(3699560), CPU_REV(1, 3)
-
 cpu_reset_func_start cortex_a715
 	/* Disable speculative loads */
 	msr	SSBS, xzr
diff --git a/lib/cpus/cpu-ops.mk b/lib/cpus/cpu-ops.mk
index 8136624..b04d617 100644
--- a/lib/cpus/cpu-ops.mk
+++ b/lib/cpus/cpu-ops.mk
@@ -1038,6 +1038,10 @@
 # only to revision r0p0, r1p0 and r1p1. It is fixed in r1p2.
 CPU_FLAG_LIST += ERRATA_A715_2728106
 
+# Flag to apply erratum 2804830 workaround during reset. This erratum applies
+# to revisions r0p0, r1p0, r1p1 and r1p2. It is fixed in r1p3.
+CPU_FLAG_LIST += ERRATA_A715_2804830
+
 # Flag to apply erratum 3699560 workaround during context save/restore of
 # ICH_VMCR_EL2 reg. This erratum applies to revisions r0p0, r1p0, r1p2, r1p3
 # of the Cortex-A715 cpu and is still open.