Browse Source

Merge changes from topic "sm/framework_optimize" into integration

* changes:
  chore: rearrange the fvp_cpu_errata.mk file
  fix(cpus): add erratum 2701951 to Cortex-X3's list
  refactor(errata-abi): workaround platforms non-arm interconnect
  refactor(errata-abi): optimize errata ABI using errata framework
pull/2000/merge
Lauren Wehrmeister 8 months ago
committed by TrustedFirmware Code Review
parent
commit
0cda4adae7
  1. 9
      docs/design/cpu-specific-build-macros.rst
  2. 8
      lib/cpus/cpu-ops.mk
  3. 59
      plat/arm/board/fvp/fvp_cpu_errata.mk
  4. 36
      services/std_svc/errata_abi/cpu_errata_info.h
  5. 519
      services/std_svc/errata_abi/errata_abi_main.c

9
docs/design/cpu-specific-build-macros.rst

@ -799,6 +799,11 @@ For Cortex-X3, the following errata build flags are defined :
CPU. This needs to be enabled only for revisions r0p0 and r1p0 of the CPU.
It is fixed in r1p1.
- ``ERRATA_X3_2701951``: This applies erratum 2701951 workaround to Cortex-X3
CPU and affects system configurations that do not use an ARM interconnect
IP. This needs to be applied to revisions r0p0, r1p0 and r1p1. It is fixed
in r1p2.
- ``ERRATA_X3_2742421``: This applies errata 2742421 workaround to
Cortex-X3 CPU. This needs to be enabled only for revisions r0p0, r1p0 and
r1p1. It is fixed in r1p2.
@ -884,10 +889,6 @@ For Cortex-A715, the following errata build flags are defined :
Cortex-A715 CPU. This needs to be enabled only for revision r1p0.
It is fixed in r1p1.
- ``ERRATA_A715_2701951``: This applies erratum 2701951 workaround to Cortex-A715
CPU and affects system configurations that do not use an ARM interconnect
IP. This needs to be applied to revisions r0p0, r1p0 and r1p1. It is fixed
in r1p2.
DSU Errata Workarounds
----------------------

8
lib/cpus/cpu-ops.mk

@ -802,6 +802,10 @@ CPU_FLAG_LIST += ERRATA_X3_2615812
# to revisions r0p0 and r1p0 of the Cortex-X3 cpu, it is fixed in r1p1.
CPU_FLAG_LIST += ERRATA_X3_2641945
# Flag to apply erratum 2701951 workaround for non-arm interconnect ip.
# This erratum applies to revisions r0p0, r1p0, and r1p1. Its is fixed in r1p2.
CPU_FLAG_LIST += ERRATA_X3_2701951
# Flag to apply erratum 2742421 workaround on reset. This erratum applies
# to revisions r0p0, r1p0 and r1p1 of the Cortex-X3 cpu, it is fixed in r1p2.
CPU_FLAG_LIST += ERRATA_X3_2742421
@ -915,10 +919,6 @@ CPU_FLAG_LIST += ERRATA_A715_2429384
# only to revision r1p0. It is fixed in r1p1.
CPU_FLAG_LIST += ERRATA_A715_2561034
# Flag to apply erratum 2701951 workaround for non-arm interconnect ip.
# This erratum applies to revisions r0p0, r1p0, and r1p1. Its is fixed in r1p2.
CPU_FLAG_LIST += ERRATA_A715_2701951
# Flag to apply DSU erratum 798953. This erratum applies to DSUs revision r0p0.
# Applying the workaround results in higher DSU power consumption on idle.
CPU_FLAG_LIST += ERRATA_DSU_798953

59
plat/arm/board/fvp/fvp_cpu_errata.mk

