summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoyan Karatotev <boyan.karatotev@arm.com>2023-01-25 18:50:10 +0000
committerBoyan Karatotev <boyan.karatotev@arm.com>2023-05-30 09:31:15 +0100
commitdd9fae1ce0e7b985c9fe8f8f8ae358b8c166c6a9 (patch)
treeca603a08c8d23c01257775e2a12f6f7db9d482d3
parent6bb96fa6d6e101ffeef16464f8a44104a112074f (diff)
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
-rw-r--r--bl2/bl2.mk3
-rw-r--r--include/lib/cpus/cpu_ops.h37
-rw-r--r--include/lib/cpus/errata.h13
-rw-r--r--lib/cpus/aarch32/cpu_helpers.S61
-rw-r--r--lib/cpus/aarch64/cpu_helpers.S66
-rw-r--r--lib/cpus/errata_report.c41
-rw-r--r--plat/arm/board/fvp_r/platform.mk1
7 files changed, 81 insertions, 141 deletions
diff --git a/bl2/bl2.mk b/bl2/bl2.mk
index 41bcd127b..19b955f17 100644
--- a/bl2/bl2.mk
+++ b/bl2/bl2.mk
@@ -41,8 +41,7 @@ else
BL2_SOURCES += bl2/${ARCH}/bl2_el3_entrypoint.S \
bl2/${ARCH}/bl2_el3_exceptions.S \
bl2/${ARCH}/bl2_run_next_image.S \
- lib/cpus/${ARCH}/cpu_helpers.S \
- lib/cpus/errata_report.c
+ lib/cpus/${ARCH}/cpu_helpers.S
ifeq (${DISABLE_MTPMU},1)
BL2_SOURCES += lib/extensions/mtpmu/${ARCH}/mtpmu.S
diff --git a/include/lib/cpus/cpu_ops.h b/include/lib/cpus/cpu_ops.h
index 0854fec00..475ba91d9 100644
--- a/include/lib/cpus/cpu_ops.h
+++ b/include/lib/cpus/cpu_ops.h
@@ -102,4 +102,41 @@
#define CPU_OPS_SIZE CPU_ERRATA_PRINTED + CPU_ERRATA_PRINTED_SIZE
#endif /* __aarch64__ */
+#ifndef __ASSEMBLER__
+#include <lib/cassert.h>
+#include <lib/spinlock.h>
+
+struct cpu_ops {
+ unsigned long midr;
+#ifdef IMAGE_AT_EL3
+ void (*reset_func)(void);
+#endif /* IMAGE_AT_EL3 */
+#if __aarch64__
+ void (*extra1_func)(void);
+ void (*extra2_func)(void);
+ void (*extra3_func)(void);
+ void (*e_handler_func)(long es);
+#endif /* __aarch64__ */
+#if (defined(IMAGE_BL31) || defined(IMAGE_BL32)) && CPU_MAX_PWR_DWN_OPS
+ void (*pwr_dwn_ops[CPU_MAX_PWR_DWN_OPS])(void);
+#endif /* (defined(IMAGE_BL31) || defined(IMAGE_BL32)) && CPU_MAX_PWR_DWN_OPS */
+#if REPORT_ERRATA
+ void (*errata_func)(void);
+#if defined(IMAGE_BL31) || defined(IMAGE_BL32)
+ spinlock_t *errata_lock;
+ unsigned int *errata_reported;
+#endif /* defined(IMAGE_BL31) || defined(IMAGE_BL32) */
+#endif /* REPORT_ERRATA */
+#if defined(IMAGE_BL31) && CRASH_REPORTING
+ void (*reg_dump)(void);
+#endif /* defined(IMAGE_BL31) && CRASH_REPORTING */
+} __packed;
+
+CASSERT(sizeof(struct cpu_ops) == CPU_OPS_SIZE,
+ assert_cpu_ops_asm_c_different_sizes);
+
+long cpu_get_rev_var(void);
+void *get_cpu_ops_ptr(void);
+
+#endif /* __ASSEMBLER__ */
#endif /* CPU_OPS_H */
diff --git a/include/lib/cpus/errata.h b/include/lib/cpus/errata.h
index efdedf0aa..f9ab520fc 100644
--- a/include/lib/cpus/errata.h
+++ b/include/lib/cpus/errata.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2023, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -9,19 +9,8 @@
#ifndef __ASSEMBLER__
-#include <arch.h>
-#include <arch_helpers.h>
-#include <lib/spinlock.h>
-#include <lib/utils_def.h>
-
-#if DEBUG
void print_errata_status(void);
-#else
-static inline void print_errata_status(void) {}
-#endif
-
void errata_print_msg(unsigned int status, const char *cpu, const char *id);
-int errata_needs_reporting(spinlock_t *lock, uint32_t *reported);
#endif /* __ASSEMBLER__ */
diff --git a/lib/cpus/aarch32/cpu_helpers.S b/lib/cpus/aarch32/cpu_helpers.S
index 25b6308dd..05bc5d93d 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) || \
@@ -205,62 +205,3 @@ func cpu_rev_var_hs
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 f92eeebae..a4285eda5 100644
--- a/lib/cpus/aarch64/cpu_helpers.S
+++ b/lib/cpus/aarch64/cpu_helpers.S
@@ -280,72 +280,6 @@ func cpu_rev_var_range
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 f28930213..8c043285a 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 @@ int errata_needs_reporting(spinlock_t *lock, uint32_t *reported)
}
/*
+ * 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 @@ void errata_print_msg(unsigned int status, const char *cpu, const char *id)
break;
}
}
+#endif /* !REPORT_ERRATA */
diff --git a/plat/arm/board/fvp_r/platform.mk b/plat/arm/board/fvp_r/platform.mk
index 5dd28b95d..f14ea544b 100644
--- a/plat/arm/board/fvp_r/platform.mk
+++ b/plat/arm/board/fvp_r/platform.mk
@@ -83,6 +83,7 @@ override BL1_SOURCES := drivers/arm/sp805/sp805.c \
drivers/io/io_storage.c \
drivers/io/io_semihosting.c \
lib/cpus/aarch64/cpu_helpers.S \
+ lib/cpus/errata_report.c \
lib/fconf/fconf_dyn_cfg_getter.c \
lib/semihosting/semihosting.c \
lib/semihosting/${ARCH}/semihosting_call.S \