Implement Cortex-Ares 1043202 erratum workaround

The workaround uses the instruction patching feature of the Ares cpu.

Change-Id: I868fce0dc0e8e41853dcce311f01ee3867aabb59
Signed-off-by: Dimitris Papastamos <dimitris.papastamos@arm.com>
diff --git a/include/lib/cpus/aarch64/cortex_ares.h b/include/lib/cpus/aarch64/cortex_ares.h
index b2bb633..84955b1 100644
--- a/include/lib/cpus/aarch64/cortex_ares.h
+++ b/include/lib/cpus/aarch64/cortex_ares.h
@@ -24,4 +24,10 @@
 #define CORTEX_ARES_AMU_NR_COUNTERS	U(5)
 #define CORTEX_ARES_AMU_GROUP0_MASK	U(0x1f)
 
+/* Instruction patching registers */
+#define CPUPSELR_EL3	S3_6_C15_C8_0
+#define CPUPCR_EL3	S3_6_C15_C8_1
+#define CPUPOR_EL3	S3_6_C15_C8_2
+#define CPUPMR_EL3	S3_6_C15_C8_3
+
 #endif /* __CORTEX_ARES_H__ */
diff --git a/lib/cpus/aarch64/cortex_ares.S b/lib/cpus/aarch64/cortex_ares.S
index e130201..942b6f7 100644
--- a/lib/cpus/aarch64/cortex_ares.S
+++ b/lib/cpus/aarch64/cortex_ares.S
@@ -10,7 +10,50 @@
 #include <cpuamu.h>
 #include <cpu_macros.S>
 
+/* --------------------------------------------------
+ * Errata Workaround for Cortex-Ares Errata
+ * This applies to revision r0p0 and r1p0 of Cortex-Ares.
+ * Inputs:
+ * x0: variant[4:7] and revision[0:3] of current cpu.
+ * Shall clobber: x0-x17
+ * --------------------------------------------------
+ */
+func errata_ares_1043202_wa
+	/* Compare x0 against revision r1p0 */
+	mov	x17, x30
+	bl	check_errata_1043202
+	cbz	x0, 1f
+
+	/* Apply instruction patching sequence */
+	ldr	x0, =0x0
+	msr	CPUPSELR_EL3, x0
+	ldr	x0, =0xF3BF8F2F
+	msr	CPUPOR_EL3, x0
+	ldr	x0, =0xFFFFFFFF
+	msr	CPUPMR_EL3, x0
+	ldr	x0, =0x800200071
+	msr	CPUPCR_EL3, x0
+	isb
+1:
+	ret	x17
+endfunc errata_ares_1043202_wa
+
+func check_errata_1043202
+	/* Applies to r0p0 and r1p0 */
+	mov	x1, #0x10
+	b	cpu_rev_var_ls
+endfunc check_errata_1043202
+
 func cortex_ares_reset_func
+	mov	x19, x30
+	bl	cpu_get_rev_var
+	mov	x18, x0
+
+#if ERRATA_ARES_1043202
+	mov	x0, x18
+	bl	errata_ares_1043202_wa
+#endif
+
 #if ENABLE_AMU
 	/* Make sure accesses from EL0/EL1 and EL2 are not trapped to EL3 */
 	mrs	x0, actlr_el3
@@ -29,7 +72,7 @@
 	msr	CPUAMCNTENSET_EL0, x0
 	isb
 #endif
-	ret
+	ret	x19
 endfunc cortex_ares_reset_func
 
 	/* ---------------------------------------------
@@ -48,6 +91,27 @@
 	ret
 endfunc cortex_ares_core_pwr_dwn
 
+#if REPORT_ERRATA
+/*
+ * Errata printing function for Cortex-Ares. Must follow AAPCS.
+ */
+func cortex_a72_errata_report
+	stp	x8, x30, [sp, #-16]!
+
+	bl	cpu_get_rev_var
+	mov	x8, x0
+
+	/*
+	 * Report all errata. The revision-variant information is passed to
+	 * checking functions of each errata.
+	 */
+	report_errata ERRATA_ARES_1043202, cortex_ares, 1043202
+
+	ldp	x8, x30, [sp], #16
+	ret
+endfunc cortex_a72_errata_report
+#endif
+
 	/* ---------------------------------------------
 	 * This function provides cortex_ares specific
 	 * register information for crash reporting.
diff --git a/lib/cpus/cpu-ops.mk b/lib/cpus/cpu-ops.mk
index 434c13e..456e3e5 100644
--- a/lib/cpus/cpu-ops.mk
+++ b/lib/cpus/cpu-ops.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2014-2017, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2014-2018, ARM Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -119,6 +119,10 @@
 # only to revision <= r0p3 of the Cortex A72 cpu.
 ERRATA_A72_859971	?=0
 
+# Flag to apply T32 CLREX workaround during reset. This erratum applies
+# only to r0p0 and r1p0 of the Ares cpu.
+ERRATA_ARES_1043202	?=1
+
 # Process ERRATA_A53_826319 flag
 $(eval $(call assert_boolean,ERRATA_A53_826319))
 $(eval $(call add_define,ERRATA_A53_826319))
@@ -179,6 +183,10 @@
 $(eval $(call assert_boolean,ERRATA_A72_859971))
 $(eval $(call add_define,ERRATA_A72_859971))
 
+# Process ERRATA_ARES_1043202 flag
+$(eval $(call assert_boolean,ERRATA_ARES_1043202))
+$(eval $(call add_define,ERRATA_ARES_1043202))
+
 # Errata build flags
 ifneq (${ERRATA_A53_843419},0)
 TF_LDFLAGS_aarch64	+= --fix-cortex-a53-843419