xref: /rk3399_ARM-atf/services/std_svc/errata_abi/errata_abi_main.c (revision ffb7742125def3e0acca4c7e4d3215af5ce25a31)
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