@ -1,63 +1,30 @@
#
# Copyright (c) 2023, Arm Limited and Contributors. All rights reserved.
# Copyright (c) 2023-2024, Arm Limited and Contributors. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
#/*
# * TODO: below lines of code to be removed
# * after abi and framework are synchronized
# */
# Flags to enable the cpu structures in the Errata ABI file
# file: services/std_svc/errata_abi/errata_abi_main.c. This is specifically
# for platforms that need to enable errata based on non-arm interconnect IP.
ifeq (${ERRATA_ABI_SUPPORT}, 1)
# enable the cpu macros for errata abi interface
ifeq (${ARCH}, aarch64)
ifeq (${HW_ASSISTED_COHERENCY}, 0)
CORTEX_A35_H_INC := 1
CORTEX_A53_H_INC := 1
CORTEX_A57_H_INC := 1
CORTEX_A72_H_INC := 1
CORTEX_A73_H_INC := 1
$(eval $(call add_define, CORTEX_A35_H_INC))
$(eval $(call add_define, CORTEX_A53_H_INC))
$(eval $(call add_define, CORTEX_A57_H_INC))
$(eval $(call add_define, CORTEX_A72_H_INC))
$(eval $(call add_define, CORTEX_A73_H_INC))
else
ifeq (${ERRATA_NON_ARM_INTERCONNECT}, 1)
ifeq (${CTX_INCLUDE_AARCH32_REGS}, 0)
CORTEX_A76_H_INC := 1
CORTEX_A77_H_INC := 1
CORTEX_A710_H_INC := 1
CORTEX_A78_H_INC := 1
NEOVERSE_N1_H_INC := 1
NEOVERSE_N2_H_INC := 1
NEOVERSE_V1_H_INC := 1
CORTEX_A78_AE_H_INC := 1
CORTEX_A510_H_INC := 1
CORTEX_A710_H_INC := 1
CORTEX_A715_H_INC := 1
CORTEX_A78C_H_INC := 1
CORTEX_X2_H_INC := 1
$(eval $(call add_define, CORTEX_A76_H_INC))
$(eval $(call add_define, CORTEX_A77_H_INC))
CORTEX_X3_H_INC := 1
NEOVERSE_N2_H_INC := 1
NEOVERSE_V1_H_INC := 1
$(eval $(call add_define, CORTEX_A710_H_INC))
$(eval $(call add_define, CORTEX_A78_H_INC))
$(eval $(call add_define, NEOVERSE_N1_H_INC))
$(eval $(call add_define, NEOVERSE_N2_H_INC))
$(eval $(call add_define, NEOVERSE_V1_H_INC))
$(eval $(call add_define, CORTEX_A78_AE_H_INC))
$(eval $(call add_define, CORTEX_A510_H_INC))
$(eval $(call add_define, CORTEX_A710_H_INC))
$(eval $(call add_define, CORTEX_A715_H_INC))
$(eval $(call add_define, CORTEX_A78C_H_INC))
$(eval $(call add_define, CORTEX_X2_H_INC))
endif
CORTEX_A55_H_INC := 1
CORTEX_A75_H_INC := 1
$(eval $(call add_define, CORTEX_A55_H_INC))
$(eval $(call add_define, CORTEX_A75_H_INC))
$(eval $(call add_define, CORTEX_X3_H_INC))
$(eval $(call add_define, NEOVERSE_N2_H_INC))
$(eval $(call add_define, NEOVERSE_V1_H_INC))
endif
else
CORTEX_A32_H_INC := 1
$(eval $(call add_define, CORTEX_A32_H_INC))
endif
endif

36
services/std_svc/errata_abi/cpu_errata_info.h

@ -1,5 +1,5 @@
/*
* Copyright (c) 2023, Arm Limited and Contributors. All rights reserved.
* Copyright (c) 2023-2024, Arm Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@ -11,42 +11,24 @@
#include <arch_helpers.h>
#if __aarch64__
#include <cortex_a35.h>
#include <cortex_a510.h>
#include <cortex_a520.h>
#include <cortex_a53.h>
#include <cortex_a57.h>
#include <cortex_a55.h>
#include <cortex_a710.h>
#include <cortex_a72.h>
#include <cortex_a73.h>
#include <cortex_a75.h>
#include <cortex_a76.h>
#include <cortex_a77.h>
#include <cortex_a78.h>
#include <cortex_a78_ae.h>
#include <cortex_a78c.h>
#include <cortex_a715.h>
#include <cortex_x1.h>
#include <cortex_x2.h>
#include <cortex_x3.h>
#include <neoverse_n1.h>
#include <neoverse_n2.h>
#include <neoverse_v1.h>
#include <neoverse_v2.h>
#else
#include <cortex_a15.h>
#include <cortex_a17.h>
#include <cortex_a57.h>
#include <cortex_a9.h>
#endif
#define MAX_ERRATA_ENTRIES 32
/* Max number of platform based errata with no workaround in EL3 */
#define MAX_PLAT_CPU_ERRATA_ENTRIES 2
#define ERRATA_LIST_END (MAX_ERRATA_ENTRIES - 1)
#define ERRATA_LIST_END (MAX_PLAT_CPU_ERRATA_ENTRIES - 1)
/* Default values for unused memory in the array */
#define UNDEF_ERRATA {UINT_MAX, UCHAR_MAX, UCHAR_MAX, false, false}
#define UNDEF_ERRATA {UINT_MAX, UCHAR_MAX, UCHAR_MAX}
#define EXTRACT_PARTNUM(x) ((x >> MIDR_PN_SHIFT) & MIDR_PN_MASK)
@ -59,15 +41,11 @@ struct em_cpu{
unsigned int em_errata_id;
unsigned char em_rxpx_lo; /* lowest revision of errata applicable for the cpu */
unsigned char em_rxpx_hi; /* highest revision of errata applicable for the cpu */
bool errata_enabled; /* indicate if errata enabled */
/* flag to indicate if errata query is based out of non-arm interconnect */
bool non_arm_interconnect;
};
struct em_cpu_list{
/* field to hold cpu specific part number defined in midr reg */
unsigned long cpu_partnumber;
struct em_cpu cpu_errata_list[MAX_ERRATA_ENTRIES];
unsigned long cpu_partnumber; /* cpu specific part number defined in midr reg */
struct em_cpu cpu_errata_list[MAX_PLAT_CPU_ERRATA_ENTRIES];
};
int32_t verify_errata_implemented(uint32_t errata_id, uint32_t forward_flag);

519
services/std_svc/errata_abi/errata_abi_main.c

