mirror of
https://github.com/ARM-software/arm-trusted-firmware.git
synced 2025-04-24 22:05:40 +00:00
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
This commit is contained in:
parent
6bb96fa6d6
commit
dd9fae1ce0
7 changed files with 81 additions and 141 deletions
|
@ -41,8 +41,7 @@ else
|
||||||
BL2_SOURCES += bl2/${ARCH}/bl2_el3_entrypoint.S \
|
BL2_SOURCES += bl2/${ARCH}/bl2_el3_entrypoint.S \
|
||||||
bl2/${ARCH}/bl2_el3_exceptions.S \
|
bl2/${ARCH}/bl2_el3_exceptions.S \
|
||||||
bl2/${ARCH}/bl2_run_next_image.S \
|
bl2/${ARCH}/bl2_run_next_image.S \
|
||||||
lib/cpus/${ARCH}/cpu_helpers.S \
|
lib/cpus/${ARCH}/cpu_helpers.S
|
||||||
lib/cpus/errata_report.c
|
|
||||||
|
|
||||||
ifeq (${DISABLE_MTPMU},1)
|
ifeq (${DISABLE_MTPMU},1)
|
||||||
BL2_SOURCES += lib/extensions/mtpmu/${ARCH}/mtpmu.S
|
BL2_SOURCES += lib/extensions/mtpmu/${ARCH}/mtpmu.S
|
||||||
|
|
|
@ -102,4 +102,41 @@
|
||||||
#define CPU_OPS_SIZE CPU_ERRATA_PRINTED + CPU_ERRATA_PRINTED_SIZE
|
#define CPU_OPS_SIZE CPU_ERRATA_PRINTED + CPU_ERRATA_PRINTED_SIZE
|
||||||
#endif /* __aarch64__ */
|
#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 */
|
#endif /* CPU_OPS_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
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
*/
|
*/
|
||||||
|
@ -9,19 +9,8 @@
|
||||||
|
|
||||||
#ifndef __ASSEMBLER__
|
#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);
|
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);
|
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__ */
|
#endif /* __ASSEMBLER__ */
|
||||||
|
|
||||||
|
|
|
@ -7,9 +7,9 @@
|
||||||
#include <arch.h>
|
#include <arch.h>
|
||||||
#include <asm_macros.S>
|
#include <asm_macros.S>
|
||||||
#include <assert_macros.S>
|
#include <assert_macros.S>
|
||||||
#include <lib/cpus/cpu_ops.h>
|
|
||||||
#include <cpu_macros.S>
|
#include <cpu_macros.S>
|
||||||
#include <common/bl_common.h>
|
#include <common/bl_common.h>
|
||||||
|
#include <lib/cpus/cpu_ops.h>
|
||||||
#include <lib/el3_runtime/cpu_data.h>
|
#include <lib/el3_runtime/cpu_data.h>
|
||||||
|
|
||||||
#if defined(IMAGE_BL1) || defined(IMAGE_BL32) || \
|
#if defined(IMAGE_BL1) || defined(IMAGE_BL32) || \
|
||||||
|
@ -205,62 +205,3 @@ func cpu_rev_var_hs
|
||||||
movlt r0, #ERRATA_NOT_APPLIES
|
movlt r0, #ERRATA_NOT_APPLIES
|
||||||
bx lr
|
bx lr
|
||||||
endfunc cpu_rev_var_hs
|
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
|
|
||||||
|
|
|
@ -280,72 +280,6 @@ func cpu_rev_var_range
|
||||||
ret
|
ret
|
||||||
endfunc cpu_rev_var_range
|
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);
|
* int check_wa_cve_2017_5715(void);
|
||||||
*
|
*
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
|
|
||||||
#include <arch_helpers.h>
|
#include <arch_helpers.h>
|
||||||
#include <common/debug.h>
|
#include <common/debug.h>
|
||||||
|
#include <lib/cpus/cpu_ops.h>
|
||||||
#include <lib/cpus/errata.h>
|
#include <lib/cpus/errata.h>
|
||||||
#include <lib/el3_runtime/cpu_data.h>
|
#include <lib/el3_runtime/cpu_data.h>
|
||||||
#include <lib/spinlock.h>
|
#include <lib/spinlock.h>
|
||||||
|
@ -30,11 +31,14 @@
|
||||||
/* Errata format: BL stage, CPU, errata ID, message */
|
/* Errata format: BL stage, CPU, errata ID, message */
|
||||||
#define ERRATA_FORMAT "%s: %s: CPU workaround for %s was %s\n"
|
#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
|
* Returns whether errata needs to be reported. Passed arguments are private to
|
||||||
* a CPU type.
|
* 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;
|
bool report_now;
|
||||||
|
|
||||||
|
@ -55,6 +59,40 @@ int errata_needs_reporting(spinlock_t *lock, uint32_t *reported)
|
||||||
return report_now;
|
return report_now;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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.
|
* Print errata status message.
|
||||||
*
|
*
|
||||||
|
@ -99,3 +137,4 @@ void errata_print_msg(unsigned int status, const char *cpu, const char *id)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif /* !REPORT_ERRATA */
|
||||||
|
|
|
@ -83,6 +83,7 @@ override BL1_SOURCES := drivers/arm/sp805/sp805.c \
|
||||||
drivers/io/io_storage.c \
|
drivers/io/io_storage.c \
|
||||||
drivers/io/io_semihosting.c \
|
drivers/io/io_semihosting.c \
|
||||||
lib/cpus/aarch64/cpu_helpers.S \
|
lib/cpus/aarch64/cpu_helpers.S \
|
||||||
|
lib/cpus/errata_report.c \
|
||||||
lib/fconf/fconf_dyn_cfg_getter.c \
|
lib/fconf/fconf_dyn_cfg_getter.c \
|
||||||
lib/semihosting/semihosting.c \
|
lib/semihosting/semihosting.c \
|
||||||
lib/semihosting/${ARCH}/semihosting_call.S \
|
lib/semihosting/${ARCH}/semihosting_call.S \
|
||||||
|
|
Loading…
Add table
Reference in a new issue