fix(cpus): workaround for Cortex-X4 erratum 2957258

Cortex-X4 erratum 2957258 that applies to r0p0, r0p1 and is fixed in
r0p2.

In EL3, reads of MPIDR_EL1 and MIDR_EL1 might incorrectly virtualize
which register to return when reading the value of
MPIDR_EL1/VMPIDR_EL2 and MIDR_EL1/VPIDR_EL2, respectively.

The workaround is to do an ISB prior to an MRS read to either
MPIDR_EL1 and MIDR_EL1.

SDEN documentation:
https://developer.arm.com/documentation/109148/latest/

Change-Id: I2d8e7f4ce19ca2e1d87527c31e7778d81aff0279
Signed-off-by: Govindraj Raja <govindraj.raja@arm.com>
diff --git a/docs/design/cpu-specific-build-macros.rst b/docs/design/cpu-specific-build-macros.rst
index 4637908..0e5c7a0 100644
--- a/docs/design/cpu-specific-build-macros.rst
+++ b/docs/design/cpu-specific-build-macros.rst
@@ -882,6 +882,9 @@
 - ``ERRATA_X4_2923985``: This applies errata 2923985 workaround to Cortex-X4
   CPU. This needs to be enabled for revisions r0p0 and r0p1. It is fixed in r0p2.
 
+- ``ERRATA_X4_2957258``: This applies errata 2957258 workaround to Cortex-X4
+  CPU. This needs to be enabled for revisions r0p0 and r0p1. It is fixed in r0p2.
+
 - ``ERRATA_X4_3076789``: This applies errata 3076789 workaround to Cortex-X4
   CPU. This needs to be enabled for revisions r0p0 and r0p1. It is fixed in r0p2.
 
diff --git a/lib/cpus/aarch64/cortex_x4.S b/lib/cpus/aarch64/cortex_x4.S
index fded73f..1e81892 100644
--- a/lib/cpus/aarch64/cortex_x4.S
+++ b/lib/cpus/aarch64/cortex_x4.S
@@ -89,6 +89,21 @@
 
 check_erratum_ls cortex_x4, ERRATUM(2923985), CPU_REV(0, 1)
 
+workaround_reset_start cortex_x4, ERRATUM(2957258), ERRATA_X4_2957258
+	/* Add ISB before MRS reads of MPIDR_EL1/MIDR_EL1 */
+	ldr x0, =0x1
+	msr S3_6_c15_c8_0, x0 	/* msr CPUPSELR_EL3, X0 */
+	ldr x0, =0xd5380000
+	msr S3_6_c15_c8_2, x0 	/* msr CPUPOR_EL3, X0 */
+	ldr x0, =0xFFFFFF40
+	msr S3_6_c15_c8_3,x0 	/* msr CPUPMR_EL3, X0 */
+	ldr x0, =0x000080010033f
+	msr S3_6_c15_c8_1, x0	/* msr CPUPCR_EL3, X0 */
+	isb
+workaround_reset_end cortex_x4, ERRATUM(2957258)
+
+check_erratum_ls cortex_x4, ERRATUM(2957258), CPU_REV(0, 1)
+
 workaround_reset_start cortex_x4, ERRATUM(3076789), ERRATA_X4_3076789
 	sysreg_bit_set CORTEX_X4_CPUACTLR3_EL1, BIT(14)
 	sysreg_bit_set CORTEX_X4_CPUACTLR3_EL1, BIT(13)
diff --git a/lib/cpus/cpu-ops.mk b/lib/cpus/cpu-ops.mk
index 0db7e94..38abbc7 100644
--- a/lib/cpus/cpu-ops.mk
+++ b/lib/cpus/cpu-ops.mk
@@ -885,6 +885,12 @@
 # to revisions r0p0 and r0p1 of the Cortex-X4 cpu. It is fixed in r0p2.
 CPU_FLAG_LIST += ERRATA_X4_2923985
 
+# Flag to apply erratum 2957258 workaround to avoid incorrect virtualization of
+# MPIDR_EL1/VMPIDR_EL2 and MIDR_EL1/VPIDR_EL2 when reading in EL2/EL3. This
+# erratum applies to revisions r0p0, r0p1 of the Cortex-X4 cpu. It is fixed
+# in r0p2.
+CPU_FLAG_LIST += ERRATA_X4_2957258
+
 # Flag to apply erratum 3076789 workaround on reset. This erratum applies
 # to revisions r0p0 and r0p1 of the Cortex-X4 cpu. It is fixed in r0p2.
 CPU_FLAG_LIST += ERRATA_X4_3076789