@ -6,6 +6,8 @@
#include <assert.h>
#include "cpu_errata_info.h"
#include <lib/cpus/cpu_ops.h>
#include <lib/cpus/errata.h>
#include <lib/smccc.h>
#include <lib/utils_def.h>
#include <services/errata_abi_svc.h>
@ -17,197 +19,14 @@
*/
struct em_cpu_list *cpu_ptr;
extern uint8_t cpu_get_rev_var(void);
/* Structure array that holds CPU specific errata information */
struct em_cpu_list cpu_list[] = {
#if CORTEX_A9_H_INC
{
.cpu_partnumber = CORTEX_A9_MIDR,
.cpu_errata_list = {
[0] = {794073, 0x00, 0xFF, ERRATA_A9_794073},
[1 ... ERRATA_LIST_END] = UNDEF_ERRATA,
}
},
#endif /* CORTEX_A9_H_INC */
#if CORTEX_A15_H_INC
{
.cpu_partnumber = CORTEX_A15_MIDR,
.cpu_errata_list = {
[0] = {816470, 0x30, 0xFF, ERRATA_A15_816470},
[1] = {827671, 0x30, 0xFF, ERRATA_A15_827671},
[2 ... ERRATA_LIST_END] = UNDEF_ERRATA,
}
},
#endif /* CORTEX_A15_H_INC */
#if CORTEX_A17_H_INC
{
.cpu_partnumber = CORTEX_A17_MIDR,
.cpu_errata_list = {
[0] = {852421, 0x00, 0x12, ERRATA_A17_852421},
[1] = {852423, 0x00, 0x12, ERRATA_A17_852423},
[2 ... ERRATA_LIST_END] = UNDEF_ERRATA,
}
},
#endif /* CORTEX_A17_H_INC */
#if CORTEX_A35_H_INC
{
.cpu_partnumber = CORTEX_A35_MIDR,
.cpu_errata_list = {
[0] = {855472, 0x00, 0x00, ERRATA_A35_855472},
[1 ... ERRATA_LIST_END] = UNDEF_ERRATA,
}
},
#endif /* CORTEX_A35_H_INC */
#if CORTEX_A53_H_INC
{
.cpu_partnumber = CORTEX_A53_MIDR,
.cpu_errata_list = {
[0] = {819472, 0x00, 0x01, ERRATA_A53_819472},
[1] = {824069, 0x00, 0x02, ERRATA_A53_824069},
[2] = {826319, 0x00, 0x02, ERRATA_A53_826319},
[3] = {827319, 0x00, 0x02, ERRATA_A53_827319},
[4] = {835769, 0x00, 0x04, ERRATA_A53_835769},
[5] = {836870, 0x00, 0x03, ERRATA_A53_836870},
[6] = {843419, 0x00, 0x04, ERRATA_A53_843419},
[7] = {855873, 0x03, 0xFF, ERRATA_A53_855873},
[8] = {1530924, 0x00, 0xFF, ERRATA_A53_1530924},
[9 ... ERRATA_LIST_END] = UNDEF_ERRATA,
}
},
#endif /* CORTEX_A53_H_INC */
#if CORTEX_A55_H_INC
{
.cpu_partnumber = CORTEX_A55_MIDR,
.cpu_errata_list = {
[0] = {768277, 0x00, 0x00, ERRATA_A55_768277},
[1] = {778703, 0x00, 0x00, ERRATA_A55_778703},
[2] = {798797, 0x00, 0x00, ERRATA_A55_798797},
[3] = {846532, 0x00, 0x01, ERRATA_A55_846532},
[4] = {903758, 0x00, 0x01, ERRATA_A55_903758},
[5] = {1221012, 0x00, 0x10, ERRATA_A55_1221012},
[6] = {1530923, 0x00, 0xFF, ERRATA_A55_1530923},
[7 ... ERRATA_LIST_END] = UNDEF_ERRATA,
}
},
#endif /* CORTEX_A55_H_INC */
#if CORTEX_A57_H_INC
{
.cpu_partnumber = CORTEX_A57_MIDR,
.cpu_errata_list = {
[0] = {806969, 0x00, 0x00, ERRATA_A57_806969},
[1] = {813419, 0x00, 0x00, ERRATA_A57_813419},
[2] = {813420, 0x00, 0x00, ERRATA_A57_813420},
[3] = {814670, 0x00, 0x00, ERRATA_A57_814670},
[4] = {817169, 0x00, 0x01, ERRATA_A57_817169},
[5] = {826974, 0x00, 0x11, ERRATA_A57_826974},
[6] = {826977, 0x00, 0x11, ERRATA_A57_826977},
[7] = {828024, 0x00, 0x11, ERRATA_A57_828024},
[8] = {829520, 0x00, 0x12, ERRATA_A57_829520},
[9] = {833471, 0x00, 0x12, ERRATA_A57_833471},
[10] = {859972, 0x00, 0x13, ERRATA_A57_859972},
[11] = {1319537, 0x00, 0xFF, ERRATA_A57_1319537},
[12 ... ERRATA_LIST_END] = UNDEF_ERRATA,
}
},
#endif /* CORTEX_A57_H_INC */
#if CORTEX_A72_H_INC
{
.cpu_partnumber = CORTEX_A72_MIDR,
.cpu_errata_list = {
[0] = {859971, 0x00, 0x03, ERRATA_A72_859971},
[1] = {1319367, 0x00, 0xFF, ERRATA_A72_1319367},
[2 ... ERRATA_LIST_END] = UNDEF_ERRATA,
}
},
#endif /* CORTEX_A72_H_INC */
#if CORTEX_A73_H_INC
{
.cpu_partnumber = CORTEX_A73_MIDR,
.cpu_errata_list = {
[0] = {852427, 0x00, 0x00, ERRATA_A73_852427},
[1] = {855423, 0x00, 0x01, ERRATA_A73_855423},
[2 ... ERRATA_LIST_END] = UNDEF_ERRATA,
}
},
#endif /* CORTEX_A73_H_INC */
#if CORTEX_A75_H_INC
{
.cpu_partnumber = CORTEX_A75_MIDR,
.cpu_errata_list = {
[0] = {764081, 0x00, 0x00, ERRATA_A75_764081},
[1] = {790748, 0x00, 0x00, ERRATA_A75_790748},
[2 ... ERRATA_LIST_END] = UNDEF_ERRATA,
}
},
#endif /* CORTEX_A75_H_INC */
#if CORTEX_A76_H_INC
{
.cpu_partnumber = CORTEX_A76_MIDR,
.cpu_errata_list = {
[0] = {1073348, 0x00, 0x10, ERRATA_A76_1073348},
[1] = {1130799, 0x00, 0x20, ERRATA_A76_1130799},
[2] = {1165522, 0x00, 0xFF, ERRATA_A76_1165522},
[3] = {1220197, 0x00, 0x20, ERRATA_A76_1220197},
[4] = {1257314, 0x00, 0x30, ERRATA_A76_1257314},
[5] = {1262606, 0x00, 0x30, ERRATA_A76_1262606},
[6] = {1262888, 0x00, 0x30, ERRATA_A76_1262888},
[7] = {1275112, 0x00, 0x30, ERRATA_A76_1275112},
[8] = {1286807, 0x00, 0x30, ERRATA_A76_1286807},
[9] = {1791580, 0x00, 0x40, ERRATA_A76_1791580},
[10] = {1868343, 0x00, 0x40, ERRATA_A76_1868343},
[11] = {1946160, 0x30, 0x41, ERRATA_A76_1946160},
[12] = {2743102, 0x00, 0x41, ERRATA_A76_2743102},
[13 ... ERRATA_LIST_END] = UNDEF_ERRATA,
}
},
#endif /* CORTEX_A76_H_INC */
#if CORTEX_A77_H_INC
{
.cpu_partnumber = CORTEX_A77_MIDR,
.cpu_errata_list = {
[0] = {1508412, 0x00, 0x10, ERRATA_A77_1508412},
[1] = {1791578, 0x00, 0x11, ERRATA_A77_1791578},
[2] = {1800714, 0x00, 0x11, ERRATA_A77_1800714},
[3] = {1925769, 0x00, 0x11, ERRATA_A77_1925769},
[4] = {1946167, 0x00, 0x11, ERRATA_A77_1946167},
[5] = {2356587, 0x00, 0x11, ERRATA_A77_2356587},
[6] = {2743100, 0x00, 0x11, ERRATA_A77_2743100},
[7 ... ERRATA_LIST_END] = UNDEF_ERRATA,
}
},
#endif /* CORTEX_A77_H_INC */
#if CORTEX_A78_H_INC
{
.cpu_partnumber = CORTEX_A78_MIDR,
.cpu_errata_list = {
[0] = {1688305, 0x00, 0x10, ERRATA_A78_1688305},
[1] = {1821534, 0x00, 0x10, ERRATA_A78_1821534},
[2] = {1941498, 0x00, 0x11, ERRATA_A78_1941498},
[3] = {1951500, 0x10, 0x11, ERRATA_A78_1951500},
[4] = {1952683, 0x00, 0x00, ERRATA_A78_1952683},
[5] = {2132060, 0x00, 0x12, ERRATA_A78_2132060},
[6] = {2242635, 0x10, 0x12, ERRATA_A78_2242635},
[7] = {2376745, 0x00, 0x12, ERRATA_A78_2376745},
[8] = {2395406, 0x00, 0x12, ERRATA_A78_2395406},
[9] = {2712571, 0x00, 0x12, ERRATA_A78_2712571, \
ERRATA_NON_ARM_INTERCONNECT},
[10] = {2742426, 0x00, 0x12, ERRATA_A78_2742426},
[11] = {2772019, 0x00, 0x12, ERRATA_A78_2772019},
[12] = {2779479, 0x00, 0x12, ERRATA_A78_2779479},
[13 ... ERRATA_LIST_END] = UNDEF_ERRATA,
[0] = {2712571, 0x00, 0x12},
[1 ... ERRATA_LIST_END] = UNDEF_ERRATA,
}
},
#endif /* CORTEX_A78_H_INC */
@ -216,13 +35,8 @@ struct em_cpu_list cpu_list[] = {
{
.cpu_partnumber = CORTEX_A78_AE_MIDR,
.cpu_errata_list = {
[0] = {1941500, 0x00, 0x01, ERRATA_A78_AE_1941500},
[1] = {1951502, 0x00, 0x01, ERRATA_A78_AE_1951502},
[2] = {2376748, 0x00, 0x02, ERRATA_A78_AE_2376748},
[3] = {2395408, 0x00, 0x01, ERRATA_A78_AE_2395408},
[4] = {2712574, 0x00, 0x02, ERRATA_A78_AE_2712574, \
ERRATA_NON_ARM_INTERCONNECT},
[5 ... ERRATA_LIST_END] = UNDEF_ERRATA,
[0] = {2712574, 0x00, 0x02},
[1 ... ERRATA_LIST_END] = UNDEF_ERRATA,
}
},
#endif /* CORTEX_A78_AE_H_INC */
@ -231,82 +45,18 @@ struct em_cpu_list cpu_list[] = {
{
.cpu_partnumber = CORTEX_A78C_MIDR,
.cpu_errata_list = {
[0] = {1827430, 0x00, 0x00, ERRATA_A78C_1827430},
[1] = {1827440, 0x00, 0x00, ERRATA_A78C_1827440},
[2] = {2132064, 0x01, 0x02, ERRATA_A78C_2132064},
[3] = {2242638, 0x01, 0x02, ERRATA_A78C_2242638},
[4] = {2376749, 0x01, 0x02, ERRATA_A78C_2376749},
[5] = {2395411, 0x01, 0x02, ERRATA_A78C_2395411},
[6] = {2683027, 0x01, 0x02, ERRATA_A78C_2683027},
[7] = {2712575, 0x01, 0x02, ERRATA_A78C_2712575, \
ERRATA_NON_ARM_INTERCONNECT},
[8] = {2743232, 0x01, 0x02, ERRATA_A78C_2743232},
[9] = {2772121, 0x00, 0x02, ERRATA_A78C_2772121},
[10] = {2779484, 0x01, 0x02, ERRATA_A78C_2779484},
[11 ... ERRATA_LIST_END] = UNDEF_ERRATA,
[0] = {2712575, 0x01, 0x02},
[1 ... ERRATA_LIST_END] = UNDEF_ERRATA,
}
},
#endif /* CORTEX_A78C_H_INC */
#if CORTEX_X1_H_INC
{
.cpu_partnumber = CORTEX_X1_MIDR,
.cpu_errata_list = {
[0] = {1688305, 0x00, 0x10, ERRATA_X1_1688305},
[1] = {1821534, 0x00, 0x10, ERRATA_X1_1821534},
[2] = {1827429, 0x00, 0x10, ERRATA_X1_1827429},
[3 ... ERRATA_LIST_END] = UNDEF_ERRATA,
}
},
#endif /* CORTEX_X1_H_INC */
#if NEOVERSE_N1_H_INC
{
.cpu_partnumber = NEOVERSE_N1_MIDR,
.cpu_errata_list = {
[0] = {1043202, 0x00, 0x10, ERRATA_N1_1043202},
[1] = {1073348, 0x00, 0x10, ERRATA_N1_1073348},
[2] = {1130799, 0x00, 0x20, ERRATA_N1_1130799},
[3] = {1165347, 0x00, 0x20, ERRATA_N1_1165347},
[4] = {1207823, 0x00, 0x20, ERRATA_N1_1207823},
[5] = {1220197, 0x00, 0x20, ERRATA_N1_1220197},
[6] = {1257314, 0x00, 0x30, ERRATA_N1_1257314},
[7] = {1262606, 0x00, 0x30, ERRATA_N1_1262606},
[8] = {1262888, 0x00, 0x30, ERRATA_N1_1262888},
[9] = {1275112, 0x00, 0x30, ERRATA_N1_1275112},
[10] = {1315703, 0x00, 0x30, ERRATA_N1_1315703},
[11] = {1542419, 0x30, 0x40, ERRATA_N1_1542419},
[12] = {1868343, 0x00, 0x40, ERRATA_N1_1868343},
[13] = {1946160, 0x30, 0x41, ERRATA_N1_1946160},
[14] = {2743102, 0x00, 0x41, ERRATA_N1_2743102},
[15 ... ERRATA_LIST_END] = UNDEF_ERRATA,
}
},
#endif /* NEOVERSE_N1_H_INC */
#if NEOVERSE_V1_H_INC
{
.cpu_partnumber = NEOVERSE_V1_MIDR,
.cpu_errata_list = {
[0] = {1618635, 0x00, 0x00, ERRATA_V1_1618635},
[1] = {1774420, 0x00, 0x10, ERRATA_V1_1774420},
[2] = {1791573, 0x00, 0x10, ERRATA_V1_1791573},
[3] = {1852267, 0x00, 0x10, ERRATA_V1_1852267},
[4] = {1925756, 0x00, 0x11, ERRATA_V1_1925756},
[5] = {1940577, 0x10, 0x11, ERRATA_V1_1940577},
[6] = {1966096, 0x10, 0x11, ERRATA_V1_1966096},
[7] = {2108267, 0x00, 0x12, ERRATA_V1_2108267},
[8] = {2139242, 0x00, 0x11, ERRATA_V1_2139242},
[9] = {2216392, 0x10, 0x11, ERRATA_V1_2216392},
[10] = {2294912, 0x00, 0x12, ERRATA_V1_2294912},
[11] = {2348377, 0x00, 0x11, ERRATA_V1_2348377},
[12] = {2372203, 0x00, 0x11, ERRATA_V1_2372203},
[13] = {2701953, 0x00, 0x11, ERRATA_V1_2701953, \
ERRATA_NON_ARM_INTERCONNECT},
[14] = {2743093, 0x00, 0x12, ERRATA_V1_2743093},
[15] = {2743233, 0x00, 0x12, ERRATA_V1_2743233},
[16] = {2779461, 0x00, 0x12, ERRATA_V1_2779461},
[17 ... ERRATA_LIST_END] = UNDEF_ERRATA,
[0] = {2701953, 0x00, 0x11},
[1 ... ERRATA_LIST_END] = UNDEF_ERRATA,
}
},
#endif /* NEOVERSE_V1_H_INC */
@ -315,26 +65,8 @@ struct em_cpu_list cpu_list[] = {
{
.cpu_partnumber = CORTEX_A710_MIDR,
.cpu_errata_list = {
[0] = {1987031, 0x00, 0x20, ERRATA_A710_1987031},
[1] = {2008768, 0x00, 0x20, ERRATA_A710_2008768},
[2] = {2017096, 0x00, 0x20, ERRATA_A710_2017096},
[3] = {2055002, 0x10, 0x20, ERRATA_A710_2055002},
[4] = {2058056, 0x00, 0x21, ERRATA_A710_2058056},
[5] = {2081180, 0x00, 0x20, ERRATA_A710_2081180},
[6] = {2083908, 0x20, 0x20, ERRATA_A710_2083908},
[7] = {2136059, 0x00, 0x20, ERRATA_A710_2136059},
[8] = {2147715, 0x20, 0x20, ERRATA_A710_2147715},
[9] = {2216384, 0x00, 0x20, ERRATA_A710_2216384},
[10] = {2267065, 0x00, 0x20, ERRATA_A710_2267065},
[11] = {2282622, 0x00, 0x21, ERRATA_A710_2282622},
[12] = {2291219, 0x00, 0x20, ERRATA_A710_2291219},
[13] = {2371105, 0x00, 0x20, ERRATA_A710_2371105},
[14] = {2701952, 0x00, 0x21, ERRATA_A710_2701952, \
ERRATA_NON_ARM_INTERCONNECT},
[15] = {2742423, 0x00, 0x21, ERRATA_A710_2742423},
[16] = {2768515, 0x00, 0x21, ERRATA_A710_2768515},
[17] = {2778471, 0x00, 0x21, ERRATA_A710_2778471},
[18 ... ERRATA_LIST_END] = UNDEF_ERRATA,
[0] = {2701952, 0x00, 0x21},
[1 ... ERRATA_LIST_END] = UNDEF_ERRATA,
}
},
#endif /* CORTEX_A710_H_INC */
@ -343,28 +75,8 @@ struct em_cpu_list cpu_list[] = {
{
.cpu_partnumber = NEOVERSE_N2_MIDR,
.cpu_errata_list = {
[0] = {2002655, 0x00, 0x00, ERRATA_N2_2002655},
[1] = {2009478, 0x00, 0x00, ERRATA_N2_2009478},
[2] = {2025414, 0x00, 0x00, ERRATA_N2_2025414},
[3] = {2067956, 0x00, 0x00, ERRATA_N2_2067956},
[4] = {2138953, 0x00, 0x03, ERRATA_N2_2138953},
[5] = {2138956, 0x00, 0x00, ERRATA_N2_2138956},
[6] = {2138958, 0x00, 0x00, ERRATA_N2_2138958},
[7] = {2189731, 0x00, 0x00, ERRATA_N2_2189731},
[8] = {2242400, 0x00, 0x00, ERRATA_N2_2242400},
[9] = {2242415, 0x00, 0x00, ERRATA_N2_2242415},
[10] = {2280757, 0x00, 0x00, ERRATA_N2_2280757},
[11] = {2326639, 0x00, 0x00, ERRATA_N2_2326639},
[12] = {2340933, 0x00, 0x00, ERRATA_N2_2340933},
[13] = {2346952, 0x00, 0x02, ERRATA_N2_2346952},
[14] = {2376738, 0x00, 0x00, ERRATA_N2_2376738},
[15] = {2388450, 0x00, 0x00, ERRATA_N2_2388450},
[16] = {2728475, 0x00, 0x02, ERRATA_N2_2728475, \
ERRATA_NON_ARM_INTERCONNECT},
[17] = {2743014, 0x00, 0x02, ERRATA_N2_2743014},
[18] = {2743089, 0x00, 0x02, ERRATA_N2_2743089},
[19] = {2779511, 0x00, 0x02, ERRATA_N2_2779511},
[20 ... ERRATA_LIST_END] = UNDEF_ERRATA,
[0] = {2728475, 0x00, 0x02},
[1 ... ERRATA_LIST_END] = UNDEF_ERRATA,
}
},
#endif /* NEOVERSE_N2_H_INC */
@ -373,187 +85,116 @@ struct em_cpu_list cpu_list[] = {
{
.cpu_partnumber = CORTEX_X2_MIDR,
.cpu_errata_list = {
[0] = {2002765, 0x00, 0x20, ERRATA_X2_2002765},
[1] = {2017096, 0x00, 0x20, ERRATA_X2_2017096},
[2] = {2058056, 0x00, 0x21, ERRATA_X2_2058056},
[3] = {2081180, 0x00, 0x20, ERRATA_X2_2081180},
[4] = {2083908, 0x20, 0x20, ERRATA_X2_2083908},
[5] = {2147715, 0x20, 0x20, ERRATA_X2_2147715},
[6] = {2216384, 0x00, 0x20, ERRATA_X2_2216384},
[7] = {2282622, 0x00, 0x21, ERRATA_X2_2282622},
[8] = {2371105, 0x00, 0x20, ERRATA_X2_2371105},
[9] = {2701952, 0x00, 0x21, ERRATA_X2_2701952, \
ERRATA_NON_ARM_INTERCONNECT},
[10] = {2742423, 0x00, 0x21, ERRATA_X2_2742423},
[11] = {2768515, 0x00, 0x21, ERRATA_X2_2768515},
[12] = {2778471, 0x00, 0x21, ERRATA_X2_2778471},
[13 ... ERRATA_LIST_END] = UNDEF_ERRATA,
[0] = {2701952, 0x00, 0x21},
[1 ... ERRATA_LIST_END] = UNDEF_ERRATA,
}
},
#endif /* CORTEX_X2_H_INC */
#if CORTEX_A510_H_INC
{
.cpu_partnumber = CORTEX_A510_MIDR,
.cpu_errata_list = {
[0] = {1922240, 0x00, 0x00, ERRATA_A510_1922240},
[1] = {2041909, 0x02, 0x02, ERRATA_A510_2041909},
[2] = {2042739, 0x00, 0x02, ERRATA_A510_2042739},
[3] = {2080326, 0x02, 0x02, ERRATA_A510_2080326},
[4] = {2172148, 0x00, 0x10, ERRATA_A510_2172148},
[5] = {2218950, 0x00, 0x10, ERRATA_A510_2218950},
[6] = {2250311, 0x00, 0x10, ERRATA_A510_2250311},
[7] = {2288014, 0x00, 0x10, ERRATA_A510_2288014},
[8] = {2347730, 0x00, 0x11, ERRATA_A510_2347730},
[9] = {2371937, 0x00, 0x11, ERRATA_A510_2371937},
[10] = {2666669, 0x00, 0x11, ERRATA_A510_2666669},
[11] = {2684597, 0x00, 0x12, ERRATA_A510_2684597},
[12 ... ERRATA_LIST_END] = UNDEF_ERRATA,
}
},
#endif /* CORTEX_A510_H_INC */
#if NEOVERSE_V2_H_INC
{
.cpu_partnumber = NEOVERSE_V2_MIDR,
.cpu_errata_list = {
[0] = {2331132, 0x00, 0x02, ERRATA_V2_2331132},
[1] = {2618597, 0x00, 0x01, ERRATA_V2_2618597},
[2] = {2662553, 0x00, 0x01, ERRATA_V2_2662553},
[3] = {2719103, 0x00, 0x01, ERRATA_V2_2719103, \
ERRATA_NON_ARM_INTERCONNECT},
[4] = {2719105, 0x00, 0x01, ERRATA_V2_2719105},
[5] = {2743011, 0x00, 0x01, ERRATA_V2_2743011},
[6] = {2779510, 0x00, 0x01, ERRATA_V2_2779510},
[7] = {2801372, 0x00, 0x01, ERRATA_V2_2801372},
[8 ... ERRATA_LIST_END] = UNDEF_ERRATA,
[0] = {2719103, 0x00, 0x01},
[1 ... ERRATA_LIST_END] = UNDEF_ERRATA,
}
},
#endif /* NEOVERSE_V2_H_INC */
#if CORTEX_A715_H_INC
{
.cpu_partnumber = CORTEX_A715_MIDR,
.cpu_errata_list = {
[0] = {2429384, 0x00, 0x10, ERRATA_A715_2429384},
[1] = {2561034, 0x10, 0x10, ERRATA_A715_2561034},
[2] = {2701951, 0x00, 0x11, ERRATA_A715_2701951, \
ERRATA_NON_ARM_INTERCONNECT},
[3 ... ERRATA_LIST_END] = UNDEF_ERRATA,
}
},
#endif /* CORTEX_A715_H_INC */
#if CORTEX_X3_H_INC
{
.cpu_partnumber = CORTEX_X3_MIDR,
.cpu_errata_list = {
[0] = {2070301, 0x00, 0x12, ERRATA_X3_2070301},
[1] = {2266875, 0x00, 0x10, ERRATA_X3_2266875},
[2] = {2302506, 0x00, 0x11, ERRATA_X3_2302506},
[3] = {2313909, 0x00, 0x10, ERRATA_X3_2313909},
[4] = {2372204, 0x00, 0x10, ERRATA_X3_2372204},
[5] = {2615812, 0x00, 0x11, ERRATA_X3_2615812},
[6] = {2641945, 0x00, 0x10, ERRATA_X3_2641945},
[7] = {2742421, 0x00, 0x11, ERRATA_X3_2742421},
[8] = {2743088, 0x00, 0x11, ERRATA_X3_2743088},
[9] = {2779509, 0x00, 0x11, ERRATA_X3_2779509},
[10 ... ERRATA_LIST_END] = UNDEF_ERRATA,
[0] = {2701951, 0x00, 0x11},
[1 ... ERRATA_LIST_END] = UNDEF_ERRATA,
}
},
#endif /* CORTEX_X3_H_INC */
#if CORTEX_A520_H_INC
{
.cpu_partnumber = CORTEX_A520_MIDR,
.cpu_errata_list = {
[0] = {2630792, 0x00, 0x01, ERRATA_A520_2630792},
[1] = {2858100, 0x00, 0x01, ERRATA_A520_2858100},
[2 ... ERRATA_LIST_END] = UNDEF_ERRATA,
}
},
#endif /* CORTEX_A520_H_INC */
};
/*
* Function to do binary search and check for the specific errata ID
* in the array of structures specific to the cpu identified.
*/
int32_t binary_search(struct em_cpu_list *ptr, uint32_t erratum_id, uint8_t rxpx_val)
#if ERRATA_NON_ARM_INTERCONNECT
/* Check if the errata is enabled for non-arm interconnect */
static int32_t non_arm_interconnect_errata(uint32_t errata_id, long rev_var)
{
int low_index = 0U, mid_index = 0U;
int32_t ret_val = EM_UNKNOWN_ERRATUM;
int high_index = MAX_ERRATA_ENTRIES - 1;
/* Determine the number of cpu listed in the cpu list */
uint8_t size_cpulist = ARRAY_SIZE(cpu_list);
assert(ptr != NULL);
/* Read the midr reg to extract cpu, revision and variant info */
uint32_t midr_val = read_midr();
for (uint8_t i = 0U; i < size_cpulist; i++) {
cpu_ptr = &cpu_list[i];
/*
* Pointer to the errata list of the cpu that matches
* extracted partnumber in the cpu list
* If the cpu partnumber in the cpu list, matches the midr
* part number, check to see if the errata ID matches
*/
struct em_cpu *erratum_ptr = NULL;
while (low_index <= high_index) {
mid_index = (low_index + high_index) / 2;
erratum_ptr = &ptr->cpu_errata_list[mid_index];
assert(erratum_ptr != NULL);
if (erratum_id < erratum_ptr->em_errata_id) {
high_index = mid_index - 1;
} else if (erratum_id > erratum_ptr->em_errata_id) {
low_index = mid_index + 1;
} else if (erratum_id == erratum_ptr->em_errata_id) {
if (RXPX_RANGE(rxpx_val, erratum_ptr->em_rxpx_lo, \
erratum_ptr->em_rxpx_hi)) {
if ((erratum_ptr->errata_enabled) && \
(!(erratum_ptr->non_arm_interconnect))) {
return EM_HIGHER_EL_MITIGATION;
if (EXTRACT_PARTNUM(midr_val) == EXTRACT_PARTNUM(cpu_ptr->cpu_partnumber)) {
struct em_cpu *ptr = NULL;
for (int j = 0; j < MAX_PLAT_CPU_ERRATA_ENTRIES; j++) {
ptr = &cpu_ptr->cpu_errata_list[j];
assert(ptr != NULL);
if (errata_id == ptr->em_errata_id) {
if (RXPX_RANGE(rev_var, ptr->em_rxpx_lo, ptr->em_rxpx_hi)) {
ret_val = EM_AFFECTED;
break;
}
return EM_AFFECTED;
ret_val = EM_NOT_AFFECTED;
break;
}
return EM_NOT_AFFECTED;
}
break;
}
}
/* no matching errata ID */
return EM_UNKNOWN_ERRATUM;
return ret_val;
}
#endif
/* Function to check if the errata exists for the specific CPU and rxpx */
int32_t verify_errata_implemented(uint32_t errata_id, uint32_t forward_flag)
{
/*
* Read MIDR value and extract the revision, variant and partnumber
*/
static uint32_t midr_val, cpu_partnum;
static uint8_t cpu_rxpx_val;
int32_t ret_val = EM_UNKNOWN_ERRATUM;
int32_t ret_val;
struct cpu_ops *cpu_ops;
struct erratum_entry *entry, *end;
long rev_var;
/* Determine the number of cpu listed in the cpu list */
uint8_t size_cpulist = ARRAY_SIZE(cpu_list);
ret_val = EM_UNKNOWN_ERRATUM;
rev_var = cpu_get_rev_var();
/* Read the midr reg to extract cpu, revision and variant info */
midr_val = read_midr();
#if ERRATA_NON_ARM_INTERCONNECT
ret_val = non_arm_interconnect_errata(errata_id, rev_var);
if (ret_val != EM_UNKNOWN_ERRATUM) {
return ret_val;
}
#endif
/* Extract revision and variant from the MIDR register */
cpu_rxpx_val = cpu_get_rev_var();
cpu_ops = get_cpu_ops_ptr();
assert(cpu_ops != NULL);
/* Extract the cpu partnumber and check if the cpu is in the cpu list */
cpu_partnum = EXTRACT_PARTNUM(midr_val);
entry = cpu_ops->errata_list_start;
assert(entry != NULL);
for (uint8_t i = 0; i < size_cpulist; i++) {
cpu_ptr = &cpu_list[i];
uint16_t partnum_extracted = EXTRACT_PARTNUM(cpu_ptr->cpu_partnumber);
end = cpu_ops->errata_list_end;
assert(end != NULL);
if (partnum_extracted == cpu_partnum) {
/*
* If the midr value is in the cpu list, binary search
* for the errata ID and specific revision in the list.
*/
ret_val = binary_search(cpu_ptr, errata_id, cpu_rxpx_val);
break;
end--; /* point to the last erratum entry of the queried cpu */
while ((entry <= end) && (ret_val == EM_UNKNOWN_ERRATUM)) {
if (entry->id == errata_id) {
if (entry->check_func(rev_var)) {
if (entry->chosen)
return EM_HIGHER_EL_MITIGATION;
else
return EM_AFFECTED;
}
return EM_NOT_AFFECTED;
}
entry += 1;
}
return ret_val;
}

Loading…
Cancel
Save