1*91f16700Schasinglulu /* 2*91f16700Schasinglulu * Copyright (c) 2023, Arm Limited and Contributors. All rights reserved. 3*91f16700Schasinglulu * 4*91f16700Schasinglulu * SPDX-License-Identifier: BSD-3-Clause 5*91f16700Schasinglulu */ 6*91f16700Schasinglulu 7*91f16700Schasinglulu #include <assert.h> 8*91f16700Schasinglulu #include "cpu_errata_info.h" 9*91f16700Schasinglulu #include <lib/smccc.h> 10*91f16700Schasinglulu #include <lib/utils_def.h> 11*91f16700Schasinglulu #include <services/errata_abi_svc.h> 12*91f16700Schasinglulu #include <smccc_helpers.h> 13*91f16700Schasinglulu 14*91f16700Schasinglulu /* 15*91f16700Schasinglulu * Global pointer that points to the specific 16*91f16700Schasinglulu * structure based on the MIDR part number 17*91f16700Schasinglulu */ 18*91f16700Schasinglulu struct em_cpu_list *cpu_ptr; 19*91f16700Schasinglulu 20*91f16700Schasinglulu extern uint8_t cpu_get_rev_var(void); 21*91f16700Schasinglulu 22*91f16700Schasinglulu /* Structure array that holds CPU specific errata information */ 23*91f16700Schasinglulu struct em_cpu_list cpu_list[] = { 24*91f16700Schasinglulu #if CORTEX_A9_H_INC 25*91f16700Schasinglulu { 26*91f16700Schasinglulu .cpu_partnumber = CORTEX_A9_MIDR, 27*91f16700Schasinglulu .cpu_errata_list = { 28*91f16700Schasinglulu [0] = {794073, 0x00, 0xFF, ERRATA_A9_794073}, 29*91f16700Schasinglulu [1 ... ERRATA_LIST_END] = UNDEF_ERRATA, 30*91f16700Schasinglulu } 31*91f16700Schasinglulu }, 32*91f16700Schasinglulu #endif /* CORTEX_A9_H_INC */ 33*91f16700Schasinglulu 34*91f16700Schasinglulu #if CORTEX_A15_H_INC 35*91f16700Schasinglulu { 36*91f16700Schasinglulu .cpu_partnumber = CORTEX_A15_MIDR, 37*91f16700Schasinglulu .cpu_errata_list = { 38*91f16700Schasinglulu [0] = {816470, 0x30, 0xFF, ERRATA_A15_816470}, 39*91f16700Schasinglulu [1] = {827671, 0x30, 0xFF, ERRATA_A15_827671}, 40*91f16700Schasinglulu [2 ... ERRATA_LIST_END] = UNDEF_ERRATA, 41*91f16700Schasinglulu } 42*91f16700Schasinglulu }, 43*91f16700Schasinglulu #endif /* CORTEX_A15_H_INC */ 44*91f16700Schasinglulu 45*91f16700Schasinglulu #if CORTEX_A17_H_INC 46*91f16700Schasinglulu { 47*91f16700Schasinglulu .cpu_partnumber = CORTEX_A17_MIDR, 48*91f16700Schasinglulu .cpu_errata_list = { 49*91f16700Schasinglulu [0] = {852421, 0x00, 0x12, ERRATA_A17_852421}, 50*91f16700Schasinglulu [1] = {852423, 0x00, 0x12, ERRATA_A17_852423}, 51*91f16700Schasinglulu [2 ... ERRATA_LIST_END] = UNDEF_ERRATA, 52*91f16700Schasinglulu } 53*91f16700Schasinglulu }, 54*91f16700Schasinglulu #endif /* CORTEX_A17_H_INC */ 55*91f16700Schasinglulu 56*91f16700Schasinglulu #if CORTEX_A35_H_INC 57*91f16700Schasinglulu { 58*91f16700Schasinglulu .cpu_partnumber = CORTEX_A35_MIDR, 59*91f16700Schasinglulu .cpu_errata_list = { 60*91f16700Schasinglulu [0] = {855472, 0x00, 0x00, ERRATA_A35_855472}, 61*91f16700Schasinglulu [1 ... ERRATA_LIST_END] = UNDEF_ERRATA, 62*91f16700Schasinglulu } 63*91f16700Schasinglulu }, 64*91f16700Schasinglulu #endif /* CORTEX_A35_H_INC */ 65*91f16700Schasinglulu 66*91f16700Schasinglulu #if CORTEX_A53_H_INC 67*91f16700Schasinglulu { 68*91f16700Schasinglulu .cpu_partnumber = CORTEX_A53_MIDR, 69*91f16700Schasinglulu .cpu_errata_list = { 70*91f16700Schasinglulu [0] = {819472, 0x00, 0x01, ERRATA_A53_819472}, 71*91f16700Schasinglulu [1] = {824069, 0x00, 0x02, ERRATA_A53_824069}, 72*91f16700Schasinglulu [2] = {826319, 0x00, 0x02, ERRATA_A53_826319}, 73*91f16700Schasinglulu [3] = {827319, 0x00, 0x02, ERRATA_A53_827319}, 74*91f16700Schasinglulu [4] = {835769, 0x00, 0x04, ERRATA_A53_835769}, 75*91f16700Schasinglulu [5] = {836870, 0x00, 0x03, ERRATA_A53_836870}, 76*91f16700Schasinglulu [6] = {843419, 0x00, 0x04, ERRATA_A53_843419}, 77*91f16700Schasinglulu [7] = {855873, 0x03, 0xFF, ERRATA_A53_855873}, 78*91f16700Schasinglulu [8] = {1530924, 0x00, 0xFF, ERRATA_A53_1530924}, 79*91f16700Schasinglulu [9 ... ERRATA_LIST_END] = UNDEF_ERRATA, 80*91f16700Schasinglulu } 81*91f16700Schasinglulu }, 82*91f16700Schasinglulu #endif /* CORTEX_A53_H_INC */ 83*91f16700Schasinglulu 84*91f16700Schasinglulu #if CORTEX_A55_H_INC 85*91f16700Schasinglulu { 86*91f16700Schasinglulu .cpu_partnumber = CORTEX_A55_MIDR, 87*91f16700Schasinglulu .cpu_errata_list = { 88*91f16700Schasinglulu [0] = {768277, 0x00, 0x00, ERRATA_A55_768277}, 89*91f16700Schasinglulu [1] = {778703, 0x00, 0x00, ERRATA_A55_778703}, 90*91f16700Schasinglulu [2] = {798797, 0x00, 0x00, ERRATA_A55_798797}, 91*91f16700Schasinglulu [3] = {846532, 0x00, 0x01, ERRATA_A55_846532}, 92*91f16700Schasinglulu [4] = {903758, 0x00, 0x01, ERRATA_A55_903758}, 93*91f16700Schasinglulu [5] = {1221012, 0x00, 0x10, ERRATA_A55_1221012}, 94*91f16700Schasinglulu [6] = {1530923, 0x00, 0xFF, ERRATA_A55_1530923}, 95*91f16700Schasinglulu [7 ... ERRATA_LIST_END] = UNDEF_ERRATA, 96*91f16700Schasinglulu } 97*91f16700Schasinglulu }, 98*91f16700Schasinglulu #endif /* CORTEX_A55_H_INC */ 99*91f16700Schasinglulu 100*91f16700Schasinglulu #if CORTEX_A57_H_INC 101*91f16700Schasinglulu { 102*91f16700Schasinglulu .cpu_partnumber = CORTEX_A57_MIDR, 103*91f16700Schasinglulu .cpu_errata_list = { 104*91f16700Schasinglulu [0] = {806969, 0x00, 0x00, ERRATA_A57_806969}, 105*91f16700Schasinglulu [1] = {813419, 0x00, 0x00, ERRATA_A57_813419}, 106*91f16700Schasinglulu [2] = {813420, 0x00, 0x00, ERRATA_A57_813420}, 107*91f16700Schasinglulu [3] = {814670, 0x00, 0x00, ERRATA_A57_814670}, 108*91f16700Schasinglulu [4] = {817169, 0x00, 0x01, ERRATA_A57_817169}, 109*91f16700Schasinglulu [5] = {826974, 0x00, 0x11, ERRATA_A57_826974}, 110*91f16700Schasinglulu [6] = {826977, 0x00, 0x11, ERRATA_A57_826977}, 111*91f16700Schasinglulu [7] = {828024, 0x00, 0x11, ERRATA_A57_828024}, 112*91f16700Schasinglulu [8] = {829520, 0x00, 0x12, ERRATA_A57_829520}, 113*91f16700Schasinglulu [9] = {833471, 0x00, 0x12, ERRATA_A57_833471}, 114*91f16700Schasinglulu [10] = {859972, 0x00, 0x13, ERRATA_A57_859972}, 115*91f16700Schasinglulu [11] = {1319537, 0x00, 0xFF, ERRATA_A57_1319537}, 116*91f16700Schasinglulu [12 ... ERRATA_LIST_END] = UNDEF_ERRATA, 117*91f16700Schasinglulu } 118*91f16700Schasinglulu }, 119*91f16700Schasinglulu #endif /* CORTEX_A57_H_INC */ 120*91f16700Schasinglulu 121*91f16700Schasinglulu #if CORTEX_A72_H_INC 122*91f16700Schasinglulu { 123*91f16700Schasinglulu .cpu_partnumber = CORTEX_A72_MIDR, 124*91f16700Schasinglulu .cpu_errata_list = { 125*91f16700Schasinglulu [0] = {859971, 0x00, 0x03, ERRATA_A72_859971}, 126*91f16700Schasinglulu [1] = {1319367, 0x00, 0xFF, ERRATA_A72_1319367}, 127*91f16700Schasinglulu [2 ... ERRATA_LIST_END] = UNDEF_ERRATA, 128*91f16700Schasinglulu } 129*91f16700Schasinglulu }, 130*91f16700Schasinglulu #endif /* CORTEX_A72_H_INC */ 131*91f16700Schasinglulu 132*91f16700Schasinglulu #if CORTEX_A73_H_INC 133*91f16700Schasinglulu { 134*91f16700Schasinglulu .cpu_partnumber = CORTEX_A73_MIDR, 135*91f16700Schasinglulu .cpu_errata_list = { 136*91f16700Schasinglulu [0] = {852427, 0x00, 0x00, ERRATA_A73_852427}, 137*91f16700Schasinglulu [1] = {855423, 0x00, 0x01, ERRATA_A73_855423}, 138*91f16700Schasinglulu [2 ... ERRATA_LIST_END] = UNDEF_ERRATA, 139*91f16700Schasinglulu } 140*91f16700Schasinglulu }, 141*91f16700Schasinglulu #endif /* CORTEX_A73_H_INC */ 142*91f16700Schasinglulu 143*91f16700Schasinglulu #if CORTEX_A75_H_INC 144*91f16700Schasinglulu { 145*91f16700Schasinglulu .cpu_partnumber = CORTEX_A75_MIDR, 146*91f16700Schasinglulu .cpu_errata_list = { 147*91f16700Schasinglulu [0] = {764081, 0x00, 0x00, ERRATA_A75_764081}, 148*91f16700Schasinglulu [1] = {790748, 0x00, 0x00, ERRATA_A75_790748}, 149*91f16700Schasinglulu [2 ... ERRATA_LIST_END] = UNDEF_ERRATA, 150*91f16700Schasinglulu } 151*91f16700Schasinglulu }, 152*91f16700Schasinglulu #endif /* CORTEX_A75_H_INC */ 153*91f16700Schasinglulu 154*91f16700Schasinglulu #if CORTEX_A76_H_INC 155*91f16700Schasinglulu { 156*91f16700Schasinglulu .cpu_partnumber = CORTEX_A76_MIDR, 157*91f16700Schasinglulu .cpu_errata_list = { 158*91f16700Schasinglulu [0] = {1073348, 0x00, 0x10, ERRATA_A76_1073348}, 159*91f16700Schasinglulu [1] = {1130799, 0x00, 0x20, ERRATA_A76_1130799}, 160*91f16700Schasinglulu [2] = {1165522, 0x00, 0xFF, ERRATA_A76_1165522}, 161*91f16700Schasinglulu [3] = {1220197, 0x00, 0x20, ERRATA_A76_1220197}, 162*91f16700Schasinglulu [4] = {1257314, 0x00, 0x30, ERRATA_A76_1257314}, 163*91f16700Schasinglulu [5] = {1262606, 0x00, 0x30, ERRATA_A76_1262606}, 164*91f16700Schasinglulu [6] = {1262888, 0x00, 0x30, ERRATA_A76_1262888}, 165*91f16700Schasinglulu [7] = {1275112, 0x00, 0x30, ERRATA_A76_1275112}, 166*91f16700Schasinglulu [8] = {1286807, 0x00, 0x30, ERRATA_A76_1286807}, 167*91f16700Schasinglulu [9] = {1791580, 0x00, 0x40, ERRATA_A76_1791580}, 168*91f16700Schasinglulu [10] = {1868343, 0x00, 0x40, ERRATA_A76_1868343}, 169*91f16700Schasinglulu [11] = {1946160, 0x30, 0x41, ERRATA_A76_1946160}, 170*91f16700Schasinglulu [12] = {2743102, 0x00, 0x41, ERRATA_A76_2743102}, 171*91f16700Schasinglulu [13 ... ERRATA_LIST_END] = UNDEF_ERRATA, 172*91f16700Schasinglulu } 173*91f16700Schasinglulu }, 174*91f16700Schasinglulu #endif /* CORTEX_A76_H_INC */ 175*91f16700Schasinglulu 176*91f16700Schasinglulu #if CORTEX_A77_H_INC 177*91f16700Schasinglulu { 178*91f16700Schasinglulu .cpu_partnumber = CORTEX_A77_MIDR, 179*91f16700Schasinglulu .cpu_errata_list = { 180*91f16700Schasinglulu [0] = {1508412, 0x00, 0x10, ERRATA_A77_1508412}, 181*91f16700Schasinglulu [1] = {1791578, 0x00, 0x11, ERRATA_A77_1791578}, 182*91f16700Schasinglulu [2] = {1800714, 0x00, 0x11, ERRATA_A77_1800714}, 183*91f16700Schasinglulu [3] = {1925769, 0x00, 0x11, ERRATA_A77_1925769}, 184*91f16700Schasinglulu [4] = {1946167, 0x00, 0x11, ERRATA_A77_1946167}, 185*91f16700Schasinglulu [5] = {2356587, 0x00, 0x11, ERRATA_A77_2356587}, 186*91f16700Schasinglulu [6] = {2743100, 0x00, 0x11, ERRATA_A77_2743100}, 187*91f16700Schasinglulu [7 ... ERRATA_LIST_END] = UNDEF_ERRATA, 188*91f16700Schasinglulu } 189*91f16700Schasinglulu }, 190*91f16700Schasinglulu #endif /* CORTEX_A77_H_INC */ 191*91f16700Schasinglulu 192*91f16700Schasinglulu #if CORTEX_A78_H_INC 193*91f16700Schasinglulu { 194*91f16700Schasinglulu .cpu_partnumber = CORTEX_A78_MIDR, 195*91f16700Schasinglulu .cpu_errata_list = { 196*91f16700Schasinglulu [0] = {1688305, 0x00, 0x10, ERRATA_A78_1688305}, 197*91f16700Schasinglulu [1] = {1821534, 0x00, 0x10, ERRATA_A78_1821534}, 198*91f16700Schasinglulu [2] = {1941498, 0x00, 0x11, ERRATA_A78_1941498}, 199*91f16700Schasinglulu [3] = {1951500, 0x10, 0x11, ERRATA_A78_1951500}, 200*91f16700Schasinglulu [4] = {1952683, 0x00, 0x00, ERRATA_A78_1952683}, 201*91f16700Schasinglulu [5] = {2132060, 0x00, 0x12, ERRATA_A78_2132060}, 202*91f16700Schasinglulu [6] = {2242635, 0x10, 0x12, ERRATA_A78_2242635}, 203*91f16700Schasinglulu [7] = {2376745, 0x00, 0x12, ERRATA_A78_2376745}, 204*91f16700Schasinglulu [8] = {2395406, 0x00, 0x12, ERRATA_A78_2395406}, 205*91f16700Schasinglulu [9] = {2712571, 0x00, 0x12, ERRATA_A78_2712571, \ 206*91f16700Schasinglulu ERRATA_NON_ARM_INTERCONNECT}, 207*91f16700Schasinglulu [10] = {2742426, 0x00, 0x12, ERRATA_A78_2742426}, 208*91f16700Schasinglulu [11] = {2772019, 0x00, 0x12, ERRATA_A78_2772019}, 209*91f16700Schasinglulu [12] = {2779479, 0x00, 0x12, ERRATA_A78_2779479}, 210*91f16700Schasinglulu [13 ... ERRATA_LIST_END] = UNDEF_ERRATA, 211*91f16700Schasinglulu } 212*91f16700Schasinglulu }, 213*91f16700Schasinglulu #endif /* CORTEX_A78_H_INC */ 214*91f16700Schasinglulu 215*91f16700Schasinglulu #if CORTEX_A78_AE_H_INC 216*91f16700Schasinglulu { 217*91f16700Schasinglulu .cpu_partnumber = CORTEX_A78_AE_MIDR, 218*91f16700Schasinglulu .cpu_errata_list = { 219*91f16700Schasinglulu [0] = {1941500, 0x00, 0x01, ERRATA_A78_AE_1941500}, 220*91f16700Schasinglulu [1] = {1951502, 0x00, 0x01, ERRATA_A78_AE_1951502}, 221*91f16700Schasinglulu [2] = {2376748, 0x00, 0x02, ERRATA_A78_AE_2376748}, 222*91f16700Schasinglulu [3] = {2395408, 0x00, 0x01, ERRATA_A78_AE_2395408}, 223*91f16700Schasinglulu [4] = {2712574, 0x00, 0x02, ERRATA_A78_AE_2712574, \ 224*91f16700Schasinglulu ERRATA_NON_ARM_INTERCONNECT}, 225*91f16700Schasinglulu [5 ... ERRATA_LIST_END] = UNDEF_ERRATA, 226*91f16700Schasinglulu } 227*91f16700Schasinglulu }, 228*91f16700Schasinglulu #endif /* CORTEX_A78_AE_H_INC */ 229*91f16700Schasinglulu 230*91f16700Schasinglulu #if CORTEX_A78C_H_INC 231*91f16700Schasinglulu { 232*91f16700Schasinglulu .cpu_partnumber = CORTEX_A78C_MIDR, 233*91f16700Schasinglulu .cpu_errata_list = { 234*91f16700Schasinglulu [0] = {1827430, 0x00, 0x00, ERRATA_A78C_1827430}, 235*91f16700Schasinglulu [1] = {1827440, 0x00, 0x00, ERRATA_A78C_1827440}, 236*91f16700Schasinglulu [2] = {2132064, 0x01, 0x02, ERRATA_A78C_2132064}, 237*91f16700Schasinglulu [3] = {2242638, 0x01, 0x02, ERRATA_A78C_2242638}, 238*91f16700Schasinglulu [4] = {2376749, 0x01, 0x02, ERRATA_A78C_2376749}, 239*91f16700Schasinglulu [5] = {2395411, 0x01, 0x02, ERRATA_A78C_2395411}, 240*91f16700Schasinglulu [6] = {2712575, 0x01, 0x02, ERRATA_A78C_2712575, \ 241*91f16700Schasinglulu ERRATA_NON_ARM_INTERCONNECT}, 242*91f16700Schasinglulu [7] = {2772121, 0x00, 0x02, ERRATA_A78C_2772121}, 243*91f16700Schasinglulu [8] = {2779484, 0x01, 0x02, ERRATA_A78C_2779484}, 244*91f16700Schasinglulu [9 ... ERRATA_LIST_END] = UNDEF_ERRATA, 245*91f16700Schasinglulu } 246*91f16700Schasinglulu }, 247*91f16700Schasinglulu #endif /* CORTEX_A78C_H_INC */ 248*91f16700Schasinglulu 249*91f16700Schasinglulu #if CORTEX_X1_H_INC 250*91f16700Schasinglulu { 251*91f16700Schasinglulu .cpu_partnumber = CORTEX_X1_MIDR, 252*91f16700Schasinglulu .cpu_errata_list = { 253*91f16700Schasinglulu [0] = {1688305, 0x00, 0x10, ERRATA_X1_1688305}, 254*91f16700Schasinglulu [1] = {1821534, 0x00, 0x10, ERRATA_X1_1821534}, 255*91f16700Schasinglulu [2] = {1827429, 0x00, 0x10, ERRATA_X1_1827429}, 256*91f16700Schasinglulu [3 ... ERRATA_LIST_END] = UNDEF_ERRATA, 257*91f16700Schasinglulu } 258*91f16700Schasinglulu }, 259*91f16700Schasinglulu #endif /* CORTEX_X1_H_INC */ 260*91f16700Schasinglulu 261*91f16700Schasinglulu #if NEOVERSE_N1_H_INC 262*91f16700Schasinglulu { 263*91f16700Schasinglulu .cpu_partnumber = NEOVERSE_N1_MIDR, 264*91f16700Schasinglulu .cpu_errata_list = { 265*91f16700Schasinglulu [0] = {1043202, 0x00, 0x10, ERRATA_N1_1043202}, 266*91f16700Schasinglulu [1] = {1073348, 0x00, 0x10, ERRATA_N1_1073348}, 267*91f16700Schasinglulu [2] = {1130799, 0x00, 0x20, ERRATA_N1_1130799}, 268*91f16700Schasinglulu [3] = {1165347, 0x00, 0x20, ERRATA_N1_1165347}, 269*91f16700Schasinglulu [4] = {1207823, 0x00, 0x20, ERRATA_N1_1207823}, 270*91f16700Schasinglulu [5] = {1220197, 0x00, 0x20, ERRATA_N1_1220197}, 271*91f16700Schasinglulu [6] = {1257314, 0x00, 0x30, ERRATA_N1_1257314}, 272*91f16700Schasinglulu [7] = {1262606, 0x00, 0x30, ERRATA_N1_1262606}, 273*91f16700Schasinglulu [8] = {1262888, 0x00, 0x30, ERRATA_N1_1262888}, 274*91f16700Schasinglulu [9] = {1275112, 0x00, 0x30, ERRATA_N1_1275112}, 275*91f16700Schasinglulu [10] = {1315703, 0x00, 0x30, ERRATA_N1_1315703}, 276*91f16700Schasinglulu [11] = {1542419, 0x30, 0x40, ERRATA_N1_1542419}, 277*91f16700Schasinglulu [12] = {1868343, 0x00, 0x40, ERRATA_N1_1868343}, 278*91f16700Schasinglulu [13] = {1946160, 0x30, 0x41, ERRATA_N1_1946160}, 279*91f16700Schasinglulu [14] = {2743102, 0x00, 0x41, ERRATA_N1_2743102}, 280*91f16700Schasinglulu [15 ... ERRATA_LIST_END] = UNDEF_ERRATA, 281*91f16700Schasinglulu } 282*91f16700Schasinglulu }, 283*91f16700Schasinglulu #endif /* NEOVERSE_N1_H_INC */ 284*91f16700Schasinglulu 285*91f16700Schasinglulu #if NEOVERSE_V1_H_INC 286*91f16700Schasinglulu { 287*91f16700Schasinglulu .cpu_partnumber = NEOVERSE_V1_MIDR, 288*91f16700Schasinglulu .cpu_errata_list = { 289*91f16700Schasinglulu [0] = {1618635, 0x00, 0x00, ERRATA_V1_1618635}, 290*91f16700Schasinglulu [1] = {1774420, 0x00, 0x10, ERRATA_V1_1774420}, 291*91f16700Schasinglulu [2] = {1791573, 0x00, 0x10, ERRATA_V1_1791573}, 292*91f16700Schasinglulu [3] = {1852267, 0x00, 0x10, ERRATA_V1_1852267}, 293*91f16700Schasinglulu [4] = {1925756, 0x00, 0x11, ERRATA_V1_1925756}, 294*91f16700Schasinglulu [5] = {1940577, 0x10, 0x11, ERRATA_V1_1940577}, 295*91f16700Schasinglulu [6] = {1966096, 0x10, 0x11, ERRATA_V1_1966096}, 296*91f16700Schasinglulu [7] = {2108267, 0x00, 0x12, ERRATA_V1_2108267}, 297*91f16700Schasinglulu [8] = {2139242, 0x00, 0x11, ERRATA_V1_2139242}, 298*91f16700Schasinglulu [9] = {2216392, 0x10, 0x11, ERRATA_V1_2216392}, 299*91f16700Schasinglulu [10] = {2294912, 0x00, 0x12, ERRATA_V1_2294912}, 300*91f16700Schasinglulu [11] = {2372203, 0x00, 0x11, ERRATA_V1_2372203}, 301*91f16700Schasinglulu [12] = {2701953, 0x00, 0x11, ERRATA_V1_2701953, \ 302*91f16700Schasinglulu ERRATA_NON_ARM_INTERCONNECT}, 303*91f16700Schasinglulu [13] = {2743093, 0x00, 0x12, ERRATA_V1_2743093}, 304*91f16700Schasinglulu [14] = {2743233, 0x00, 0x12, ERRATA_V1_2743233}, 305*91f16700Schasinglulu [15] = {2779461, 0x00, 0x12, ERRATA_V1_2779461}, 306*91f16700Schasinglulu [16 ... ERRATA_LIST_END] = UNDEF_ERRATA, 307*91f16700Schasinglulu } 308*91f16700Schasinglulu }, 309*91f16700Schasinglulu #endif /* NEOVERSE_V1_H_INC */ 310*91f16700Schasinglulu 311*91f16700Schasinglulu #if CORTEX_A710_H_INC 312*91f16700Schasinglulu { 313*91f16700Schasinglulu .cpu_partnumber = CORTEX_A710_MIDR, 314*91f16700Schasinglulu .cpu_errata_list = { 315*91f16700Schasinglulu [0] = {1987031, 0x00, 0x20, ERRATA_A710_1987031}, 316*91f16700Schasinglulu [1] = {2008768, 0x00, 0x20, ERRATA_A710_2008768}, 317*91f16700Schasinglulu [2] = {2017096, 0x00, 0x20, ERRATA_A710_2017096}, 318*91f16700Schasinglulu [3] = {2055002, 0x10, 0x20, ERRATA_A710_2055002}, 319*91f16700Schasinglulu [4] = {2058056, 0x00, 0x21, ERRATA_A710_2058056}, 320*91f16700Schasinglulu [5] = {2081180, 0x00, 0x20, ERRATA_A710_2081180}, 321*91f16700Schasinglulu [6] = {2083908, 0x20, 0x20, ERRATA_A710_2083908}, 322*91f16700Schasinglulu [7] = {2136059, 0x00, 0x20, ERRATA_A710_2136059}, 323*91f16700Schasinglulu [8] = {2147715, 0x20, 0x20, ERRATA_A710_2147715}, 324*91f16700Schasinglulu [9] = {2216384, 0x00, 0x20, ERRATA_A710_2216384}, 325*91f16700Schasinglulu [10] = {2267065, 0x00, 0x20, ERRATA_A710_2267065}, 326*91f16700Schasinglulu [11] = {2282622, 0x00, 0x21, ERRATA_A710_2282622}, 327*91f16700Schasinglulu [12] = {2291219, 0x00, 0x20, ERRATA_A710_2291219}, 328*91f16700Schasinglulu [13] = {2371105, 0x00, 0x20, ERRATA_A710_2371105}, 329*91f16700Schasinglulu [14] = {2701952, 0x00, 0x21, ERRATA_A710_2701952, \ 330*91f16700Schasinglulu ERRATA_NON_ARM_INTERCONNECT}, 331*91f16700Schasinglulu [15] = {2742423, 0x00, 0x21, ERRATA_A710_2742423}, 332*91f16700Schasinglulu [16] = {2768515, 0x00, 0x21, ERRATA_A710_2768515}, 333*91f16700Schasinglulu [17 ... ERRATA_LIST_END] = UNDEF_ERRATA, 334*91f16700Schasinglulu } 335*91f16700Schasinglulu }, 336*91f16700Schasinglulu #endif /* CORTEX_A710_H_INC */ 337*91f16700Schasinglulu 338*91f16700Schasinglulu #if NEOVERSE_N2_H_INC 339*91f16700Schasinglulu { 340*91f16700Schasinglulu .cpu_partnumber = NEOVERSE_N2_MIDR, 341*91f16700Schasinglulu .cpu_errata_list = { 342*91f16700Schasinglulu [0] = {2002655, 0x00, 0x00, ERRATA_N2_2002655}, 343*91f16700Schasinglulu [1] = {2009478, 0x00, 0x00, ERRATA_N2_2009478}, 344*91f16700Schasinglulu [2] = {2025414, 0x00, 0x00, ERRATA_N2_2025414}, 345*91f16700Schasinglulu [3] = {2067956, 0x00, 0x00, ERRATA_N2_2067956}, 346*91f16700Schasinglulu [4] = {2138953, 0x00, 0x03, ERRATA_N2_2138953}, 347*91f16700Schasinglulu [5] = {2138956, 0x00, 0x00, ERRATA_N2_2138956}, 348*91f16700Schasinglulu [6] = {2138958, 0x00, 0x00, ERRATA_N2_2138958}, 349*91f16700Schasinglulu [7] = {2189731, 0x00, 0x00, ERRATA_N2_2189731}, 350*91f16700Schasinglulu [8] = {2242400, 0x00, 0x00, ERRATA_N2_2242400}, 351*91f16700Schasinglulu [9] = {2242415, 0x00, 0x00, ERRATA_N2_2242415}, 352*91f16700Schasinglulu [10] = {2280757, 0x00, 0x00, ERRATA_N2_2280757}, 353*91f16700Schasinglulu [11] = {2326639, 0x00, 0x00, ERRATA_N2_2326639}, 354*91f16700Schasinglulu [12] = {2340933, 0x00, 0x00, ERRATA_N2_2340933}, 355*91f16700Schasinglulu [13] = {2346952, 0x00, 0x02, ERRATA_N2_2346952}, 356*91f16700Schasinglulu [14] = {2376738, 0x00, 0x00, ERRATA_N2_2376738}, 357*91f16700Schasinglulu [15] = {2388450, 0x00, 0x00, ERRATA_N2_2388450}, 358*91f16700Schasinglulu [16] = {2728475, 0x00, 0x02, ERRATA_N2_2728475, \ 359*91f16700Schasinglulu ERRATA_NON_ARM_INTERCONNECT}, 360*91f16700Schasinglulu [17] = {2743014, 0x00, 0x02, ERRATA_N2_2743014}, 361*91f16700Schasinglulu [18] = {2743089, 0x00, 0x02, ERRATA_N2_2743089}, 362*91f16700Schasinglulu [19] = {2779511, 0x00, 0x02, ERRATA_N2_2779511}, 363*91f16700Schasinglulu [20 ... ERRATA_LIST_END] = UNDEF_ERRATA, 364*91f16700Schasinglulu } 365*91f16700Schasinglulu }, 366*91f16700Schasinglulu #endif /* NEOVERSE_N2_H_INC */ 367*91f16700Schasinglulu 368*91f16700Schasinglulu #if CORTEX_X2_H_INC 369*91f16700Schasinglulu { 370*91f16700Schasinglulu .cpu_partnumber = CORTEX_X2_MIDR, 371*91f16700Schasinglulu .cpu_errata_list = { 372*91f16700Schasinglulu [0] = {2002765, 0x00, 0x20, ERRATA_X2_2002765}, 373*91f16700Schasinglulu [1] = {2017096, 0x00, 0x20, ERRATA_X2_2017096}, 374*91f16700Schasinglulu [2] = {2058056, 0x00, 0x21, ERRATA_X2_2058056}, 375*91f16700Schasinglulu [3] = {2081180, 0x00, 0x20, ERRATA_X2_2081180}, 376*91f16700Schasinglulu [4] = {2083908, 0x20, 0x20, ERRATA_X2_2083908}, 377*91f16700Schasinglulu [5] = {2147715, 0x20, 0x20, ERRATA_X2_2147715}, 378*91f16700Schasinglulu [6] = {2216384, 0x00, 0x20, ERRATA_X2_2216384}, 379*91f16700Schasinglulu [7] = {2282622, 0x00, 0x21, ERRATA_X2_2282622}, 380*91f16700Schasinglulu [8] = {2371105, 0x00, 0x20, ERRATA_X2_2371105}, 381*91f16700Schasinglulu [9] = {2701952, 0x00, 0x21, ERRATA_X2_2701952, \ 382*91f16700Schasinglulu ERRATA_NON_ARM_INTERCONNECT}, 383*91f16700Schasinglulu [10] = {2742423, 0x00, 0x21, ERRATA_X2_2742423}, 384*91f16700Schasinglulu [11] = {2768515, 0x00, 0x21, ERRATA_X2_2768515}, 385*91f16700Schasinglulu [12 ... ERRATA_LIST_END] = UNDEF_ERRATA, 386*91f16700Schasinglulu } 387*91f16700Schasinglulu }, 388*91f16700Schasinglulu #endif /* CORTEX_X2_H_INC */ 389*91f16700Schasinglulu 390*91f16700Schasinglulu #if CORTEX_A510_H_INC 391*91f16700Schasinglulu { 392*91f16700Schasinglulu .cpu_partnumber = CORTEX_A510_MIDR, 393*91f16700Schasinglulu .cpu_errata_list = { 394*91f16700Schasinglulu [0] = {1922240, 0x00, 0x00, ERRATA_A510_1922240}, 395*91f16700Schasinglulu [1] = {2041909, 0x02, 0x02, ERRATA_A510_2041909}, 396*91f16700Schasinglulu [2] = {2042739, 0x00, 0x02, ERRATA_A510_2042739}, 397*91f16700Schasinglulu [3] = {2080326, 0x02, 0x02, ERRATA_A510_2080326}, 398*91f16700Schasinglulu [4] = {2172148, 0x00, 0x10, ERRATA_A510_2172148}, 399*91f16700Schasinglulu [5] = {2218950, 0x00, 0x10, ERRATA_A510_2218950}, 400*91f16700Schasinglulu [6] = {2250311, 0x00, 0x10, ERRATA_A510_2250311}, 401*91f16700Schasinglulu [7] = {2288014, 0x00, 0x10, ERRATA_A510_2288014}, 402*91f16700Schasinglulu [8] = {2347730, 0x00, 0x11, ERRATA_A510_2347730}, 403*91f16700Schasinglulu [9] = {2371937, 0x00, 0x11, ERRATA_A510_2371937}, 404*91f16700Schasinglulu [10] = {2666669, 0x00, 0x11, ERRATA_A510_2666669}, 405*91f16700Schasinglulu [11] = {2684597, 0x00, 0x12, ERRATA_A510_2684597}, 406*91f16700Schasinglulu [12 ... ERRATA_LIST_END] = UNDEF_ERRATA, 407*91f16700Schasinglulu } 408*91f16700Schasinglulu }, 409*91f16700Schasinglulu #endif /* CORTEX_A510_H_INC */ 410*91f16700Schasinglulu 411*91f16700Schasinglulu #if NEOVERSE_V2_H_INC 412*91f16700Schasinglulu { 413*91f16700Schasinglulu .cpu_partnumber = NEOVERSE_V2_MIDR, 414*91f16700Schasinglulu .cpu_errata_list = { 415*91f16700Schasinglulu [0] = {2331132, 0x00, 0x02, ERRATA_V2_2331132}, 416*91f16700Schasinglulu [1] = {2719103, 0x00, 0x01, ERRATA_V2_2719103, \ 417*91f16700Schasinglulu ERRATA_NON_ARM_INTERCONNECT}, 418*91f16700Schasinglulu [2] = {2719105, 0x00, 0x01, ERRATA_V2_2719105}, 419*91f16700Schasinglulu [3] = {2743011, 0x00, 0x01, ERRATA_V2_2743011}, 420*91f16700Schasinglulu [4] = {2779510, 0x00, 0x01, ERRATA_V2_2779510}, 421*91f16700Schasinglulu [5] = {2801372, 0x00, 0x01, ERRATA_V2_2801372}, 422*91f16700Schasinglulu [6 ... ERRATA_LIST_END] = UNDEF_ERRATA, 423*91f16700Schasinglulu } 424*91f16700Schasinglulu }, 425*91f16700Schasinglulu #endif /* NEOVERSE_V2_H_INC */ 426*91f16700Schasinglulu 427*91f16700Schasinglulu #if CORTEX_A715_H_INC 428*91f16700Schasinglulu { 429*91f16700Schasinglulu .cpu_partnumber = CORTEX_A715_MIDR, 430*91f16700Schasinglulu .cpu_errata_list = { 431*91f16700Schasinglulu [0] = {2701951, 0x00, 0x11, ERRATA_A715_2701951, \ 432*91f16700Schasinglulu ERRATA_NON_ARM_INTERCONNECT}, 433*91f16700Schasinglulu [1 ... ERRATA_LIST_END] = UNDEF_ERRATA, 434*91f16700Schasinglulu } 435*91f16700Schasinglulu }, 436*91f16700Schasinglulu #endif /* CORTEX_A715_H_INC */ 437*91f16700Schasinglulu 438*91f16700Schasinglulu #if CORTEX_X3_H_INC 439*91f16700Schasinglulu { 440*91f16700Schasinglulu .cpu_partnumber = CORTEX_X3_MIDR, 441*91f16700Schasinglulu .cpu_errata_list = { 442*91f16700Schasinglulu [0] = {2070301, 0x00, 0x12, ERRATA_X3_2070301}, 443*91f16700Schasinglulu [1] = {2313909, 0x00, 0x10, ERRATA_X3_2313909}, 444*91f16700Schasinglulu [2] = {2615812, 0x00, 0x11, ERRATA_X3_2615812}, 445*91f16700Schasinglulu [3] = {2742421, 0x00, 0x11, ERRATA_X3_2742421}, 446*91f16700Schasinglulu [4 ... ERRATA_LIST_END] = UNDEF_ERRATA, 447*91f16700Schasinglulu } 448*91f16700Schasinglulu }, 449*91f16700Schasinglulu #endif /* CORTEX_X3_H_INC */ 450*91f16700Schasinglulu }; 451*91f16700Schasinglulu 452*91f16700Schasinglulu /* 453*91f16700Schasinglulu * Function to do binary search and check for the specific errata ID 454*91f16700Schasinglulu * in the array of structures specific to the cpu identified. 455*91f16700Schasinglulu */ 456*91f16700Schasinglulu int32_t binary_search(struct em_cpu_list *ptr, uint32_t erratum_id, uint8_t rxpx_val) 457*91f16700Schasinglulu { 458*91f16700Schasinglulu int low_index = 0U, mid_index = 0U; 459*91f16700Schasinglulu 460*91f16700Schasinglulu int high_index = MAX_ERRATA_ENTRIES - 1; 461*91f16700Schasinglulu 462*91f16700Schasinglulu assert(ptr != NULL); 463*91f16700Schasinglulu 464*91f16700Schasinglulu /* 465*91f16700Schasinglulu * Pointer to the errata list of the cpu that matches 466*91f16700Schasinglulu * extracted partnumber in the cpu list 467*91f16700Schasinglulu */ 468*91f16700Schasinglulu struct em_cpu *erratum_ptr = NULL; 469*91f16700Schasinglulu 470*91f16700Schasinglulu while (low_index <= high_index) { 471*91f16700Schasinglulu mid_index = (low_index + high_index) / 2; 472*91f16700Schasinglulu 473*91f16700Schasinglulu erratum_ptr = &ptr->cpu_errata_list[mid_index]; 474*91f16700Schasinglulu assert(erratum_ptr != NULL); 475*91f16700Schasinglulu 476*91f16700Schasinglulu if (erratum_id < erratum_ptr->em_errata_id) { 477*91f16700Schasinglulu high_index = mid_index - 1; 478*91f16700Schasinglulu } else if (erratum_id > erratum_ptr->em_errata_id) { 479*91f16700Schasinglulu low_index = mid_index + 1; 480*91f16700Schasinglulu } else if (erratum_id == erratum_ptr->em_errata_id) { 481*91f16700Schasinglulu if (RXPX_RANGE(rxpx_val, erratum_ptr->em_rxpx_lo, \ 482*91f16700Schasinglulu erratum_ptr->em_rxpx_hi)) { 483*91f16700Schasinglulu if ((erratum_ptr->errata_enabled) && \ 484*91f16700Schasinglulu (!(erratum_ptr->non_arm_interconnect))) { 485*91f16700Schasinglulu return EM_HIGHER_EL_MITIGATION; 486*91f16700Schasinglulu } 487*91f16700Schasinglulu return EM_AFFECTED; 488*91f16700Schasinglulu } 489*91f16700Schasinglulu return EM_NOT_AFFECTED; 490*91f16700Schasinglulu } 491*91f16700Schasinglulu } 492*91f16700Schasinglulu /* no matching errata ID */ 493*91f16700Schasinglulu return EM_UNKNOWN_ERRATUM; 494*91f16700Schasinglulu } 495*91f16700Schasinglulu 496*91f16700Schasinglulu /* Function to check if the errata exists for the specific CPU and rxpx */ 497*91f16700Schasinglulu int32_t verify_errata_implemented(uint32_t errata_id, uint32_t forward_flag) 498*91f16700Schasinglulu { 499*91f16700Schasinglulu /* 500*91f16700Schasinglulu * Read MIDR value and extract the revision, variant and partnumber 501*91f16700Schasinglulu */ 502*91f16700Schasinglulu static uint32_t midr_val, cpu_partnum; 503*91f16700Schasinglulu static uint8_t cpu_rxpx_val; 504*91f16700Schasinglulu int32_t ret_val = EM_UNKNOWN_ERRATUM; 505*91f16700Schasinglulu 506*91f16700Schasinglulu /* Determine the number of cpu listed in the cpu list */ 507*91f16700Schasinglulu uint8_t size_cpulist = ARRAY_SIZE(cpu_list); 508*91f16700Schasinglulu 509*91f16700Schasinglulu /* Read the midr reg to extract cpu, revision and variant info */ 510*91f16700Schasinglulu midr_val = read_midr(); 511*91f16700Schasinglulu 512*91f16700Schasinglulu /* Extract revision and variant from the MIDR register */ 513*91f16700Schasinglulu cpu_rxpx_val = cpu_get_rev_var(); 514*91f16700Schasinglulu 515*91f16700Schasinglulu /* Extract the cpu partnumber and check if the cpu is in the cpu list */ 516*91f16700Schasinglulu cpu_partnum = EXTRACT_PARTNUM(midr_val); 517*91f16700Schasinglulu 518*91f16700Schasinglulu for (uint8_t i = 0; i < size_cpulist; i++) { 519*91f16700Schasinglulu cpu_ptr = &cpu_list[i]; 520*91f16700Schasinglulu uint16_t partnum_extracted = EXTRACT_PARTNUM(cpu_ptr->cpu_partnumber); 521*91f16700Schasinglulu 522*91f16700Schasinglulu if (partnum_extracted == cpu_partnum) { 523*91f16700Schasinglulu /* 524*91f16700Schasinglulu * If the midr value is in the cpu list, binary search 525*91f16700Schasinglulu * for the errata ID and specific revision in the list. 526*91f16700Schasinglulu */ 527*91f16700Schasinglulu ret_val = binary_search(cpu_ptr, errata_id, cpu_rxpx_val); 528*91f16700Schasinglulu break; 529*91f16700Schasinglulu } 530*91f16700Schasinglulu } 531*91f16700Schasinglulu return ret_val; 532*91f16700Schasinglulu } 533*91f16700Schasinglulu 534*91f16700Schasinglulu /* Predicate indicating that a function id is part of EM_ABI */ 535*91f16700Schasinglulu bool is_errata_fid(uint32_t smc_fid) 536*91f16700Schasinglulu { 537*91f16700Schasinglulu return ((smc_fid == ARM_EM_VERSION) || 538*91f16700Schasinglulu (smc_fid == ARM_EM_FEATURES) || 539*91f16700Schasinglulu (smc_fid == ARM_EM_CPU_ERRATUM_FEATURES)); 540*91f16700Schasinglulu 541*91f16700Schasinglulu } 542*91f16700Schasinglulu 543*91f16700Schasinglulu bool validate_spsr_mode(void) 544*91f16700Schasinglulu { 545*91f16700Schasinglulu /* In AArch64, if the caller is EL1, return true */ 546*91f16700Schasinglulu 547*91f16700Schasinglulu #if __aarch64__ 548*91f16700Schasinglulu if (GET_EL(read_spsr_el3()) == MODE_EL1) { 549*91f16700Schasinglulu return true; 550*91f16700Schasinglulu } 551*91f16700Schasinglulu return false; 552*91f16700Schasinglulu #else 553*91f16700Schasinglulu 554*91f16700Schasinglulu /* In AArch32, if in system/svc mode, return true */ 555*91f16700Schasinglulu uint8_t read_el_state = GET_M32(read_spsr()); 556*91f16700Schasinglulu 557*91f16700Schasinglulu if ((read_el_state == (MODE32_svc)) || (read_el_state == MODE32_sys)) { 558*91f16700Schasinglulu return true; 559*91f16700Schasinglulu } 560*91f16700Schasinglulu return false; 561*91f16700Schasinglulu #endif /* __aarch64__ */ 562*91f16700Schasinglulu } 563*91f16700Schasinglulu 564*91f16700Schasinglulu uintptr_t errata_abi_smc_handler(uint32_t smc_fid, u_register_t x1, 565*91f16700Schasinglulu u_register_t x2, u_register_t x3, u_register_t x4, 566*91f16700Schasinglulu void *cookie, void *handle, u_register_t flags) 567*91f16700Schasinglulu { 568*91f16700Schasinglulu int32_t ret_id = EM_UNKNOWN_ERRATUM; 569*91f16700Schasinglulu 570*91f16700Schasinglulu switch (smc_fid) { 571*91f16700Schasinglulu case ARM_EM_VERSION: 572*91f16700Schasinglulu SMC_RET1(handle, MAKE_SMCCC_VERSION( 573*91f16700Schasinglulu EM_VERSION_MAJOR, EM_VERSION_MINOR 574*91f16700Schasinglulu )); 575*91f16700Schasinglulu break; /* unreachable */ 576*91f16700Schasinglulu case ARM_EM_FEATURES: 577*91f16700Schasinglulu if (is_errata_fid((uint32_t)x1)) { 578*91f16700Schasinglulu SMC_RET1(handle, EM_SUCCESS); 579*91f16700Schasinglulu } 580*91f16700Schasinglulu 581*91f16700Schasinglulu SMC_RET1(handle, EM_NOT_SUPPORTED); 582*91f16700Schasinglulu break; /* unreachable */ 583*91f16700Schasinglulu case ARM_EM_CPU_ERRATUM_FEATURES: 584*91f16700Schasinglulu 585*91f16700Schasinglulu /* 586*91f16700Schasinglulu * If the forward flag is greater than zero and the calling EL 587*91f16700Schasinglulu * is EL1 in AArch64 or in system mode or svc mode in case of AArch32, 588*91f16700Schasinglulu * return Invalid Parameters. 589*91f16700Schasinglulu */ 590*91f16700Schasinglulu if (((uint32_t)x2 != 0) && (validate_spsr_mode())) { 591*91f16700Schasinglulu SMC_RET1(handle, EM_INVALID_PARAMETERS); 592*91f16700Schasinglulu } 593*91f16700Schasinglulu ret_id = verify_errata_implemented((uint32_t)x1, (uint32_t)x2); 594*91f16700Schasinglulu SMC_RET1(handle, ret_id); 595*91f16700Schasinglulu break; /* unreachable */ 596*91f16700Schasinglulu default: 597*91f16700Schasinglulu { 598*91f16700Schasinglulu WARN("Unimplemented Errata ABI Service Call: 0x%x\n", smc_fid); 599*91f16700Schasinglulu SMC_RET1(handle, EM_UNKNOWN_ERRATUM); 600*91f16700Schasinglulu break; /* unreachable */ 601*91f16700Schasinglulu } 602*91f16700Schasinglulu } 603*91f16700Schasinglulu } 604