refactor(cpus): convert print_errata_status to C
The function is called in a fully initialised C environment and calls
into other C functions. The Aarch differences are minimal and are hidden
by the pre-existing headers. Converting it results into cleaner code
that is the same across both Aarch64 and Aarch32.
To avoid having to do very ugly pointer arithmetic, define a C struct
for the cpu_ops for both Aarch64 and Aarch32.
Signed-off-by: Boyan Karatotev <boyan.karatotev@arm.com>
Change-Id: Idc07c4064e03143c88a4a0e2d10ceda70ba19a50
(cherry picked from commit dd9fae1ce0e7b985c9fe8f8f8ae358b8c166c6a9)
diff --git a/lib/cpus/aarch32/cpu_helpers.S b/lib/cpus/aarch32/cpu_helpers.S
index bd982ed..fb84ce9 100644
--- a/lib/cpus/aarch32/cpu_helpers.S
+++ b/lib/cpus/aarch32/cpu_helpers.S
@@ -7,9 +7,9 @@
#include <arch.h>
#include <asm_macros.S>
#include <assert_macros.S>
-#include <lib/cpus/cpu_ops.h>
#include <cpu_macros.S>
#include <common/bl_common.h>
+#include <lib/cpus/cpu_ops.h>
#include <lib/el3_runtime/cpu_data.h>
#if defined(IMAGE_BL1) || defined(IMAGE_BL32) || (defined(IMAGE_BL2) && BL2_AT_EL3)
@@ -204,62 +204,3 @@
movlt r0, #ERRATA_NOT_APPLIES
bx lr
endfunc cpu_rev_var_hs
-
-#if REPORT_ERRATA
-/*
- * void print_errata_status(void);
- *
- * Function to print errata status for CPUs of its class. Must be called only:
- *
- * - with MMU and data caches are enabled;
- * - after cpu_ops have been initialized in per-CPU data.
- */
- .globl print_errata_status
-func print_errata_status
- /* r12 is pushed only for the sake of 8-byte stack alignment */
- push {r4, r5, r12, lr}
-#ifdef IMAGE_BL1
- /*
- * BL1 doesn't have per-CPU data. So retrieve the CPU operations
- * directly.
- */
- bl get_cpu_ops_ptr
- ldr r0, [r0, #CPU_ERRATA_FUNC]
- cmp r0, #0
- blxne r0
-#else
- /*
- * Retrieve pointer to cpu_ops, and further, the errata printing
- * function. If it's non-NULL, jump to the function in turn.
- */
- bl _cpu_data
-#if ENABLE_ASSERTIONS
- cmp r0, #0
- ASM_ASSERT(ne)
-#endif
- ldr r1, [r0, #CPU_DATA_CPU_OPS_PTR]
-#if ENABLE_ASSERTIONS
- cmp r1, #0
- ASM_ASSERT(ne)
-#endif
- ldr r0, [r1, #CPU_ERRATA_FUNC]
- cmp r0, #0
- beq 1f
-
- mov r4, r0
-
- /*
- * Load pointers to errata lock and printed flag. Call
- * errata_needs_reporting to check whether this CPU needs to report
- * errata status pertaining to its class.
- */
- ldr r0, [r1, #CPU_ERRATA_LOCK]
- ldr r1, [r1, #CPU_ERRATA_PRINTED]
- bl errata_needs_reporting
- cmp r0, #0
- blxne r4
-1:
-#endif
- pop {r4, r5, r12, pc}
-endfunc print_errata_status
-#endif
diff --git a/lib/cpus/aarch64/cpu_helpers.S b/lib/cpus/aarch64/cpu_helpers.S
index 86c932a..f93e8f8 100644
--- a/lib/cpus/aarch64/cpu_helpers.S
+++ b/lib/cpus/aarch64/cpu_helpers.S
@@ -279,72 +279,6 @@
ret
endfunc cpu_rev_var_range
-#if REPORT_ERRATA
-/*
- * void print_errata_status(void);
- *
- * Function to print errata status for CPUs of its class. Must be called only:
- *
- * - with MMU and data caches are enabled;
- * - after cpu_ops have been initialized in per-CPU data.
- */
- .globl print_errata_status
-func print_errata_status
-#ifdef IMAGE_BL1
- /*
- * BL1 doesn't have per-CPU data. So retrieve the CPU operations
- * directly.
- */
- stp xzr, x30, [sp, #-16]!
- bl get_cpu_ops_ptr
- ldp xzr, x30, [sp], #16
- ldr x1, [x0, #CPU_ERRATA_FUNC]
- cbnz x1, .Lprint
-#else
- /*
- * Retrieve pointer to cpu_ops from per-CPU data, and further, the
- * errata printing function. If it's non-NULL, jump to the function in
- * turn.
- */
- mrs x0, tpidr_el3
-#if ENABLE_ASSERTIONS
- cmp x0, #0
- ASM_ASSERT(ne)
-#endif
- ldr x1, [x0, #CPU_DATA_CPU_OPS_PTR]
-#if ENABLE_ASSERTIONS
- cmp x1, #0
- ASM_ASSERT(ne)
-#endif
- ldr x0, [x1, #CPU_ERRATA_FUNC]
- cbz x0, .Lnoprint
-
- /*
- * Printing errata status requires atomically testing the printed flag.
- */
- stp x19, x30, [sp, #-16]!
- mov x19, x0
-
- /*
- * Load pointers to errata lock and printed flag. Call
- * errata_needs_reporting to check whether this CPU needs to report
- * errata status pertaining to its class.
- */
- ldr x0, [x1, #CPU_ERRATA_LOCK]
- ldr x1, [x1, #CPU_ERRATA_PRINTED]
- bl errata_needs_reporting
- mov x1, x19
- ldp x19, x30, [sp], #16
- cbnz x0, .Lprint
-#endif
-.Lnoprint:
- ret
-.Lprint:
- /* Jump to errata reporting function for this CPU */
- br x1
-endfunc print_errata_status
-#endif
-
/*
* int check_wa_cve_2017_5715(void);
*
diff --git a/lib/cpus/errata_report.c b/lib/cpus/errata_report.c
index 61424c9..4c131a3 100644
--- a/lib/cpus/errata_report.c
+++ b/lib/cpus/errata_report.c
@@ -11,6 +11,7 @@
#include <arch_helpers.h>
#include <common/debug.h>
+#include <lib/cpus/cpu_ops.h>
#include <lib/cpus/errata.h>
#include <lib/el3_runtime/cpu_data.h>
#include <lib/spinlock.h>
@@ -30,11 +31,14 @@
/* Errata format: BL stage, CPU, errata ID, message */
#define ERRATA_FORMAT "%s: %s: CPU workaround for %s was %s\n"
+#if !REPORT_ERRATA
+void print_errata_status(void) {}
+#else /* !REPORT_ERRATA */
/*
* Returns whether errata needs to be reported. Passed arguments are private to
* a CPU type.
*/
-int errata_needs_reporting(spinlock_t *lock, uint32_t *reported)
+static __unused int errata_needs_reporting(spinlock_t *lock, uint32_t *reported)
{
bool report_now;
@@ -56,6 +60,40 @@
}
/*
+ * Function to print errata status for the calling CPU (and others of the same
+ * type). Must be called only:
+ * - when MMU and data caches are enabled;
+ * - after cpu_ops have been initialized in per-CPU data.
+ */
+void print_errata_status(void)
+{
+ struct cpu_ops *cpu_ops;
+#ifdef IMAGE_BL1
+ /*
+ * BL1 doesn't have per-CPU data. So retrieve the CPU operations
+ * directly.
+ */
+ cpu_ops = get_cpu_ops_ptr();
+
+ if (cpu_ops->errata_func != NULL) {
+ cpu_ops->errata_func();
+ }
+#else /* IMAGE_BL1 */
+ cpu_ops = (void *) get_cpu_data(cpu_ops_ptr);
+
+ assert(cpu_ops != NULL);
+
+ if (cpu_ops->errata_func == NULL) {
+ return;
+ }
+
+ if (errata_needs_reporting(cpu_ops->errata_lock, cpu_ops->errata_reported)) {
+ cpu_ops->errata_func();
+ }
+#endif /* IMAGE_BL1 */
+}
+
+/*
* Print errata status message.
*
* Unknown: WARN
@@ -99,3 +137,4 @@
break;
}
}
+#endif /* !REPORT_ERRATA */