Sona Mathew | 7fe0352 | 2022-11-18 18:05:38 -0600 | [diff] [blame] | 1 | /* |
| 2 | * Copyright (c) 2023, 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] = {1791580, 0x00, 0x40, ERRATA_A76_1791580}, |
| 167 | [9] = {1868343, 0x00, 0x40, ERRATA_A76_1868343}, |
| 168 | [10] = {1946160, 0x30, 0x41, ERRATA_A76_1946160}, |
| 169 | [11 ... ERRATA_LIST_END] = UNDEF_ERRATA, |
| 170 | } |
| 171 | }, |
| 172 | #endif /* CORTEX_A76_H_INC */ |
| 173 | |
| 174 | #if CORTEX_A77_H_INC |
| 175 | { |
| 176 | .cpu_partnumber = CORTEX_A77_MIDR, |
| 177 | .cpu_errata_list = { |
| 178 | [0] = {1508412, 0x00, 0x10, ERRATA_A77_1508412}, |
| 179 | [1] = {1791578, 0x00, 0x11, ERRATA_A77_1791578}, |
| 180 | [2] = {1800714, 0x00, 0x11, ERRATA_A77_1800714}, |
| 181 | [3] = {1925769, 0x00, 0x11, ERRATA_A77_1925769}, |
| 182 | [4] = {1946167, 0x00, 0x11, ERRATA_A77_1946167}, |
| 183 | [5] = {2356587, 0x00, 0x11, ERRATA_A77_2356587}, |
| 184 | [6] = {2743100, 0x00, 0x11, ERRATA_A77_2743100}, |
| 185 | [7 ... ERRATA_LIST_END] = UNDEF_ERRATA, |
| 186 | } |
| 187 | }, |
| 188 | #endif /* CORTEX_A77_H_INC */ |
| 189 | |
| 190 | #if CORTEX_A78_H_INC |
| 191 | { |
| 192 | .cpu_partnumber = CORTEX_A78_MIDR, |
| 193 | .cpu_errata_list = { |
| 194 | [0] = {1688305, 0x00, 0x10, ERRATA_A78_1688305}, |
| 195 | [1] = {1821534, 0x00, 0x10, ERRATA_A78_1821534}, |
| 196 | [2] = {1941498, 0x00, 0x11, ERRATA_A78_1941498}, |
| 197 | [3] = {1951500, 0x10, 0x11, ERRATA_A78_1951500}, |
| 198 | [4] = {1952683, 0x00, 0x00, ERRATA_A78_1952683}, |
| 199 | [5] = {2132060, 0x00, 0x12, ERRATA_A78_2132060}, |
| 200 | [6] = {2242635, 0x10, 0x12, ERRATA_A78_2242635}, |
| 201 | [7] = {2376745, 0x00, 0x12, ERRATA_A78_2376745}, |
| 202 | [8] = {2395406, 0x00, 0x12, ERRATA_A78_2395406}, |
Sona Mathew | c5b386d | 2023-03-14 16:50:36 -0500 | [diff] [blame] | 203 | [9] = {2712571, 0x00, 0x12, ERRATA_A78_2712571, \ |
| 204 | ERRATA_NON_ARM_INTERCONNECT}, |
| 205 | [10] = {2742426, 0x00, 0x12, ERRATA_A78_2742426}, |
| 206 | [11] = {2772019, 0x00, 0x12, ERRATA_A78_2772019}, |
| 207 | [12] = {2779479, 0x00, 0x12, ERRATA_A78_2779479}, |
| 208 | [13 ... ERRATA_LIST_END] = UNDEF_ERRATA, |
Sona Mathew | 7fe0352 | 2022-11-18 18:05:38 -0600 | [diff] [blame] | 209 | } |
| 210 | }, |
| 211 | #endif /* CORTEX_A78_H_INC */ |
| 212 | |
| 213 | #if CORTEX_A78_AE_H_INC |
| 214 | { |
| 215 | .cpu_partnumber = CORTEX_A78_AE_MIDR, |
| 216 | .cpu_errata_list = { |
| 217 | [0] = {1941500, 0x00, 0x01, ERRATA_A78_AE_1941500}, |
| 218 | [1] = {1951502, 0x00, 0x01, ERRATA_A78_AE_1951502}, |
| 219 | [2] = {2376748, 0x00, 0x01, ERRATA_A78_AE_2376748}, |
| 220 | [3] = {2395408, 0x00, 0x01, ERRATA_A78_AE_2395408}, |
Sona Mathew | c5b386d | 2023-03-14 16:50:36 -0500 | [diff] [blame] | 221 | [4] = {2712574, 0x00, 0x02, ERRATA_A78_AE_2712574, \ |
| 222 | ERRATA_NON_ARM_INTERCONNECT}, |
| 223 | [5 ... ERRATA_LIST_END] = UNDEF_ERRATA, |
Sona Mathew | 7fe0352 | 2022-11-18 18:05:38 -0600 | [diff] [blame] | 224 | } |
| 225 | }, |
| 226 | #endif /* CORTEX_A78_AE_H_INC */ |
| 227 | |
| 228 | #if CORTEX_A78C_H_INC |
| 229 | { |
| 230 | .cpu_partnumber = CORTEX_A78C_MIDR, |
| 231 | .cpu_errata_list = { |
| 232 | [0] = {2132064, 0x01, 0x02, ERRATA_A78C_2132064}, |
| 233 | [1] = {2242638, 0x01, 0x02, ERRATA_A78C_2242638}, |
| 234 | [2] = {2376749, 0x01, 0x02, ERRATA_A78C_2376749}, |
| 235 | [3] = {2395411, 0x01, 0x02, ERRATA_A78C_2395411}, |
Sona Mathew | c5b386d | 2023-03-14 16:50:36 -0500 | [diff] [blame] | 236 | [4] = {2712575, 0x01, 0x02, ERRATA_A78C_2712575, \ |
| 237 | ERRATA_NON_ARM_INTERCONNECT}, |
| 238 | [5] = {2772121, 0x00, 0x02, ERRATA_A78C_2772121}, |
| 239 | [6] = {2779484, 0x01, 0x02, ERRATA_A78C_2779484}, |
| 240 | [7 ... ERRATA_LIST_END] = UNDEF_ERRATA, |
Sona Mathew | 7fe0352 | 2022-11-18 18:05:38 -0600 | [diff] [blame] | 241 | } |
| 242 | }, |
| 243 | #endif /* CORTEX_A78C_H_INC */ |
| 244 | |
| 245 | #if CORTEX_X1_H_INC |
| 246 | { |
| 247 | .cpu_partnumber = CORTEX_X1_MIDR, |
| 248 | .cpu_errata_list = { |
| 249 | [0] = {1688305, 0x00, 0x10, ERRATA_X1_1688305}, |
| 250 | [1] = {1821534, 0x00, 0x10, ERRATA_X1_1821534}, |
| 251 | [2] = {1827429, 0x00, 0x10, ERRATA_X1_1827429}, |
| 252 | [3 ... ERRATA_LIST_END] = UNDEF_ERRATA, |
| 253 | } |
| 254 | }, |
| 255 | #endif /* CORTEX_X1_H_INC */ |
| 256 | |
| 257 | #if NEOVERSE_N1_H_INC |
| 258 | { |
| 259 | .cpu_partnumber = NEOVERSE_N1_MIDR, |
| 260 | .cpu_errata_list = { |
| 261 | [0] = {1073348, 0x00, 0x10, ERRATA_N1_1073348}, |
| 262 | [1] = {1130799, 0x00, 0x20, ERRATA_N1_1130799}, |
| 263 | [2] = {1165347, 0x00, 0x20, ERRATA_N1_1165347}, |
| 264 | [3] = {1207823, 0x00, 0x20, ERRATA_N1_1207823}, |
| 265 | [4] = {1220197, 0x00, 0x20, ERRATA_N1_1220197}, |
| 266 | [5] = {1257314, 0x00, 0x30, ERRATA_N1_1257314}, |
| 267 | [6] = {1262606, 0x00, 0x30, ERRATA_N1_1262606}, |
| 268 | [7] = {1262888, 0x00, 0x30, ERRATA_N1_1262888}, |
| 269 | [8] = {1275112, 0x00, 0x30, ERRATA_N1_1275112}, |
| 270 | [9] = {1315703, 0x00, 0x30, ERRATA_N1_1315703}, |
| 271 | [10] = {1542419, 0x30, 0x40, ERRATA_N1_1542419}, |
| 272 | [11] = {1868343, 0x00, 0x40, ERRATA_N1_1868343}, |
| 273 | [12] = {1946160, 0x30, 0x41, ERRATA_N1_1946160}, |
| 274 | [13] = {2743102, 0x00, 0x41, ERRATA_N1_2743102}, |
| 275 | [14 ... ERRATA_LIST_END] = UNDEF_ERRATA, |
| 276 | } |
| 277 | }, |
| 278 | #endif /* NEOVERSE_N1_H_INC */ |
| 279 | |
| 280 | #if NEOVERSE_V1_H_INC |
| 281 | { |
| 282 | .cpu_partnumber = NEOVERSE_V1_MIDR, |
| 283 | .cpu_errata_list = { |
| 284 | [0] = {1618635, 0x00, 0x0F, ERRATA_V1_1618635}, |
| 285 | [1] = {1774420, 0x00, 0x10, ERRATA_V1_1774420}, |
| 286 | [2] = {1791573, 0x00, 0x10, ERRATA_V1_1791573}, |
| 287 | [3] = {1852267, 0x00, 0x10, ERRATA_V1_1852267}, |
| 288 | [4] = {1925756, 0x00, 0x11, ERRATA_V1_1925756}, |
| 289 | [5] = {1940577, 0x10, 0x11, ERRATA_V1_1940577}, |
| 290 | [6] = {1966096, 0x10, 0x11, ERRATA_V1_1966096}, |
| 291 | [7] = {2108267, 0x00, 0x11, ERRATA_V1_2108267}, |
| 292 | [8] = {2139242, 0x00, 0x11, ERRATA_V1_2139242}, |
| 293 | [9] = {2216392, 0x10, 0x11, ERRATA_V1_2216392}, |
| 294 | [10] = {2294912, 0x00, 0x11, ERRATA_V1_2294912}, |
| 295 | [11] = {2372203, 0x00, 0x11, ERRATA_V1_2372203}, |
Sona Mathew | c5b386d | 2023-03-14 16:50:36 -0500 | [diff] [blame] | 296 | [12] = {2701953, 0x00, 0x11, ERRATA_V1_2701953, \ |
| 297 | ERRATA_NON_ARM_INTERCONNECT}, |
| 298 | [13] = {2743093, 0x00, 0x12, ERRATA_V1_2743093}, |
| 299 | [14] = {2779461, 0x00, 0x12, ERRATA_V1_2779461}, |
| 300 | [15 ... ERRATA_LIST_END] = UNDEF_ERRATA, |
Sona Mathew | 7fe0352 | 2022-11-18 18:05:38 -0600 | [diff] [blame] | 301 | } |
| 302 | }, |
| 303 | #endif /* NEOVERSE_V1_H_INC */ |
| 304 | |
| 305 | #if CORTEX_A710_H_INC |
| 306 | { |
| 307 | .cpu_partnumber = CORTEX_A710_MIDR, |
| 308 | .cpu_errata_list = { |
| 309 | [0] = {1987031, 0x00, 0x20, ERRATA_A710_1987031}, |
| 310 | [1] = {2008768, 0x00, 0x20, ERRATA_A710_2008768}, |
| 311 | [2] = {2017096, 0x00, 0x20, ERRATA_A710_2017096}, |
| 312 | [3] = {2055002, 0x10, 0x20, ERRATA_A710_2055002}, |
| 313 | [4] = {2058056, 0x00, 0x10, ERRATA_A710_2058056}, |
| 314 | [5] = {2081180, 0x00, 0x20, ERRATA_A710_2081180}, |
| 315 | [6] = {2083908, 0x20, 0x20, ERRATA_A710_2083908}, |
| 316 | [7] = {2136059, 0x00, 0x20, ERRATA_A710_2136059}, |
| 317 | [8] = {2147715, 0x20, 0x20, ERRATA_A710_2147715}, |
| 318 | [9] = {2216384, 0x00, 0x20, ERRATA_A710_2216384}, |
| 319 | [10] = {2267065, 0x00, 0x20, ERRATA_A710_2267065}, |
| 320 | [11] = {2282622, 0x00, 0x21, ERRATA_A710_2282622}, |
| 321 | [12] = {2291219, 0x00, 0x20, ERRATA_A710_2291219}, |
| 322 | [13] = {2371105, 0x00, 0x20, ERRATA_A710_2371105}, |
Sona Mathew | c5b386d | 2023-03-14 16:50:36 -0500 | [diff] [blame] | 323 | [14] = {2701952, 0x00, 0x21, ERRATA_A710_2701952, \ |
| 324 | ERRATA_NON_ARM_INTERCONNECT}, |
| 325 | [15] = {2768515, 0x00, 0x21, ERRATA_A710_2768515} |
Sona Mathew | 7fe0352 | 2022-11-18 18:05:38 -0600 | [diff] [blame] | 326 | } |
| 327 | }, |
| 328 | #endif /* CORTEX_A710_H_INC */ |
| 329 | |
| 330 | #if NEOVERSE_N2_H_INC |
| 331 | { |
| 332 | .cpu_partnumber = NEOVERSE_N2_MIDR, |
| 333 | .cpu_errata_list = { |
| 334 | [0] = {2002655, 0x00, 0x00, ERRATA_N2_2002655}, |
| 335 | [1] = {2025414, 0x00, 0x00, ERRATA_N2_2025414}, |
| 336 | [2] = {2067956, 0x00, 0x00, ERRATA_N2_2067956}, |
| 337 | [3] = {2138953, 0x00, 0x00, ERRATA_N2_2138953}, |
| 338 | [4] = {2138956, 0x00, 0x00, ERRATA_N2_2138956}, |
| 339 | [5] = {2138958, 0x00, 0x00, ERRATA_N2_2138958}, |
| 340 | [6] = {2189731, 0x00, 0x00, ERRATA_N2_2189731}, |
| 341 | [7] = {2242400, 0x00, 0x00, ERRATA_N2_2242400}, |
| 342 | [8] = {2242415, 0x00, 0x00, ERRATA_N2_2242415}, |
| 343 | [9] = {2280757, 0x00, 0x00, ERRATA_N2_2280757}, |
| 344 | [10] = {2326639, 0x00, 0x00, ERRATA_N2_2326639}, |
| 345 | [11] = {2376738, 0x00, 0x00, ERRATA_N2_2376738}, |
| 346 | [12] = {2388450, 0x00, 0x00, ERRATA_N2_2388450}, |
Sona Mathew | c5b386d | 2023-03-14 16:50:36 -0500 | [diff] [blame] | 347 | [13] = {2728475, 0x00, 0x02, ERRATA_N2_2728475, \ |
| 348 | ERRATA_NON_ARM_INTERCONNECT}, |
Arvind Ram Prakash | 465f93b | 2023-07-05 17:24:23 -0500 | [diff] [blame] | 349 | [14] = {2743014, 0x00, 0x02, ERRATA_N2_2743014}, |
| 350 | [15] = {2743089, 0x00, 0x02, ERRATA_N2_2743089}, |
Arvind Ram Prakash | 189622a | 2023-07-17 14:46:14 -0500 | [diff] [blame] | 351 | [16] = {2779511, 0x00, 0x02, ERRATA_N2_2779511}, |
| 352 | [17 ... ERRATA_LIST_END] = UNDEF_ERRATA, |
Sona Mathew | 7fe0352 | 2022-11-18 18:05:38 -0600 | [diff] [blame] | 353 | } |
| 354 | }, |
| 355 | #endif /* NEOVERSE_N2_H_INC */ |
| 356 | |
| 357 | #if CORTEX_X2_H_INC |
| 358 | { |
| 359 | .cpu_partnumber = CORTEX_X2_MIDR, |
| 360 | .cpu_errata_list = { |
| 361 | [0] = {2002765, 0x00, 0x20, ERRATA_X2_2002765}, |
| 362 | [1] = {2017096, 0x00, 0x20, ERRATA_X2_2017096}, |
| 363 | [2] = {2058056, 0x00, 0x20, ERRATA_X2_2058056}, |
| 364 | [3] = {2081180, 0x00, 0x20, ERRATA_X2_2081180}, |
| 365 | [4] = {2083908, 0x00, 0x20, ERRATA_X2_2083908}, |
| 366 | [5] = {2147715, 0x20, 0x20, ERRATA_X2_2147715}, |
| 367 | [6] = {2216384, 0x00, 0x20, ERRATA_X2_2216384}, |
| 368 | [7] = {2282622, 0x00, 0x21, ERRATA_X2_2282622}, |
| 369 | [8] = {2371105, 0x00, 0x21, ERRATA_X2_2371105}, |
Sona Mathew | c5b386d | 2023-03-14 16:50:36 -0500 | [diff] [blame] | 370 | [9] = {2701952, 0x00, 0x21, ERRATA_X2_2701952, \ |
| 371 | ERRATA_NON_ARM_INTERCONNECT}, |
| 372 | [10] = {2768515, 0x00, 0x21, ERRATA_X2_2768515}, |
| 373 | [11 ... ERRATA_LIST_END] = UNDEF_ERRATA, |
Sona Mathew | 7fe0352 | 2022-11-18 18:05:38 -0600 | [diff] [blame] | 374 | } |
| 375 | }, |
| 376 | #endif /* CORTEX_X2_H_INC */ |
| 377 | |
| 378 | #if CORTEX_A510_H_INC |
| 379 | { |
| 380 | .cpu_partnumber = CORTEX_A510_MIDR, |
| 381 | .cpu_errata_list = { |
| 382 | [0] = {1922240, 0x00, 0x00, ERRATA_A510_1922240}, |
| 383 | [1] = {2041909, 0x02, 0x02, ERRATA_A510_2041909}, |
| 384 | [2] = {2042739, 0x00, 0x02, ERRATA_A510_2042739}, |
| 385 | [3] = {2172148, 0x00, 0x10, ERRATA_A510_2172148}, |
| 386 | [4] = {2218950, 0x00, 0x10, ERRATA_A510_2218950}, |
| 387 | [5] = {2250311, 0x00, 0x10, ERRATA_A510_2250311}, |
| 388 | [6] = {2288014, 0x00, 0x10, ERRATA_A510_2288014}, |
| 389 | [7] = {2347730, 0x00, 0x11, ERRATA_A510_2347730}, |
| 390 | [8] = {2371937, 0x00, 0x11, ERRATA_A510_2371937}, |
| 391 | [9] = {2666669, 0x00, 0x11, ERRATA_A510_2666669}, |
| 392 | [10] = {2684597, 0x00, 0x12, ERRATA_A510_2684597}, |
| 393 | [11 ... ERRATA_LIST_END] = UNDEF_ERRATA, |
| 394 | } |
| 395 | }, |
| 396 | #endif /* CORTEX_A510_H_INC */ |
Sona Mathew | c5b386d | 2023-03-14 16:50:36 -0500 | [diff] [blame] | 397 | |
| 398 | #if NEOVERSE_V2_H_INC |
| 399 | { |
| 400 | .cpu_partnumber = NEOVERSE_V2_MIDR, |
| 401 | .cpu_errata_list = { |
| 402 | [0] = {2719103, 0x00, 0x01, ERRATA_V2_2719103, \ |
| 403 | ERRATA_NON_ARM_INTERCONNECT}, |
Moritz Fischer | 9887006 | 2023-07-06 00:01:23 +0000 | [diff] [blame] | 404 | [1] = {2801372, 0x00, 0x01, ERRATA_V2_2801372}, |
| 405 | [2 ... ERRATA_LIST_END] = UNDEF_ERRATA, |
Sona Mathew | c5b386d | 2023-03-14 16:50:36 -0500 | [diff] [blame] | 406 | } |
| 407 | }, |
| 408 | #endif /* NEOVERSE_V2_H_INC */ |
| 409 | |
| 410 | #if CORTEX_A715_H_INC |
| 411 | { |
Harrison Mutai | e5004c1 | 2023-05-23 17:28:03 +0100 | [diff] [blame] | 412 | .cpu_partnumber = CORTEX_A715_MIDR, |
Sona Mathew | c5b386d | 2023-03-14 16:50:36 -0500 | [diff] [blame] | 413 | .cpu_errata_list = { |
| 414 | [0] = {2701951, 0x00, 0x11, ERRATA_A715_2701951, \ |
| 415 | ERRATA_NON_ARM_INTERCONNECT}, |
| 416 | [1 ... ERRATA_LIST_END] = UNDEF_ERRATA, |
| 417 | } |
| 418 | }, |
| 419 | #endif /* CORTEX_A715_H_INC */ |
Sona Mathew | 7fe0352 | 2022-11-18 18:05:38 -0600 | [diff] [blame] | 420 | }; |
| 421 | |
| 422 | /* |
| 423 | * Function to do binary search and check for the specific errata ID |
| 424 | * in the array of structures specific to the cpu identified. |
| 425 | */ |
Sona Mathew | 5a4c9fc | 2023-03-14 14:02:03 -0500 | [diff] [blame] | 426 | int32_t binary_search(struct em_cpu_list *ptr, uint32_t erratum_id, uint8_t rxpx_val) |
Sona Mathew | 7fe0352 | 2022-11-18 18:05:38 -0600 | [diff] [blame] | 427 | { |
| 428 | int low_index = 0U, mid_index = 0U; |
| 429 | |
| 430 | int high_index = MAX_ERRATA_ENTRIES - 1; |
| 431 | |
Sona Mathew | 5a4c9fc | 2023-03-14 14:02:03 -0500 | [diff] [blame] | 432 | assert(ptr != NULL); |
| 433 | |
| 434 | /* |
| 435 | * Pointer to the errata list of the cpu that matches |
| 436 | * extracted partnumber in the cpu list |
| 437 | */ |
| 438 | struct em_cpu *erratum_ptr = NULL; |
| 439 | |
Sona Mathew | 7fe0352 | 2022-11-18 18:05:38 -0600 | [diff] [blame] | 440 | while (low_index <= high_index) { |
| 441 | mid_index = (low_index + high_index) / 2; |
Sona Mathew | 5a4c9fc | 2023-03-14 14:02:03 -0500 | [diff] [blame] | 442 | |
| 443 | erratum_ptr = &ptr->cpu_errata_list[mid_index]; |
| 444 | assert(erratum_ptr != NULL); |
| 445 | |
| 446 | if (erratum_id < erratum_ptr->em_errata_id) { |
Sona Mathew | 7fe0352 | 2022-11-18 18:05:38 -0600 | [diff] [blame] | 447 | high_index = mid_index - 1; |
Sona Mathew | 5a4c9fc | 2023-03-14 14:02:03 -0500 | [diff] [blame] | 448 | } else if (erratum_id > erratum_ptr->em_errata_id) { |
Sona Mathew | 7fe0352 | 2022-11-18 18:05:38 -0600 | [diff] [blame] | 449 | low_index = mid_index + 1; |
Sona Mathew | 5a4c9fc | 2023-03-14 14:02:03 -0500 | [diff] [blame] | 450 | } else if (erratum_id == erratum_ptr->em_errata_id) { |
| 451 | if (RXPX_RANGE(rxpx_val, erratum_ptr->em_rxpx_lo, \ |
| 452 | erratum_ptr->em_rxpx_hi)) { |
| 453 | if ((erratum_ptr->errata_enabled) && \ |
| 454 | (!(erratum_ptr->non_arm_interconnect))) { |
| 455 | return EM_HIGHER_EL_MITIGATION; |
| 456 | } |
| 457 | return EM_AFFECTED; |
Sona Mathew | 7fe0352 | 2022-11-18 18:05:38 -0600 | [diff] [blame] | 458 | } |
| 459 | return EM_NOT_AFFECTED; |
| 460 | } |
| 461 | } |
| 462 | /* no matching errata ID */ |
| 463 | return EM_UNKNOWN_ERRATUM; |
| 464 | } |
| 465 | |
| 466 | /* Function to check if the errata exists for the specific CPU and rxpx */ |
| 467 | int32_t verify_errata_implemented(uint32_t errata_id, uint32_t forward_flag) |
| 468 | { |
| 469 | /* |
| 470 | * Read MIDR value and extract the revision, variant and partnumber |
| 471 | */ |
| 472 | static uint32_t midr_val, cpu_partnum; |
| 473 | static uint8_t cpu_rxpx_val; |
| 474 | int32_t ret_val = EM_UNKNOWN_ERRATUM; |
| 475 | |
| 476 | /* Determine the number of cpu listed in the cpu list */ |
| 477 | uint8_t size_cpulist = ARRAY_SIZE(cpu_list); |
| 478 | |
| 479 | /* Read the midr reg to extract cpu, revision and variant info */ |
| 480 | midr_val = read_midr(); |
| 481 | |
| 482 | /* Extract revision and variant from the MIDR register */ |
| 483 | cpu_rxpx_val = cpu_get_rev_var(); |
| 484 | |
| 485 | /* Extract the cpu partnumber and check if the cpu is in the cpu list */ |
| 486 | cpu_partnum = EXTRACT_PARTNUM(midr_val); |
| 487 | |
| 488 | for (uint8_t i = 0; i < size_cpulist; i++) { |
| 489 | cpu_ptr = &cpu_list[i]; |
| 490 | uint16_t partnum_extracted = EXTRACT_PARTNUM(cpu_ptr->cpu_partnumber); |
| 491 | |
| 492 | if (partnum_extracted == cpu_partnum) { |
| 493 | /* |
| 494 | * If the midr value is in the cpu list, binary search |
| 495 | * for the errata ID and specific revision in the list. |
| 496 | */ |
| 497 | ret_val = binary_search(cpu_ptr, errata_id, cpu_rxpx_val); |
| 498 | break; |
| 499 | } |
| 500 | } |
| 501 | return ret_val; |
| 502 | } |
| 503 | |
| 504 | /* Predicate indicating that a function id is part of EM_ABI */ |
| 505 | bool is_errata_fid(uint32_t smc_fid) |
| 506 | { |
| 507 | return ((smc_fid == ARM_EM_VERSION) || |
| 508 | (smc_fid == ARM_EM_FEATURES) || |
| 509 | (smc_fid == ARM_EM_CPU_ERRATUM_FEATURES)); |
| 510 | |
| 511 | } |
| 512 | |
| 513 | bool validate_spsr_mode(void) |
| 514 | { |
| 515 | /* In AArch64, if the caller is EL1, return true */ |
| 516 | |
| 517 | #if __aarch64__ |
| 518 | if (GET_EL(read_spsr_el3()) == MODE_EL1) { |
| 519 | return true; |
| 520 | } |
| 521 | return false; |
| 522 | #else |
| 523 | |
| 524 | /* In AArch32, if in system/svc mode, return true */ |
| 525 | uint8_t read_el_state = GET_M32(read_spsr()); |
| 526 | |
| 527 | if ((read_el_state == (MODE32_svc)) || (read_el_state == MODE32_sys)) { |
| 528 | return true; |
| 529 | } |
| 530 | return false; |
| 531 | #endif /* __aarch64__ */ |
| 532 | } |
| 533 | |
| 534 | uintptr_t errata_abi_smc_handler(uint32_t smc_fid, u_register_t x1, |
| 535 | u_register_t x2, u_register_t x3, u_register_t x4, |
| 536 | void *cookie, void *handle, u_register_t flags) |
| 537 | { |
| 538 | int32_t ret_id = EM_UNKNOWN_ERRATUM; |
| 539 | |
| 540 | switch (smc_fid) { |
| 541 | case ARM_EM_VERSION: |
| 542 | SMC_RET1(handle, MAKE_SMCCC_VERSION( |
| 543 | EM_VERSION_MAJOR, EM_VERSION_MINOR |
| 544 | )); |
| 545 | break; /* unreachable */ |
| 546 | case ARM_EM_FEATURES: |
| 547 | if (is_errata_fid((uint32_t)x1)) { |
| 548 | SMC_RET1(handle, EM_SUCCESS); |
| 549 | } |
| 550 | |
| 551 | SMC_RET1(handle, EM_NOT_SUPPORTED); |
| 552 | break; /* unreachable */ |
| 553 | case ARM_EM_CPU_ERRATUM_FEATURES: |
| 554 | |
| 555 | /* |
| 556 | * If the forward flag is greater than zero and the calling EL |
| 557 | * is EL1 in AArch64 or in system mode or svc mode in case of AArch32, |
| 558 | * return Invalid Parameters. |
| 559 | */ |
| 560 | if (((uint32_t)x2 != 0) && (validate_spsr_mode())) { |
| 561 | SMC_RET1(handle, EM_INVALID_PARAMETERS); |
| 562 | } |
| 563 | ret_id = verify_errata_implemented((uint32_t)x1, (uint32_t)x2); |
| 564 | SMC_RET1(handle, ret_id); |
| 565 | break; /* unreachable */ |
| 566 | default: |
| 567 | { |
| 568 | WARN("Unimplemented Errata ABI Service Call: 0x%x\n", smc_fid); |
| 569 | SMC_RET1(handle, EM_UNKNOWN_ERRATUM); |
| 570 | break; /* unreachable */ |
| 571 | } |
| 572 | } |
| 573 | } |