mirror of
https://github.com/CTCaer/switch-l4t-atf.git
synced 2024-11-27 11:50:33 +00:00
Merge pull request #821 from jeenu-arm/errata-printing
Errata printing infrastructure
This commit is contained in:
commit
bcc2bf0977
3
Makefile
3
Makefile
@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 2013-2016, ARM Limited and Contributors. All rights reserved.
|
||||
# Copyright (c) 2013-2017, ARM Limited and Contributors. All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
@ -180,6 +180,7 @@ INCLUDES += -Iinclude/bl1 \
|
||||
-Iinclude/drivers/ti/uart \
|
||||
-Iinclude/lib \
|
||||
-Iinclude/lib/${ARCH} \
|
||||
-Iinclude/lib/cpus \
|
||||
-Iinclude/lib/cpus/${ARCH} \
|
||||
-Iinclude/lib/el3_runtime \
|
||||
-Iinclude/lib/el3_runtime/${ARCH} \
|
||||
|
@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 2013-2016, ARM Limited and Contributors. All rights reserved.
|
||||
# Copyright (c) 2013-2017, ARM Limited and Contributors. All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
@ -34,6 +34,7 @@ BL1_SOURCES += bl1/bl1_main.c \
|
||||
bl1/${ARCH}/bl1_entrypoint.S \
|
||||
bl1/${ARCH}/bl1_exceptions.S \
|
||||
lib/cpus/${ARCH}/cpu_helpers.S \
|
||||
lib/cpus/errata_report.c \
|
||||
lib/el3_runtime/${ARCH}/context_mgmt.c \
|
||||
plat/common/plat_bl1_common.c
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2016, ARM Limited and Contributors. All rights reserved.
|
||||
* Copyright (c) 2013-2017, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
@ -35,6 +35,7 @@
|
||||
#include <bl1.h>
|
||||
#include <bl_common.h>
|
||||
#include <debug.h>
|
||||
#include <errata_report.h>
|
||||
#include <platform.h>
|
||||
#include <platform_def.h>
|
||||
#include <smcc_helpers.h>
|
||||
@ -110,6 +111,7 @@ void bl1_main(void)
|
||||
INFO("BL1: RAM %p - %p\n", (void *)BL1_RAM_BASE,
|
||||
(void *)BL1_RAM_LIMIT);
|
||||
|
||||
print_errata_status();
|
||||
|
||||
#if DEBUG
|
||||
u_register_t val;
|
||||
|
@ -34,6 +34,9 @@ errata notice document. The format of the define used to enable/disable the
|
||||
errata workaround is `ERRATA_<Processor name>_<ID>`, where the `Processor name`
|
||||
is for example `A57` for the `Cortex_A57` CPU.
|
||||
|
||||
Refer to the section _CPU errata status reporting_ in [Firmware Design
|
||||
guide][Firmware Design] for information on to write errata workaround functions.
|
||||
|
||||
All workarounds are disabled by default. The platform is responsible for
|
||||
enabling these workarounds according to its requirement by defining the
|
||||
errata workaround build flags in the platform specific makefile. In case
|
||||
@ -116,3 +119,4 @@ _Copyright (c) 2014-2016, ARM Limited and Contributors. All rights reserved._
|
||||
[A57 SW Optimization Guide]: http://infocenter.arm.com/help/topic/com.arm.doc.uan0015b/Cortex_A57_Software_Optimization_Guide_external.pdf
|
||||
[A53 Errata Notice]: http://infocenter.arm.com/help/topic/com.arm.doc.epm048406/index.html
|
||||
[A57 Errata Notice]: http://infocenter.arm.com/help/topic/com.arm.doc.epm049219/cortex_a57_mpcore_software_developers_errata_notice.pdf
|
||||
[Firmware Design]: firmware-design.md
|
||||
|
@ -1087,7 +1087,7 @@ already been performed and act as appropriate. Possible courses of actions are,
|
||||
e.g. skip the action the second time, or undo/redo it.
|
||||
|
||||
8. CPU specific operations framework
|
||||
-----------------------------
|
||||
-------------------------------------
|
||||
|
||||
Certain aspects of the ARMv8 architecture are implementation defined,
|
||||
that is, certain behaviours are not architecturally defined, but must be defined
|
||||
@ -1102,6 +1102,8 @@ behaviour. The categories are:
|
||||
|
||||
3. Processor specific register dumping as a part of crash reporting.
|
||||
|
||||
4. Errata status reporting.
|
||||
|
||||
Each of the above categories fulfils a different requirement.
|
||||
|
||||
1. allows any processor specific initialization before the caches and MMU
|
||||
@ -1115,6 +1117,9 @@ Each of the above categories fulfils a different requirement.
|
||||
in the event of a crash, for example Cortex-A53 has registers which
|
||||
can expose the data cache contents.
|
||||
|
||||
4. allows a processor to define a function that inspects and reports the status
|
||||
of all errata workarounds on that processor.
|
||||
|
||||
Please note that only 2. is mandated by the TRM.
|
||||
|
||||
The CPU specific operations framework scales to accommodate a large number of
|
||||
@ -1185,6 +1190,70 @@ reporting framework calls `do_cpu_reg_dump` which retrieves the matching
|
||||
be reported and a pointer to the ASCII list of register names in a format
|
||||
expected by the crash reporting framework.
|
||||
|
||||
### CPU errata status reporting
|
||||
|
||||
Errata workarounds for CPUs supported in ARM Trusted Firmware are applied during
|
||||
both cold and warm boots, shortly after reset. Individual Errata workarounds are
|
||||
enabled as build options. Some errata workarounds have potential run-time
|
||||
implications; therefore some are enabled by default, others not. Platform ports
|
||||
shall override build options to enable or disable errata as appropriate. The CPU
|
||||
drivers take care of applying errata workarounds that are enabled and applicable
|
||||
to a given CPU. Refer to the section titled _CPU Errata Workarounds_ in [CPUBM]
|
||||
for more information.
|
||||
|
||||
Functions in CPU drivers that apply errata workaround must follow the
|
||||
conventions listed below.
|
||||
|
||||
The errata workaround must be authored as two separate functions:
|
||||
|
||||
* One that checks for errata. This function must determine whether that errata
|
||||
applies to the current CPU. Typically this involves matching the current
|
||||
CPUs revision and variant against a value that's known to be affected by the
|
||||
errata. If the function determines that the errata applies to this CPU, it
|
||||
must return `ERRATA_APPLIES`; otherwise, it must return
|
||||
`ERRATA_NOT_APPLIES`. The utility functions `cpu_get_rev_var` and
|
||||
`cpu_rev_var_ls` functions may come in handy for this purpose.
|
||||
|
||||
For an errata identified as `E`, the check function must be named
|
||||
`check_errata_E`.
|
||||
|
||||
This function will be invoked at different times, both from assembly and from
|
||||
C run time. Therefore it must follow AAPCS, and must not use stack.
|
||||
|
||||
* Another one that applies the errata workaround. This function would call the
|
||||
check function described above, and applies errata workaround if required.
|
||||
|
||||
CPU drivers that apply errata workaround can optionally implement an assembly
|
||||
function that report the status of errata workarounds pertaining to that CPU.
|
||||
For a driver that registers the CPU, for example, `cpux` via. `declare_cpu_ops`
|
||||
macro, the errata reporting function, if it exists, must be named
|
||||
`cpux_errata_report`. This function will always be called with MMU enabled; it
|
||||
must follow AAPCS and may use stack.
|
||||
|
||||
In a debug build of ARM Trusted Firmware, on a CPU that comes out of reset, both
|
||||
BL1 and the run time firmware (BL31 in AArch64, and BL32 in AArch32) will invoke
|
||||
errata status reporting function, if one exists, for that type of CPU.
|
||||
|
||||
To report the status of each errata workaround, the function shall use the
|
||||
assembler macro `report_errata`, passing it:
|
||||
|
||||
* The build option that enables the errata;
|
||||
|
||||
* The name of the CPU: this must be the same identifier that CPU driver
|
||||
registered itself with, using `declare_cpu_ops`;
|
||||
|
||||
* And the errata identifier: the identifier must match what's used in the
|
||||
errata's check function described above.
|
||||
|
||||
The errata status reporting function will be called once per CPU type/errata
|
||||
combination during the software's active life time.
|
||||
|
||||
It's expected that whenever an errata workaround is submitted to ARM Trusted
|
||||
Firmware, the errata reporting function is appropriately extended to report its
|
||||
status as well.
|
||||
|
||||
Reporting the status of errata workaround is for informational purpose only; it
|
||||
has no functional significance.
|
||||
|
||||
9. Memory layout of BL images
|
||||
-----------------------------
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
|
||||
* Copyright (c) 2016-2017, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
@ -32,6 +32,7 @@
|
||||
|
||||
#include <arch.h>
|
||||
#include <asm_macros_common.S>
|
||||
#include <spinlock.h>
|
||||
|
||||
#define WORD_SIZE 4
|
||||
|
||||
@ -124,4 +125,13 @@
|
||||
#endif
|
||||
.endm
|
||||
|
||||
/*
|
||||
* Reserve space for a spin lock in assembly file.
|
||||
*/
|
||||
.macro define_asm_spinlock _name:req
|
||||
.align SPINLOCK_ASM_ALIGN
|
||||
\_name:
|
||||
.space SPINLOCK_ASM_SIZE
|
||||
.endm
|
||||
|
||||
#endif /* __ASM_MACROS_S__ */
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2016, ARM Limited and Contributors. All rights reserved.
|
||||
* Copyright (c) 2013-2017, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
@ -32,6 +32,7 @@
|
||||
|
||||
#include <arch.h>
|
||||
#include <asm_macros_common.S>
|
||||
#include <spinlock.h>
|
||||
|
||||
|
||||
.macro func_prologue
|
||||
@ -200,4 +201,13 @@
|
||||
#endif
|
||||
.endm
|
||||
|
||||
/*
|
||||
* Reserve space for a spin lock in assembly file.
|
||||
*/
|
||||
.macro define_asm_spinlock _name:req
|
||||
.align SPINLOCK_ASM_ALIGN
|
||||
\_name:
|
||||
.space SPINLOCK_ASM_SIZE
|
||||
.endm
|
||||
|
||||
#endif /* __ASM_MACROS_S__ */
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2016, ARM Limited and Contributors. All rights reserved.
|
||||
* Copyright (c) 2013-2017, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
@ -39,8 +39,10 @@
|
||||
#define MIDR_IMPL_SHIFT 0x18
|
||||
#define MIDR_VAR_SHIFT 20
|
||||
#define MIDR_VAR_BITS 4
|
||||
#define MIDR_VAR_MASK 0xf
|
||||
#define MIDR_REV_SHIFT 0
|
||||
#define MIDR_REV_BITS 4
|
||||
#define MIDR_REV_MASK 0xf
|
||||
#define MIDR_PN_MASK 0xfff
|
||||
#define MIDR_PN_SHIFT 0x4
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
|
||||
* Copyright (c) 2016-2017, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
@ -31,6 +31,7 @@
|
||||
#define __CPU_MACROS_S__
|
||||
|
||||
#include <arch.h>
|
||||
#include <errata_report.h>
|
||||
|
||||
#define CPU_IMPL_PN_MASK (MIDR_IMPL_MASK << MIDR_IMPL_SHIFT) | \
|
||||
(MIDR_PN_MASK << MIDR_PN_SHIFT)
|
||||
@ -44,6 +45,16 @@
|
||||
/* Word size for 32-bit CPUs */
|
||||
#define CPU_WORD_SIZE 4
|
||||
|
||||
/*
|
||||
* Whether errata status needs reporting. Errata status is printed in debug
|
||||
* builds for both BL1 and BL32 images.
|
||||
*/
|
||||
#if (defined(IMAGE_BL1) || defined(IMAGE_BL32)) && DEBUG
|
||||
# define REPORT_ERRATA 1
|
||||
#else
|
||||
# define REPORT_ERRATA 0
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Define the offsets to the fields in cpu_ops structure.
|
||||
*/
|
||||
@ -59,6 +70,22 @@ CPU_RESET_FUNC: /* cpu_ops reset_func */
|
||||
CPU_PWR_DWN_OPS: /* cpu_ops power down functions */
|
||||
.space (4 * CPU_MAX_PWR_DWN_OPS)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Fields required to print errata status. Only in BL32 that the printing
|
||||
* require mutual exclusion and printed flag.
|
||||
*/
|
||||
#if REPORT_ERRATA
|
||||
CPU_ERRATA_FUNC: /* CPU errata status printing function */
|
||||
.space 4
|
||||
#ifdef IMAGE_BL32
|
||||
CPU_ERRATA_LOCK:
|
||||
.space 4
|
||||
CPU_ERRATA_PRINTED:
|
||||
.space 4
|
||||
#endif
|
||||
#endif
|
||||
|
||||
CPU_OPS_SIZE = .
|
||||
|
||||
/*
|
||||
@ -136,7 +163,80 @@ CPU_OPS_SIZE = .
|
||||
.error "More than CPU_MAX_PWR_DWN_OPS functions specified"
|
||||
.endif
|
||||
.endif
|
||||
#endif
|
||||
|
||||
#if REPORT_ERRATA
|
||||
.ifndef \_name\()_cpu_str
|
||||
/*
|
||||
* Place errata reported flag, and the spinlock to arbitrate access to
|
||||
* it in the data section.
|
||||
*/
|
||||
.pushsection .data
|
||||
define_asm_spinlock \_name\()_errata_lock
|
||||
\_name\()_errata_reported:
|
||||
.word 0
|
||||
.popsection
|
||||
|
||||
/* Place CPU string in rodata */
|
||||
.pushsection .rodata
|
||||
\_name\()_cpu_str:
|
||||
.asciz "\_name"
|
||||
.popsection
|
||||
.endif
|
||||
|
||||
/*
|
||||
* Weakly-bound, optional errata status printing function for CPUs of
|
||||
* this class.
|
||||
*/
|
||||
.weak \_name\()_errata_report
|
||||
.word \_name\()_errata_report
|
||||
|
||||
#ifdef IMAGE_BL32
|
||||
/* Pointers to errata lock and reported flag */
|
||||
.word \_name\()_errata_lock
|
||||
.word \_name\()_errata_reported
|
||||
#endif
|
||||
#endif
|
||||
.endm
|
||||
|
||||
#if REPORT_ERRATA
|
||||
/*
|
||||
* Print status of a CPU errata
|
||||
*
|
||||
* _chosen:
|
||||
* Identifier indicating whether or not a CPU errata has been
|
||||
* compiled in.
|
||||
* _cpu:
|
||||
* Name of the CPU
|
||||
* _id:
|
||||
* Errata identifier
|
||||
* _rev_var:
|
||||
* Register containing the combined value CPU revision and variant
|
||||
* - typically the return value of cpu_get_rev_var
|
||||
*/
|
||||
.macro report_errata _chosen, _cpu, _id, _rev_var=r4
|
||||
/* Stash a string with errata ID */
|
||||
.pushsection .rodata
|
||||
\_cpu\()_errata_\_id\()_str:
|
||||
.asciz "\_id"
|
||||
.popsection
|
||||
|
||||
/* Check whether errata applies */
|
||||
mov r0, \_rev_var
|
||||
bl check_errata_\_id
|
||||
|
||||
.ifeq \_chosen
|
||||
/*
|
||||
* Errata workaround has not been compiled in. If the errata would have
|
||||
* applied had it been compiled in, print its status as missing.
|
||||
*/
|
||||
cmp r0, #0
|
||||
movne r0, #ERRATA_MISSING
|
||||
.endif
|
||||
ldr r1, =\_cpu\()_cpu_str
|
||||
ldr r2, =\_cpu\()_errata_\_id\()_str
|
||||
bl errata_print_msg
|
||||
.endm
|
||||
#endif
|
||||
|
||||
#endif /* __CPU_MACROS_S__ */
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2014-2016, ARM Limited and Contributors. All rights reserved.
|
||||
* Copyright (c) 2014-2017, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
@ -31,6 +31,7 @@
|
||||
#define __CPU_MACROS_S__
|
||||
|
||||
#include <arch.h>
|
||||
#include <errata_report.h>
|
||||
|
||||
#define CPU_IMPL_PN_MASK (MIDR_IMPL_MASK << MIDR_IMPL_SHIFT) | \
|
||||
(MIDR_PN_MASK << MIDR_PN_SHIFT)
|
||||
@ -44,6 +45,16 @@
|
||||
/* Word size for 64-bit CPUs */
|
||||
#define CPU_WORD_SIZE 8
|
||||
|
||||
/*
|
||||
* Whether errata status needs reporting. Errata status is printed in debug
|
||||
* builds for both BL1 and BL31 images.
|
||||
*/
|
||||
#if (defined(IMAGE_BL1) || defined(IMAGE_BL31)) && DEBUG
|
||||
# define REPORT_ERRATA 1
|
||||
#else
|
||||
# define REPORT_ERRATA 0
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Define the offsets to the fields in cpu_ops structure.
|
||||
*/
|
||||
@ -59,6 +70,22 @@ CPU_RESET_FUNC: /* cpu_ops reset_func */
|
||||
CPU_PWR_DWN_OPS: /* cpu_ops power down functions */
|
||||
.space (8 * CPU_MAX_PWR_DWN_OPS)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Fields required to print errata status. Only in BL31 that the printing
|
||||
* require mutual exclusion and printed flag.
|
||||
*/
|
||||
#if REPORT_ERRATA
|
||||
CPU_ERRATA_FUNC:
|
||||
.space 8
|
||||
#ifdef IMAGE_BL31
|
||||
CPU_ERRATA_LOCK:
|
||||
.space 8
|
||||
CPU_ERRATA_PRINTED:
|
||||
.space 8
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(IMAGE_BL31) && CRASH_REPORTING
|
||||
CPU_REG_DUMP: /* cpu specific register dump for crash reporting */
|
||||
.space 8
|
||||
@ -141,9 +168,84 @@ CPU_OPS_SIZE = .
|
||||
.endif
|
||||
.endif
|
||||
#endif
|
||||
|
||||
#if REPORT_ERRATA
|
||||
.ifndef \_name\()_cpu_str
|
||||
/*
|
||||
* Place errata reported flag, and the spinlock to arbitrate access to
|
||||
* it in the data section.
|
||||
*/
|
||||
.pushsection .data
|
||||
define_asm_spinlock \_name\()_errata_lock
|
||||
\_name\()_errata_reported:
|
||||
.word 0
|
||||
.popsection
|
||||
|
||||
/* Place CPU string in rodata */
|
||||
.pushsection .rodata
|
||||
\_name\()_cpu_str:
|
||||
.asciz "\_name"
|
||||
.popsection
|
||||
.endif
|
||||
|
||||
/*
|
||||
* Weakly-bound, optional errata status printing function for CPUs of
|
||||
* this class.
|
||||
*/
|
||||
.weak \_name\()_errata_report
|
||||
.quad \_name\()_errata_report
|
||||
|
||||
#ifdef IMAGE_BL31
|
||||
/* Pointers to errata lock and reported flag */
|
||||
.quad \_name\()_errata_lock
|
||||
.quad \_name\()_errata_reported
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(IMAGE_BL31) && CRASH_REPORTING
|
||||
.quad \_name\()_cpu_reg_dump
|
||||
#endif
|
||||
.endm
|
||||
|
||||
#if REPORT_ERRATA
|
||||
/*
|
||||
* Print status of a CPU errata
|
||||
*
|
||||
* _chosen:
|
||||
* Identifier indicating whether or not a CPU errata has been
|
||||
* compiled in.
|
||||
* _cpu:
|
||||
* Name of the CPU
|
||||
* _id:
|
||||
* Errata identifier
|
||||
* _rev_var:
|
||||
* Register containing the combined value CPU revision and variant
|
||||
* - typically the return value of cpu_get_rev_var
|
||||
*/
|
||||
.macro report_errata _chosen, _cpu, _id, _rev_var=x8
|
||||
/* Stash a string with errata ID */
|
||||
.pushsection .rodata
|
||||
\_cpu\()_errata_\_id\()_str:
|
||||
.asciz "\_id"
|
||||
.popsection
|
||||
|
||||
/* Check whether errata applies */
|
||||
mov x0, \_rev_var
|
||||
bl check_errata_\_id
|
||||
|
||||
.ifeq \_chosen
|
||||
/*
|
||||
* Errata workaround has not been compiled in. If the errata would have
|
||||
* applied had it been compiled in, print its status as missing.
|
||||
*/
|
||||
cbz x0, 900f
|
||||
mov x0, #ERRATA_MISSING
|
||||
.endif
|
||||
900:
|
||||
adr x1, \_cpu\()_cpu_str
|
||||
adr x2, \_cpu\()_errata_\_id\()_str
|
||||
bl errata_print_msg
|
||||
.endm
|
||||
#endif
|
||||
|
||||
#endif /* __CPU_MACROS_S__ */
|
||||
|
55
include/lib/cpus/errata_report.h
Normal file
55
include/lib/cpus/errata_report.h
Normal file
@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* Neither the name of ARM nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific
|
||||
* prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef __ERRATA_H__
|
||||
#define __ERRATA_H__
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
#include <arch.h>
|
||||
#include <arch_helpers.h>
|
||||
#include <spinlock.h>
|
||||
#include <utils.h>
|
||||
|
||||
#if DEBUG
|
||||
void print_errata_status(void);
|
||||
#else
|
||||
static inline void print_errata_status(void) {}
|
||||
#endif
|
||||
|
||||
#endif /* __ASSEMBLY__ */
|
||||
|
||||
/* Errata status */
|
||||
#define ERRATA_NOT_APPLIES 0
|
||||
#define ERRATA_APPLIES 1
|
||||
#define ERRATA_MISSING 2
|
||||
|
||||
#endif /* __ERRATA_H__ */
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved.
|
||||
* Copyright (c) 2013-2017, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
@ -31,11 +31,23 @@
|
||||
#ifndef __SPINLOCK_H__
|
||||
#define __SPINLOCK_H__
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
#include <types.h>
|
||||
|
||||
typedef struct spinlock {
|
||||
volatile unsigned int lock;
|
||||
volatile uint32_t lock;
|
||||
} spinlock_t;
|
||||
|
||||
void spin_lock(spinlock_t *lock);
|
||||
void spin_unlock(spinlock_t *lock);
|
||||
|
||||
#else
|
||||
|
||||
/* Spin lock definitions for use in assembly */
|
||||
#define SPINLOCK_ASM_ALIGN 2
|
||||
#define SPINLOCK_ASM_SIZE 4
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* __SPINLOCK_H__ */
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
|
||||
* Copyright (c) 2016-2017, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
@ -172,3 +172,86 @@ func get_cpu_ops_ptr
|
||||
error_exit:
|
||||
bx lr
|
||||
endfunc get_cpu_ops_ptr
|
||||
|
||||
/*
|
||||
* Extract CPU revision and variant, and combine them into a single numeric for
|
||||
* easier comparison.
|
||||
*/
|
||||
.globl cpu_get_rev_var
|
||||
func cpu_get_rev_var
|
||||
ldcopr r1, MIDR
|
||||
|
||||
/*
|
||||
* Extract the variant[23:20] and revision[3:0] from r1 and pack it in
|
||||
* r0[0:7] as variant[7:4] and revision[3:0]:
|
||||
*
|
||||
* First extract r1[23:16] to r0[7:0] and zero fill the rest. Then
|
||||
* extract r1[3:0] into r0[3:0] retaining other bits.
|
||||
*/
|
||||
ubfx r0, r1, #(MIDR_VAR_SHIFT - MIDR_REV_BITS), #(MIDR_REV_BITS + MIDR_VAR_BITS)
|
||||
bfi r0, r1, #MIDR_REV_SHIFT, #MIDR_REV_BITS
|
||||
bx lr
|
||||
endfunc cpu_get_rev_var
|
||||
|
||||
/*
|
||||
* Compare the CPU's revision-variant (r0) with a given value (r1), for errata
|
||||
* application purposes. If the revision-variant is less than or same as a given
|
||||
* value, indicates that errata applies; otherwise not.
|
||||
*/
|
||||
.globl cpu_rev_var_ls
|
||||
func cpu_rev_var_ls
|
||||
cmp r0, r1
|
||||
movls r0, #ERRATA_APPLIES
|
||||
movhi r0, #ERRATA_NOT_APPLIES
|
||||
bx lr
|
||||
endfunc cpu_rev_var_ls
|
||||
|
||||
#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
|
||||
push {r4, 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
|
||||
ldr r1, [r0, #CPU_DATA_CPU_OPS_PTR]
|
||||
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, pc}
|
||||
endfunc print_errata_status
|
||||
#endif
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2014-2016, ARM Limited and Contributors. All rights reserved.
|
||||
* Copyright (c) 2014-2017, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
@ -35,6 +35,11 @@
|
||||
#include <debug.h>
|
||||
#include <plat_macros.S>
|
||||
|
||||
#if A53_DISABLE_NON_TEMPORAL_HINT
|
||||
#undef ERRATA_A53_836870
|
||||
#define ERRATA_A53_836870 1
|
||||
#endif
|
||||
|
||||
/* ---------------------------------------------
|
||||
* Disable L1 data cache and unified L2 cache
|
||||
* ---------------------------------------------
|
||||
@ -65,28 +70,29 @@ endfunc cortex_a53_disable_smp
|
||||
* This applies only to revision <= r0p2 of Cortex A53.
|
||||
* Inputs:
|
||||
* x0: variant[4:7] and revision[0:3] of current cpu.
|
||||
* Clobbers : x0 - x5
|
||||
* Shall clobber: x0-x17
|
||||
* --------------------------------------------------
|
||||
*/
|
||||
func errata_a53_826319_wa
|
||||
/*
|
||||
* Compare x0 against revision r0p2
|
||||
*/
|
||||
cmp x0, #2
|
||||
b.ls apply_826319
|
||||
#if LOG_LEVEL >= LOG_LEVEL_VERBOSE
|
||||
b print_revision_warning
|
||||
#else
|
||||
ret
|
||||
#endif
|
||||
apply_826319:
|
||||
mov x17, x30
|
||||
bl check_errata_826319
|
||||
cbz x0, 1f
|
||||
mrs x1, L2ACTLR_EL1
|
||||
bic x1, x1, #L2ACTLR_ENABLE_UNIQUECLEAN
|
||||
orr x1, x1, #L2ACTLR_DISABLE_CLEAN_PUSH
|
||||
msr L2ACTLR_EL1, x1
|
||||
ret
|
||||
1:
|
||||
ret x17
|
||||
endfunc errata_a53_826319_wa
|
||||
|
||||
func check_errata_826319
|
||||
mov x1, #0x02
|
||||
b cpu_rev_var_ls
|
||||
endfunc check_errata_826319
|
||||
|
||||
/* ---------------------------------------------------------------------
|
||||
* Disable the cache non-temporal hint.
|
||||
*
|
||||
@ -101,53 +107,46 @@ endfunc errata_a53_826319_wa
|
||||
*
|
||||
* Inputs:
|
||||
* x0: variant[4:7] and revision[0:3] of current cpu.
|
||||
* Clobbers : x0 - x5
|
||||
* Shall clobber: x0-x17
|
||||
* ---------------------------------------------------------------------
|
||||
*/
|
||||
func a53_disable_non_temporal_hint
|
||||
/*
|
||||
* Compare x0 against revision r0p3
|
||||
*/
|
||||
cmp x0, #3
|
||||
b.ls disable_hint
|
||||
#if LOG_LEVEL >= LOG_LEVEL_VERBOSE
|
||||
b print_revision_warning
|
||||
#else
|
||||
ret
|
||||
#endif
|
||||
disable_hint:
|
||||
mov x17, x30
|
||||
bl check_errata_disable_non_temporal_hint
|
||||
cbz x0, 1f
|
||||
mrs x1, CPUACTLR_EL1
|
||||
orr x1, x1, #CPUACTLR_DTAH
|
||||
msr CPUACTLR_EL1, x1
|
||||
ret
|
||||
1:
|
||||
ret x17
|
||||
endfunc a53_disable_non_temporal_hint
|
||||
|
||||
func check_errata_disable_non_temporal_hint
|
||||
mov x1, #0x03
|
||||
b cpu_rev_var_ls
|
||||
endfunc check_errata_disable_non_temporal_hint
|
||||
|
||||
/* -------------------------------------------------
|
||||
* The CPU Ops reset function for Cortex-A53.
|
||||
* Clobbers: x0-x5, x15, x19, x30
|
||||
* Shall clobber: x0-x19
|
||||
* -------------------------------------------------
|
||||
*/
|
||||
func cortex_a53_reset_func
|
||||
mov x19, x30
|
||||
mrs x0, midr_el1
|
||||
bl cpu_get_rev_var
|
||||
mov x18, x0
|
||||
|
||||
/*
|
||||
* Extract the variant[20:23] and revision[0:3] from x0
|
||||
* and pack it in x15[0:7] as variant[4:7] and revision[0:3].
|
||||
* First extract x0[16:23] to x15[0:7] and zero fill the rest.
|
||||
* Then extract x0[0:3] into x15[0:3] retaining other bits.
|
||||
*/
|
||||
ubfx x15, x0, #(MIDR_VAR_SHIFT - MIDR_REV_BITS), \
|
||||
#(MIDR_REV_BITS + MIDR_VAR_BITS)
|
||||
bfxil x15, x0, #MIDR_REV_SHIFT, #MIDR_REV_BITS
|
||||
|
||||
#if ERRATA_A53_826319
|
||||
mov x0, x15
|
||||
mov x0, x18
|
||||
bl errata_a53_826319_wa
|
||||
#endif
|
||||
|
||||
#if ERRATA_A53_836870 || A53_DISABLE_NON_TEMPORAL_HINT
|
||||
mov x0, x15
|
||||
#if ERRATA_A53_836870
|
||||
mov x0, x18
|
||||
bl a53_disable_non_temporal_hint
|
||||
#endif
|
||||
|
||||
@ -223,6 +222,28 @@ func cortex_a53_cluster_pwr_dwn
|
||||
b cortex_a53_disable_smp
|
||||
endfunc cortex_a53_cluster_pwr_dwn
|
||||
|
||||
#if REPORT_ERRATA
|
||||
/*
|
||||
* Errata printing function for Cortex A53. Must follow AAPCS.
|
||||
*/
|
||||
func cortex_a53_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_A53_826319, cortex_a53, 826319
|
||||
report_errata ERRATA_A53_836870, cortex_a53, disable_non_temporal_hint
|
||||
|
||||
ldp x8, x30, [sp], #16
|
||||
ret
|
||||
endfunc cortex_a53_errata_report
|
||||
#endif
|
||||
|
||||
/* ---------------------------------------------
|
||||
* This function provides cortex_a53 specific
|
||||
* register information for crash reporting.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2014-2016, ARM Limited and Contributors. All rights reserved.
|
||||
* Copyright (c) 2014-2017, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
@ -92,52 +92,55 @@ endfunc cortex_a57_disable_ext_debug
|
||||
* This applies only to revision r0p0 of Cortex A57.
|
||||
* Inputs:
|
||||
* x0: variant[4:7] and revision[0:3] of current cpu.
|
||||
* Clobbers : x0 - x5
|
||||
* Shall clobber: x0-x17
|
||||
* --------------------------------------------------
|
||||
*/
|
||||
func errata_a57_806969_wa
|
||||
/*
|
||||
* Compare x0 against revision r0p0
|
||||
*/
|
||||
cbz x0, apply_806969
|
||||
#if LOG_LEVEL >= LOG_LEVEL_VERBOSE
|
||||
b print_revision_warning
|
||||
#else
|
||||
ret
|
||||
#endif
|
||||
apply_806969:
|
||||
mov x17, x30
|
||||
bl check_errata_806969
|
||||
cbz x0, 1f
|
||||
mrs x1, CPUACTLR_EL1
|
||||
orr x1, x1, #CPUACTLR_NO_ALLOC_WBWA
|
||||
msr CPUACTLR_EL1, x1
|
||||
ret
|
||||
1:
|
||||
ret x17
|
||||
endfunc errata_a57_806969_wa
|
||||
|
||||
func check_errata_806969
|
||||
mov x1, #0x00
|
||||
b cpu_rev_var_ls
|
||||
endfunc check_errata_806969
|
||||
|
||||
/* ---------------------------------------------------
|
||||
* Errata Workaround for Cortex A57 Errata #813420.
|
||||
* This applies only to revision r0p0 of Cortex A57.
|
||||
* Inputs:
|
||||
* x0: variant[4:7] and revision[0:3] of current cpu.
|
||||
* Clobbers : x0 - x5
|
||||
* Shall clobber: x0-x17
|
||||
* ---------------------------------------------------
|
||||
*/
|
||||
func errata_a57_813420_wa
|
||||
/*
|
||||
* Compare x0 against revision r0p0
|
||||
*/
|
||||
cbz x0, apply_813420
|
||||
#if LOG_LEVEL >= LOG_LEVEL_VERBOSE
|
||||
b print_revision_warning
|
||||
#else
|
||||
ret
|
||||
#endif
|
||||
apply_813420:
|
||||
mov x17, x30
|
||||
bl check_errata_813420
|
||||
cbz x0, 1f
|
||||
mrs x1, CPUACTLR_EL1
|
||||
orr x1, x1, #CPUACTLR_DCC_AS_DCCI
|
||||
msr CPUACTLR_EL1, x1
|
||||
ret
|
||||
1:
|
||||
ret x17
|
||||
endfunc errata_a57_813420_wa
|
||||
|
||||
func check_errata_813420
|
||||
mov x1, #0x00
|
||||
b cpu_rev_var_ls
|
||||
endfunc check_errata_813420
|
||||
|
||||
/* --------------------------------------------------------------------
|
||||
* Disable the over-read from the LDNP instruction.
|
||||
*
|
||||
@ -146,99 +149,97 @@ endfunc errata_a57_813420_wa
|
||||
*
|
||||
* Inputs:
|
||||
* x0: variant[4:7] and revision[0:3] of current cpu.
|
||||
* Clobbers : x0 - x5, x30
|
||||
* Shall clobber: x0-x17
|
||||
* ---------------------------------------------------------------------
|
||||
*/
|
||||
func a57_disable_ldnp_overread
|
||||
/*
|
||||
* Compare x0 against revision r1p2
|
||||
*/
|
||||
cmp x0, #0x12
|
||||
b.ls disable_hint
|
||||
#if LOG_LEVEL >= LOG_LEVEL_VERBOSE
|
||||
b print_revision_warning
|
||||
#else
|
||||
ret
|
||||
#endif
|
||||
disable_hint:
|
||||
mov x17, x30
|
||||
bl check_errata_disable_ldnp_overread
|
||||
cbz x0, 1f
|
||||
mrs x1, CPUACTLR_EL1
|
||||
orr x1, x1, #CPUACTLR_DIS_OVERREAD
|
||||
msr CPUACTLR_EL1, x1
|
||||
ret
|
||||
1:
|
||||
ret x17
|
||||
endfunc a57_disable_ldnp_overread
|
||||
|
||||
func check_errata_disable_ldnp_overread
|
||||
mov x1, #0x12
|
||||
b cpu_rev_var_ls
|
||||
endfunc check_errata_disable_ldnp_overread
|
||||
|
||||
/* ---------------------------------------------------
|
||||
* Errata Workaround for Cortex A57 Errata #826974.
|
||||
* This applies only to revision <= r1p1 of Cortex A57.
|
||||
* Inputs:
|
||||
* x0: variant[4:7] and revision[0:3] of current cpu.
|
||||
* Clobbers : x0 - x5
|
||||
* Shall clobber: x0-x17
|
||||
* ---------------------------------------------------
|
||||
*/
|
||||
func errata_a57_826974_wa
|
||||
/*
|
||||
* Compare x0 against revision r1p1
|
||||
*/
|
||||
cmp x0, #0x11
|
||||
b.ls apply_826974
|
||||
#if LOG_LEVEL >= LOG_LEVEL_VERBOSE
|
||||
b print_revision_warning
|
||||
#else
|
||||
ret
|
||||
#endif
|
||||
apply_826974:
|
||||
mov x17, x30
|
||||
bl check_errata_826974
|
||||
cbz x0, 1f
|
||||
mrs x1, CPUACTLR_EL1
|
||||
orr x1, x1, #CPUACTLR_DIS_LOAD_PASS_DMB
|
||||
msr CPUACTLR_EL1, x1
|
||||
ret
|
||||
1:
|
||||
ret x17
|
||||
endfunc errata_a57_826974_wa
|
||||
|
||||
func check_errata_826974
|
||||
mov x1, #0x11
|
||||
b cpu_rev_var_ls
|
||||
endfunc check_errata_826974
|
||||
|
||||
/* ---------------------------------------------------
|
||||
* Errata Workaround for Cortex A57 Errata #826977.
|
||||
* This applies only to revision <= r1p1 of Cortex A57.
|
||||
* Inputs:
|
||||
* x0: variant[4:7] and revision[0:3] of current cpu.
|
||||
* Clobbers : x0 - x5
|
||||
* Shall clobber: x0-x17
|
||||
* ---------------------------------------------------
|
||||
*/
|
||||
func errata_a57_826977_wa
|
||||
/*
|
||||
* Compare x0 against revision r1p1
|
||||
*/
|
||||
cmp x0, #0x11
|
||||
b.ls apply_826977
|
||||
#if LOG_LEVEL >= LOG_LEVEL_VERBOSE
|
||||
b print_revision_warning
|
||||
#else
|
||||
ret
|
||||
#endif
|
||||
apply_826977:
|
||||
mov x17, x30
|
||||
bl check_errata_826977
|
||||
cbz x0, 1f
|
||||
mrs x1, CPUACTLR_EL1
|
||||
orr x1, x1, #CPUACTLR_GRE_NGRE_AS_NGNRE
|
||||
msr CPUACTLR_EL1, x1
|
||||
ret
|
||||
1:
|
||||
ret x17
|
||||
endfunc errata_a57_826977_wa
|
||||
|
||||
func check_errata_826977
|
||||
mov x1, #0x11
|
||||
b cpu_rev_var_ls
|
||||
endfunc check_errata_826977
|
||||
|
||||
/* ---------------------------------------------------
|
||||
* Errata Workaround for Cortex A57 Errata #828024.
|
||||
* This applies only to revision <= r1p1 of Cortex A57.
|
||||
* Inputs:
|
||||
* x0: variant[4:7] and revision[0:3] of current cpu.
|
||||
* Clobbers : x0 - x5
|
||||
* Shall clobber: x0-x17
|
||||
* ---------------------------------------------------
|
||||
*/
|
||||
func errata_a57_828024_wa
|
||||
/*
|
||||
* Compare x0 against revision r1p1
|
||||
*/
|
||||
cmp x0, #0x11
|
||||
b.ls apply_828024
|
||||
#if LOG_LEVEL >= LOG_LEVEL_VERBOSE
|
||||
b print_revision_warning
|
||||
#else
|
||||
ret
|
||||
#endif
|
||||
apply_828024:
|
||||
mov x17, x30
|
||||
bl check_errata_828024
|
||||
cbz x0, 1f
|
||||
mrs x1, CPUACTLR_EL1
|
||||
/*
|
||||
* Setting the relevant bits in CPUACTLR_EL1 has to be done in 2
|
||||
@ -248,116 +249,116 @@ apply_828024:
|
||||
orr x1, x1, #CPUACTLR_NO_ALLOC_WBWA
|
||||
orr x1, x1, #(CPUACTLR_DIS_L1_STREAMING | CPUACTLR_DIS_STREAMING)
|
||||
msr CPUACTLR_EL1, x1
|
||||
ret
|
||||
1:
|
||||
ret x17
|
||||
endfunc errata_a57_828024_wa
|
||||
|
||||
func check_errata_828024
|
||||
mov x1, #0x11
|
||||
b cpu_rev_var_ls
|
||||
endfunc check_errata_828024
|
||||
|
||||
/* ---------------------------------------------------
|
||||
* Errata Workaround for Cortex A57 Errata #829520.
|
||||
* This applies only to revision <= r1p2 of Cortex A57.
|
||||
* Inputs:
|
||||
* x0: variant[4:7] and revision[0:3] of current cpu.
|
||||
* Clobbers : x0 - x5
|
||||
* Shall clobber: x0-x17
|
||||
* ---------------------------------------------------
|
||||
*/
|
||||
func errata_a57_829520_wa
|
||||
/*
|
||||
* Compare x0 against revision r1p2
|
||||
*/
|
||||
cmp x0, #0x12
|
||||
b.ls apply_829520
|
||||
#if LOG_LEVEL >= LOG_LEVEL_VERBOSE
|
||||
b print_revision_warning
|
||||
#else
|
||||
ret
|
||||
#endif
|
||||
apply_829520:
|
||||
mov x17, x30
|
||||
bl check_errata_829520
|
||||
cbz x0, 1f
|
||||
mrs x1, CPUACTLR_EL1
|
||||
orr x1, x1, #CPUACTLR_DIS_INDIRECT_PREDICTOR
|
||||
msr CPUACTLR_EL1, x1
|
||||
ret
|
||||
1:
|
||||
ret x17
|
||||
endfunc errata_a57_829520_wa
|
||||
|
||||
func check_errata_829520
|
||||
mov x1, #0x12
|
||||
b cpu_rev_var_ls
|
||||
endfunc check_errata_829520
|
||||
|
||||
/* ---------------------------------------------------
|
||||
* Errata Workaround for Cortex A57 Errata #833471.
|
||||
* This applies only to revision <= r1p2 of Cortex A57.
|
||||
* Inputs:
|
||||
* x0: variant[4:7] and revision[0:3] of current cpu.
|
||||
* Clobbers : x0 - x5
|
||||
* Shall clobber: x0-x17
|
||||
* ---------------------------------------------------
|
||||
*/
|
||||
func errata_a57_833471_wa
|
||||
/*
|
||||
* Compare x0 against revision r1p2
|
||||
*/
|
||||
cmp x0, #0x12
|
||||
b.ls apply_833471
|
||||
#if LOG_LEVEL >= LOG_LEVEL_VERBOSE
|
||||
b print_revision_warning
|
||||
#else
|
||||
ret
|
||||
#endif
|
||||
apply_833471:
|
||||
mov x17, x30
|
||||
bl check_errata_833471
|
||||
cbz x0, 1f
|
||||
mrs x1, CPUACTLR_EL1
|
||||
orr x1, x1, #CPUACTLR_FORCE_FPSCR_FLUSH
|
||||
msr CPUACTLR_EL1, x1
|
||||
ret
|
||||
1:
|
||||
ret x17
|
||||
endfunc errata_a57_833471_wa
|
||||
|
||||
func check_errata_833471
|
||||
mov x1, #0x12
|
||||
b cpu_rev_var_ls
|
||||
endfunc check_errata_833471
|
||||
|
||||
/* -------------------------------------------------
|
||||
* The CPU Ops reset function for Cortex-A57.
|
||||
* Clobbers: x0-x5, x15, x19, x30
|
||||
* Shall clobber: x0-x19
|
||||
* -------------------------------------------------
|
||||
*/
|
||||
func cortex_a57_reset_func
|
||||
mov x19, x30
|
||||
mrs x0, midr_el1
|
||||
|
||||
/*
|
||||
* Extract the variant[20:23] and revision[0:3] from x0
|
||||
* and pack it in x15[0:7] as variant[4:7] and revision[0:3].
|
||||
* First extract x0[16:23] to x15[0:7] and zero fill the rest.
|
||||
* Then extract x0[0:3] into x15[0:3] retaining other bits.
|
||||
*/
|
||||
ubfx x15, x0, #(MIDR_VAR_SHIFT - MIDR_REV_BITS), #(MIDR_REV_BITS + MIDR_VAR_BITS)
|
||||
bfxil x15, x0, #MIDR_REV_SHIFT, #MIDR_REV_BITS
|
||||
bl cpu_get_rev_var
|
||||
mov x18, x0
|
||||
|
||||
#if ERRATA_A57_806969
|
||||
mov x0, x15
|
||||
mov x0, x18
|
||||
bl errata_a57_806969_wa
|
||||
#endif
|
||||
|
||||
#if ERRATA_A57_813420
|
||||
mov x0, x15
|
||||
mov x0, x18
|
||||
bl errata_a57_813420_wa
|
||||
#endif
|
||||
|
||||
#if A57_DISABLE_NON_TEMPORAL_HINT
|
||||
mov x0, x15
|
||||
mov x0, x18
|
||||
bl a57_disable_ldnp_overread
|
||||
#endif
|
||||
|
||||
#if ERRATA_A57_826974
|
||||
mov x0, x15
|
||||
mov x0, x18
|
||||
bl errata_a57_826974_wa
|
||||
#endif
|
||||
|
||||
#if ERRATA_A57_826977
|
||||
mov x0, x15
|
||||
mov x0, x18
|
||||
bl errata_a57_826977_wa
|
||||
#endif
|
||||
|
||||
#if ERRATA_A57_828024
|
||||
mov x0, x15
|
||||
mov x0, x18
|
||||
bl errata_a57_828024_wa
|
||||
#endif
|
||||
|
||||
#if ERRATA_A57_829520
|
||||
mov x0, x15
|
||||
mov x0, x18
|
||||
bl errata_a57_829520_wa
|
||||
#endif
|
||||
|
||||
#if ERRATA_A57_833471
|
||||
mov x0, x15
|
||||
mov x0, x18
|
||||
bl errata_a57_833471_wa
|
||||
#endif
|
||||
|
||||
@ -466,6 +467,35 @@ func cortex_a57_cluster_pwr_dwn
|
||||
b cortex_a57_disable_ext_debug
|
||||
endfunc cortex_a57_cluster_pwr_dwn
|
||||
|
||||
#if REPORT_ERRATA
|
||||
/*
|
||||
* Errata printing function for Cortex A57. Must follow AAPCS.
|
||||
*/
|
||||
func cortex_a57_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_A57_806969, cortex_a57, 806969
|
||||
report_errata ERRATA_A57_813420, cortex_a57, 813420
|
||||
report_errata A57_DISABLE_NON_TEMPORAL_HINT, cortex_a57, \
|
||||
disable_ldnp_overread
|
||||
report_errata ERRATA_A57_826974, cortex_a57, 826974
|
||||
report_errata ERRATA_A57_826977, cortex_a57, 826977
|
||||
report_errata ERRATA_A57_828024, cortex_a57, 828024
|
||||
report_errata ERRATA_A57_829520, cortex_a57, 829520
|
||||
report_errata ERRATA_A57_833471, cortex_a57, 833471
|
||||
|
||||
ldp x8, x30, [sp], #16
|
||||
ret
|
||||
endfunc cortex_a57_errata_report
|
||||
#endif
|
||||
|
||||
/* ---------------------------------------------
|
||||
* This function provides cortex_a57 specific
|
||||
* register information for crash reporting.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2014-2016, ARM Limited and Contributors. All rights reserved.
|
||||
* Copyright (c) 2014-2017, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
@ -36,6 +36,7 @@
|
||||
#endif
|
||||
#include <cpu_macros.S>
|
||||
#include <debug.h>
|
||||
#include <errata_report.h>
|
||||
|
||||
/* Reset fn is needed in BL at reset vector */
|
||||
#if defined(IMAGE_BL1) || defined(IMAGE_BL31)
|
||||
@ -199,30 +200,94 @@ error_exit:
|
||||
ret
|
||||
endfunc get_cpu_ops_ptr
|
||||
|
||||
#if LOG_LEVEL >= LOG_LEVEL_VERBOSE
|
||||
.section .rodata.rev_verbose_str, "aS"
|
||||
rev_verbose_str:
|
||||
.asciz "VERBOSE: Skipping CPU specific reset operation for non-matching CPU revision number.\n"
|
||||
/*
|
||||
* Extract CPU revision and variant, and combine them into a single numeric for
|
||||
* easier comparison.
|
||||
*/
|
||||
.globl cpu_get_rev_var
|
||||
func cpu_get_rev_var
|
||||
mrs x1, midr_el1
|
||||
|
||||
/*
|
||||
* This function prints the above warning message to the crash console.
|
||||
* It should be called when a CPU specific operation is enabled in the
|
||||
* build but doesn't apply to this CPU revision/part number.
|
||||
* Extract the variant[23:20] and revision[3:0] from MIDR, and pack them
|
||||
* as variant[7:4] and revision[3:0] of x0.
|
||||
*
|
||||
* Clobber: x30, x0 - x5
|
||||
* First extract x1[23:16] to x0[7:0] and zero fill the rest. Then
|
||||
* extract x1[3:0] into x0[3:0] retaining other bits.
|
||||
*/
|
||||
.globl print_revision_warning
|
||||
func print_revision_warning
|
||||
mov x5, x30
|
||||
/* Ensure the console is initialized */
|
||||
bl plat_crash_console_init
|
||||
/* Check if the console is initialized */
|
||||
cbz x0, 1f
|
||||
/* The console is initialized */
|
||||
adr x4, rev_verbose_str
|
||||
bl asm_print_str
|
||||
1:
|
||||
ret x5
|
||||
endfunc print_revision_warning
|
||||
#endif
|
||||
ubfx x0, x1, #(MIDR_VAR_SHIFT - MIDR_REV_BITS), #(MIDR_REV_BITS + MIDR_VAR_BITS)
|
||||
bfxil x0, x1, #MIDR_REV_SHIFT, #MIDR_REV_BITS
|
||||
ret
|
||||
endfunc cpu_get_rev_var
|
||||
|
||||
/*
|
||||
* Compare the CPU's revision-variant (x0) with a given value (x1), for errata
|
||||
* application purposes. If the revision-variant is less than or same as a given
|
||||
* value, indicates that errata applies; otherwise not.
|
||||
*/
|
||||
.globl cpu_rev_var_ls
|
||||
func cpu_rev_var_ls
|
||||
mov x2, #ERRATA_APPLIES
|
||||
mov x3, #ERRATA_NOT_APPLIES
|
||||
cmp x0, x1
|
||||
csel x0, x2, x3, ls
|
||||
ret
|
||||
endfunc cpu_rev_var_ls
|
||||
|
||||
#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
|
||||
ldr x1, [x0, #CPU_DATA_CPU_OPS_PTR]
|
||||
ldr x0, [x1, #CPU_ERRATA_FUNC]
|
||||
cbz x0, .Lnoprint
|
||||
|
||||
/*
|
||||
* Printing errata status requires atomically testing the printed flag.
|
||||
*/
|
||||
stp x8, x30, [sp, #-16]!
|
||||
mov x8, 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, x8
|
||||
ldp x8, 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
|
||||
|
122
lib/cpus/errata_report.c
Normal file
122
lib/cpus/errata_report.c
Normal file
@ -0,0 +1,122 @@
|
||||
/*
|
||||
* Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* Neither the name of ARM nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific
|
||||
* prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/* Runtime firmware routines to report errata status for the current CPU. */
|
||||
|
||||
#include <arch_helpers.h>
|
||||
#include <assert.h>
|
||||
#include <cpu_data.h>
|
||||
#include <debug.h>
|
||||
#include <errata_report.h>
|
||||
#include <spinlock.h>
|
||||
#include <utils.h>
|
||||
|
||||
#ifdef IMAGE_BL1
|
||||
# define BL_STRING "BL1"
|
||||
#elif defined(AARCH64) && defined(IMAGE_BL31)
|
||||
# define BL_STRING "BL31"
|
||||
#elif defined(AARCH32) && defined(IMAGE_BL32)
|
||||
# define BL_STRING "BL32"
|
||||
#else
|
||||
# error This image should not be printing errata status
|
||||
#endif
|
||||
|
||||
/* Errata format: BL stage, CPU, errata ID, message */
|
||||
#define ERRATA_FORMAT "%s: %s: errata workaround for %s was %s\n"
|
||||
|
||||
/*
|
||||
* 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)
|
||||
{
|
||||
int report_now;
|
||||
|
||||
/* If already reported, return false. */
|
||||
if (*reported)
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* Acquire lock. Determine whether status needs reporting, and then mark
|
||||
* report status to true.
|
||||
*/
|
||||
spin_lock(lock);
|
||||
report_now = !(*reported);
|
||||
if (report_now)
|
||||
*reported = 1;
|
||||
spin_unlock(lock);
|
||||
|
||||
return report_now;
|
||||
}
|
||||
|
||||
/*
|
||||
* Print errata status message.
|
||||
*
|
||||
* Unknown: WARN
|
||||
* Missing: WARN
|
||||
* Applied: INFO
|
||||
* Not applied: VERBOSE
|
||||
*/
|
||||
void errata_print_msg(int status, const char *cpu, const char *id)
|
||||
{
|
||||
/* Errata status strings */
|
||||
static const char *const errata_status_str[] = {
|
||||
[ERRATA_NOT_APPLIES] = "not applied",
|
||||
[ERRATA_APPLIES] = "applied",
|
||||
[ERRATA_MISSING] = "missing!"
|
||||
};
|
||||
static const char *const __unused bl_str = BL_STRING;
|
||||
const char *msg __unused;
|
||||
|
||||
|
||||
assert(status >= 0 && status < ARRAY_SIZE(errata_status_str));
|
||||
assert(cpu);
|
||||
assert(id);
|
||||
|
||||
msg = errata_status_str[status];
|
||||
|
||||
switch (status) {
|
||||
case ERRATA_NOT_APPLIES:
|
||||
VERBOSE(ERRATA_FORMAT, bl_str, cpu, id, msg);
|
||||
break;
|
||||
|
||||
case ERRATA_APPLIES:
|
||||
INFO(ERRATA_FORMAT, bl_str, cpu, id, msg);
|
||||
break;
|
||||
|
||||
case ERRATA_MISSING:
|
||||
WARN(ERRATA_FORMAT, bl_str, cpu, id, msg);
|
||||
break;
|
||||
|
||||
default:
|
||||
WARN(ERRATA_FORMAT, bl_str, cpu, id, "unknown");
|
||||
break;
|
||||
}
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
|
||||
# Copyright (c) 2016-2017, ARM Limited and Contributors. All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
@ -32,6 +32,7 @@ PSCI_LIB_SOURCES := lib/el3_runtime/cpu_data_array.c \
|
||||
lib/el3_runtime/${ARCH}/cpu_data.S \
|
||||
lib/el3_runtime/${ARCH}/context_mgmt.c \
|
||||
lib/cpus/${ARCH}/cpu_helpers.S \
|
||||
lib/cpus/errata_report.c \
|
||||
lib/locks/exclusive/${ARCH}/spinlock.S \
|
||||
lib/psci/psci_off.c \
|
||||
lib/psci/psci_on.c \
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2016, ARM Limited and Contributors. All rights reserved.
|
||||
* Copyright (c) 2013-2017, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
@ -34,6 +34,7 @@
|
||||
#include <bl_common.h>
|
||||
#include <context.h>
|
||||
#include <context_mgmt.h>
|
||||
#include <errata_report.h>
|
||||
#include <platform.h>
|
||||
#include <stddef.h>
|
||||
#include "psci_private.h"
|
||||
@ -287,6 +288,9 @@ void psci_arch_setup(void)
|
||||
|
||||
/* Initialize the cpu_ops pointer. */
|
||||
init_cpu_ops();
|
||||
|
||||
/* Having initialized cpu_ops, we can now print errata status */
|
||||
print_errata_status();
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
|
Loading…
Reference in New Issue
Block a user