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